Merge "Added code for stylable transitions" 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     const std::string style = value.Get< std::string >();
112     DALI_LOG_INFO( gLogFilter, Debug::General, "Text Control %p FONT_STYLE %s\n", controller.Get(), style.c_str() );
113
114     // Parses and applies the style.
115     Property::Map map;
116     ParsePropertyString( style, map );
117
118     if( !map.Empty() )
119     {
120       /// Weight key
121       Property::Value* weightValue = map.Find( WEIGHT_KEY );
122
123       FontWeight weight = TextAbstraction::FontWeight::NONE;
124       const bool weightDefined = weightValue != NULL;
125       if( weightDefined )
126       {
127         const std::string weightStr = weightValue->Get<std::string>();
128
129         Scripting::GetEnumeration< FontWeight >( weightStr.c_str(),
130                                                  FONT_WEIGHT_STRING_TABLE,
131                                                  FONT_WEIGHT_STRING_TABLE_COUNT,
132                                                  weight );
133       }
134
135       /// Width key
136       Property::Value* widthValue = map.Find( WIDTH_KEY );
137
138       FontWidth width = TextAbstraction::FontWidth::NONE;
139       const bool widthDefined = widthValue != NULL;
140       if( widthDefined )
141       {
142         const std::string widthStr = widthValue->Get<std::string>();
143
144         Scripting::GetEnumeration< FontWidth >( widthStr.c_str(),
145                                                 FONT_WIDTH_STRING_TABLE,
146                                                 FONT_WIDTH_STRING_TABLE_COUNT,
147                                                 width );
148       }
149
150       /// Slant key
151       Property::Value* slantValue = map.Find( SLANT_KEY );
152
153       FontSlant slant = TextAbstraction::FontSlant::NONE;
154       const bool slantDefined = slantValue != NULL;
155       if( slantDefined )
156       {
157         const std::string slantStr = slantValue->Get<std::string>();
158
159         Scripting::GetEnumeration< FontSlant >( slantStr.c_str(),
160                                                 FONT_SLANT_STRING_TABLE,
161                                                 FONT_SLANT_STRING_TABLE_COUNT,
162                                                 slant );
163       }
164
165       switch( type )
166       {
167         case FontStyle::DEFAULT:
168         {
169           // Sets the default font's style values.
170           if( !weightDefined ||
171               ( weightDefined && ( controller->GetDefaultFontWeight() != weight ) ) )
172           {
173             controller->SetDefaultFontWeight( weight );
174           }
175
176           if( !widthDefined ||
177               ( widthDefined && ( controller->GetDefaultFontWidth() != width ) ) )
178           {
179             controller->SetDefaultFontWidth( width );
180           }
181
182           if( !slantDefined ||
183               ( slantDefined && ( controller->GetDefaultFontSlant() != slant ) ) )
184           {
185             controller->SetDefaultFontSlant( slant );
186           }
187           break;
188         }
189         case FontStyle::INPUT:
190         {
191           // Sets the input font's style values.
192           if( !weightDefined ||
193               ( weightDefined && ( controller->GetInputFontWeight() != weight ) ) )
194           {
195             controller->SetInputFontWeight( weight );
196           }
197
198           if( !widthDefined ||
199               ( widthDefined && ( controller->GetInputFontWidth() != width ) ) )
200           {
201             controller->SetInputFontWidth( width );
202           }
203
204           if( !slantDefined ||
205               ( slantDefined && ( controller->GetInputFontSlant() != slant ) ) )
206           {
207             controller->SetInputFontSlant( slant );
208           }
209           break;
210         }
211       } // switch
212     } // map not empty
213     else
214     {
215       switch( type )
216       {
217         case FontStyle::DEFAULT:
218         {
219           controller->SetDefaultFontWeight( TextAbstraction::FontWeight::NONE );
220           controller->SetDefaultFontWidth( TextAbstraction::FontWidth::NONE );
221           controller->SetDefaultFontSlant( TextAbstraction::FontSlant::NONE );
222           break;
223         }
224         case FontStyle::INPUT:
225         {
226           controller->SetInputFontWeight( TextAbstraction::FontWeight::NONE );
227           controller->SetInputFontWidth( TextAbstraction::FontWidth::NONE );
228           controller->SetInputFontSlant( TextAbstraction::FontSlant::NONE );
229           break;
230         }
231       } // switch
232     } // map.Empty()
233   } // controller
234 }
235
236 void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type )
237 {
238   if( controller )
239   {
240     const bool isDefaultStyle = FontStyle::DEFAULT == type;
241
242     bool weightDefined = false;
243     bool widthDefined = false;
244     bool slantDefined = false;
245     FontWeight weight = TextAbstraction::FontWeight::NONE;
246     FontWidth width = TextAbstraction::FontWidth::NONE;
247     FontSlant slant = TextAbstraction::FontSlant::NONE;
248
249     if( isDefaultStyle )
250     {
251       weightDefined = controller->IsDefaultFontWeightDefined();
252       widthDefined = controller->IsDefaultFontWidthDefined();
253       slantDefined = controller->IsDefaultFontSlantDefined();
254
255       if( weightDefined )
256       {
257         weight = controller->GetDefaultFontWeight();
258       }
259
260       if( widthDefined )
261       {
262         width = controller->GetDefaultFontWidth();
263       }
264
265       if( slantDefined )
266       {
267         slant = controller->GetDefaultFontSlant();
268       }
269     }
270     else
271     {
272       weightDefined = controller->IsInputFontWeightDefined();
273       widthDefined = controller->IsInputFontWidthDefined();
274       slantDefined = controller->IsInputFontSlantDefined();
275
276       if( weightDefined )
277       {
278         weight = controller->GetInputFontWeight();
279       }
280
281       if( widthDefined )
282       {
283         width = controller->GetInputFontWidth();
284       }
285
286       if( slantDefined )
287       {
288         slant = controller->GetInputFontSlant();
289       }
290     }
291
292     if( weightDefined || widthDefined || slantDefined )
293     {
294       std::string styleString("{");
295       if( weightDefined )
296       {
297         if( TextAbstraction::FontWeight::NONE != weight )
298         {
299           const std::string weightStr( GetEnumerationName( weight,
300                                                            FONT_WEIGHT_STRING_TABLE,
301                                                            FONT_WEIGHT_STRING_TABLE_COUNT ) );
302
303           styleString += "\"weight\":\"" + weightStr + "\"";
304         }
305         else
306         {
307           weightDefined = false;
308         }
309       }
310
311       if( widthDefined )
312       {
313         if( TextAbstraction::FontWidth::NONE != width )
314         {
315           const std::string widthStr( GetEnumerationName( width,
316                                                           FONT_WIDTH_STRING_TABLE,
317                                                           FONT_WIDTH_STRING_TABLE_COUNT ) );
318
319           if( weightDefined )
320           {
321             styleString += ",";
322           }
323           styleString += "\"width\":\"" + widthStr + "\"";
324         }
325         else
326         {
327           widthDefined = false;
328         }
329       }
330
331       if( slantDefined )
332       {
333         if( TextAbstraction::FontSlant::NONE != slant )
334         {
335           const std::string slantStr( GetEnumerationName( slant,
336                                                           FONT_SLANT_STRING_TABLE,
337                                                           FONT_SLANT_STRING_TABLE_COUNT ) );
338
339           if( weightDefined || widthDefined )
340           {
341             styleString += ",";
342           }
343           styleString += "\"slant\":\"" + slantStr + "\"";
344         }
345         else
346         {
347           slantDefined = false;
348         }
349       }
350
351       if( weightDefined || widthDefined || slantDefined )
352       {
353         styleString += "}";
354       }
355       else
356       {
357         styleString.clear();
358       }
359
360       value = styleString;
361     }
362   }
363 }
364
365 FontWeight StringToWeight( const char* const weightStr )
366 {
367   FontWeight weight = TextAbstraction::FontWeight::NORMAL;
368   Scripting::GetEnumeration<FontWeight>( weightStr,
369                                          FONT_WEIGHT_STRING_TABLE,
370                                          FONT_WEIGHT_STRING_TABLE_COUNT,
371                                          weight );
372
373   return weight;
374 }
375
376 FontWidth StringToWidth( const char* const widthStr )
377 {
378   FontWidth width = TextAbstraction::FontWidth::NORMAL;
379   Scripting::GetEnumeration<FontWidth>( widthStr,
380                                         FONT_WIDTH_STRING_TABLE,
381                                         FONT_WIDTH_STRING_TABLE_COUNT,
382                                         width );
383
384   return width;
385 }
386
387 FontSlant StringToSlant( const char* const slantStr )
388 {
389   FontSlant slant = TextAbstraction::FontSlant::NORMAL;
390   Scripting::GetEnumeration<FontSlant>( slantStr,
391                                         FONT_SLANT_STRING_TABLE,
392                                         FONT_SLANT_STRING_TABLE_COUNT,
393                                         slant );
394
395   return slant;
396 }
397
398 } // namespace Text
399
400 } // namespace Toolkit
401
402 } // namespace Dali