117268ac31e6d4d32efa8d036664736eda816290
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-font-style.cpp
1 /*
2  * Copyright (c) 2021 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/markup-processor-helper-functions.h>
26 #include <dali-toolkit/internal/text/property-string-parser.h>
27
28 namespace Dali
29 {
30 namespace Toolkit
31 {
32 namespace Text
33 {
34 namespace
35 {
36 const std::string STYLE_KEY("style");
37 const std::string WEIGHT_KEY("weight");
38 const std::string WIDTH_KEY("width");
39 const std::string SLANT_KEY("slant");
40 const std::string FAMILY_KEY("family");
41 const std::string TYPE_KEY("type");
42
43 const std::string SYSTEM_TOKEN("system");
44
45 } // namespace
46
47 void SetFontFamilyProperty(ControllerPtr controller, const Property::Value& value)
48 {
49   if(controller)
50   {
51     const std::string fontFamilyValue = value.Get<std::string>();
52
53     if(fontFamilyValue.empty())
54     {
55       // Resets the default's font family name.
56       controller->SetDefaultFontFamily("");
57       return;
58     }
59
60     Property::Map map;
61     ParsePropertyString(fontFamilyValue, map);
62
63     if(map.Empty())
64     {
65       // There is no map. The font has been passed as a font's family name with no format.
66       controller->SetDefaultFontFamily(fontFamilyValue);
67     }
68     else
69     {
70       /// Family key
71       Property::Value* familyValue = map.Find(FAMILY_KEY);
72
73       std::string fontFamilyName;
74       if(NULL != familyValue)
75       {
76         fontFamilyName = familyValue->Get<std::string>();
77       }
78
79       /// Type key
80       Property::Value* typeValue = map.Find(TYPE_KEY);
81
82       std::string typeStr;
83       if(NULL != typeValue)
84       {
85         typeStr = typeValue->Get<std::string>();
86       }
87
88       if(TokenComparison(SYSTEM_TOKEN, typeStr.c_str(), typeStr.size()))
89       {
90         controller->UpdateAfterFontChange(fontFamilyName);
91       }
92       else
93       {
94         controller->SetDefaultFontFamily(fontFamilyName);
95       }
96     }
97   }
98 }
99
100 void SetFontStyleProperty(ControllerPtr controller, const Property::Value& value, FontStyle::Type type)
101 {
102   if(controller)
103   {
104     Property::Map map;
105     if(Property::STRING == value.GetType())
106     {
107       const std::string& fontStyleProperties = value.Get<std::string>();
108
109       ParsePropertyString(fontStyleProperties, map);
110       controller->FontStyleSetByString(true);
111     }
112     else
113     {
114       map = value.Get<Property::Map>();
115       controller->FontStyleSetByString(false);
116     }
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         case FontStyle::PLACEHOLDER:
212         {
213           // Sets the placeholder text font's style values.
214           if(!weightDefined ||
215              (weightDefined && (controller->GetPlaceholderTextFontWeight() != weight)))
216           {
217             controller->SetPlaceholderTextFontWeight(weight);
218           }
219
220           if(!widthDefined ||
221              (widthDefined && (controller->GetPlaceholderTextFontWidth() != width)))
222           {
223             controller->SetPlaceholderTextFontWidth(width);
224           }
225
226           if(!slantDefined ||
227              (slantDefined && (controller->GetPlaceholderTextFontSlant() != slant)))
228           {
229             controller->SetPlaceholderTextFontSlant(slant);
230           }
231           break;
232         }
233       } // switch
234     }   // map not empty
235     else
236     {
237       switch(type)
238       {
239         case FontStyle::DEFAULT:
240         {
241           controller->SetDefaultFontWeight(TextAbstraction::FontWeight::NONE);
242           controller->SetDefaultFontWidth(TextAbstraction::FontWidth::NONE);
243           controller->SetDefaultFontSlant(TextAbstraction::FontSlant::NONE);
244           break;
245         }
246         case FontStyle::INPUT:
247         {
248           controller->SetInputFontWeight(TextAbstraction::FontWeight::NONE);
249           controller->SetInputFontWidth(TextAbstraction::FontWidth::NONE);
250           controller->SetInputFontSlant(TextAbstraction::FontSlant::NONE);
251           break;
252         }
253         case FontStyle::PLACEHOLDER:
254         {
255           controller->SetPlaceholderTextFontWeight(TextAbstraction::FontWeight::NONE);
256           controller->SetPlaceholderTextFontWidth(TextAbstraction::FontWidth::NONE);
257           controller->SetPlaceholderTextFontSlant(TextAbstraction::FontSlant::NONE);
258           break;
259         }
260       } // switch
261     }   // map.Empty()
262   }     // controller
263 }
264
265 void GetFontStyleProperty(ControllerPtr controller, Property::Value& value, FontStyle::Type type)
266 {
267   if(controller)
268   {
269     const bool isSetbyString = controller->IsFontStyleSetByString();
270
271     bool       weightDefined = false;
272     bool       widthDefined  = false;
273     bool       slantDefined  = false;
274     FontWeight weight        = TextAbstraction::FontWeight::NONE;
275     FontWidth  width         = TextAbstraction::FontWidth::NONE;
276     FontSlant  slant         = TextAbstraction::FontSlant::NONE;
277
278     switch(type)
279     {
280       case FontStyle::DEFAULT:
281       {
282         weightDefined = controller->IsDefaultFontWeightDefined();
283         widthDefined  = controller->IsDefaultFontWidthDefined();
284         slantDefined  = controller->IsDefaultFontSlantDefined();
285
286         if(weightDefined)
287         {
288           weight = controller->GetDefaultFontWeight();
289         }
290
291         if(widthDefined)
292         {
293           width = controller->GetDefaultFontWidth();
294         }
295
296         if(slantDefined)
297         {
298           slant = controller->GetDefaultFontSlant();
299         }
300         break;
301       }
302       case FontStyle::INPUT:
303       {
304         weightDefined = controller->IsInputFontWeightDefined();
305         widthDefined  = controller->IsInputFontWidthDefined();
306         slantDefined  = controller->IsInputFontSlantDefined();
307
308         if(weightDefined)
309         {
310           weight = controller->GetInputFontWeight();
311         }
312
313         if(widthDefined)
314         {
315           width = controller->GetInputFontWidth();
316         }
317
318         if(slantDefined)
319         {
320           slant = controller->GetInputFontSlant();
321         }
322         break;
323       }
324       case FontStyle::PLACEHOLDER:
325       {
326         // The type is FontStyle::PLACEHOLDER
327         weightDefined = controller->IsPlaceholderTextFontWeightDefined();
328         widthDefined  = controller->IsPlaceholderTextFontWidthDefined();
329         slantDefined  = controller->IsPlaceholderTextFontSlantDefined();
330
331         if(weightDefined)
332         {
333           weight = controller->GetPlaceholderTextFontWeight();
334         }
335
336         if(widthDefined)
337         {
338           width = controller->GetPlaceholderTextFontWidth();
339         }
340
341         if(slantDefined)
342         {
343           slant = controller->GetPlaceholderTextFontSlant();
344         }
345         break;
346       }
347     }
348
349     if(!isSetbyString)
350     {
351       Property::Map map;
352
353       if(weightDefined)
354       {
355         if(TextAbstraction::FontWeight::NONE != weight)
356         {
357           const std::string weightStr(GetEnumerationName(weight,
358                                                          FONT_WEIGHT_STRING_TABLE,
359                                                          FONT_WEIGHT_STRING_TABLE_COUNT));
360
361           map.Insert(WEIGHT_KEY, weightStr);
362         }
363       }
364
365       if(widthDefined)
366       {
367         if(TextAbstraction::FontWidth::NONE != width)
368         {
369           const std::string widthStr(GetEnumerationName(width,
370                                                         FONT_WIDTH_STRING_TABLE,
371                                                         FONT_WIDTH_STRING_TABLE_COUNT));
372
373           map.Insert(WIDTH_KEY, widthStr);
374         }
375       }
376
377       if(slantDefined)
378       {
379         if(TextAbstraction::FontSlant::NONE != slant)
380         {
381           const std::string slantStr(GetEnumerationName(slant,
382                                                         FONT_SLANT_STRING_TABLE,
383                                                         FONT_SLANT_STRING_TABLE_COUNT));
384
385           map.Insert(SLANT_KEY, slantStr);
386         }
387       }
388
389       value = map;
390     } // SetbyMAP
391     else
392     {
393       std::string fontStyleProperties = "{";
394
395       if(weightDefined)
396       {
397         if(TextAbstraction::FontWeight::NONE != weight)
398         {
399           const std::string weightStr(GetEnumerationName(weight,
400                                                          FONT_WEIGHT_STRING_TABLE,
401                                                          FONT_WEIGHT_STRING_TABLE_COUNT));
402
403           fontStyleProperties += "\"weight\":\"" + weightStr + "\",";
404         }
405       }
406
407       if(widthDefined)
408       {
409         if(TextAbstraction::FontWidth::NONE != width)
410         {
411           const std::string widthStr(GetEnumerationName(width,
412                                                         FONT_WIDTH_STRING_TABLE,
413                                                         FONT_WIDTH_STRING_TABLE_COUNT));
414           fontStyleProperties += "\"width\":\"" + widthStr + "\",";
415         }
416       }
417
418       if(slantDefined)
419       {
420         if(TextAbstraction::FontSlant::NONE != slant)
421         {
422           const std::string slantStr(GetEnumerationName(slant,
423                                                         FONT_SLANT_STRING_TABLE,
424                                                         FONT_SLANT_STRING_TABLE_COUNT));
425
426           fontStyleProperties += "\"slant\":\"" + slantStr + "\"";
427         }
428       }
429
430       // If last character is comma, it will be removed.
431       if((*fontStyleProperties.rbegin()) == ',')
432       {
433         fontStyleProperties = fontStyleProperties.substr(0, fontStyleProperties.size() - 1);
434       }
435       fontStyleProperties += "}";
436
437       value = fontStyleProperties;
438     } // SetbyString
439   }   // controller
440 }
441
442 FontWeight StringToWeight(const char* const weightStr)
443 {
444   FontWeight weight = TextAbstraction::FontWeight::NORMAL;
445   Scripting::GetEnumeration<FontWeight>(weightStr,
446                                         FONT_WEIGHT_STRING_TABLE,
447                                         FONT_WEIGHT_STRING_TABLE_COUNT,
448                                         weight);
449
450   return weight;
451 }
452
453 FontWidth StringToWidth(const char* const widthStr)
454 {
455   FontWidth width = TextAbstraction::FontWidth::NORMAL;
456   Scripting::GetEnumeration<FontWidth>(widthStr,
457                                        FONT_WIDTH_STRING_TABLE,
458                                        FONT_WIDTH_STRING_TABLE_COUNT,
459                                        width);
460
461   return width;
462 }
463
464 FontSlant StringToSlant(const char* const slantStr)
465 {
466   FontSlant slant = TextAbstraction::FontSlant::NORMAL;
467   Scripting::GetEnumeration<FontSlant>(slantStr,
468                                        FONT_SLANT_STRING_TABLE,
469                                        FONT_SLANT_STRING_TABLE_COUNT,
470                                        slant);
471
472   return slant;
473 }
474
475 } // namespace Text
476
477 } // namespace Toolkit
478
479 } // namespace Dali