DALi Version 2.1.5
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / markup-processor-helper-functions.cpp
1 /*
2  * Copyright (c) 2015 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/markup-processor-helper-functions.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/constants.h>
23 #include <dali/public-api/math/vector2.h>
24 #include <stdlib.h>
25 #include <iomanip>
26 #include <sstream>
27
28 namespace Dali
29 {
30 namespace Toolkit
31 {
32 namespace Text
33 {
34 namespace
35 {
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.
40
41 const char        WEB_COLOR_TOKEN('#');
42 const char* const HEX_COLOR_TOKEN("0x");
43 const char* const ALPHA_ONE("FF");
44
45 const std::string BLACK_COLOR("black");
46 const std::string WHITE_COLOR("white");
47 const std::string RED_COLOR("red");
48 const std::string GREEN_COLOR("green");
49 const std::string BLUE_COLOR("blue");
50 const std::string YELLOW_COLOR("yellow");
51 const std::string MAGENTA_COLOR("magenta");
52 const std::string CYAN_COLOR("cyan");
53 const std::string TRANSPARENT_COLOR("transparent");
54
55 const std::string SOLID_UNDERLINE("solid");
56 const std::string DASHED_UNDERLINE("dashed");
57 const std::string DOUBLE_UNDERLINE("double");
58 } // namespace
59
60 bool TokenComparison(const std::string& string1, const char* const stringBuffer2, Length length)
61 {
62   const Length stringSize = string1.size();
63   if(stringSize != length)
64   {
65     // Early return. Strings have different sizes.
66     return false;
67   }
68
69   const char* const stringBuffer1 = string1.c_str();
70
71   for(std::size_t index = 0; index < stringSize; ++index)
72   {
73     const char character = *(stringBuffer2 + index);
74     const bool toLower   = (character < LAST_UPPER_CASE) && (character >= FIRST_UPPER_CASE);
75     if(*(stringBuffer1 + index) != (toLower ? character + TO_LOWER_CASE : character))
76     {
77       return false;
78     }
79   }
80
81   return true;
82 }
83
84 void SkipWhiteSpace(const char*&      stringBuffer,
85                     const char* const stringEndBuffer)
86 {
87   for(; (WHITE_SPACE >= *stringBuffer) && (stringBuffer < stringEndBuffer); ++stringBuffer)
88     ;
89 }
90
91 void JumpToWhiteSpace(const char*&      stringBuffer,
92                       const char* const stringEndBuffer)
93 {
94   for(; (WHITE_SPACE != *stringBuffer) && (stringBuffer < stringEndBuffer); ++stringBuffer)
95     ;
96 }
97
98 unsigned int StringToUint(const char* const uintStr)
99 {
100   return static_cast<unsigned int>(strtoul(uintStr, NULL, 10));
101 }
102
103 unsigned int StringToHex(const char* const uintStr)
104 {
105   return static_cast<unsigned int>(strtoul(uintStr, NULL, 16));
106 }
107
108 float StringToFloat(const char* const floatStr)
109 {
110   return static_cast<float>(strtod(floatStr, NULL));
111 }
112
113 void FloatToString(float value, std::string& floatStr)
114 {
115   std::stringstream ss;
116   ss << value;
117   floatStr = ss.str();
118 }
119
120 void UintToString(unsigned int value, std::string& uIntStr)
121 {
122   std::stringstream ss;
123   ss << value;
124   uIntStr = ss.str();
125 }
126
127 void UintColorToVector4(unsigned int color, Vector4& retColor)
128 {
129   retColor.a = static_cast<float>((color & 0xFF000000) >> 24u) / 255.f;
130   retColor.r = static_cast<float>((color & 0x00FF0000) >> 16u) / 255.f;
131   retColor.g = static_cast<float>((color & 0x0000FF00) >> 8u) / 255.f;
132   retColor.b = static_cast<float>(color & 0x000000FF) / 255.f;
133 }
134
135 void ColorStringToVector4(const char* const colorStr, Length length, Vector4& retColor)
136 {
137   if(WEB_COLOR_TOKEN == *colorStr)
138   {
139     std::string webColor(colorStr + 1u, length - 1u);
140     if(4u == length) // 3 component web color #F00 (red)
141     {
142       webColor.insert(2u, &(webColor[2]), 1u);
143       webColor.insert(1u, &(webColor[1]), 1u);
144       webColor.insert(0u, &(webColor[0]), 1u);
145       webColor.insert(0u, ALPHA_ONE);
146     }
147     else if(7u == length) // 6 component web color #FF0000 (red)
148     {
149       webColor.insert(0u, ALPHA_ONE);
150     }
151
152     UintColorToVector4(StringToHex(webColor.c_str()), retColor);
153   }
154   else if(TokenComparison(HEX_COLOR_TOKEN, colorStr, 2u))
155   {
156     UintColorToVector4(StringToHex(colorStr + 2u), retColor);
157   }
158   else if(TokenComparison(BLACK_COLOR, colorStr, length))
159   {
160     retColor = Color::BLACK;
161   }
162   else if(TokenComparison(WHITE_COLOR, colorStr, length))
163   {
164     retColor = Color::WHITE;
165   }
166   else if(TokenComparison(RED_COLOR, colorStr, length))
167   {
168     retColor = Color::RED;
169   }
170   else if(TokenComparison(GREEN_COLOR, colorStr, length))
171   {
172     retColor = Color::GREEN;
173   }
174   else if(TokenComparison(BLUE_COLOR, colorStr, length))
175   {
176     retColor = Color::BLUE;
177   }
178   else if(TokenComparison(YELLOW_COLOR, colorStr, length))
179   {
180     retColor = Color::YELLOW;
181   }
182   else if(TokenComparison(MAGENTA_COLOR, colorStr, length))
183   {
184     retColor = Color::MAGENTA;
185   }
186   else if(TokenComparison(CYAN_COLOR, colorStr, length))
187   {
188     retColor = Color::CYAN;
189   }
190   else if(TokenComparison(TRANSPARENT_COLOR, colorStr, length))
191   {
192     retColor = Color::TRANSPARENT;
193   }
194 }
195
196 void Vector4ToColorString(const Vector4& value, std::string& vector2Str)
197 {
198   if(Color::BLACK == value)
199   {
200     vector2Str = BLACK_COLOR;
201     return;
202   }
203
204   if(Color::WHITE == value)
205   {
206     vector2Str = WHITE_COLOR;
207     return;
208   }
209
210   if(Color::RED == value)
211   {
212     vector2Str = RED_COLOR;
213     return;
214   }
215
216   if(Color::GREEN == value)
217   {
218     vector2Str = GREEN_COLOR;
219     return;
220   }
221
222   if(Color::BLUE == value)
223   {
224     vector2Str = BLUE_COLOR;
225     return;
226   }
227
228   if(Color::YELLOW == value)
229   {
230     vector2Str = YELLOW_COLOR;
231     return;
232   }
233
234   if(Color::MAGENTA == value)
235   {
236     vector2Str = MAGENTA_COLOR;
237     return;
238   }
239
240   if(Color::CYAN == value)
241   {
242     vector2Str = CYAN_COLOR;
243     return;
244   }
245
246   if(Color::TRANSPARENT == value)
247   {
248     vector2Str = TRANSPARENT_COLOR;
249     return;
250   }
251
252   const unsigned int alpha = static_cast<unsigned int>(255.f * value.a);
253   const unsigned int red   = static_cast<unsigned int>(255.f * value.r);
254   const unsigned int green = static_cast<unsigned int>(255.f * value.g);
255   const unsigned int blue  = static_cast<unsigned int>(255.f * value.b);
256
257   std::stringstream  ss;
258   const unsigned int size = 2u * sizeof(unsigned char);
259
260   ss << "0x"
261      << std::setfill('0') << std::setw(size)
262      << std::hex << alpha
263      << std::setfill('0') << std::setw(size)
264      << std::hex << red
265      << std::setfill('0') << std::setw(size)
266      << std::hex << green
267      << std::setfill('0') << std::setw(size)
268      << std::hex << blue;
269   vector2Str = ss.str();
270 }
271
272 void StringToVector2(const char* const vectorStr, Length length, Vector2& vector2)
273 {
274   // Points to the first character of the string.
275   const char* strBuffer = vectorStr;
276
277   // Points to the first character of the 'x' value.
278   const char* const xBuffer = strBuffer;
279
280   // Jumps to the next white space.
281   JumpToWhiteSpace(strBuffer, strBuffer + length);
282
283   // Points to the first character of the 'y' value.
284   const char* const yBuffer = strBuffer;
285
286   // Converts the shadow's offset to float.
287   vector2.x = StringToFloat(xBuffer);
288   vector2.y = StringToFloat(yBuffer);
289 }
290
291 void Vector2ToString(const Vector2& value, std::string& vector2Str)
292 {
293   FloatToString(value.x, vector2Str);
294   vector2Str += " ";
295
296   std::string yStr;
297   FloatToString(value.y, yStr);
298
299   vector2Str += yStr;
300 }
301
302 void UnderlineTypeStringToTypeValue(const char* const typeStr, Length length, Text::Underline::Type& retType)
303 {
304   if(TokenComparison(SOLID_UNDERLINE, typeStr, length))
305   {
306     retType = Text::Underline::SOLID;
307   }
308   else if(TokenComparison(DASHED_UNDERLINE, typeStr, length))
309   {
310     retType = Text::Underline::DASHED;
311   }
312   else if(TokenComparison(DOUBLE_UNDERLINE, typeStr, length))
313   {
314     retType = Text::Underline::DOUBLE;
315   }
316 }
317
318 } // namespace Text
319
320 } // namespace Toolkit
321
322 } // namespace Dali