1 | /* |
2 | * Copyright 2006 The Android Open Source Project |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | |
9 | #include "include/utils/SkParse.h" |
10 | |
11 | static constexpr const char* gColorNames[] = { |
12 | "aliceblue" , |
13 | "antiquewhite" , |
14 | "aqua" , |
15 | "aquamarine" , |
16 | "azure" , |
17 | "beige" , |
18 | "bisque" , |
19 | "black" , |
20 | "blanchedalmond" , |
21 | "blue" , |
22 | "blueviolet" , |
23 | "brown" , |
24 | "burlywood" , |
25 | "cadetblue" , |
26 | "chartreuse" , |
27 | "chocolate" , |
28 | "coral" , |
29 | "cornflowerblue" , |
30 | "cornsilk" , |
31 | "crimson" , |
32 | "cyan" , |
33 | "darkblue" , |
34 | "darkcyan" , |
35 | "darkgoldenrod" , |
36 | "darkgray" , |
37 | "darkgreen" , |
38 | "darkkhaki" , |
39 | "darkmagenta" , |
40 | "darkolivegreen" , |
41 | "darkorange" , |
42 | "darkorchid" , |
43 | "darkred" , |
44 | "darksalmon" , |
45 | "darkseagreen" , |
46 | "darkslateblue" , |
47 | "darkslategray" , |
48 | "darkturquoise" , |
49 | "darkviolet" , |
50 | "deeppink" , |
51 | "deepskyblue" , |
52 | "dimgray" , |
53 | "dodgerblue" , |
54 | "firebrick" , |
55 | "floralwhite" , |
56 | "forestgreen" , |
57 | "fuchsia" , |
58 | "gainsboro" , |
59 | "ghostwhite" , |
60 | "gold" , |
61 | "goldenrod" , |
62 | "gray" , |
63 | "green" , |
64 | "greenyellow" , |
65 | "honeydew" , |
66 | "hotpink" , |
67 | "indianred" , |
68 | "indigo" , |
69 | "ivory" , |
70 | "khaki" , |
71 | "lavender" , |
72 | "lavenderblush" , |
73 | "lawngreen" , |
74 | "lemonchiffon" , |
75 | "lightblue" , |
76 | "lightcoral" , |
77 | "lightcyan" , |
78 | "lightgoldenrodyellow" , |
79 | "lightgreen" , |
80 | "lightgrey" , |
81 | "lightpink" , |
82 | "lightsalmon" , |
83 | "lightseagreen" , |
84 | "lightskyblue" , |
85 | "lightslategray" , |
86 | "lightsteelblue" , |
87 | "lightyellow" , |
88 | "lime" , |
89 | "limegreen" , |
90 | "linen" , |
91 | "magenta" , |
92 | "maroon" , |
93 | "mediumaquamarine" , |
94 | "mediumblue" , |
95 | "mediumorchid" , |
96 | "mediumpurple" , |
97 | "mediumseagreen" , |
98 | "mediumslateblue" , |
99 | "mediumspringgreen" , |
100 | "mediumturquoise" , |
101 | "mediumvioletred" , |
102 | "midnightblue" , |
103 | "mintcream" , |
104 | "mistyrose" , |
105 | "moccasin" , |
106 | "navajowhite" , |
107 | "navy" , |
108 | "oldlace" , |
109 | "olive" , |
110 | "olivedrab" , |
111 | "orange" , |
112 | "orangered" , |
113 | "orchid" , |
114 | "palegoldenrod" , |
115 | "palegreen" , |
116 | "paleturquoise" , |
117 | "palevioletred" , |
118 | "papayawhip" , |
119 | "peachpuff" , |
120 | "peru" , |
121 | "pink" , |
122 | "plum" , |
123 | "powderblue" , |
124 | "purple" , |
125 | "red" , |
126 | "rosybrown" , |
127 | "royalblue" , |
128 | "saddlebrown" , |
129 | "salmon" , |
130 | "sandybrown" , |
131 | "seagreen" , |
132 | "seashell" , |
133 | "sienna" , |
134 | "silver" , |
135 | "skyblue" , |
136 | "slateblue" , |
137 | "slategray" , |
138 | "snow" , |
139 | "springgreen" , |
140 | "steelblue" , |
141 | "tan" , |
142 | "teal" , |
143 | "thistle" , |
144 | "tomato" , |
145 | "turquoise" , |
146 | "violet" , |
147 | "wheat" , |
148 | "white" , |
149 | "whitesmoke" , |
150 | "yellow" , |
151 | "yellowgreen" , |
152 | }; |
153 | |
154 | static constexpr struct ColorRec { |
155 | uint8_t r, g, b; |
156 | } gColors[] = { |
157 | { 0xf0,0xf8,0xff }, // aliceblue |
158 | { 0xfa,0xeb,0xd7 }, // antiquewhite |
159 | { 0x00,0xff,0xff }, // aqua |
160 | { 0x7f,0xff,0xd4 }, // aquamarine |
161 | { 0xf0,0xff,0xff }, // azure |
162 | { 0xf5,0xf5,0xdc }, // beige |
163 | { 0xff,0xe4,0xc4 }, // bisque |
164 | { 0x00,0x00,0x00 }, // black |
165 | { 0xff,0xeb,0xcd }, // blanchedalmond |
166 | { 0x00,0x00,0xff }, // blue |
167 | { 0x8a,0x2b,0xe2 }, // blueviolet |
168 | { 0xa5,0x2a,0x2a }, // brown |
169 | { 0xde,0xb8,0x87 }, // burlywood |
170 | { 0x5f,0x9e,0xa0 }, // cadetblue |
171 | { 0x7f,0xff,0x00 }, // chartreuse |
172 | { 0xd2,0x69,0x1e }, // chocolate |
173 | { 0xff,0x7f,0x50 }, // coral |
174 | { 0x64,0x95,0xed }, // cornflowerblue |
175 | { 0xff,0xf8,0xdc }, // cornsilk |
176 | { 0xdc,0x14,0x3c }, // crimson |
177 | { 0x00,0xff,0xff }, // cyan |
178 | { 0x00,0x00,0x8b }, // darkblue |
179 | { 0x00,0x8b,0x8b }, // darkcyan |
180 | { 0xb8,0x86,0x0b }, // darkgoldenrod |
181 | { 0xa9,0xa9,0xa9 }, // darkgray |
182 | { 0x00,0x64,0x00 }, // darkgreen |
183 | { 0xbd,0xb7,0x6b }, // darkkhaki |
184 | { 0x8b,0x00,0x8b }, // darkmagenta |
185 | { 0x55,0x6b,0x2f }, // darkolivegreen |
186 | { 0xff,0x8c,0x00 }, // darkorange |
187 | { 0x99,0x32,0xcc }, // darkorchid |
188 | { 0x8b,0x00,0x00 }, // darkred |
189 | { 0xe9,0x96,0x7a }, // darksalmon |
190 | { 0x8f,0xbc,0x8f }, // darkseagreen |
191 | { 0x48,0x3d,0x8b }, // darkslateblue |
192 | { 0x2f,0x4f,0x4f }, // darkslategray |
193 | { 0x00,0xce,0xd1 }, // darkturquoise |
194 | { 0x94,0x00,0xd3 }, // darkviolet |
195 | { 0xff,0x14,0x93 }, // deeppink |
196 | { 0x00,0xbf,0xff }, // deepskyblue |
197 | { 0x69,0x69,0x69 }, // dimgray |
198 | { 0x1e,0x90,0xff }, // dodgerblue |
199 | { 0xb2,0x22,0x22 }, // firebrick |
200 | { 0xff,0xfa,0xf0 }, // floralwhite |
201 | { 0x22,0x8b,0x22 }, // forestgreen |
202 | { 0xff,0x00,0xff }, // fuchsia |
203 | { 0xdc,0xdc,0xdc }, // gainsboro |
204 | { 0xf8,0xf8,0xff }, // ghostwhite |
205 | { 0xff,0xd7,0x00 }, // gold |
206 | { 0xda,0xa5,0x20 }, // goldenrod |
207 | { 0x80,0x80,0x80 }, // gray |
208 | { 0x00,0x80,0x00 }, // green |
209 | { 0xad,0xff,0x2f }, // greenyellow |
210 | { 0xf0,0xff,0xf0 }, // honeydew |
211 | { 0xff,0x69,0xb4 }, // hotpink |
212 | { 0xcd,0x5c,0x5c }, // indianred |
213 | { 0x4b,0x00,0x82 }, // indigo |
214 | { 0xff,0xff,0xf0 }, // ivory |
215 | { 0xf0,0xe6,0x8c }, // khaki |
216 | { 0xe6,0xe6,0xfa }, // lavender |
217 | { 0xff,0xf0,0xf5 }, // lavenderblush |
218 | { 0x7c,0xfc,0x00 }, // lawngreen |
219 | { 0xff,0xfa,0xcd }, // lemonchiffon |
220 | { 0xad,0xd8,0xe6 }, // lightblue |
221 | { 0xf0,0x80,0x80 }, // lightcoral |
222 | { 0xe0,0xff,0xff }, // lightcyan |
223 | { 0xfa,0xfa,0xd2 }, // lightgoldenrodyellow |
224 | { 0x90,0xee,0x90 }, // lightgreen |
225 | { 0xd3,0xd3,0xd3 }, // lightgrey |
226 | { 0xff,0xb6,0xc1 }, // lightpink |
227 | { 0xff,0xa0,0x7a }, // lightsalmon |
228 | { 0x20,0xb2,0xaa }, // lightseagreen |
229 | { 0x87,0xce,0xfa }, // lightskyblue |
230 | { 0x77,0x88,0x99 }, // lightslategray |
231 | { 0xb0,0xc4,0xde }, // lightsteelblue |
232 | { 0xff,0xff,0xe0 }, // lightyellow |
233 | { 0x00,0xff,0x00 }, // lime |
234 | { 0x32,0xcd,0x32 }, // limegreen |
235 | { 0xfa,0xf0,0xe6 }, // linen |
236 | { 0xff,0x00,0xff }, // magenta |
237 | { 0x80,0x00,0x00 }, // maroon |
238 | { 0x66,0xcd,0xaa }, // mediumaquamarine |
239 | { 0x00,0x00,0xcd }, // mediumblue |
240 | { 0xba,0x55,0xd3 }, // mediumorchid |
241 | { 0x93,0x70,0xdb }, // mediumpurple |
242 | { 0x3c,0xb3,0x71 }, // mediumseagreen |
243 | { 0x7b,0x68,0xee }, // mediumslateblue |
244 | { 0x00,0xfa,0x9a }, // mediumspringgreen |
245 | { 0x48,0xd1,0xcc }, // mediumturquoise |
246 | { 0xc7,0x15,0x85 }, // mediumvioletred |
247 | { 0x19,0x19,0x70 }, // midnightblue |
248 | { 0xf5,0xff,0xfa }, // mintcream |
249 | { 0xff,0xe4,0xe1 }, // mistyrose |
250 | { 0xff,0xe4,0xb5 }, // moccasin |
251 | { 0xff,0xde,0xad }, // navajowhite |
252 | { 0x00,0x00,0x80 }, // navy |
253 | { 0xfd,0xf5,0xe6 }, // oldlace |
254 | { 0x80,0x80,0x00 }, // olive |
255 | { 0x6b,0x8e,0x23 }, // olivedrab |
256 | { 0xff,0xa5,0x00 }, // orange |
257 | { 0xff,0x45,0x00 }, // orangered |
258 | { 0xda,0x70,0xd6 }, // orchid |
259 | { 0xee,0xe8,0xaa }, // palegoldenrod |
260 | { 0x98,0xfb,0x98 }, // palegreen |
261 | { 0xaf,0xee,0xee }, // paleturquoise |
262 | { 0xdb,0x70,0x93 }, // palevioletred |
263 | { 0xff,0xef,0xd5 }, // papayawhip |
264 | { 0xff,0xda,0xb9 }, // peachpuff |
265 | { 0xcd,0x85,0x3f }, // peru |
266 | { 0xff,0xc0,0xcb }, // pink |
267 | { 0xdd,0xa0,0xdd }, // plum |
268 | { 0xb0,0xe0,0xe6 }, // powderblue |
269 | { 0x80,0x00,0x80 }, // purple |
270 | { 0xff,0x00,0x00 }, // red |
271 | { 0xbc,0x8f,0x8f }, // rosybrown |
272 | { 0x41,0x69,0xe1 }, // royalblue |
273 | { 0x8b,0x45,0x13 }, // saddlebrown |
274 | { 0xfa,0x80,0x72 }, // salmon |
275 | { 0xf4,0xa4,0x60 }, // sandybrown |
276 | { 0x2e,0x8b,0x57 }, // seagreen |
277 | { 0xff,0xf5,0xee }, // seashell |
278 | { 0xa0,0x52,0x2d }, // sienna |
279 | { 0xc0,0xc0,0xc0 }, // silver |
280 | { 0x87,0xce,0xeb }, // skyblue |
281 | { 0x6a,0x5a,0xcd }, // slateblue |
282 | { 0x70,0x80,0x90 }, // slategray |
283 | { 0xff,0xfa,0xfa }, // snow |
284 | { 0x00,0xff,0x7f }, // springgreen |
285 | { 0x46,0x82,0xb4 }, // steelblue |
286 | { 0xd2,0xb4,0x8c }, // tan |
287 | { 0x00,0x80,0x80 }, // teal |
288 | { 0xd8,0xbf,0xd8 }, // thistle |
289 | { 0xff,0x63,0x47 }, // tomato |
290 | { 0x40,0xe0,0xd0 }, // turquoise |
291 | { 0xee,0x82,0xee }, // violet |
292 | { 0xf5,0xde,0xb3 }, // wheat |
293 | { 0xff,0xff,0xff }, // white |
294 | { 0xf5,0xf5,0xf5 }, // whitesmoke |
295 | { 0xff,0xff,0x00 }, // yellow |
296 | { 0x9a,0xcd,0x32 }, // yellowgreen |
297 | }; |
298 | |
299 | const char* SkParse::FindNamedColor(const char* name, size_t len, SkColor* color) { |
300 | const auto rec = std::lower_bound(std::begin(gColorNames), |
301 | std::end (gColorNames), |
302 | name, // key |
303 | [](const char* name, const char* key) { |
304 | return strcmp(name, key) < 0; |
305 | }); |
306 | |
307 | if (rec == std::end(gColorNames) || strcmp(name, *rec)) { |
308 | return nullptr; |
309 | } |
310 | |
311 | if (color) { |
312 | int index = rec - gColorNames; |
313 | *color = SkColorSetRGB(gColors[index].r, gColors[index].g, gColors[index].b); |
314 | } |
315 | |
316 | return name + strlen(*rec); |
317 | } |
318 | |
319 | // !!! move to char utilities |
320 | //static int count_separators(const char* str, const char* sep) { |
321 | // char c; |
322 | // int separators = 0; |
323 | // while ((c = *str++) != '\0') { |
324 | // if (strchr(sep, c) == nullptr) |
325 | // continue; |
326 | // do { |
327 | // if ((c = *str++) == '\0') |
328 | // goto goHome; |
329 | // } while (strchr(sep, c) != nullptr); |
330 | // separators++; |
331 | // } |
332 | //goHome: |
333 | // return separators; |
334 | //} |
335 | |
336 | static inline unsigned nib2byte(unsigned n) |
337 | { |
338 | SkASSERT((n & ~0xF) == 0); |
339 | return (n << 4) | n; |
340 | } |
341 | |
342 | const char* SkParse::FindColor(const char* value, SkColor* colorPtr) { |
343 | unsigned int oldAlpha = SkColorGetA(*colorPtr); |
344 | if (value[0] == '#') { |
345 | uint32_t hex; |
346 | const char* end = SkParse::FindHex(value + 1, &hex); |
347 | // SkASSERT(end); |
348 | if (end == nullptr) |
349 | return end; |
350 | size_t len = end - value - 1; |
351 | if (len == 3 || len == 4) { |
352 | unsigned a = len == 4 ? nib2byte(hex >> 12) : oldAlpha; |
353 | unsigned r = nib2byte((hex >> 8) & 0xF); |
354 | unsigned g = nib2byte((hex >> 4) & 0xF); |
355 | unsigned b = nib2byte(hex & 0xF); |
356 | *colorPtr = SkColorSetARGB(a, r, g, b); |
357 | return end; |
358 | } else if (len == 6 || len == 8) { |
359 | if (len == 6) |
360 | hex |= oldAlpha << 24; |
361 | *colorPtr = hex; |
362 | return end; |
363 | } else { |
364 | // SkASSERT(0); |
365 | return nullptr; |
366 | } |
367 | // } else if (strchr(value, ',')) { |
368 | // SkScalar array[4]; |
369 | // int count = count_separators(value, ",") + 1; // !!! count commas, add 1 |
370 | // SkASSERT(count == 3 || count == 4); |
371 | // array[0] = SK_Scalar1 * 255; |
372 | // const char* end = SkParse::FindScalars(value, &array[4 - count], count); |
373 | // if (end == nullptr) |
374 | // return nullptr; |
375 | // !!! range check for errors? |
376 | // *colorPtr = SkColorSetARGB(SkScalarRoundToInt(array[0]), SkScalarRoundToInt(array[1]), |
377 | // SkScalarRoundToInt(array[2]), SkScalarRoundToInt(array[3])); |
378 | // return end; |
379 | } else |
380 | return FindNamedColor(value, strlen(value), colorPtr); |
381 | } |
382 | |