2 * Copyright (c) 2022 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/markup-processor-helper-functions.h>
22 #include <dali/public-api/common/constants.h>
23 #include <dali/public-api/math/vector2.h>
36 const char WHITE_SPACE = 0x20; // ASCII value of the white space.
37 const char FIRST_UPPER_CASE = 0x41; // ASCII value of the one after the first upper case character (A).
38 const char LAST_UPPER_CASE = 0x5b; // ASCII value of the one after the last upper case character (Z).
39 const char TO_LOWER_CASE = 32; // Value to add to a upper case character to transform it into a lower case.
41 const unsigned int MAX_FLOAT_ATTRIBUTE_SIZE = 17u; ///< The maximum length of any of the possible float values. +99999.999999999f (sign, five digits, dot, nine digits, f)
43 const char WEB_COLOR_TOKEN('#');
44 const char* const HEX_COLOR_TOKEN("0x");
45 const char* const ALPHA_ONE("FF");
47 const std::string BLACK_COLOR("black");
48 const std::string WHITE_COLOR("white");
49 const std::string RED_COLOR("red");
50 const std::string GREEN_COLOR("green");
51 const std::string BLUE_COLOR("blue");
52 const std::string YELLOW_COLOR("yellow");
53 const std::string MAGENTA_COLOR("magenta");
54 const std::string CYAN_COLOR("cyan");
55 const std::string TRANSPARENT_COLOR("transparent");
57 const std::string SOLID_UNDERLINE("solid");
58 const std::string DASHED_UNDERLINE("dashed");
59 const std::string DOUBLE_UNDERLINE("double");
61 const std::string BEGIN_HORIZONTAL_ALIGNMENT("begin");
62 const std::string CENTER_HORIZONTAL_ALIGNMENT("center");
63 const std::string END_HORIZONTAL_ALIGNMENT("end");
67 bool TokenComparison(const std::string& string1, const char* const stringBuffer2, Length length)
69 const Length stringSize = string1.size();
70 if(stringSize != length)
72 // Early return. Strings have different sizes.
76 const char* const stringBuffer1 = string1.c_str();
78 for(std::size_t index = 0; index < stringSize; ++index)
80 const char character = *(stringBuffer2 + index);
81 const bool toLower = (character < LAST_UPPER_CASE) && (character >= FIRST_UPPER_CASE);
82 if(*(stringBuffer1 + index) != (toLower ? character + TO_LOWER_CASE : character))
91 void SkipWhiteSpace(const char*& stringBuffer,
92 const char* const stringEndBuffer)
94 for(; (WHITE_SPACE >= *stringBuffer) && (stringBuffer < stringEndBuffer); ++stringBuffer)
98 void JumpToWhiteSpace(const char*& stringBuffer,
99 const char* const stringEndBuffer)
101 for(; (WHITE_SPACE != *stringBuffer) && (stringBuffer < stringEndBuffer); ++stringBuffer)
105 unsigned int StringToUint(const char* const uintStr)
107 return static_cast<unsigned int>(strtoul(uintStr, NULL, 10));
110 unsigned int StringToHex(const char* const uintStr)
112 return static_cast<unsigned int>(strtoul(uintStr, NULL, 16));
115 float StringToFloat(const char* const floatStr)
117 return static_cast<float>(strtod(floatStr, NULL));
120 void FloatToString(float value, std::string& floatStr)
122 std::stringstream ss;
127 void UintToString(unsigned int value, std::string& uIntStr)
129 std::stringstream ss;
134 void UintColorToVector4(unsigned int color, Vector4& retColor)
136 retColor.a = static_cast<float>((color & 0xFF000000) >> 24u) / 255.f;
137 retColor.r = static_cast<float>((color & 0x00FF0000) >> 16u) / 255.f;
138 retColor.g = static_cast<float>((color & 0x0000FF00) >> 8u) / 255.f;
139 retColor.b = static_cast<float>(color & 0x000000FF) / 255.f;
142 void ColorStringToVector4(const char* const colorStr, Length length, Vector4& retColor)
144 if(WEB_COLOR_TOKEN == *colorStr)
146 std::string webColor(colorStr + 1u, length - 1u);
147 if(4u == length) // 3 component web color #F00 (red)
149 webColor.insert(2u, &(webColor[2]), 1u);
150 webColor.insert(1u, &(webColor[1]), 1u);
151 webColor.insert(0u, &(webColor[0]), 1u);
152 webColor.insert(0u, ALPHA_ONE);
154 else if(7u == length) // 6 component web color #FF0000 (red)
156 webColor.insert(0u, ALPHA_ONE);
159 UintColorToVector4(StringToHex(webColor.c_str()), retColor);
161 else if(TokenComparison(HEX_COLOR_TOKEN, colorStr, 2u))
163 UintColorToVector4(StringToHex(colorStr + 2u), retColor);
165 else if(TokenComparison(BLACK_COLOR, colorStr, length))
167 retColor = Color::BLACK;
169 else if(TokenComparison(WHITE_COLOR, colorStr, length))
171 retColor = Color::WHITE;
173 else if(TokenComparison(RED_COLOR, colorStr, length))
175 retColor = Color::RED;
177 else if(TokenComparison(GREEN_COLOR, colorStr, length))
179 retColor = Color::GREEN;
181 else if(TokenComparison(BLUE_COLOR, colorStr, length))
183 retColor = Color::BLUE;
185 else if(TokenComparison(YELLOW_COLOR, colorStr, length))
187 retColor = Color::YELLOW;
189 else if(TokenComparison(MAGENTA_COLOR, colorStr, length))
191 retColor = Color::MAGENTA;
193 else if(TokenComparison(CYAN_COLOR, colorStr, length))
195 retColor = Color::CYAN;
197 else if(TokenComparison(TRANSPARENT_COLOR, colorStr, length))
199 retColor = Color::TRANSPARENT;
203 void Vector4ToColorString(const Vector4& value, std::string& vector2Str)
205 if(Color::BLACK == value)
207 vector2Str = BLACK_COLOR;
211 if(Color::WHITE == value)
213 vector2Str = WHITE_COLOR;
217 if(Color::RED == value)
219 vector2Str = RED_COLOR;
223 if(Color::GREEN == value)
225 vector2Str = GREEN_COLOR;
229 if(Color::BLUE == value)
231 vector2Str = BLUE_COLOR;
235 if(Color::YELLOW == value)
237 vector2Str = YELLOW_COLOR;
241 if(Color::MAGENTA == value)
243 vector2Str = MAGENTA_COLOR;
247 if(Color::CYAN == value)
249 vector2Str = CYAN_COLOR;
253 if(Color::TRANSPARENT == value)
255 vector2Str = TRANSPARENT_COLOR;
259 const unsigned int alpha = static_cast<unsigned int>(255.f * value.a);
260 const unsigned int red = static_cast<unsigned int>(255.f * value.r);
261 const unsigned int green = static_cast<unsigned int>(255.f * value.g);
262 const unsigned int blue = static_cast<unsigned int>(255.f * value.b);
264 std::stringstream ss;
265 const unsigned int size = 2u * sizeof(unsigned char);
268 << std::setfill('0') << std::setw(size)
270 << std::setfill('0') << std::setw(size)
272 << std::setfill('0') << std::setw(size)
274 << std::setfill('0') << std::setw(size)
276 vector2Str = ss.str();
279 void StringToVector2(const char* const vectorStr, Length length, Vector2& vector2)
281 // Points to the first character of the string.
282 const char* strBuffer = vectorStr;
284 // Points to the first character of the 'x' value.
285 const char* const xBuffer = strBuffer;
287 // Jumps to the next white space.
288 JumpToWhiteSpace(strBuffer, strBuffer + length);
290 // Points to the first character of the 'y' value.
291 const char* const yBuffer = strBuffer;
293 // Converts the shadow's offset to float.
294 vector2.x = StringToFloat(xBuffer);
295 vector2.y = StringToFloat(yBuffer);
298 void Vector2ToString(const Vector2& value, std::string& vector2Str)
300 FloatToString(value.x, vector2Str);
304 FloatToString(value.y, yStr);
309 void UnderlineTypeStringToTypeValue(const char* const typeStr, Length length, Text::Underline::Type& retType)
311 if(TokenComparison(SOLID_UNDERLINE, typeStr, length))
313 retType = Text::Underline::SOLID;
315 else if(TokenComparison(DASHED_UNDERLINE, typeStr, length))
317 retType = Text::Underline::DASHED;
319 else if(TokenComparison(DOUBLE_UNDERLINE, typeStr, length))
321 retType = Text::Underline::DOUBLE;
325 bool HorizontalAlignmentTypeStringToTypeValue(const char* const typeStr, Length length, Text::HorizontalAlignment::Type& retType)
327 // The string is valid value for HorizontalAlignment
329 if(TokenComparison(BEGIN_HORIZONTAL_ALIGNMENT, typeStr, length))
331 retType = Text::HorizontalAlignment::BEGIN;
334 else if(TokenComparison(CENTER_HORIZONTAL_ALIGNMENT, typeStr, length))
336 retType = Text::HorizontalAlignment::CENTER;
339 else if(TokenComparison(END_HORIZONTAL_ALIGNMENT, typeStr, length))
341 retType = Text::HorizontalAlignment::END;
350 } // namespace Toolkit