2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/text/text-effects-style.h>
22 #include <dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h>
23 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
24 #include <dali-toolkit/internal/text/property-string-parser.h>
34 const std::string COLOR_KEY("color");
35 const std::string OFFSET_KEY("offset");
36 const std::string BLUR_RADIUS_KEY("blurRadius");
37 const std::string WIDTH_KEY("width");
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");
44 bool ParseShadowProperties(const Property::Map& shadowPropertiesMap,
49 bool& blurRadiusDefined,
52 const unsigned int numberOfItems = shadowPropertiesMap.Count();
54 // Parses and applies the style.
55 for(unsigned int index = 0u; index < numberOfItems; ++index)
57 const KeyValuePair& valueGet = shadowPropertiesMap.GetKeyValue(index);
59 if((DevelText::Shadow::Property::COLOR == valueGet.first.indexKey) || (COLOR_KEY == valueGet.first.stringKey))
64 if(valueGet.second.GetType() == Dali::Property::STRING)
66 const std::string colorStr = valueGet.second.Get<std::string>();
67 Text::ColorStringToVector4(colorStr.c_str(), colorStr.size(), color);
71 color = valueGet.second.Get<Vector4>();
74 else if((DevelText::Shadow::Property::OFFSET == valueGet.first.indexKey) || (OFFSET_KEY == valueGet.first.stringKey))
79 if(valueGet.second.GetType() == Dali::Property::STRING)
81 const std::string offsetStr = valueGet.second.Get<std::string>();
82 StringToVector2(offsetStr.c_str(), offsetStr.size(), offset);
86 offset = valueGet.second.Get<Vector2>();
89 else if((DevelText::Shadow::Property::BLUR_RADIUS == valueGet.first.indexKey) || (BLUR_RADIUS_KEY == valueGet.first.stringKey))
92 blurRadiusDefined = true;
94 if(valueGet.second.GetType() == Dali::Property::STRING)
96 const std::string blurRadiusStr = valueGet.second.Get<std::string>();
97 blurRadius = StringToFloat(blurRadiusStr.c_str());
101 blurRadius = valueGet.second.Get<float>();
106 return 0u == numberOfItems;
109 bool ParseUnderlineProperties(const Property::Map& underlinePropertiesMap,
116 const unsigned int numberOfItems = underlinePropertiesMap.Count();
118 // Parses and applies the style.
119 for(unsigned int index = 0u; index < numberOfItems; ++index)
121 const KeyValuePair& valueGet = underlinePropertiesMap.GetKeyValue(index);
123 if((DevelText::Underline::Property::ENABLE == valueGet.first.indexKey) || (ENABLE_KEY == valueGet.first.stringKey))
126 if(valueGet.second.GetType() == Dali::Property::STRING)
128 const std::string enableStr = valueGet.second.Get<std::string>();
129 enabled = Text::TokenComparison(TRUE_TOKEN, enableStr.c_str(), enableStr.size());
133 enabled = valueGet.second.Get<bool>();
136 else if((DevelText::Underline::Property::COLOR == valueGet.first.indexKey) || (COLOR_KEY == valueGet.first.stringKey))
141 if(valueGet.second.GetType() == Dali::Property::STRING)
143 const std::string colorStr = valueGet.second.Get<std::string>();
144 Text::ColorStringToVector4(colorStr.c_str(), colorStr.size(), color);
148 color = valueGet.second.Get<Vector4>();
151 else if((DevelText::Underline::Property::HEIGHT == valueGet.first.indexKey) || (HEIGHT_KEY == valueGet.first.stringKey))
154 heightDefined = true;
156 if(valueGet.second.GetType() == Dali::Property::STRING)
158 const std::string heightStr = valueGet.second.Get<std::string>();
159 height = StringToFloat(heightStr.c_str());
163 height = valueGet.second.Get<float>();
168 return 0u == numberOfItems;
171 bool ParseOutlineProperties(const Property::Map& underlinePropertiesMap,
177 const unsigned int numberOfItems = underlinePropertiesMap.Count();
179 // Parses and applies the style.
180 for(unsigned int index = 0u; index < numberOfItems; ++index)
182 const KeyValuePair& valueGet = underlinePropertiesMap.GetKeyValue(index);
184 if((DevelText::Outline::Property::COLOR == valueGet.first.indexKey) || (COLOR_KEY == valueGet.first.stringKey))
188 color = valueGet.second.Get<Vector4>();
190 else if((DevelText::Outline::Property::WIDTH == valueGet.first.indexKey) || (WIDTH_KEY == valueGet.first.stringKey))
194 width = static_cast<uint16_t>(valueGet.second.Get<float>());
198 return 0u == numberOfItems;
201 bool ParseBackgroundProperties(const Property::Map& backgroundProperties,
206 const unsigned int numberOfItems = backgroundProperties.Count();
208 // Parses and applies the style.
209 for(unsigned int index = 0u; index < numberOfItems; ++index)
211 const KeyValuePair& valueGet = backgroundProperties.GetKeyValue(index);
213 if((DevelText::Background::Property::ENABLE == valueGet.first.indexKey) || (ENABLE_KEY == valueGet.first.stringKey))
216 enabled = valueGet.second.Get<bool>();
218 else if((DevelText::Background::Property::COLOR == valueGet.first.indexKey) || (COLOR_KEY == valueGet.first.stringKey))
222 color = valueGet.second.Get<Vector4>();
226 return 0u == numberOfItems;
229 bool SetUnderlineProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
237 case EffectStyle::DEFAULT:
239 const Property::Map& propertiesMap = value.Get<Property::Map>();
241 bool enabled = false;
242 bool colorDefined = false;
244 bool heightDefined = false;
249 if(propertiesMap.Empty())
251 // Map empty so check if a string provided
252 const std::string propertyString = value.Get<std::string>();
254 if(!propertyString.empty())
256 Property::Map parsedStringMap;
257 Text::ParsePropertyString(propertyString, parsedStringMap);
259 empty = ParseUnderlineProperties(parsedStringMap,
266 controller->UnderlineSetByString(!empty);
271 empty = ParseUnderlineProperties(propertiesMap,
278 controller->UnderlineSetByString(false);
283 if(enabled != controller->IsUnderlineEnabled())
285 controller->SetUnderlineEnabled(enabled);
289 // Sets the default underline values.
290 if(colorDefined && (controller->GetUnderlineColor() != color))
292 controller->SetUnderlineColor(color);
296 if(heightDefined && (fabsf(controller->GetUnderlineHeight() - height) > Math::MACHINE_EPSILON_1000))
298 controller->SetUnderlineHeight(height);
304 // Disable underline.
305 if(controller->IsUnderlineEnabled())
307 controller->SetUnderlineEnabled(false);
313 case EffectStyle::INPUT:
315 const std::string& underlineProperties = value.Get<std::string>();
317 controller->SetInputUnderlineProperties(underlineProperties);
321 } // if( controller )
326 void GetUnderlineProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type)
332 case EffectStyle::DEFAULT:
334 const bool enabled = controller->IsUnderlineEnabled();
335 const Vector4& color = controller->GetUnderlineColor();
336 const float height = controller->GetUnderlineHeight();
338 if(controller->IsUnderlineSetByString())
340 std::string underlineProperties = "{\"enable\":";
341 const std::string enabledStr = enabled ? "true" : "false";
342 underlineProperties += "\"" + enabledStr + "\",";
344 std::string colorStr;
345 Vector4ToColorString(color, colorStr);
346 underlineProperties += "\"color\":\"" + colorStr + "\",";
348 std::string heightStr;
349 FloatToString(height, heightStr);
350 underlineProperties += "\"height\":\"" + heightStr + "\"}";
352 value = underlineProperties;
358 map.Insert(ENABLE_KEY, enabled);
359 map.Insert(COLOR_KEY, color);
360 map.Insert(HEIGHT_KEY, height);
367 case EffectStyle::INPUT:
369 value = controller->GetInputUnderlineProperties();
376 bool SetShadowProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
384 case EffectStyle::DEFAULT:
386 const Property::Map& propertiesMap = value.Get<Property::Map>();
388 bool colorDefined = false;
390 bool offsetDefined = false;
392 bool blurRadiusDefined = false;
397 if(propertiesMap.Empty())
399 // Map empty so check if a string provided
400 const std::string propertyString = value.Get<std::string>();
402 Property::Map parsedStringMap;
403 Text::ParsePropertyString(propertyString, parsedStringMap);
405 empty = ParseShadowProperties(parsedStringMap,
413 controller->ShadowSetByString(!empty);
417 empty = ParseShadowProperties(propertiesMap,
425 controller->ShadowSetByString(false);
430 // Sets the default shadow values.
431 if(colorDefined && (controller->GetShadowColor() != color))
433 controller->SetShadowColor(color);
437 if(offsetDefined && (controller->GetShadowOffset() != offset))
439 controller->SetShadowOffset(offset);
443 if(blurRadiusDefined && (controller->GetShadowBlurRadius() != blurRadius))
445 controller->SetShadowBlurRadius(blurRadius);
452 if(Vector2::ZERO != controller->GetShadowOffset())
454 controller->SetShadowOffset(Vector2::ZERO);
459 case EffectStyle::INPUT:
461 const std::string& shadowString = value.Get<std::string>();
463 controller->SetInputShadowProperties(shadowString);
467 } // if( controller )
472 void GetShadowProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type)
478 case EffectStyle::DEFAULT:
480 const Vector4& color = controller->GetShadowColor();
481 const Vector2& offset = controller->GetShadowOffset();
482 const float& blurRadius = controller->GetShadowBlurRadius();
484 if(controller->IsShadowSetByString())
486 std::string shadowProperties = "{";
488 std::string colorStr;
489 Vector4ToColorString(color, colorStr);
490 shadowProperties += "\"color\":\"" + colorStr + "\",";
492 std::string offsetStr;
493 Vector2ToString(offset, offsetStr);
494 shadowProperties += "\"offset\":\"" + offsetStr + "\",";
496 std::string blurRadiusStr;
497 FloatToString(blurRadius, blurRadiusStr);
498 shadowProperties += "\"blurRadius\":\"" + blurRadiusStr + "\"}";
500 value = shadowProperties;
506 map.Insert(COLOR_KEY, color);
507 map.Insert(OFFSET_KEY, offset);
508 map.Insert(BLUR_RADIUS_KEY, blurRadius);
514 case EffectStyle::INPUT:
516 value = controller->GetInputShadowProperties();
523 bool SetEmbossProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
529 const std::string properties = value.Get<std::string>();
533 case EffectStyle::DEFAULT:
535 // Stores the default emboss's properties string to be recovered by the GetEmbossProperties() function.
536 controller->SetDefaultEmbossProperties(properties);
539 case EffectStyle::INPUT:
541 // Stores the input emboss's properties string to be recovered by the GetEmbossProperties() function.
542 controller->SetInputEmbossProperties(properties);
551 void GetEmbossProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type)
557 case EffectStyle::DEFAULT:
559 value = controller->GetDefaultEmbossProperties();
562 case EffectStyle::INPUT:
564 value = controller->GetInputEmbossProperties();
571 bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
579 case EffectStyle::DEFAULT:
581 const Property::Map& propertiesMap = value.Get<Property::Map>();
583 bool colorDefined = false;
585 bool widthDefined = false;
590 if(propertiesMap.Empty())
592 // Map empty so check if a string provided
593 // This is purely to maintain backward compatibility, but we don't parse the string to be a property map.
594 const std::string propertyString = value.Get<std::string>();
596 // Stores the default outline's properties string to be recovered by the GetOutlineProperties() function.
597 controller->SetDefaultOutlineProperties(propertyString);
599 controller->OutlineSetByString(true);
603 empty = ParseOutlineProperties(propertiesMap,
609 controller->OutlineSetByString(false);
614 // Sets the default outline values.
615 if(colorDefined && (controller->GetOutlineColor() != color))
617 controller->SetOutlineColor(color);
621 if(widthDefined && (controller->GetOutlineWidth() != width))
623 controller->SetOutlineWidth(width);
630 if(0u != controller->GetOutlineWidth())
632 controller->SetOutlineWidth(0u);
638 case EffectStyle::INPUT:
640 const std::string& outlineProperties = value.Get<std::string>();
642 controller->SetInputOutlineProperties(outlineProperties);
646 } // if( controller )
651 void GetOutlineProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type)
657 case EffectStyle::DEFAULT:
659 if(controller->IsOutlineSetByString())
661 value = controller->GetDefaultOutlineProperties();
666 const Vector4& color = controller->GetOutlineColor();
667 const uint16_t width = controller->GetOutlineWidth();
670 map.Insert(COLOR_KEY, color);
671 map.Insert(WIDTH_KEY, static_cast<int>(width));
678 case EffectStyle::INPUT:
680 value = controller->GetInputOutlineProperties();
687 bool SetBackgroundProperties(ControllerPtr controller, const Property::Value& value, EffectStyle::Type type)
695 case EffectStyle::DEFAULT:
697 const Property::Map& propertiesMap = value.Get<Property::Map>();
699 bool enabled = false;
700 bool colorDefined = false;
705 if(!propertiesMap.Empty())
707 empty = ParseBackgroundProperties(propertiesMap,
715 if(enabled != controller->IsBackgroundEnabled())
717 controller->SetBackgroundEnabled(enabled);
721 if(colorDefined && (controller->GetBackgroundColor() != color))
723 controller->SetBackgroundColor(color);
729 // Disable background.
730 if(controller->IsBackgroundEnabled())
732 controller->SetBackgroundEnabled(false);
738 case EffectStyle::INPUT:
740 // Text background is not supported while inputting yet
744 } // if( controller )
749 void GetBackgroundProperties(ControllerPtr controller, Property::Value& value, EffectStyle::Type type)
755 case EffectStyle::DEFAULT:
757 const bool enabled = controller->IsBackgroundEnabled();
758 const Vector4& color = controller->GetBackgroundColor();
761 map.Insert(ENABLE_KEY, enabled);
762 map.Insert(COLOR_KEY, color);
768 case EffectStyle::INPUT:
770 // Text background is not supported while inputting yet
779 } // namespace Toolkit