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