Merge "Text scroller renderer bug fix" into devel/master
[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       } // switch
220     } // map not empty
221     else
222     {
223       switch( type )
224       {
225         case FontStyle::DEFAULT:
226         {
227           controller->SetDefaultFontWeight( TextAbstraction::FontWeight::NONE );
228           controller->SetDefaultFontWidth( TextAbstraction::FontWidth::NONE );
229           controller->SetDefaultFontSlant( TextAbstraction::FontSlant::NONE );
230           break;
231         }
232         case FontStyle::INPUT:
233         {
234           controller->SetInputFontWeight( TextAbstraction::FontWeight::NONE );
235           controller->SetInputFontWidth( TextAbstraction::FontWidth::NONE );
236           controller->SetInputFontSlant( TextAbstraction::FontSlant::NONE );
237           break;
238         }
239       } // switch
240     } // map.Empty()
241   } // controller
242 }
243
244 void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type )
245 {
246   if( controller )
247   {
248     const bool isDefaultStyle = FontStyle::DEFAULT == type;
249     const bool isSetbyString = controller->IsFontStyleSetByString();
250
251     bool weightDefined = false;
252     bool widthDefined = false;
253     bool slantDefined = false;
254     FontWeight weight = TextAbstraction::FontWeight::NONE;
255     FontWidth width = TextAbstraction::FontWidth::NONE;
256     FontSlant slant = TextAbstraction::FontSlant::NONE;
257
258     if( isDefaultStyle )
259     {
260       weightDefined = controller->IsDefaultFontWeightDefined();
261       widthDefined = controller->IsDefaultFontWidthDefined();
262       slantDefined = controller->IsDefaultFontSlantDefined();
263
264       if( weightDefined )
265       {
266         weight = controller->GetDefaultFontWeight();
267       }
268
269       if( widthDefined )
270       {
271         width = controller->GetDefaultFontWidth();
272       }
273
274       if( slantDefined )
275       {
276         slant = controller->GetDefaultFontSlant();
277       }
278     }
279     else
280     {
281       weightDefined = controller->IsInputFontWeightDefined();
282       widthDefined = controller->IsInputFontWidthDefined();
283       slantDefined = controller->IsInputFontSlantDefined();
284
285       if( weightDefined )
286       {
287         weight = controller->GetInputFontWeight();
288       }
289
290       if( widthDefined )
291       {
292         width = controller->GetInputFontWidth();
293       }
294
295       if( slantDefined )
296       {
297         slant = controller->GetInputFontSlant();
298       }
299     }
300
301     if( !isSetbyString )
302     {
303       Property::Map map;
304
305       if( weightDefined )
306       {
307         if( TextAbstraction::FontWeight::NONE != weight )
308         {
309           const std::string weightStr( GetEnumerationName( weight,
310                                                           FONT_WEIGHT_STRING_TABLE,
311                                                           FONT_WEIGHT_STRING_TABLE_COUNT ) );
312
313           map.Insert( WEIGHT_KEY, weightStr );
314         }
315       }
316
317       if( widthDefined )
318       {
319         if( TextAbstraction::FontWidth::NONE != width )
320         {
321           const std::string widthStr( GetEnumerationName( width,
322                                                           FONT_WIDTH_STRING_TABLE,
323                                                           FONT_WIDTH_STRING_TABLE_COUNT ) );
324
325           map.Insert( WIDTH_KEY, widthStr );
326         }
327       }
328
329       if( slantDefined )
330       {
331         if( TextAbstraction::FontSlant::NONE != slant )
332         {
333           const std::string slantStr( GetEnumerationName( slant,
334                                                           FONT_SLANT_STRING_TABLE,
335                                                           FONT_SLANT_STRING_TABLE_COUNT ) );
336
337           map.Insert( SLANT_KEY, slantStr );
338         }
339       }
340
341       value = map;
342     } // SetbyMAP
343     else
344     {
345       std::string fontStyleProperties = "{";
346
347       if( weightDefined )
348       {
349         if( TextAbstraction::FontWeight::NONE != weight )
350         {
351           const std::string weightStr( GetEnumerationName( weight,
352                                                           FONT_WEIGHT_STRING_TABLE,
353                                                           FONT_WEIGHT_STRING_TABLE_COUNT ) );
354
355           fontStyleProperties += "\"weight\":\"" + weightStr + "\",";
356         }
357       }
358
359       if( widthDefined )
360       {
361         if( TextAbstraction::FontWidth::NONE != width )
362         {
363           const std::string widthStr( GetEnumerationName( width,
364                                                           FONT_WIDTH_STRING_TABLE,
365                                                           FONT_WIDTH_STRING_TABLE_COUNT ) );
366           fontStyleProperties += "\"width\":\"" + widthStr + "\",";
367         }
368       }
369
370       if( slantDefined )
371       {
372         if( TextAbstraction::FontSlant::NONE != slant )
373         {
374           const std::string slantStr( GetEnumerationName( slant,
375                                                           FONT_SLANT_STRING_TABLE,
376                                                           FONT_SLANT_STRING_TABLE_COUNT ) );
377
378           fontStyleProperties += "\"slant\":\"" + slantStr + "\"";
379         }
380       }
381
382       // If last character is comma, it will be removed.
383       if((*fontStyleProperties.rbegin()) == ',' )
384       {
385         fontStyleProperties = fontStyleProperties.substr( 0, fontStyleProperties.size()-1 );
386       }
387       fontStyleProperties += "}";
388
389       value = fontStyleProperties;
390     } // SetbyString
391   }// controller
392 }
393
394 FontWeight StringToWeight( const char* const weightStr )
395 {
396   FontWeight weight = TextAbstraction::FontWeight::NORMAL;
397   Scripting::GetEnumeration<FontWeight>( weightStr,
398                                          FONT_WEIGHT_STRING_TABLE,
399                                          FONT_WEIGHT_STRING_TABLE_COUNT,
400                                          weight );
401
402   return weight;
403 }
404
405 FontWidth StringToWidth( const char* const widthStr )
406 {
407   FontWidth width = TextAbstraction::FontWidth::NORMAL;
408   Scripting::GetEnumeration<FontWidth>( widthStr,
409                                         FONT_WIDTH_STRING_TABLE,
410                                         FONT_WIDTH_STRING_TABLE_COUNT,
411                                         width );
412
413   return width;
414 }
415
416 FontSlant StringToSlant( const char* const slantStr )
417 {
418   FontSlant slant = TextAbstraction::FontSlant::NORMAL;
419   Scripting::GetEnumeration<FontSlant>( slantStr,
420                                         FONT_SLANT_STRING_TABLE,
421                                         FONT_SLANT_STRING_TABLE_COUNT,
422                                         slant );
423
424   return slant;
425 }
426
427 } // namespace Text
428
429 } // namespace Toolkit
430
431 } // namespace Dali