2 * Copyright 2006 The Android Open Source Project
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "include/utils/SkParse.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkTypes.h"
17 static constexpr const char* gColorNames[] = {
84 "lightgoldenrodyellow",
160 static constexpr struct ColorRec {
163 { 0xf0,0xf8,0xff }, // aliceblue
164 { 0xfa,0xeb,0xd7 }, // antiquewhite
165 { 0x00,0xff,0xff }, // aqua
166 { 0x7f,0xff,0xd4 }, // aquamarine
167 { 0xf0,0xff,0xff }, // azure
168 { 0xf5,0xf5,0xdc }, // beige
169 { 0xff,0xe4,0xc4 }, // bisque
170 { 0x00,0x00,0x00 }, // black
171 { 0xff,0xeb,0xcd }, // blanchedalmond
172 { 0x00,0x00,0xff }, // blue
173 { 0x8a,0x2b,0xe2 }, // blueviolet
174 { 0xa5,0x2a,0x2a }, // brown
175 { 0xde,0xb8,0x87 }, // burlywood
176 { 0x5f,0x9e,0xa0 }, // cadetblue
177 { 0x7f,0xff,0x00 }, // chartreuse
178 { 0xd2,0x69,0x1e }, // chocolate
179 { 0xff,0x7f,0x50 }, // coral
180 { 0x64,0x95,0xed }, // cornflowerblue
181 { 0xff,0xf8,0xdc }, // cornsilk
182 { 0xdc,0x14,0x3c }, // crimson
183 { 0x00,0xff,0xff }, // cyan
184 { 0x00,0x00,0x8b }, // darkblue
185 { 0x00,0x8b,0x8b }, // darkcyan
186 { 0xb8,0x86,0x0b }, // darkgoldenrod
187 { 0xa9,0xa9,0xa9 }, // darkgray
188 { 0x00,0x64,0x00 }, // darkgreen
189 { 0xbd,0xb7,0x6b }, // darkkhaki
190 { 0x8b,0x00,0x8b }, // darkmagenta
191 { 0x55,0x6b,0x2f }, // darkolivegreen
192 { 0xff,0x8c,0x00 }, // darkorange
193 { 0x99,0x32,0xcc }, // darkorchid
194 { 0x8b,0x00,0x00 }, // darkred
195 { 0xe9,0x96,0x7a }, // darksalmon
196 { 0x8f,0xbc,0x8f }, // darkseagreen
197 { 0x48,0x3d,0x8b }, // darkslateblue
198 { 0x2f,0x4f,0x4f }, // darkslategray
199 { 0x00,0xce,0xd1 }, // darkturquoise
200 { 0x94,0x00,0xd3 }, // darkviolet
201 { 0xff,0x14,0x93 }, // deeppink
202 { 0x00,0xbf,0xff }, // deepskyblue
203 { 0x69,0x69,0x69 }, // dimgray
204 { 0x1e,0x90,0xff }, // dodgerblue
205 { 0xb2,0x22,0x22 }, // firebrick
206 { 0xff,0xfa,0xf0 }, // floralwhite
207 { 0x22,0x8b,0x22 }, // forestgreen
208 { 0xff,0x00,0xff }, // fuchsia
209 { 0xdc,0xdc,0xdc }, // gainsboro
210 { 0xf8,0xf8,0xff }, // ghostwhite
211 { 0xff,0xd7,0x00 }, // gold
212 { 0xda,0xa5,0x20 }, // goldenrod
213 { 0x80,0x80,0x80 }, // gray
214 { 0x00,0x80,0x00 }, // green
215 { 0xad,0xff,0x2f }, // greenyellow
216 { 0xf0,0xff,0xf0 }, // honeydew
217 { 0xff,0x69,0xb4 }, // hotpink
218 { 0xcd,0x5c,0x5c }, // indianred
219 { 0x4b,0x00,0x82 }, // indigo
220 { 0xff,0xff,0xf0 }, // ivory
221 { 0xf0,0xe6,0x8c }, // khaki
222 { 0xe6,0xe6,0xfa }, // lavender
223 { 0xff,0xf0,0xf5 }, // lavenderblush
224 { 0x7c,0xfc,0x00 }, // lawngreen
225 { 0xff,0xfa,0xcd }, // lemonchiffon
226 { 0xad,0xd8,0xe6 }, // lightblue
227 { 0xf0,0x80,0x80 }, // lightcoral
228 { 0xe0,0xff,0xff }, // lightcyan
229 { 0xfa,0xfa,0xd2 }, // lightgoldenrodyellow
230 { 0x90,0xee,0x90 }, // lightgreen
231 { 0xd3,0xd3,0xd3 }, // lightgrey
232 { 0xff,0xb6,0xc1 }, // lightpink
233 { 0xff,0xa0,0x7a }, // lightsalmon
234 { 0x20,0xb2,0xaa }, // lightseagreen
235 { 0x87,0xce,0xfa }, // lightskyblue
236 { 0x77,0x88,0x99 }, // lightslategray
237 { 0xb0,0xc4,0xde }, // lightsteelblue
238 { 0xff,0xff,0xe0 }, // lightyellow
239 { 0x00,0xff,0x00 }, // lime
240 { 0x32,0xcd,0x32 }, // limegreen
241 { 0xfa,0xf0,0xe6 }, // linen
242 { 0xff,0x00,0xff }, // magenta
243 { 0x80,0x00,0x00 }, // maroon
244 { 0x66,0xcd,0xaa }, // mediumaquamarine
245 { 0x00,0x00,0xcd }, // mediumblue
246 { 0xba,0x55,0xd3 }, // mediumorchid
247 { 0x93,0x70,0xdb }, // mediumpurple
248 { 0x3c,0xb3,0x71 }, // mediumseagreen
249 { 0x7b,0x68,0xee }, // mediumslateblue
250 { 0x00,0xfa,0x9a }, // mediumspringgreen
251 { 0x48,0xd1,0xcc }, // mediumturquoise
252 { 0xc7,0x15,0x85 }, // mediumvioletred
253 { 0x19,0x19,0x70 }, // midnightblue
254 { 0xf5,0xff,0xfa }, // mintcream
255 { 0xff,0xe4,0xe1 }, // mistyrose
256 { 0xff,0xe4,0xb5 }, // moccasin
257 { 0xff,0xde,0xad }, // navajowhite
258 { 0x00,0x00,0x80 }, // navy
259 { 0xfd,0xf5,0xe6 }, // oldlace
260 { 0x80,0x80,0x00 }, // olive
261 { 0x6b,0x8e,0x23 }, // olivedrab
262 { 0xff,0xa5,0x00 }, // orange
263 { 0xff,0x45,0x00 }, // orangered
264 { 0xda,0x70,0xd6 }, // orchid
265 { 0xee,0xe8,0xaa }, // palegoldenrod
266 { 0x98,0xfb,0x98 }, // palegreen
267 { 0xaf,0xee,0xee }, // paleturquoise
268 { 0xdb,0x70,0x93 }, // palevioletred
269 { 0xff,0xef,0xd5 }, // papayawhip
270 { 0xff,0xda,0xb9 }, // peachpuff
271 { 0xcd,0x85,0x3f }, // peru
272 { 0xff,0xc0,0xcb }, // pink
273 { 0xdd,0xa0,0xdd }, // plum
274 { 0xb0,0xe0,0xe6 }, // powderblue
275 { 0x80,0x00,0x80 }, // purple
276 { 0xff,0x00,0x00 }, // red
277 { 0xbc,0x8f,0x8f }, // rosybrown
278 { 0x41,0x69,0xe1 }, // royalblue
279 { 0x8b,0x45,0x13 }, // saddlebrown
280 { 0xfa,0x80,0x72 }, // salmon
281 { 0xf4,0xa4,0x60 }, // sandybrown
282 { 0x2e,0x8b,0x57 }, // seagreen
283 { 0xff,0xf5,0xee }, // seashell
284 { 0xa0,0x52,0x2d }, // sienna
285 { 0xc0,0xc0,0xc0 }, // silver
286 { 0x87,0xce,0xeb }, // skyblue
287 { 0x6a,0x5a,0xcd }, // slateblue
288 { 0x70,0x80,0x90 }, // slategray
289 { 0xff,0xfa,0xfa }, // snow
290 { 0x00,0xff,0x7f }, // springgreen
291 { 0x46,0x82,0xb4 }, // steelblue
292 { 0xd2,0xb4,0x8c }, // tan
293 { 0x00,0x80,0x80 }, // teal
294 { 0xd8,0xbf,0xd8 }, // thistle
295 { 0xff,0x63,0x47 }, // tomato
296 { 0x40,0xe0,0xd0 }, // turquoise
297 { 0xee,0x82,0xee }, // violet
298 { 0xf5,0xde,0xb3 }, // wheat
299 { 0xff,0xff,0xff }, // white
300 { 0xf5,0xf5,0xf5 }, // whitesmoke
301 { 0xff,0xff,0x00 }, // yellow
302 { 0x9a,0xcd,0x32 }, // yellowgreen
305 const char* SkParse::FindNamedColor(const char* name, size_t len, SkColor* color) {
306 const auto rec = std::lower_bound(std::begin(gColorNames),
307 std::end (gColorNames),
309 [](const char* name, const char* key) {
310 return strcmp(name, key) < 0;
313 if (rec == std::end(gColorNames) || 0 != strcmp(name, *rec)) {
318 int index = rec - gColorNames;
319 *color = SkColorSetRGB(gColors[index].r, gColors[index].g, gColors[index].b);
322 return name + strlen(*rec);
325 // !!! move to char utilities
326 //static int count_separators(const char* str, const char* sep) {
328 // int separators = 0;
329 // while ((c = *str++) != '\0') {
330 // if (strchr(sep, c) == nullptr)
333 // if ((c = *str++) == '\0')
335 // } while (strchr(sep, c) != nullptr);
339 // return separators;
342 static inline unsigned nib2byte(unsigned n)
344 SkASSERT((n & ~0xF) == 0);
348 const char* SkParse::FindColor(const char* value, SkColor* colorPtr) {
349 unsigned int oldAlpha = SkColorGetA(*colorPtr);
350 if (value[0] == '#') {
352 const char* end = SkParse::FindHex(value + 1, &hex);
356 size_t len = end - value - 1;
357 if (len == 3 || len == 4) {
358 unsigned a = len == 4 ? nib2byte(hex >> 12) : oldAlpha;
359 unsigned r = nib2byte((hex >> 8) & 0xF);
360 unsigned g = nib2byte((hex >> 4) & 0xF);
361 unsigned b = nib2byte(hex & 0xF);
362 *colorPtr = SkColorSetARGB(a, r, g, b);
364 } else if (len == 6 || len == 8) {
366 hex |= oldAlpha << 24;
373 // } else if (strchr(value, ',')) {
374 // SkScalar array[4];
375 // int count = count_separators(value, ",") + 1; // !!! count commas, add 1
376 // SkASSERT(count == 3 || count == 4);
377 // array[0] = SK_Scalar1 * 255;
378 // const char* end = SkParse::FindScalars(value, &array[4 - count], count);
379 // if (end == nullptr)
381 // !!! range check for errors?
382 // *colorPtr = SkColorSetARGB(SkScalarRoundToInt(array[0]), SkScalarRoundToInt(array[1]),
383 // SkScalarRoundToInt(array[2]), SkScalarRoundToInt(array[3]));
386 return FindNamedColor(value, strlen(value), colorPtr);