Implement Placeholder additional property
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-font-style.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // FILE HEADER
19 #include <dali-toolkit/internal/text/text-font-style.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/internal/text/property-string-parser.h>
26 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
27
28 namespace Dali
29 {
30
31 namespace Toolkit
32 {
33
34 namespace Text
35 {
36
37 namespace
38 {
39 const std::string STYLE_KEY( "style" );
40 const std::string WEIGHT_KEY( "weight" );
41 const std::string WIDTH_KEY( "width" );
42 const std::string SLANT_KEY( "slant" );
43 const std::string FAMILY_KEY( "family" );
44 const std::string TYPE_KEY( "type" );
45
46 const std::string SYSTEM_TOKEN( "system" );
47
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
50 #endif
51
52 } // namespace
53
54 void SetFontFamilyProperty( ControllerPtr controller, const Property::Value& value )
55 {
56   if( controller )
57   {
58     const std::string fontFamilyValue = value.Get<std::string>();
59
60     if( fontFamilyValue.empty() )
61     {
62       // Resets the default's font family name.
63       controller->SetDefaultFontFamily( "" );
64       return;
65     }
66
67     Property::Map map;
68     ParsePropertyString( fontFamilyValue, map );
69
70     if( map.Empty() )
71     {
72       // There is no map. The font has been passed as a font's family name with no format.
73       controller->SetDefaultFontFamily( fontFamilyValue );
74     }
75     else
76     {
77       /// Family key
78       Property::Value* familyValue = map.Find( FAMILY_KEY );
79
80       std::string fontFamilyName;
81       if( NULL != familyValue )
82       {
83         fontFamilyName = familyValue->Get<std::string>();
84       }
85
86       /// Type key
87       Property::Value* typeValue = map.Find( TYPE_KEY );
88
89       std::string typeStr;
90       if( NULL != typeValue )
91       {
92         typeStr = typeValue->Get<std::string>();
93       }
94
95       if( TokenComparison( SYSTEM_TOKEN, typeStr.c_str(), typeStr.size() ) )
96       {
97         controller->UpdateAfterFontChange( fontFamilyName );
98       }
99       else
100       {
101         controller->SetDefaultFontFamily( fontFamilyName );
102       }
103     }
104   }
105 }
106
107 void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type )
108 {
109   if( controller )
110   {
111     Property::Map map;
112     if( Property::STRING == value.GetType() )
113     {
114       const std::string& fontStyleProperties = value.Get<std::string>();
115
116       ParsePropertyString( fontStyleProperties, map );
117       controller->FontStyleSetByString( true );
118
119     }
120     else
121     {
122       map = value.Get<Property::Map>();
123       controller->FontStyleSetByString( false );
124     }
125
126     if( !map.Empty() )
127     {
128       /// Weight key
129       Property::Value* weightValue = map.Find( WEIGHT_KEY );
130
131       FontWeight weight = TextAbstraction::FontWeight::NONE;
132       const bool weightDefined = weightValue != NULL;
133       if( weightDefined )
134       {
135         const std::string weightStr = weightValue->Get<std::string>();
136
137         Scripting::GetEnumeration< FontWeight >( weightStr.c_str(),
138                                                  FONT_WEIGHT_STRING_TABLE,
139                                                  FONT_WEIGHT_STRING_TABLE_COUNT,
140                                                  weight );
141       }
142
143       /// Width key
144       Property::Value* widthValue = map.Find( WIDTH_KEY );
145
146       FontWidth width = TextAbstraction::FontWidth::NONE;
147       const bool widthDefined = widthValue != NULL;
148       if( widthDefined )
149       {
150         const std::string widthStr = widthValue->Get<std::string>();
151
152         Scripting::GetEnumeration< FontWidth >( widthStr.c_str(),
153                                                 FONT_WIDTH_STRING_TABLE,
154                                                 FONT_WIDTH_STRING_TABLE_COUNT,
155                                                 width );
156       }
157
158       /// Slant key
159       Property::Value* slantValue = map.Find( SLANT_KEY );
160
161       FontSlant slant = TextAbstraction::FontSlant::NONE;
162       const bool slantDefined = slantValue != NULL;
163       if( slantDefined )
164       {
165         const std::string slantStr = slantValue->Get<std::string>();
166
167         Scripting::GetEnumeration< FontSlant >( slantStr.c_str(),
168                                                 FONT_SLANT_STRING_TABLE,
169                                                 FONT_SLANT_STRING_TABLE_COUNT,
170                                                 slant );
171       }
172
173       switch( type )
174       {
175         case FontStyle::DEFAULT:
176         {
177           // Sets the default font's style values.
178           if( !weightDefined ||
179               ( weightDefined && ( controller->GetDefaultFontWeight() != weight ) ) )
180           {
181             controller->SetDefaultFontWeight( weight );
182           }
183
184           if( !widthDefined ||
185               ( widthDefined && ( controller->GetDefaultFontWidth() != width ) ) )
186           {
187             controller->SetDefaultFontWidth( width );
188           }
189
190           if( !slantDefined ||
191               ( slantDefined && ( controller->GetDefaultFontSlant() != slant ) ) )
192           {
193             controller->SetDefaultFontSlant( slant );
194           }
195           break;
196         }
197         case FontStyle::INPUT:
198         {
199           // Sets the input font's style values.
200           if( !weightDefined ||
201               ( weightDefined && ( controller->GetInputFontWeight() != weight ) ) )
202           {
203             controller->SetInputFontWeight( weight );
204           }
205
206           if( !widthDefined ||
207               ( widthDefined && ( controller->GetInputFontWidth() != width ) ) )
208           {
209             controller->SetInputFontWidth( width );
210           }
211
212           if( !slantDefined ||
213               ( slantDefined && ( controller->GetInputFontSlant() != slant ) ) )
214           {
215             controller->SetInputFontSlant( slant );
216           }
217           break;
218         }
219         case FontStyle::PLACEHOLDER:
220         {
221           // Sets the placeholder text font's style values.
222           if( !weightDefined ||
223               ( weightDefined && ( controller->GetPlaceholderTextFontWeight() != weight ) ) )
224           {
225             controller->SetPlaceholderTextFontWeight( weight );
226           }
227
228           if( !widthDefined ||
229               ( widthDefined && ( controller->GetPlaceholderTextFontWidth() != width ) ) )
230           {
231             controller->SetPlaceholderTextFontWidth( width );
232           }
233
234           if( !slantDefined ||
235               ( slantDefined && ( controller->GetPlaceholderTextFontSlant() != slant ) ) )
236           {
237             controller->SetPlaceholderTextFontSlant( slant );
238           }
239           break;
240         }
241       } // switch
242     } // map not empty
243     else
244     {
245       switch( type )
246       {
247         case FontStyle::DEFAULT:
248         {
249           controller->SetDefaultFontWeight( TextAbstraction::FontWeight::NONE );
250           controller->SetDefaultFontWidth( TextAbstraction::FontWidth::NONE );
251           controller->SetDefaultFontSlant( TextAbstraction::FontSlant::NONE );
252           break;
253         }
254         case FontStyle::INPUT:
255         {
256           controller->SetInputFontWeight( TextAbstraction::FontWeight::NONE );
257           controller->SetInputFontWidth( TextAbstraction::FontWidth::NONE );
258           controller->SetInputFontSlant( TextAbstraction::FontSlant::NONE );
259           break;
260         }
261         case FontStyle::PLACEHOLDER:
262         {
263           controller->SetPlaceholderTextFontWeight( TextAbstraction::FontWeight::NONE );
264           controller->SetPlaceholderTextFontWidth( TextAbstraction::FontWidth::NONE );
265           controller->SetPlaceholderTextFontSlant( TextAbstraction::FontSlant::NONE );
266           break;
267         }
268       } // switch
269     } // map.Empty()
270   } // controller
271 }
272
273 void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type )
274 {
275   if( controller )
276   {
277     const bool isSetbyString = controller->IsFontStyleSetByString();
278
279     bool weightDefined = false;
280     bool widthDefined = false;
281     bool slantDefined = false;
282     FontWeight weight = TextAbstraction::FontWeight::NONE;
283     FontWidth width = TextAbstraction::FontWidth::NONE;
284     FontSlant slant = TextAbstraction::FontSlant::NONE;
285
286     switch( type )
287     {
288       case FontStyle::DEFAULT:
289       {
290         weightDefined = controller->IsDefaultFontWeightDefined();
291         widthDefined = controller->IsDefaultFontWidthDefined();
292         slantDefined = controller->IsDefaultFontSlantDefined();
293
294         if( weightDefined )
295         {
296           weight = controller->GetDefaultFontWeight();
297         }
298
299         if( widthDefined )
300         {
301           width = controller->GetDefaultFontWidth();
302         }
303
304         if( slantDefined )
305         {
306           slant = controller->GetDefaultFontSlant();
307         }
308         break;
309       }
310       case FontStyle::INPUT:
311       {
312         weightDefined = controller->IsInputFontWeightDefined();
313         widthDefined = controller->IsInputFontWidthDefined();
314         slantDefined = controller->IsInputFontSlantDefined();
315
316         if( weightDefined )
317         {
318           weight = controller->GetInputFontWeight();
319         }
320
321         if( widthDefined )
322         {
323           width = controller->GetInputFontWidth();
324         }
325
326         if( slantDefined )
327         {
328           slant = controller->GetInputFontSlant();
329         }
330         break;
331       }
332       case FontStyle::PLACEHOLDER:
333       {
334         // The type is FontStyle::PLACEHOLDER
335         weightDefined = controller->IsPlaceholderTextFontWeightDefined();
336         widthDefined = controller->IsPlaceholderTextFontWidthDefined();
337         slantDefined = controller->IsPlaceholderTextFontSlantDefined();
338
339         if( weightDefined )
340         {
341           weight = controller->GetPlaceholderTextFontWeight();
342         }
343
344         if( widthDefined )
345         {
346           width = controller->GetPlaceholderTextFontWidth();
347         }
348
349         if( slantDefined )
350         {
351           slant = controller->GetPlaceholderTextFontSlant();
352         }
353         break;
354       }
355     }
356
357     if( !isSetbyString )
358     {
359       Property::Map map;
360
361       if( weightDefined )
362       {
363         if( TextAbstraction::FontWeight::NONE != weight )
364         {
365           const std::string weightStr( GetEnumerationName( weight,
366                                                           FONT_WEIGHT_STRING_TABLE,
367                                                           FONT_WEIGHT_STRING_TABLE_COUNT ) );
368
369           map.Insert( WEIGHT_KEY, weightStr );
370         }
371       }
372
373       if( widthDefined )
374       {
375         if( TextAbstraction::FontWidth::NONE != width )
376         {
377           const std::string widthStr( GetEnumerationName( width,
378                                                           FONT_WIDTH_STRING_TABLE,
379                                                           FONT_WIDTH_STRING_TABLE_COUNT ) );
380
381           map.Insert( WIDTH_KEY, widthStr );
382         }
383       }
384
385       if( slantDefined )
386       {
387         if( TextAbstraction::FontSlant::NONE != slant )
388         {
389           const std::string slantStr( GetEnumerationName( slant,
390                                                           FONT_SLANT_STRING_TABLE,
391                                                           FONT_SLANT_STRING_TABLE_COUNT ) );
392
393           map.Insert( SLANT_KEY, slantStr );
394         }
395       }
396
397       value = map;
398     } // SetbyMAP
399     else
400     {
401       std::string fontStyleProperties = "{";
402
403       if( weightDefined )
404       {
405         if( TextAbstraction::FontWeight::NONE != weight )
406         {
407           const std::string weightStr( GetEnumerationName( weight,
408                                                           FONT_WEIGHT_STRING_TABLE,
409                                                           FONT_WEIGHT_STRING_TABLE_COUNT ) );
410
411           fontStyleProperties += "\"weight\":\"" + weightStr + "\",";
412         }
413       }
414
415       if( widthDefined )
416       {
417         if( TextAbstraction::FontWidth::NONE != width )
418         {
419           const std::string widthStr( GetEnumerationName( width,
420                                                           FONT_WIDTH_STRING_TABLE,
421                                                           FONT_WIDTH_STRING_TABLE_COUNT ) );
422           fontStyleProperties += "\"width\":\"" + widthStr + "\",";
423         }
424       }
425
426       if( slantDefined )
427       {
428         if( TextAbstraction::FontSlant::NONE != slant )
429         {
430           const std::string slantStr( GetEnumerationName( slant,
431                                                           FONT_SLANT_STRING_TABLE,
432                                                           FONT_SLANT_STRING_TABLE_COUNT ) );
433
434           fontStyleProperties += "\"slant\":\"" + slantStr + "\"";
435         }
436       }
437
438       // If last character is comma, it will be removed.
439       if((*fontStyleProperties.rbegin()) == ',' )
440       {
441         fontStyleProperties = fontStyleProperties.substr( 0, fontStyleProperties.size()-1 );
442       }
443       fontStyleProperties += "}";
444
445       value = fontStyleProperties;
446     } // SetbyString
447   }// controller
448 }
449
450 FontWeight StringToWeight( const char* const weightStr )
451 {
452   FontWeight weight = TextAbstraction::FontWeight::NORMAL;
453   Scripting::GetEnumeration<FontWeight>( weightStr,
454                                          FONT_WEIGHT_STRING_TABLE,
455                                          FONT_WEIGHT_STRING_TABLE_COUNT,
456                                          weight );
457
458   return weight;
459 }
460
461 FontWidth StringToWidth( const char* const widthStr )
462 {
463   FontWidth width = TextAbstraction::FontWidth::NORMAL;
464   Scripting::GetEnumeration<FontWidth>( widthStr,
465                                         FONT_WIDTH_STRING_TABLE,
466                                         FONT_WIDTH_STRING_TABLE_COUNT,
467                                         width );
468
469   return width;
470 }
471
472 FontSlant StringToSlant( const char* const slantStr )
473 {
474   FontSlant slant = TextAbstraction::FontSlant::NORMAL;
475   Scripting::GetEnumeration<FontSlant>( slantStr,
476                                         FONT_SLANT_STRING_TABLE,
477                                         FONT_SLANT_STRING_TABLE_COUNT,
478                                         slant );
479
480   return slant;
481 }
482
483 } // namespace Text
484
485 } // namespace Toolkit
486
487 } // namespace Dali