1
/* libs/graphics/xml/SkParseColor.cpp
3
** Copyright 2006, The Android Open Source Project
5
** Licensed under the Apache License, Version 2.0 (the "License");
6
** you may not use this file except in compliance with the License.
7
** You may obtain a copy of the License at
9
** http://www.apache.org/licenses/LICENSE-2.0
11
** Unless required by applicable law or agreed to in writing, software
12
** distributed under the License is distributed on an "AS IS" BASIS,
13
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
** See the License for the specific language governing permissions and
15
** limitations under the License.
23
// compress names 6 chars per long (packed 5 bits/char )
24
// note: little advantage to splitting chars across longs, since 3 longs at 2 unused bits each
25
// allow for one additional split char (vs. the 18 unsplit chars in the three longs)
26
// use extra two bits to represent:
27
// 00 : final 6 (or fewer) chars (if 'a' is 0x01, zero could have special meaning)
28
// 01 : not final 6 chars
30
// 11 : unused, except as debugging sentinal? (could be -1 for easier test)
31
// !!! the bit to end the word (last) is at the low bit for binary search
32
// lookup first character in offset for quick start
33
// offset is 27-entry table of bytes(?) that trims linear search to at most 21 entries ('d')
34
// shift match into long; set bit 30 if it all doesn't fit
35
// while longs don't match, march forward
36
// if they do match, and bit 30 is set, advance match, clearing bit 30 if
37
// final chars, and advance to next test
38
// if they do match, and bit 30 is clear, get next long (color) and return it
39
// stop at lookup of first char + 1
40
static const struct SkNameRGB {
44
{ "aliceblue", 0xF0F8FF },
45
{ "antiquewhite", 0xFAEBD7 },
47
{ "aquamarine", 0x7FFFD4 },
48
{ "azure", 0xF0FFFF },
49
{ "beige", 0xF5F5DC },
50
{ "bisque", 0xFFE4C4 },
51
{ "black", 0x000000 },
52
{ "blanchedalmond", 0xFFEBCD },
54
{ "blueviolet", 0x8A2BE2 },
55
{ "brown", 0xA52A2A },
56
{ "burlywood", 0xDEB887 },
57
{ "cadetblue", 0x5F9EA0 },
58
{ "chartreuse", 0x7FFF00 },
59
{ "chocolate", 0xD2691E },
60
{ "coral", 0xFF7F50 },
61
{ "cornflowerblue", 0x6495ED },
62
{ "cornsilk", 0xFFF8DC },
63
{ "crimson", 0xDC143C },
65
{ "darkblue", 0x00008B },
66
{ "darkcyan", 0x008B8B },
67
{ "darkgoldenrod", 0xB8860B },
68
{ "darkgray", 0xA9A9A9 },
69
{ "darkgreen", 0x006400 },
70
{ "darkkhaki", 0xBDB76B },
71
{ "darkmagenta", 0x8B008B },
72
{ "darkolivegreen", 0x556B2F },
73
{ "darkorange", 0xFF8C00 },
74
{ "darkorchid", 0x9932CC },
75
{ "darkred", 0x8B0000 },
76
{ "darksalmon", 0xE9967A },
77
{ "darkseagreen", 0x8FBC8F },
78
{ "darkslateblue", 0x483D8B },
79
{ "darkslategray", 0x2F4F4F },
80
{ "darkturquoise", 0x00CED1 },
81
{ "darkviolet", 0x9400D3 },
82
{ "deeppink", 0xFF1493 },
83
{ "deepskyblue", 0x00BFFF },
84
{ "dimgray", 0x696969 },
85
{ "dodgerblue", 0x1E90FF },
86
{ "firebrick", 0xB22222 },
87
{ "floralwhite", 0xFFFAF0 },
88
{ "forestgreen", 0x228B22 },
89
{ "fuchsia", 0xFF00FF },
90
{ "gainsboro", 0xDCDCDC },
91
{ "ghostwhite", 0xF8F8FF },
93
{ "goldenrod", 0xDAA520 },
95
{ "green", 0x008000 },
96
{ "greenyellow", 0xADFF2F },
97
{ "honeydew", 0xF0FFF0 },
98
{ "hotpink", 0xFF69B4 },
99
{ "indianred", 0xCD5C5C },
100
{ "indigo", 0x4B0082 },
101
{ "ivory", 0xFFFFF0 },
102
{ "khaki", 0xF0E68C },
103
{ "lavender", 0xE6E6FA },
104
{ "lavenderblush", 0xFFF0F5 },
105
{ "lawngreen", 0x7CFC00 },
106
{ "lemonchiffon", 0xFFFACD },
107
{ "lightblue", 0xADD8E6 },
108
{ "lightcoral", 0xF08080 },
109
{ "lightcyan", 0xE0FFFF },
110
{ "lightgoldenrodyellow", 0xFAFAD2 },
111
{ "lightgreen", 0x90EE90 },
112
{ "lightgrey", 0xD3D3D3 },
113
{ "lightpink", 0xFFB6C1 },
114
{ "lightsalmon", 0xFFA07A },
115
{ "lightseagreen", 0x20B2AA },
116
{ "lightskyblue", 0x87CEFA },
117
{ "lightslategray", 0x778899 },
118
{ "lightsteelblue", 0xB0C4DE },
119
{ "lightyellow", 0xFFFFE0 },
120
{ "lime", 0x00FF00 },
121
{ "limegreen", 0x32CD32 },
122
{ "linen", 0xFAF0E6 },
123
{ "magenta", 0xFF00FF },
124
{ "maroon", 0x800000 },
125
{ "mediumaquamarine", 0x66CDAA },
126
{ "mediumblue", 0x0000CD },
127
{ "mediumorchid", 0xBA55D3 },
128
{ "mediumpurple", 0x9370DB },
129
{ "mediumseagreen", 0x3CB371 },
130
{ "mediumslateblue", 0x7B68EE },
131
{ "mediumspringgreen", 0x00FA9A },
132
{ "mediumturquoise", 0x48D1CC },
133
{ "mediumvioletred", 0xC71585 },
134
{ "midnightblue", 0x191970 },
135
{ "mintcream", 0xF5FFFA },
136
{ "mistyrose", 0xFFE4E1 },
137
{ "moccasin", 0xFFE4B5 },
138
{ "navajowhite", 0xFFDEAD },
139
{ "navy", 0x000080 },
140
{ "oldlace", 0xFDF5E6 },
141
{ "olive", 0x808000 },
142
{ "olivedrab", 0x6B8E23 },
143
{ "orange", 0xFFA500 },
144
{ "orangered", 0xFF4500 },
145
{ "orchid", 0xDA70D6 },
146
{ "palegoldenrod", 0xEEE8AA },
147
{ "palegreen", 0x98FB98 },
148
{ "paleturquoise", 0xAFEEEE },
149
{ "palevioletred", 0xDB7093 },
150
{ "papayawhip", 0xFFEFD5 },
151
{ "peachpuff", 0xFFDAB9 },
152
{ "peru", 0xCD853F },
153
{ "pink", 0xFFC0CB },
154
{ "plum", 0xDDA0DD },
155
{ "powderblue", 0xB0E0E6 },
156
{ "purple", 0x800080 },
158
{ "rosybrown", 0xBC8F8F },
159
{ "royalblue", 0x4169E1 },
160
{ "saddlebrown", 0x8B4513 },
161
{ "salmon", 0xFA8072 },
162
{ "sandybrown", 0xF4A460 },
163
{ "seagreen", 0x2E8B57 },
164
{ "seashell", 0xFFF5EE },
165
{ "sienna", 0xA0522D },
166
{ "silver", 0xC0C0C0 },
167
{ "skyblue", 0x87CEEB },
168
{ "slateblue", 0x6A5ACD },
169
{ "slategray", 0x708090 },
170
{ "snow", 0xFFFAFA },
171
{ "springgreen", 0x00FF7F },
172
{ "steelblue", 0x4682B4 },
174
{ "teal", 0x008080 },
175
{ "thistle", 0xD8BFD8 },
176
{ "tomato", 0xFF6347 },
177
{ "turquoise", 0x40E0D0 },
178
{ "violet", 0xEE82EE },
179
{ "wheat", 0xF5DEB3 },
180
{ "white", 0xFFFFFF },
181
{ "whitesmoke", 0xF5F5F5 },
182
{ "yellow", 0xFFFF00 },
183
{ "yellowgreen", 0x9ACD32 }
186
int colorNamesSize = sizeof(colorNames) / sizeof(colorNames[0]);
188
static void CreateTable() {
190
size_t originalSize = 0;
192
for (int index = 0; index < colorNamesSize; index++) {
193
SkNameRGB nameRGB = colorNames[index];
194
const char* name = nameRGB.name;
195
size_t len = strlen(name);
196
originalSize += len + 9;
201
const char* start = name;
202
for (int chIndex = 0; chIndex < 6; chIndex++) {
204
compressed |= *name ? *name++ - 'a' + 1 : 0 ;
206
replacement += sizeof(int);
210
compressed |= 0x80000000;
213
if (len <= 6) { // last
218
SkDebugf("0x%08x, ", compressed);
219
comment.append(start, name - start);
220
} while (last == false);
221
replacement += sizeof(int);
222
SkDebugf("0x%08x, ", nameRGB.rgb);
223
SkDebugf("// %s\n", comment.c_str());
226
SkDebugf("// original = %d : replacement = %d\n", originalSize, replacement);
227
SkASSERT(0); // always stop after creating table
232
static const unsigned int gColorNames[] = {
233
0x85891945, 0x32a50000, 0x00f0f8ff, // aliceblue
234
0x85d44c6b, 0x16e84d0a, 0x00faebd7, // antiquewhite
235
0x86350800, 0x0000ffff, // aqua
236
0x86350b43, 0x492e2800, 0x007fffd4, // aquamarine
237
0x87559140, 0x00f0ffff, // azure
238
0x88a93940, 0x00f5f5dc, // beige
239
0x89338d4a, 0x00ffe4c4, // bisque
240
0x89811ac0, 0x00000000, // black
241
0x898170d1, 0x1481635f, 0x38800000, 0x00ffebcd, // blanchedalmond
242
0x89952800, 0x000000ff, // blue
243
0x89952d93, 0x3d85a000, 0x008a2be2, // blueviolet
244
0x8a4fbb80, 0x00a52a2a, // brown
245
0x8ab2666f, 0x3de40000, 0x00deb887, // burlywood
246
0x8c242d05, 0x32a50000, 0x005f9ea0, // cadetblue
247
0x8d019525, 0x16b32800, 0x007fff00, // chartreuse
248
0x8d0f1bd9, 0x06850000, 0x00d2691e, // chocolate
249
0x8df20b00, 0x00ff7f50, // coral
250
0x8df27199, 0x3ee59099, 0x54a00000, 0x006495ed, // cornflowerblue
251
0x8df274d3, 0x31600000, 0x00fff8dc, // cornsilk
252
0x8e496cdf, 0x38000000, 0x00dc143c, // crimson
253
0x8f217000, 0x0000ffff, // cyan
254
0x90325899, 0x54a00000, 0x0000008b, // darkblue
255
0x903258f3, 0x05c00000, 0x00008b8b, // darkcyan
256
0x903259df, 0x3085749f, 0x10000000, 0x00b8860b, // darkgoldenrod
257
0x903259e5, 0x07200000, 0x00a9a9a9, // darkgray
258
0x903259e5, 0x14ae0000, 0x00006400, // darkgreen
259
0x90325ad1, 0x05690000, 0x00bdb76b, // darkkhaki
260
0x90325b43, 0x1caea040, 0x008b008b, // darkmagenta
261
0x90325bd9, 0x26c53c8b, 0x15c00000, 0x00556b2f, // darkolivegreen
262
0x90325be5, 0x05c72800, 0x00ff8c00, // darkorange
263
0x90325be5, 0x0d092000, 0x009932cc, // darkorchid
264
0x90325c8b, 0x10000000, 0x008b0000, // darkred
265
0x90325cc3, 0x31af7000, 0x00e9967a, // darksalmon
266
0x90325ccb, 0x04f2295c, 0x008fbc8f, // darkseagreen
267
0x90325cd9, 0x0685132b, 0x14000000, 0x00483d8b, // darkslateblue
268
0x90325cd9, 0x06853c83, 0x64000000, 0x002f4f4f, // darkslategray
269
0x90325d2b, 0x4a357a67, 0x14000000, 0x0000ced1, // darkturquoise
270
0x90325d93, 0x3d85a000, 0x009400d3, // darkviolet
271
0x90a58413, 0x39600000, 0x00ff1493, // deeppink
272
0x90a584d7, 0x644ca940, 0x0000bfff, // deepskyblue
273
0x912d3c83, 0x64000000, 0x00696969, // dimgray
274
0x91e43965, 0x09952800, 0x001e90ff, // dodgerblue
275
0x993228a5, 0x246b0000, 0x00b22222, // firebrick
276
0x998f9059, 0x5d09a140, 0x00fffaf0, // floralwhite
277
0x99f22ce9, 0x1e452b80, 0x00228b22, // forestgreen
278
0x9aa344d3, 0x04000000, 0x00ff00ff, // fuchsia
279
0x9c2974c5, 0x3e4f0000, 0x00dcdcdc, // gainsboro
280
0x9d0f9d2f, 0x21342800, 0x00f8f8ff, // ghostwhite
281
0x9dec2000, 0x00ffd700, // gold
282
0x9dec215d, 0x49e40000, 0x00daa520, // goldenrod
283
0x9e41c800, 0x00808080, // gray
284
0x9e452b80, 0x00008000, // green
285
0x9e452bb3, 0x158c7dc0, 0x00adff2f, // greenyellow
286
0xa1ee2e49, 0x16e00000, 0x00f0fff0, // honeydew
287
0xa1f4825d, 0x2c000000, 0x00ff69b4, // hotpink
288
0xa5c4485d, 0x48a40000, 0x00cd5c5c, // indianred
289
0xa5c449de, 0x004b0082, // indigo
290
0xa6cf9640, 0x00fffff0, // ivory
291
0xad015a40, 0x00f0e68c, // khaki
292
0xb0362b89, 0x16400000, 0x00e6e6fa, // lavender
293
0xb0362b89, 0x16426567, 0x20000000, 0x00fff0f5, // lavenderblush
294
0xb03771e5, 0x14ae0000, 0x007cfc00, // lawngreen
295
0xb0ad7b87, 0x212633dc, 0x00fffacd, // lemonchiffon
296
0xb1274505, 0x32a50000, 0x00add8e6, // lightblue
297
0xb1274507, 0x3e416000, 0x00f08080, // lightcoral
298
0xb1274507, 0x642e0000, 0x00e0ffff, // lightcyan
299
0xb127450f, 0x3d842ba5, 0x3c992b19, 0x3ee00000, 0x00fafad2, // lightgoldenrodyellow
300
0xb127450f, 0x48a57000, 0x0090ee90, // lightgreen
301
0xb127450f, 0x48b90000, 0x00d3d3d3, // lightgrey
302
0xb1274521, 0x25cb0000, 0x00ffb6c1, // lightpink
303
0xb1274527, 0x058d7b80, 0x00ffa07a, // lightsalmon
304
0xb1274527, 0x1427914b, 0x38000000, 0x0020b2aa, // lightseagreen
305
0xb1274527, 0x2f22654a, 0x0087cefa, // lightskyblue
306
0xb1274527, 0x303429e5, 0x07200000, 0x00778899, // lightslategray
307
0xb1274527, 0x50a56099, 0x54a00000, 0x00b0c4de, // lightsteelblue
308
0xb1274533, 0x158c7dc0, 0x00ffffe0, // lightyellow
309
0xb12d2800, 0x0000ff00, // lime
310
0xb12d29e5, 0x14ae0000, 0x0032cd32, // limegreen
311
0xb12e2b80, 0x00faf0e6, // linen
312
0xb4272ba9, 0x04000000, 0x00ff00ff, // magenta
313
0xb4327bdc, 0x00800000, // maroon
314
0xb4a44d5b, 0x06350b43, 0x492e2800, 0x0066cdaa, // mediumaquamarine
315
0xb4a44d5b, 0x09952800, 0x000000cd, // mediumblue
316
0xb4a44d5b, 0x3e434248, 0x00ba55d3, // mediumorchid
317
0xb4a44d5b, 0x42b2830a, 0x009370db, // mediumpurple
318
0xb4a44d5b, 0x4ca13c8b, 0x15c00000, 0x003cb371, // mediumseagreen
319
0xb4a44d5b, 0x4d81a145, 0x32a50000, 0x007b68ee, // mediumslateblue
320
0xb4a44d5b, 0x4e124b8f, 0x1e452b80, 0x0000fa9a, // mediumspringgreen
321
0xb4a44d5b, 0x52b28d5f, 0x26650000, 0x0048d1cc, // mediumturquoise
322
0xb4a44d5b, 0x592f6169, 0x48a40000, 0x00c71585, // mediumvioletred
323
0xb524724f, 0x2282654a, 0x00191970, // midnightblue
324
0xb52ea0e5, 0x142d0000, 0x00f5fffa, // mintcream
325
0xb533a665, 0x3e650000, 0x00ffe4e1, // mistyrose
326
0xb5e31867, 0x25c00000, 0x00ffe4b5, // moccasin
327
0xb8360a9f, 0x5d09a140, 0x00ffdead, // navajowhite
328
0xb836c800, 0x00000080, // navy
329
0xbd846047, 0x14000000, 0x00fdf5e6, // oldlace
330
0xbd89b140, 0x00808000, // olive
331
0xbd89b149, 0x48220000, 0x006b8e23, // olivedrab
332
0xbe4171ca, 0x00ffa500, // orange
333
0xbe4171cb, 0x48a40000, 0x00ff4500, // orangered
334
0xbe434248, 0x00da70d6, // orchid
335
0xc02c29df, 0x3085749f, 0x10000000, 0x00eee8aa, // palegoldenrod
336
0xc02c29e5, 0x14ae0000, 0x0098fb98, // palegreen
337
0xc02c2d2b, 0x4a357a67, 0x14000000, 0x00afeeee, // paleturquoise
338
0xc02c2d93, 0x3d85a48b, 0x10000000, 0x00db7093, // palevioletred
339
0xc0300e43, 0x5d098000, 0x00ffefd5, // papayawhip
340
0xc0a11a21, 0x54c60000, 0x00ffdab9, // peachpuff
341
0xc0b2a800, 0x00cd853f, // peru
342
0xc12e5800, 0x00ffc0cb, // pink
343
0xc1956800, 0x00dda0dd, // plum
344
0xc1f72165, 0x09952800, 0x00b0e0e6, // powderblue
345
0xc2b2830a, 0x00800080, // purple
346
0xc8a40000, 0x00ff0000, // red
347
0xc9f3c8a5, 0x3eee0000, 0x00bc8f8f, // rosybrown
348
0xc9f90b05, 0x32a50000, 0x004169e1, // royalblue
349
0xcc24230b, 0x0a4fbb80, 0x008b4513, // saddlebrown
350
0xcc2c6bdc, 0x00fa8072, // salmon
351
0xcc2e2645, 0x49f77000, 0x00f4a460, // sandybrown
352
0xcca13c8b, 0x15c00000, 0x002e8b57, // seagreen
353
0xcca19a0b, 0x31800000, 0x00fff5ee, // seashell
354
0xcd257382, 0x00a0522d, // sienna
355
0xcd2cb164, 0x00c0c0c0, // silver
356
0xcd79132b, 0x14000000, 0x0087ceeb, // skyblue
357
0xcd81a145, 0x32a50000, 0x006a5acd, // slateblue
358
0xcd81a14f, 0x48390000, 0x00708090, // slategray
359
0xcdcfb800, 0x00fffafa, // snow
360
0xce124b8f, 0x1e452b80, 0x0000ff7f, // springgreen
361
0xce852b05, 0x32a50000, 0x004682b4, // steelblue
362
0xd02e0000, 0x00d2b48c, // tan
363
0xd0a16000, 0x00008080, // teal
364
0xd1099d19, 0x14000000, 0x00d8bfd8, // thistle
365
0xd1ed0d1e, 0x00ff6347, // tomato
366
0xd2b28d5f, 0x26650000, 0x0040e0d0, // turquoise
367
0xd92f6168, 0x00ee82ee, // violet
368
0xdd050d00, 0x00f5deb3, // wheat
369
0xdd09a140, 0x00ffffff, // white
370
0xdd09a167, 0x35eb2800, 0x00f5f5f5, // whitesmoke
371
0xe4ac63ee, 0x00ffff00, // yellow
372
0xe4ac63ef, 0x1e452b80, 0x009acd32 // yellowgreen
373
}; // original = 2505 : replacement = 1616
376
const char* SkParse::FindNamedColor(const char* name, size_t len, SkColor* color) {
377
const char* namePtr = name;
378
unsigned int sixMatches[4];
379
unsigned int* sixMatchPtr = sixMatches;
384
unsigned int sixMatch = 0;
385
for (int chIndex = 0; chIndex < 6; chIndex++) {
387
ch = *namePtr | 0x20;
388
if (ch < 'a' || ch > 'z')
394
sixMatch |= ch ; // turn 'A' (0x41) into 'a' (0x61);
399
sixMatch |= 0x80000000;
402
ch = *namePtr | 0x20;
403
last = ch < 'a' || ch > 'z';
407
*sixMatchPtr++ = sixMatch;
408
} while (last == false && len > 0);
409
const int colorNameSize = sizeof(gColorNames) / sizeof(unsigned int);
411
int hi = colorNameSize - 3; // back off to beginning of yellowgreen
413
int mid = (hi + lo) >> 1;
414
while ((int) gColorNames[mid] >= 0)
416
sixMatchPtr = sixMatches;
417
while (gColorNames[mid] == *sixMatchPtr) {
419
if ((*sixMatchPtr & 1) == 0) { // last
420
*color = gColorNames[mid] | 0xFF000000;
425
int sixMask = *sixMatchPtr & ~0x80000000;
426
int midMask = gColorNames[mid] & ~0x80000000;
427
if (sixMask > midMask) {
428
lo = mid + 2; // skip color
429
while ((int) gColorNames[lo] >= 0)
431
} else if (hi == mid)
439
// !!! move to char utilities
440
//static int count_separators(const char* str, const char* sep) {
442
// int separators = 0;
443
// while ((c = *str++) != '\0') {
444
// if (strchr(sep, c) == NULL)
447
// if ((c = *str++) == '\0')
449
// } while (strchr(sep, c) != NULL);
453
// return separators;
456
static inline unsigned nib2byte(unsigned n)
458
SkASSERT((n & ~0xF) == 0);
462
// BEGIN GEARS MODIFICATION
463
// TODO(nigeltao): Get this code upstream into Skia trunk. When that happens,
464
// we should also delete the commented out count_separators function above, and
465
// the (also commented out) code that calls it below (in SkParse::FindColor).
466
static bool is_a_z(char value, char lc_target) {
467
SkASSERT(lc_target >= 'a' && lc_target <= 'z');
468
return (value | 32) == lc_target;
471
static const char* ParseRGBAOrHSLA(const char* value, SkColor* colorPtr) {
472
bool isRgb = is_a_z(value[0], 'r') &&
473
is_a_z(value[1], 'g') &&
474
is_a_z(value[2], 'b');
475
bool isHsl = is_a_z(value[0], 'h') &&
476
is_a_z(value[1], 's') &&
477
is_a_z(value[2], 'l');
478
if (!isRgb && !isHsl)
481
bool hasAlpha = value[0] == 'a' || value[0] == 'A';
484
while (*value == ' ')
490
value = SkParse::FindScalars(value, args, hasAlpha ? 4 : 3);
493
while (*value == ' ')
501
a = SkPin32(SkScalarRound(args[3] * 255), 0, 255);
504
// The r, g and b components are in the range [0-255], but the alpha
505
// component is in the range [0.0-1.0].
506
// Furthermore (and strictly speaking), the CSS spec (and also WebKit's
507
// CSSParser::parseColorParameters in WebCore/css/CSSParser.cpp) also
508
// lets r, g and b be specified in terms of percentages (e.g.
509
// "rgb(100%,50%,0)" is equivalent to "rgb(255,128,0)", but we ignore
510
// this case for now, since it isn't that common, and it would make
511
// this function a little more complicated than just calling
512
// SkParse::FindScalars.
513
int r = SkPin32(SkScalarRound(args[0]), 0, 255);
514
int g = SkPin32(SkScalarRound(args[1]), 0, 255);
515
int b = SkPin32(SkScalarRound(args[2]), 0, 255);
516
*colorPtr = SkColorSetARGB(a, r, g, b);
519
*colorPtr = SkHSVToColor(a, args);
523
// END GEARS MODIFICATION
525
const char* SkParse::FindColor(const char* value, SkColor* colorPtr) {
526
unsigned int oldAlpha = SkColorGetA(*colorPtr);
527
if (value[0] == '#') {
529
const char* end = SkParse::FindHex(value + 1, &hex);
533
size_t len = end - value - 1;
534
if (len == 3 || len == 4) {
535
unsigned a = len == 4 ? nib2byte(hex >> 12) : oldAlpha;
536
unsigned r = nib2byte((hex >> 8) & 0xF);
537
unsigned g = nib2byte((hex >> 4) & 0xF);
538
unsigned b = nib2byte(hex & 0xF);
539
*colorPtr = SkColorSetARGB(a, r, g, b);
541
} else if (len == 6 || len == 8) {
543
hex |= oldAlpha << 24;
550
// } else if (strchr(value, ',')) {
551
// SkScalar array[4];
552
// int count = count_separators(value, ",") + 1; // !!! count commas, add 1
553
// SkASSERT(count == 3 || count == 4);
554
// array[0] = SK_Scalar1 * 255;
555
// const char* end = SkParse::FindScalars(value, &array[4 - count], count);
558
// !!! range check for errors?
559
// *colorPtr = SkColorSetARGB(SkScalarRound(array[0]), SkScalarRound(array[1]),
560
// SkScalarRound(array[2]), SkScalarRound(array[3]));
563
const char* rgbaColor = ParseRGBAOrHSLA(value, colorPtr);
564
return rgbaColor ? rgbaColor
565
: FindNamedColor(value, strlen(value), colorPtr);
569
#ifdef SK_SUPPORT_UNITTEST
570
void SkParse::TestColor() {
572
CreateTable(); // regenerates data table in the output window
575
for (index = 0; index < colorNamesSize; index++) {
576
result = SK_ColorBLACK;
577
SkNameRGB nameRGB = colorNames[index];
578
SkASSERT(FindColor(nameRGB.name, &result) != NULL);
579
SkASSERT(result == (SkColor) (nameRGB.rgb | 0xFF000000));
581
for (index = 0; index < colorNamesSize; index++) {
582
result = SK_ColorBLACK;
583
SkNameRGB nameRGB = colorNames[index];
585
size_t len = strlen(nameRGB.name);
586
memcpy(bad, nameRGB.name, len);
588
SkASSERT(FindColor(bad, &result) == false);
590
SkASSERT(FindColor(bad, &result) == false);
592
result = SK_ColorBLACK;
593
SkASSERT(FindColor("lightGrey", &result));
594
SkASSERT(result == 0xffd3d3d3);
595
// SkASSERT(FindColor("12,34,56,78", &result));
596
// SkASSERT(result == ((12 << 24) | (34 << 16) | (56 << 8) | (78 << 0)));
597
result = SK_ColorBLACK;
598
SkASSERT(FindColor("#ABCdef", &result));
599
SkASSERT(result == 0XFFABCdef);
600
SkASSERT(FindColor("#12ABCdef", &result));
601
SkASSERT(result == 0X12ABCdef);
602
result = SK_ColorBLACK;
603
SkASSERT(FindColor("#123", &result));
604
SkASSERT(result == 0Xff112233);
605
SkASSERT(FindColor("#abcd", &result));
606
SkASSERT(result == 0Xaabbccdd);
607
result = SK_ColorBLACK;
608
// SkASSERT(FindColor("71,162,253", &result));
609
// SkASSERT(result == ((0xFF << 24) | (71 << 16) | (162 << 8) | (253 << 0)));
611
SkASSERT(FindColor("rgb(100,50,0)", &result));
612
SkASSERT(result == 0xff643200);
613
SkASSERT(FindColor("rgb( 1, 2, 3 )", &result));
614
SkASSERT(result == 0xff010203);
615
SkASSERT(FindColor("RGBA(0,255,0,0.5)", &result));
616
SkASSERT(result == 0x8000ff00);
617
SkASSERT(FindColor("rgba(300,-17,1.1,999)", &result));
618
SkASSERT(result == 0xffff0001);
620
SkASSERT(FindColor("hsl(0, 1, 1)", &result));
621
SkASSERT(result == 0xffff0000);
622
SkASSERT(FindColor("hsl(180, 1, 0.75)", &result));
623
SkASSERT(result == 0xff00c0c0);
624
SkASSERT(FindColor("hsl(180, 0.5, 0.5)", &result));
625
SkASSERT(result == 0xff3f8080);
626
SkASSERT(FindColor("HslA(120, 1.0, 0.5, 0.25)", &result));
627
SkASSERT(result == 0x40008000);
628
SkASSERT(FindColor("HSL(180, 1.2, -33)", &result));
629
SkASSERT(result == 0xff000000);
631
SkASSERT(FindColor("rgb(10\0,50,0)", &result) == NULL);
632
SkASSERT(FindColor("rgba(100,50,0)", &result) == NULL);
633
SkASSERT(FindColor("roygbiv(1,2,3,4,5,6,7)", &result) == NULL);