Add U0 case to Utf8ToUtf32
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-effects-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-effects-style.h>
20
21 // INTERNAL INCLUDES
22 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
23 #include <dali-toolkit/internal/text/property-string-parser.h>
24
25 namespace Dali
26 {
27
28 namespace Toolkit
29 {
30
31 namespace Text
32 {
33
34 namespace
35 {
36 const std::string COLOR_KEY( "color" );
37 const std::string OFFSET_KEY( "offset" );
38 const std::string HEIGHT_KEY( "height" );
39 const std::string ENABLE_KEY( "enable" );
40 const std::string TRUE_TOKEN( "true" );
41 const std::string FALSE_TOKEN( "false" );
42 }
43
44 bool ParseShadowProperties( const Property::Map& shadowPropertiesMap,
45                             bool& colorDefined,
46                             Vector4& color,
47                             bool& offsetDefined,
48                             Vector2& offset )
49 {
50   const unsigned int numberOfItems = shadowPropertiesMap.Count();
51
52   // Parses and applies the style.
53   for( unsigned int index = 0u; index < numberOfItems; ++index )
54   {
55     const KeyValuePair& valueGet = shadowPropertiesMap.GetKeyValue( index );
56
57     if( COLOR_KEY == valueGet.first.stringKey )
58     {
59       /// Color key.
60       colorDefined = true;
61
62       const std::string colorStr = valueGet.second.Get<std::string>();
63
64       Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
65     }
66     else if( OFFSET_KEY == valueGet.first.stringKey )
67     {
68       /// Offset key.
69       offsetDefined = true;
70
71       const std::string offsetStr = valueGet.second.Get<std::string>();
72
73       StringToVector2( offsetStr.c_str(), offsetStr.size(), offset );
74     }
75   }
76
77   return 0u == numberOfItems;
78 }
79
80 bool ParseUnderlineProperties( const Property::Map& underlinePropertiesMap,
81                                bool& enabled,
82                                bool& colorDefined,
83                                Vector4& color,
84                                bool& heightDefined,
85                                float& height )
86 {
87   const unsigned int numberOfItems = underlinePropertiesMap.Count();
88
89   // Parses and applies the style.
90   for( unsigned int index = 0u; index < numberOfItems; ++index )
91   {
92     const KeyValuePair& valueGet = underlinePropertiesMap.GetKeyValue( index );
93
94     if( ENABLE_KEY == valueGet.first.stringKey )
95     {
96       /// Enable key.
97       const std::string enableStr = valueGet.second.Get<std::string>();
98       enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() );
99     }
100     else if( COLOR_KEY == valueGet.first.stringKey )
101     {
102       /// Color key.
103       colorDefined = true;
104
105       const std::string colorStr = valueGet.second.Get<std::string>();
106
107       Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
108     }
109     else if( HEIGHT_KEY == valueGet.first.stringKey )
110     {
111       /// Height key.
112       heightDefined = true;
113
114       const std::string heightStr = valueGet.second.Get<std::string>();
115
116       height = StringToFloat( heightStr.c_str() );
117     }
118   }
119
120   return 0u == numberOfItems;
121 }
122
123 bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
124 {
125   bool update = false;
126
127   if( controller )
128   {
129     switch( type )
130     {
131       case EffectStyle::DEFAULT:
132       {
133         const Property::Map& propertiesMap = value.Get<Property::Map>();
134
135         bool enabled = false;
136         bool colorDefined = false;
137         Vector4 color;
138         bool heightDefined = false;
139         float height = 0.f;
140
141         bool empty = true;
142
143         if ( propertiesMap.Empty() )
144         {
145           // Map empty so check if a string provided
146           const std::string propertyString = value.Get<std::string>();
147
148           if ( !propertyString.empty() )
149           {
150             Property::Map parsedStringMap;
151             Text::ParsePropertyString( propertyString, parsedStringMap );
152
153             empty = ParseUnderlineProperties( parsedStringMap,
154                                               enabled,
155                                               colorDefined,
156                                               color,
157                                               heightDefined,
158                                               height );
159
160             controller->UnderlineSetByString( !empty);
161           }
162         }
163         else
164         {
165            empty = ParseUnderlineProperties( propertiesMap,
166                                              enabled,
167                                              colorDefined,
168                                              color,
169                                              heightDefined,
170                                              height );
171
172            controller->UnderlineSetByString( false );
173         }
174
175         if( !empty )
176         {
177           if( enabled != controller->IsUnderlineEnabled() )
178           {
179             controller->SetUnderlineEnabled( enabled );
180             update = true;
181           }
182
183           // Sets the default underline values.
184           if( colorDefined && ( controller->GetUnderlineColor() != color ) )
185           {
186             controller->SetUnderlineColor( color );
187             update = true;
188           }
189
190           if( heightDefined && ( fabsf( controller->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 ) )
191           {
192             controller->SetUnderlineHeight( height );
193             update = true;
194           }
195         }
196         else
197         {
198           // Disable underline.
199           if( controller->IsUnderlineEnabled() )
200           {
201             controller->SetUnderlineEnabled( false );
202             update = true;
203           }
204         }
205         break;
206       }
207       case EffectStyle::INPUT:
208       {
209         const std::string& underlineProperties = value.Get<std::string>();
210
211         controller->SetInputUnderlineProperties( underlineProperties );
212         break;
213       }
214     } // switch
215   } // if( controller )
216
217   return update;
218 }
219
220 void GetUnderlineProperties( ControllerPtr controller, Property::Value& value, EffectStyle::Type type )
221 {
222   if( controller )
223   {
224     switch( type )
225     {
226       case EffectStyle::DEFAULT:
227       {
228         const bool enabled = controller->IsUnderlineEnabled();
229         const Vector4& color = controller->GetUnderlineColor();
230         const float height = controller->GetUnderlineHeight();
231
232         if ( controller->IsUnderlineSetByString() )
233         {
234           std::string underlineProperties = "{\"enable\":";
235           const std::string enabledStr = enabled ? "true" : "false";
236           underlineProperties += "\"" + enabledStr + "\",";
237
238           std::string colorStr;
239           Vector4ToColorString( color, colorStr );
240           underlineProperties += "\"color\":\"" + colorStr + "\",";
241
242           std::string heightStr;
243           FloatToString( height, heightStr );
244           underlineProperties += "\"height\":\"" + heightStr + "\"}";
245
246           value = underlineProperties;
247         }
248         else
249         {
250           Property::Map map;
251
252           const std::string enabledStr = enabled ? TRUE_TOKEN : FALSE_TOKEN;
253           map.Insert( ENABLE_KEY, enabledStr );
254
255           std::string colorStr;
256           Vector4ToColorString( color, colorStr );
257           map.Insert( COLOR_KEY, colorStr );
258
259           std::string heightStr;
260           FloatToString( height, heightStr );
261           map.Insert( HEIGHT_KEY, heightStr );
262
263           value = map;
264         }
265
266         break;
267       }
268       case EffectStyle::INPUT:
269       {
270         value = controller->GetInputUnderlineProperties();
271         break;
272       }
273     }
274   }
275 }
276
277 bool SetShadowProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
278 {
279   bool update = false;
280
281   if( controller )
282   {
283     switch( type )
284     {
285       case EffectStyle::DEFAULT:
286       {
287         const Property::Map& propertiesMap = value.Get<Property::Map>();
288
289         bool colorDefined = false;
290         Vector4 color;
291         bool offsetDefined = false;
292         Vector2 offset;
293
294         bool empty = true;
295
296         if ( propertiesMap.Empty() )
297         {
298            // Map empty so check if a string provided
299            const std::string propertyString = value.Get<std::string>();
300
301            Property::Map parsedStringMap;
302            Text::ParsePropertyString( propertyString, parsedStringMap );
303
304            empty = ParseShadowProperties( parsedStringMap,
305                                           colorDefined,
306                                           color,
307                                           offsetDefined,
308                                           offset );
309
310            controller->ShadowSetByString( !empty );
311
312         }
313         else
314         {
315           empty = ParseShadowProperties( propertiesMap,
316                                          colorDefined,
317                                          color,
318                                          offsetDefined,
319                                          offset );
320
321           controller->ShadowSetByString( false );
322         }
323
324         if( !empty )
325         {
326           // Sets the default shadow values.
327           if( colorDefined && ( controller->GetShadowColor() != color ) )
328           {
329             controller->SetShadowColor( color );
330             update = true;
331           }
332
333           if( offsetDefined && ( controller->GetShadowOffset() != offset ) )
334           {
335             controller->SetShadowOffset( offset );
336             update = true;
337           }
338         }
339         else
340         {
341           // Disable shadow.
342           if( Vector2::ZERO != controller->GetShadowOffset() )
343           {
344             controller->SetShadowOffset( Vector2::ZERO );
345           }
346         }
347         break;
348       }
349       case EffectStyle::INPUT:
350       {
351         const std::string& shadowString = value.Get<std::string>();
352
353         controller->SetInputShadowProperties( shadowString );
354         break;
355       }
356     } // switch
357   } // if( controller )
358
359   return update;
360 }
361
362 void GetShadowProperties( ControllerPtr controller, Property::Value& value, EffectStyle::Type type )
363 {
364   if( controller )
365   {
366     switch( type )
367     {
368       case EffectStyle::DEFAULT:
369       {
370         const Vector4& color = controller->GetShadowColor();
371         const Vector2& offset = controller->GetShadowOffset();
372
373         if ( controller->IsShadowSetByString() )
374         {
375           std::string shadowProperties = "{";
376
377           std::string colorStr;
378           Vector4ToColorString( color, colorStr );
379           shadowProperties += "\"color\":\"" + colorStr + "\",";
380
381           std::string offsetStr;
382           Vector2ToString( offset, offsetStr );
383           shadowProperties += "\"offset\":\"" + offsetStr + "\"}";
384
385           value = shadowProperties;
386         }
387         else
388         {
389           Property::Map map;
390
391           std::string colorStr;
392           Vector4ToColorString( color, colorStr );
393           map.Insert( COLOR_KEY, colorStr );
394
395           std::string offsetStr;
396           Vector2ToString( offset, offsetStr );
397           map.Insert( OFFSET_KEY, offsetStr );
398
399           value = map;
400         }
401         break;
402       }
403       case EffectStyle::INPUT:
404       {
405         value = controller->GetInputShadowProperties();
406         break;
407       }
408     }
409   }
410 }
411
412 bool SetEmbossProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
413 {
414   bool update = false;
415
416   if( controller )
417   {
418     const std::string properties = value.Get< std::string >();
419
420     switch( type )
421     {
422       case EffectStyle::DEFAULT:
423       {
424         // Stores the default emboss's properties string to be recovered by the GetEmbossProperties() function.
425         controller->SetDefaultEmbossProperties( properties );
426         break;
427       }
428       case EffectStyle::INPUT:
429       {
430         // Stores the input emboss's properties string to be recovered by the GetEmbossProperties() function.
431         controller->SetInputEmbossProperties( properties );
432         break;
433       }
434     }
435   }
436
437   return update;
438 }
439
440 void GetEmbossProperties( ControllerPtr controller, Property::Value& value, EffectStyle::Type type )
441 {
442   if( controller )
443   {
444     switch( type )
445     {
446       case EffectStyle::DEFAULT:
447       {
448         value = controller->GetDefaultEmbossProperties();
449         break;
450       }
451       case EffectStyle::INPUT:
452       {
453         value = controller->GetInputEmbossProperties();
454         break;
455       }
456     }
457   }
458 }
459
460 bool SetOutlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
461 {
462   bool update = false;
463
464   if( controller )
465   {
466     const std::string properties = value.Get< std::string >();
467
468     switch( type )
469     {
470       case EffectStyle::DEFAULT:
471       {
472         // Stores the default outline's properties string to be recovered by the GetOutlineProperties() function.
473         controller->SetDefaultOutlineProperties( properties );
474         break;
475       }
476       case EffectStyle::INPUT:
477       {
478         // Stores the input outline's properties string to be recovered by the GetOutlineProperties() function.
479         controller->SetInputOutlineProperties( properties );
480         break;
481       }
482     }
483   }
484
485   return update;
486 }
487
488 void GetOutlineProperties( ControllerPtr controller, Property::Value& value, EffectStyle::Type type )
489 {
490   if( controller )
491   {
492     switch( type )
493     {
494       case EffectStyle::DEFAULT:
495       {
496         value = controller->GetDefaultOutlineProperties();
497         break;
498       }
499       case EffectStyle::INPUT:
500       {
501         value = controller->GetInputOutlineProperties();
502         break;
503       }
504     }
505   }
506 }
507
508 } // namespace Text
509
510 } // namespace Toolkit
511
512 } // namespace Dali