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