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 "SkParse.h" 10 11#ifdef SK_DEBUG 12#include "SkString.h" 13 14#ifdef SK_SUPPORT_UNITTEST 15 // compress names 6 chars per long (packed 5 bits/char ) 16 // note: little advantage to splitting chars across longs, since 3 longs at 2 unused bits each 17 // allow for one additional split char (vs. the 18 unsplit chars in the three longs) 18 // use extra two bits to represent: 19 // 00 : final 6 (or fewer) chars (if 'a' is 0x01, zero could have special meaning) 20 // 01 : not final 6 chars 21 // 10 : color 22 // 11 : unused, except as debugging sentinal? (could be -1 for easier test) 23 // !!! the bit to end the word (last) is at the low bit for binary search 24 // lookup first character in offset for quick start 25 // offset is 27-entry table of bytes(?) that trims linear search to at most 21 entries ('d') 26 // shift match into long; set bit 30 if it all doesn't fit 27 // while longs don't match, march forward 28 // if they do match, and bit 30 is set, advance match, clearing bit 30 if 29 // final chars, and advance to next test 30 // if they do match, and bit 30 is clear, get next long (color) and return it 31 // stop at lookup of first char + 1 32static const struct SkNameRGB { 33 const char* name; 34 int rgb; 35} colorNames[] = { 36 { "aliceblue", 0xF0F8FF }, 37 { "antiquewhite", 0xFAEBD7 }, 38 { "aqua", 0x00FFFF }, 39 { "aquamarine", 0x7FFFD4 }, 40 { "azure", 0xF0FFFF }, 41 { "beige", 0xF5F5DC }, 42 { "bisque", 0xFFE4C4 }, 43 { "black", 0x000000 }, 44 { "blanchedalmond", 0xFFEBCD }, 45 { "blue", 0x0000FF }, 46 { "blueviolet", 0x8A2BE2 }, 47 { "brown", 0xA52A2A }, 48 { "burlywood", 0xDEB887 }, 49 { "cadetblue", 0x5F9EA0 }, 50 { "chartreuse", 0x7FFF00 }, 51 { "chocolate", 0xD2691E }, 52 { "coral", 0xFF7F50 }, 53 { "cornflowerblue", 0x6495ED }, 54 { "cornsilk", 0xFFF8DC }, 55 { "crimson", 0xDC143C }, 56 { "cyan", 0x00FFFF }, 57 { "darkblue", 0x00008B }, 58 { "darkcyan", 0x008B8B }, 59 { "darkgoldenrod", 0xB8860B }, 60 { "darkgray", 0xA9A9A9 }, 61 { "darkgreen", 0x006400 }, 62 { "darkkhaki", 0xBDB76B }, 63 { "darkmagenta", 0x8B008B }, 64 { "darkolivegreen", 0x556B2F }, 65 { "darkorange", 0xFF8C00 }, 66 { "darkorchid", 0x9932CC }, 67 { "darkred", 0x8B0000 }, 68 { "darksalmon", 0xE9967A }, 69 { "darkseagreen", 0x8FBC8F }, 70 { "darkslateblue", 0x483D8B }, 71 { "darkslategray", 0x2F4F4F }, 72 { "darkturquoise", 0x00CED1 }, 73 { "darkviolet", 0x9400D3 }, 74 { "deeppink", 0xFF1493 }, 75 { "deepskyblue", 0x00BFFF }, 76 { "dimgray", 0x696969 }, 77 { "dodgerblue", 0x1E90FF }, 78 { "firebrick", 0xB22222 }, 79 { "floralwhite", 0xFFFAF0 }, 80 { "forestgreen", 0x228B22 }, 81 { "fuchsia", 0xFF00FF }, 82 { "gainsboro", 0xDCDCDC }, 83 { "ghostwhite", 0xF8F8FF }, 84 { "gold", 0xFFD700 }, 85 { "goldenrod", 0xDAA520 }, 86 { "gray", 0x808080 }, 87 { "green", 0x008000 }, 88 { "greenyellow", 0xADFF2F }, 89 { "honeydew", 0xF0FFF0 }, 90 { "hotpink", 0xFF69B4 }, 91 { "indianred", 0xCD5C5C }, 92 { "indigo", 0x4B0082 }, 93 { "ivory", 0xFFFFF0 }, 94 { "khaki", 0xF0E68C }, 95 { "lavender", 0xE6E6FA }, 96 { "lavenderblush", 0xFFF0F5 }, 97 { "lawngreen", 0x7CFC00 }, 98 { "lemonchiffon", 0xFFFACD }, 99 { "lightblue", 0xADD8E6 }, 100 { "lightcoral", 0xF08080 }, 101 { "lightcyan", 0xE0FFFF }, 102 { "lightgoldenrodyellow", 0xFAFAD2 }, 103 { "lightgreen", 0x90EE90 }, 104 { "lightgrey", 0xD3D3D3 }, 105 { "lightpink", 0xFFB6C1 }, 106 { "lightsalmon", 0xFFA07A }, 107 { "lightseagreen", 0x20B2AA }, 108 { "lightskyblue", 0x87CEFA }, 109 { "lightslategray", 0x778899 }, 110 { "lightsteelblue", 0xB0C4DE }, 111 { "lightyellow", 0xFFFFE0 }, 112 { "lime", 0x00FF00 }, 113 { "limegreen", 0x32CD32 }, 114 { "linen", 0xFAF0E6 }, 115 { "magenta", 0xFF00FF }, 116 { "maroon", 0x800000 }, 117 { "mediumaquamarine", 0x66CDAA }, 118 { "mediumblue", 0x0000CD }, 119 { "mediumorchid", 0xBA55D3 }, 120 { "mediumpurple", 0x9370DB }, 121 { "mediumseagreen", 0x3CB371 }, 122 { "mediumslateblue", 0x7B68EE }, 123 { "mediumspringgreen", 0x00FA9A }, 124 { "mediumturquoise", 0x48D1CC }, 125 { "mediumvioletred", 0xC71585 }, 126 { "midnightblue", 0x191970 }, 127 { "mintcream", 0xF5FFFA }, 128 { "mistyrose", 0xFFE4E1 }, 129 { "moccasin", 0xFFE4B5 }, 130 { "navajowhite", 0xFFDEAD }, 131 { "navy", 0x000080 }, 132 { "oldlace", 0xFDF5E6 }, 133 { "olive", 0x808000 }, 134 { "olivedrab", 0x6B8E23 }, 135 { "orange", 0xFFA500 }, 136 { "orangered", 0xFF4500 }, 137 { "orchid", 0xDA70D6 }, 138 { "palegoldenrod", 0xEEE8AA }, 139 { "palegreen", 0x98FB98 }, 140 { "paleturquoise", 0xAFEEEE }, 141 { "palevioletred", 0xDB7093 }, 142 { "papayawhip", 0xFFEFD5 }, 143 { "peachpuff", 0xFFDAB9 }, 144 { "peru", 0xCD853F }, 145 { "pink", 0xFFC0CB }, 146 { "plum", 0xDDA0DD }, 147 { "powderblue", 0xB0E0E6 }, 148 { "purple", 0x800080 }, 149 { "red", 0xFF0000 }, 150 { "rosybrown", 0xBC8F8F }, 151 { "royalblue", 0x4169E1 }, 152 { "saddlebrown", 0x8B4513 }, 153 { "salmon", 0xFA8072 }, 154 { "sandybrown", 0xF4A460 }, 155 { "seagreen", 0x2E8B57 }, 156 { "seashell", 0xFFF5EE }, 157 { "sienna", 0xA0522D }, 158 { "silver", 0xC0C0C0 }, 159 { "skyblue", 0x87CEEB }, 160 { "slateblue", 0x6A5ACD }, 161 { "slategray", 0x708090 }, 162 { "snow", 0xFFFAFA }, 163 { "springgreen", 0x00FF7F }, 164 { "steelblue", 0x4682B4 }, 165 { "tan", 0xD2B48C }, 166 { "teal", 0x008080 }, 167 { "thistle", 0xD8BFD8 }, 168 { "tomato", 0xFF6347 }, 169 { "turquoise", 0x40E0D0 }, 170 { "violet", 0xEE82EE }, 171 { "wheat", 0xF5DEB3 }, 172 { "white", 0xFFFFFF }, 173 { "whitesmoke", 0xF5F5F5 }, 174 { "yellow", 0xFFFF00 }, 175 { "yellowgreen", 0x9ACD32 } 176}; 177 178int colorNamesSize = SK_ARRAY_COUNT(colorNames); 179 180static void CreateTable() { 181 SkString comment; 182 size_t originalSize = 0; 183 int replacement = 0; 184 for (int index = 0; index < colorNamesSize; index++) { 185 SkNameRGB nameRGB = colorNames[index]; 186 const char* name = nameRGB.name; 187 size_t len = strlen(name); 188 originalSize += len + 9; 189 bool first = true; 190 bool last = false; 191 do { 192 int compressed = 0; 193 const char* start = name; 194 for (int chIndex = 0; chIndex < 6; chIndex++) { 195 compressed <<= 5; 196 compressed |= *name ? *name++ - 'a' + 1 : 0 ; 197 } 198 replacement += sizeof(int); 199 compressed <<= 1; 200 compressed |= 1; 201 if (first) { 202 compressed |= 0x80000000; 203 first = false; 204 } 205 if (len <= 6) { // last 206 compressed &= ~1; 207 last = true; 208 } 209 len -= 6; 210 SkDebugf("0x%08x, ", compressed); 211 comment.append(start, name - start); 212 } while (last == false); 213 replacement += sizeof(int); 214 SkDebugf("0x%08x, ", nameRGB.rgb); 215 SkDebugf("// %s\n", comment.c_str()); 216 comment.reset(); 217 } 218 SkDebugf("// original = %d : replacement = %d\n", originalSize, replacement); 219 SkASSERT(0); // always stop after creating table 220} 221#endif 222 223#endif 224 225static const unsigned int gColorNames[] = { 2260x85891945, 0x32a50000, 0x00f0f8ff, // aliceblue 2270x85d44c6b, 0x16e84d0a, 0x00faebd7, // antiquewhite 2280x86350800, 0x0000ffff, // aqua 2290x86350b43, 0x492e2800, 0x007fffd4, // aquamarine 2300x87559140, 0x00f0ffff, // azure 2310x88a93940, 0x00f5f5dc, // beige 2320x89338d4a, 0x00ffe4c4, // bisque 2330x89811ac0, 0x00000000, // black 2340x898170d1, 0x1481635f, 0x38800000, 0x00ffebcd, // blanchedalmond 2350x89952800, 0x000000ff, // blue 2360x89952d93, 0x3d85a000, 0x008a2be2, // blueviolet 2370x8a4fbb80, 0x00a52a2a, // brown 2380x8ab2666f, 0x3de40000, 0x00deb887, // burlywood 2390x8c242d05, 0x32a50000, 0x005f9ea0, // cadetblue 2400x8d019525, 0x16b32800, 0x007fff00, // chartreuse 2410x8d0f1bd9, 0x06850000, 0x00d2691e, // chocolate 2420x8df20b00, 0x00ff7f50, // coral 2430x8df27199, 0x3ee59099, 0x54a00000, 0x006495ed, // cornflowerblue 2440x8df274d3, 0x31600000, 0x00fff8dc, // cornsilk 2450x8e496cdf, 0x38000000, 0x00dc143c, // crimson 2460x8f217000, 0x0000ffff, // cyan 2470x90325899, 0x54a00000, 0x0000008b, // darkblue 2480x903258f3, 0x05c00000, 0x00008b8b, // darkcyan 2490x903259df, 0x3085749f, 0x10000000, 0x00b8860b, // darkgoldenrod 2500x903259e5, 0x07200000, 0x00a9a9a9, // darkgray 2510x903259e5, 0x14ae0000, 0x00006400, // darkgreen 2520x90325ad1, 0x05690000, 0x00bdb76b, // darkkhaki 2530x90325b43, 0x1caea040, 0x008b008b, // darkmagenta 2540x90325bd9, 0x26c53c8b, 0x15c00000, 0x00556b2f, // darkolivegreen 2550x90325be5, 0x05c72800, 0x00ff8c00, // darkorange 2560x90325be5, 0x0d092000, 0x009932cc, // darkorchid 2570x90325c8b, 0x10000000, 0x008b0000, // darkred 2580x90325cc3, 0x31af7000, 0x00e9967a, // darksalmon 2590x90325ccb, 0x04f2295c, 0x008fbc8f, // darkseagreen 2600x90325cd9, 0x0685132b, 0x14000000, 0x00483d8b, // darkslateblue 2610x90325cd9, 0x06853c83, 0x64000000, 0x002f4f4f, // darkslategray 2620x90325d2b, 0x4a357a67, 0x14000000, 0x0000ced1, // darkturquoise 2630x90325d93, 0x3d85a000, 0x009400d3, // darkviolet 2640x90a58413, 0x39600000, 0x00ff1493, // deeppink 2650x90a584d7, 0x644ca940, 0x0000bfff, // deepskyblue 2660x912d3c83, 0x64000000, 0x00696969, // dimgray 2670x91e43965, 0x09952800, 0x001e90ff, // dodgerblue 2680x993228a5, 0x246b0000, 0x00b22222, // firebrick 2690x998f9059, 0x5d09a140, 0x00fffaf0, // floralwhite 2700x99f22ce9, 0x1e452b80, 0x00228b22, // forestgreen 2710x9aa344d3, 0x04000000, 0x00ff00ff, // fuchsia 2720x9c2974c5, 0x3e4f0000, 0x00dcdcdc, // gainsboro 2730x9d0f9d2f, 0x21342800, 0x00f8f8ff, // ghostwhite 2740x9dec2000, 0x00ffd700, // gold 2750x9dec215d, 0x49e40000, 0x00daa520, // goldenrod 2760x9e41c800, 0x00808080, // gray 2770x9e452b80, 0x00008000, // green 2780x9e452bb3, 0x158c7dc0, 0x00adff2f, // greenyellow 2790xa1ee2e49, 0x16e00000, 0x00f0fff0, // honeydew 2800xa1f4825d, 0x2c000000, 0x00ff69b4, // hotpink 2810xa5c4485d, 0x48a40000, 0x00cd5c5c, // indianred 2820xa5c449de, 0x004b0082, // indigo 2830xa6cf9640, 0x00fffff0, // ivory 2840xad015a40, 0x00f0e68c, // khaki 2850xb0362b89, 0x16400000, 0x00e6e6fa, // lavender 2860xb0362b89, 0x16426567, 0x20000000, 0x00fff0f5, // lavenderblush 2870xb03771e5, 0x14ae0000, 0x007cfc00, // lawngreen 2880xb0ad7b87, 0x212633dc, 0x00fffacd, // lemonchiffon 2890xb1274505, 0x32a50000, 0x00add8e6, // lightblue 2900xb1274507, 0x3e416000, 0x00f08080, // lightcoral 2910xb1274507, 0x642e0000, 0x00e0ffff, // lightcyan 2920xb127450f, 0x3d842ba5, 0x3c992b19, 0x3ee00000, 0x00fafad2, // lightgoldenrodyellow 2930xb127450f, 0x48a57000, 0x0090ee90, // lightgreen 2940xb127450f, 0x48b90000, 0x00d3d3d3, // lightgrey 2950xb1274521, 0x25cb0000, 0x00ffb6c1, // lightpink 2960xb1274527, 0x058d7b80, 0x00ffa07a, // lightsalmon 2970xb1274527, 0x1427914b, 0x38000000, 0x0020b2aa, // lightseagreen 2980xb1274527, 0x2f22654a, 0x0087cefa, // lightskyblue 2990xb1274527, 0x303429e5, 0x07200000, 0x00778899, // lightslategray 3000xb1274527, 0x50a56099, 0x54a00000, 0x00b0c4de, // lightsteelblue 3010xb1274533, 0x158c7dc0, 0x00ffffe0, // lightyellow 3020xb12d2800, 0x0000ff00, // lime 3030xb12d29e5, 0x14ae0000, 0x0032cd32, // limegreen 3040xb12e2b80, 0x00faf0e6, // linen 3050xb4272ba9, 0x04000000, 0x00ff00ff, // magenta 3060xb4327bdc, 0x00800000, // maroon 3070xb4a44d5b, 0x06350b43, 0x492e2800, 0x0066cdaa, // mediumaquamarine 3080xb4a44d5b, 0x09952800, 0x000000cd, // mediumblue 3090xb4a44d5b, 0x3e434248, 0x00ba55d3, // mediumorchid 3100xb4a44d5b, 0x42b2830a, 0x009370db, // mediumpurple 3110xb4a44d5b, 0x4ca13c8b, 0x15c00000, 0x003cb371, // mediumseagreen 3120xb4a44d5b, 0x4d81a145, 0x32a50000, 0x007b68ee, // mediumslateblue 3130xb4a44d5b, 0x4e124b8f, 0x1e452b80, 0x0000fa9a, // mediumspringgreen 3140xb4a44d5b, 0x52b28d5f, 0x26650000, 0x0048d1cc, // mediumturquoise 3150xb4a44d5b, 0x592f6169, 0x48a40000, 0x00c71585, // mediumvioletred 3160xb524724f, 0x2282654a, 0x00191970, // midnightblue 3170xb52ea0e5, 0x142d0000, 0x00f5fffa, // mintcream 3180xb533a665, 0x3e650000, 0x00ffe4e1, // mistyrose 3190xb5e31867, 0x25c00000, 0x00ffe4b5, // moccasin 3200xb8360a9f, 0x5d09a140, 0x00ffdead, // navajowhite 3210xb836c800, 0x00000080, // navy 3220xbd846047, 0x14000000, 0x00fdf5e6, // oldlace 3230xbd89b140, 0x00808000, // olive 3240xbd89b149, 0x48220000, 0x006b8e23, // olivedrab 3250xbe4171ca, 0x00ffa500, // orange 3260xbe4171cb, 0x48a40000, 0x00ff4500, // orangered 3270xbe434248, 0x00da70d6, // orchid 3280xc02c29df, 0x3085749f, 0x10000000, 0x00eee8aa, // palegoldenrod 3290xc02c29e5, 0x14ae0000, 0x0098fb98, // palegreen 3300xc02c2d2b, 0x4a357a67, 0x14000000, 0x00afeeee, // paleturquoise 3310xc02c2d93, 0x3d85a48b, 0x10000000, 0x00db7093, // palevioletred 3320xc0300e43, 0x5d098000, 0x00ffefd5, // papayawhip 3330xc0a11a21, 0x54c60000, 0x00ffdab9, // peachpuff 3340xc0b2a800, 0x00cd853f, // peru 3350xc12e5800, 0x00ffc0cb, // pink 3360xc1956800, 0x00dda0dd, // plum 3370xc1f72165, 0x09952800, 0x00b0e0e6, // powderblue 3380xc2b2830a, 0x00800080, // purple 3390xc8a40000, 0x00ff0000, // red 3400xc9f3c8a5, 0x3eee0000, 0x00bc8f8f, // rosybrown 3410xc9f90b05, 0x32a50000, 0x004169e1, // royalblue 3420xcc24230b, 0x0a4fbb80, 0x008b4513, // saddlebrown 3430xcc2c6bdc, 0x00fa8072, // salmon 3440xcc2e2645, 0x49f77000, 0x00f4a460, // sandybrown 3450xcca13c8b, 0x15c00000, 0x002e8b57, // seagreen 3460xcca19a0b, 0x31800000, 0x00fff5ee, // seashell 3470xcd257382, 0x00a0522d, // sienna 3480xcd2cb164, 0x00c0c0c0, // silver 3490xcd79132b, 0x14000000, 0x0087ceeb, // skyblue 3500xcd81a145, 0x32a50000, 0x006a5acd, // slateblue 3510xcd81a14f, 0x48390000, 0x00708090, // slategray 3520xcdcfb800, 0x00fffafa, // snow 3530xce124b8f, 0x1e452b80, 0x0000ff7f, // springgreen 3540xce852b05, 0x32a50000, 0x004682b4, // steelblue 3550xd02e0000, 0x00d2b48c, // tan 3560xd0a16000, 0x00008080, // teal 3570xd1099d19, 0x14000000, 0x00d8bfd8, // thistle 3580xd1ed0d1e, 0x00ff6347, // tomato 3590xd2b28d5f, 0x26650000, 0x0040e0d0, // turquoise 3600xd92f6168, 0x00ee82ee, // violet 3610xdd050d00, 0x00f5deb3, // wheat 3620xdd09a140, 0x00ffffff, // white 3630xdd09a167, 0x35eb2800, 0x00f5f5f5, // whitesmoke 3640xe4ac63ee, 0x00ffff00, // yellow 3650xe4ac63ef, 0x1e452b80, 0x009acd32 // yellowgreen 366}; // original = 2505 : replacement = 1616 367 368 369const char* SkParse::FindNamedColor(const char* name, size_t len, SkColor* color) { 370 const char* namePtr = name; 371 unsigned int sixMatches[4]; 372 unsigned int* sixMatchPtr = sixMatches; 373 bool first = true; 374 bool last = false; 375 char ch; 376 do { 377 unsigned int sixMatch = 0; 378 for (int chIndex = 0; chIndex < 6; chIndex++) { 379 sixMatch <<= 5; 380 ch = *namePtr | 0x20; 381 if (ch < 'a' || ch > 'z') 382 ch = 0; 383 else { 384 ch = ch - 'a' + 1; 385 namePtr++; 386 } 387 sixMatch |= ch ; // turn 'A' (0x41) into 'a' (0x61); 388 } 389 sixMatch <<= 1; 390 sixMatch |= 1; 391 if (first) { 392 sixMatch |= 0x80000000; 393 first = false; 394 } 395 ch = *namePtr | 0x20; 396 last = ch < 'a' || ch > 'z'; 397 if (last) 398 sixMatch &= ~1; 399 len -= 6; 400 *sixMatchPtr++ = sixMatch; 401 } while (last == false && len > 0); 402 const int colorNameSize = sizeof(gColorNames) / sizeof(unsigned int); 403 int lo = 0; 404 int hi = colorNameSize - 3; // back off to beginning of yellowgreen 405 while (lo <= hi) { 406 int mid = (hi + lo) >> 1; 407 while ((int) gColorNames[mid] >= 0) 408 --mid; 409 sixMatchPtr = sixMatches; 410 while (gColorNames[mid] == *sixMatchPtr) { 411 ++mid; 412 if ((*sixMatchPtr & 1) == 0) { // last 413 *color = gColorNames[mid] | 0xFF000000; 414 return namePtr; 415 } 416 ++sixMatchPtr; 417 } 418 int sixMask = *sixMatchPtr & ~0x80000000; 419 int midMask = gColorNames[mid] & ~0x80000000; 420 if (sixMask > midMask) { 421 lo = mid + 2; // skip color 422 while ((int) gColorNames[lo] >= 0) 423 ++lo; 424 } else if (hi == mid) 425 return nullptr; 426 else 427 hi = mid; 428 } 429 return nullptr; 430} 431 432// !!! move to char utilities 433//static int count_separators(const char* str, const char* sep) { 434// char c; 435// int separators = 0; 436// while ((c = *str++) != '\0') { 437// if (strchr(sep, c) == nullptr) 438// continue; 439// do { 440// if ((c = *str++) == '\0') 441// goto goHome; 442// } while (strchr(sep, c) != nullptr); 443// separators++; 444// } 445//goHome: 446// return separators; 447//} 448 449static inline unsigned nib2byte(unsigned n) 450{ 451 SkASSERT((n & ~0xF) == 0); 452 return (n << 4) | n; 453} 454 455const char* SkParse::FindColor(const char* value, SkColor* colorPtr) { 456 unsigned int oldAlpha = SkColorGetA(*colorPtr); 457 if (value[0] == '#') { 458 uint32_t hex; 459 const char* end = SkParse::FindHex(value + 1, &hex); 460// SkASSERT(end); 461 if (end == nullptr) 462 return end; 463 size_t len = end - value - 1; 464 if (len == 3 || len == 4) { 465 unsigned a = len == 4 ? nib2byte(hex >> 12) : oldAlpha; 466 unsigned r = nib2byte((hex >> 8) & 0xF); 467 unsigned g = nib2byte((hex >> 4) & 0xF); 468 unsigned b = nib2byte(hex & 0xF); 469 *colorPtr = SkColorSetARGB(a, r, g, b); 470 return end; 471 } else if (len == 6 || len == 8) { 472 if (len == 6) 473 hex |= oldAlpha << 24; 474 *colorPtr = hex; 475 return end; 476 } else { 477// SkASSERT(0); 478 return nullptr; 479 } 480// } else if (strchr(value, ',')) { 481// SkScalar array[4]; 482// int count = count_separators(value, ",") + 1; // !!! count commas, add 1 483// SkASSERT(count == 3 || count == 4); 484// array[0] = SK_Scalar1 * 255; 485// const char* end = SkParse::FindScalars(value, &array[4 - count], count); 486// if (end == nullptr) 487// return nullptr; 488 // !!! range check for errors? 489// *colorPtr = SkColorSetARGB(SkScalarRoundToInt(array[0]), SkScalarRoundToInt(array[1]), 490// SkScalarRoundToInt(array[2]), SkScalarRoundToInt(array[3])); 491// return end; 492 } else 493 return FindNamedColor(value, strlen(value), colorPtr); 494} 495 496#ifdef SK_SUPPORT_UNITTEST 497void SkParse::TestColor() { 498 if (false) 499 CreateTable(); // regenerates data table in the output window 500 SkColor result; 501 int index; 502 for (index = 0; index < colorNamesSize; index++) { 503 result = SK_ColorBLACK; 504 SkNameRGB nameRGB = colorNames[index]; 505 SkASSERT(FindColor(nameRGB.name, &result) != nullptr); 506 SkASSERT(result == (SkColor) (nameRGB.rgb | 0xFF000000)); 507 } 508 for (index = 0; index < colorNamesSize; index++) { 509 result = SK_ColorBLACK; 510 SkNameRGB nameRGB = colorNames[index]; 511 char bad[24]; 512 size_t len = strlen(nameRGB.name); 513 memcpy(bad, nameRGB.name, len); 514 bad[len - 1] -= 1; 515 SkASSERT(FindColor(bad, &result) == nullptr); 516 bad[len - 1] += 2; 517 SkASSERT(FindColor(bad, &result) == nullptr); 518 } 519 result = SK_ColorBLACK; 520 SkASSERT(FindColor("lightGrey", &result)); 521 SkASSERT(result == 0xffd3d3d3); 522// SkASSERT(FindColor("12,34,56,78", &result)); 523// SkASSERT(result == ((12 << 24) | (34 << 16) | (56 << 8) | (78 << 0))); 524 result = SK_ColorBLACK; 525 SkASSERT(FindColor("#ABCdef", &result)); 526 SkASSERT(result == 0XFFABCdef); 527 SkASSERT(FindColor("#12ABCdef", &result)); 528 SkASSERT(result == 0X12ABCdef); 529 result = SK_ColorBLACK; 530 SkASSERT(FindColor("#123", &result)); 531 SkASSERT(result == 0Xff112233); 532 SkASSERT(FindColor("#abcd", &result)); 533 SkASSERT(result == 0Xaabbccdd); 534 result = SK_ColorBLACK; 535// SkASSERT(FindColor("71,162,253", &result)); 536// SkASSERT(result == ((0xFF << 24) | (71 << 16) | (162 << 8) | (253 << 0))); 537} 538#endif 539