SkParseColor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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. static const unsigned int gColorNames[] = {
  9. 0x85891945, 0x32a50000, 0x00f0f8ff, // aliceblue
  10. 0x85d44c6b, 0x16e84d0a, 0x00faebd7, // antiquewhite
  11. 0x86350800, 0x0000ffff, // aqua
  12. 0x86350b43, 0x492e2800, 0x007fffd4, // aquamarine
  13. 0x87559140, 0x00f0ffff, // azure
  14. 0x88a93940, 0x00f5f5dc, // beige
  15. 0x89338d4a, 0x00ffe4c4, // bisque
  16. 0x89811ac0, 0x00000000, // black
  17. 0x898170d1, 0x1481635f, 0x38800000, 0x00ffebcd, // blanchedalmond
  18. 0x89952800, 0x000000ff, // blue
  19. 0x89952d93, 0x3d85a000, 0x008a2be2, // blueviolet
  20. 0x8a4fbb80, 0x00a52a2a, // brown
  21. 0x8ab2666f, 0x3de40000, 0x00deb887, // burlywood
  22. 0x8c242d05, 0x32a50000, 0x005f9ea0, // cadetblue
  23. 0x8d019525, 0x16b32800, 0x007fff00, // chartreuse
  24. 0x8d0f1bd9, 0x06850000, 0x00d2691e, // chocolate
  25. 0x8df20b00, 0x00ff7f50, // coral
  26. 0x8df27199, 0x3ee59099, 0x54a00000, 0x006495ed, // cornflowerblue
  27. 0x8df274d3, 0x31600000, 0x00fff8dc, // cornsilk
  28. 0x8e496cdf, 0x38000000, 0x00dc143c, // crimson
  29. 0x8f217000, 0x0000ffff, // cyan
  30. 0x90325899, 0x54a00000, 0x0000008b, // darkblue
  31. 0x903258f3, 0x05c00000, 0x00008b8b, // darkcyan
  32. 0x903259df, 0x3085749f, 0x10000000, 0x00b8860b, // darkgoldenrod
  33. 0x903259e5, 0x07200000, 0x00a9a9a9, // darkgray
  34. 0x903259e5, 0x14ae0000, 0x00006400, // darkgreen
  35. 0x90325ad1, 0x05690000, 0x00bdb76b, // darkkhaki
  36. 0x90325b43, 0x1caea040, 0x008b008b, // darkmagenta
  37. 0x90325bd9, 0x26c53c8b, 0x15c00000, 0x00556b2f, // darkolivegreen
  38. 0x90325be5, 0x05c72800, 0x00ff8c00, // darkorange
  39. 0x90325be5, 0x0d092000, 0x009932cc, // darkorchid
  40. 0x90325c8b, 0x10000000, 0x008b0000, // darkred
  41. 0x90325cc3, 0x31af7000, 0x00e9967a, // darksalmon
  42. 0x90325ccb, 0x04f2295c, 0x008fbc8f, // darkseagreen
  43. 0x90325cd9, 0x0685132b, 0x14000000, 0x00483d8b, // darkslateblue
  44. 0x90325cd9, 0x06853c83, 0x64000000, 0x002f4f4f, // darkslategray
  45. 0x90325d2b, 0x4a357a67, 0x14000000, 0x0000ced1, // darkturquoise
  46. 0x90325d93, 0x3d85a000, 0x009400d3, // darkviolet
  47. 0x90a58413, 0x39600000, 0x00ff1493, // deeppink
  48. 0x90a584d7, 0x644ca940, 0x0000bfff, // deepskyblue
  49. 0x912d3c83, 0x64000000, 0x00696969, // dimgray
  50. 0x91e43965, 0x09952800, 0x001e90ff, // dodgerblue
  51. 0x993228a5, 0x246b0000, 0x00b22222, // firebrick
  52. 0x998f9059, 0x5d09a140, 0x00fffaf0, // floralwhite
  53. 0x99f22ce9, 0x1e452b80, 0x00228b22, // forestgreen
  54. 0x9aa344d3, 0x04000000, 0x00ff00ff, // fuchsia
  55. 0x9c2974c5, 0x3e4f0000, 0x00dcdcdc, // gainsboro
  56. 0x9d0f9d2f, 0x21342800, 0x00f8f8ff, // ghostwhite
  57. 0x9dec2000, 0x00ffd700, // gold
  58. 0x9dec215d, 0x49e40000, 0x00daa520, // goldenrod
  59. 0x9e41c800, 0x00808080, // gray
  60. 0x9e452b80, 0x00008000, // green
  61. 0x9e452bb3, 0x158c7dc0, 0x00adff2f, // greenyellow
  62. 0xa1ee2e49, 0x16e00000, 0x00f0fff0, // honeydew
  63. 0xa1f4825d, 0x2c000000, 0x00ff69b4, // hotpink
  64. 0xa5c4485d, 0x48a40000, 0x00cd5c5c, // indianred
  65. 0xa5c449de, 0x004b0082, // indigo
  66. 0xa6cf9640, 0x00fffff0, // ivory
  67. 0xad015a40, 0x00f0e68c, // khaki
  68. 0xb0362b89, 0x16400000, 0x00e6e6fa, // lavender
  69. 0xb0362b89, 0x16426567, 0x20000000, 0x00fff0f5, // lavenderblush
  70. 0xb03771e5, 0x14ae0000, 0x007cfc00, // lawngreen
  71. 0xb0ad7b87, 0x212633dc, 0x00fffacd, // lemonchiffon
  72. 0xb1274505, 0x32a50000, 0x00add8e6, // lightblue
  73. 0xb1274507, 0x3e416000, 0x00f08080, // lightcoral
  74. 0xb1274507, 0x642e0000, 0x00e0ffff, // lightcyan
  75. 0xb127450f, 0x3d842ba5, 0x3c992b19, 0x3ee00000, 0x00fafad2, // lightgoldenrodyellow
  76. 0xb127450f, 0x48a57000, 0x0090ee90, // lightgreen
  77. 0xb127450f, 0x48b90000, 0x00d3d3d3, // lightgrey
  78. 0xb1274521, 0x25cb0000, 0x00ffb6c1, // lightpink
  79. 0xb1274527, 0x058d7b80, 0x00ffa07a, // lightsalmon
  80. 0xb1274527, 0x1427914b, 0x38000000, 0x0020b2aa, // lightseagreen
  81. 0xb1274527, 0x2f22654a, 0x0087cefa, // lightskyblue
  82. 0xb1274527, 0x303429e5, 0x07200000, 0x00778899, // lightslategray
  83. 0xb1274527, 0x50a56099, 0x54a00000, 0x00b0c4de, // lightsteelblue
  84. 0xb1274533, 0x158c7dc0, 0x00ffffe0, // lightyellow
  85. 0xb12d2800, 0x0000ff00, // lime
  86. 0xb12d29e5, 0x14ae0000, 0x0032cd32, // limegreen
  87. 0xb12e2b80, 0x00faf0e6, // linen
  88. 0xb4272ba9, 0x04000000, 0x00ff00ff, // magenta
  89. 0xb4327bdc, 0x00800000, // maroon
  90. 0xb4a44d5b, 0x06350b43, 0x492e2800, 0x0066cdaa, // mediumaquamarine
  91. 0xb4a44d5b, 0x09952800, 0x000000cd, // mediumblue
  92. 0xb4a44d5b, 0x3e434248, 0x00ba55d3, // mediumorchid
  93. 0xb4a44d5b, 0x42b2830a, 0x009370db, // mediumpurple
  94. 0xb4a44d5b, 0x4ca13c8b, 0x15c00000, 0x003cb371, // mediumseagreen
  95. 0xb4a44d5b, 0x4d81a145, 0x32a50000, 0x007b68ee, // mediumslateblue
  96. 0xb4a44d5b, 0x4e124b8f, 0x1e452b80, 0x0000fa9a, // mediumspringgreen
  97. 0xb4a44d5b, 0x52b28d5f, 0x26650000, 0x0048d1cc, // mediumturquoise
  98. 0xb4a44d5b, 0x592f6169, 0x48a40000, 0x00c71585, // mediumvioletred
  99. 0xb524724f, 0x2282654a, 0x00191970, // midnightblue
  100. 0xb52ea0e5, 0x142d0000, 0x00f5fffa, // mintcream
  101. 0xb533a665, 0x3e650000, 0x00ffe4e1, // mistyrose
  102. 0xb5e31867, 0x25c00000, 0x00ffe4b5, // moccasin
  103. 0xb8360a9f, 0x5d09a140, 0x00ffdead, // navajowhite
  104. 0xb836c800, 0x00000080, // navy
  105. 0xbd846047, 0x14000000, 0x00fdf5e6, // oldlace
  106. 0xbd89b140, 0x00808000, // olive
  107. 0xbd89b149, 0x48220000, 0x006b8e23, // olivedrab
  108. 0xbe4171ca, 0x00ffa500, // orange
  109. 0xbe4171cb, 0x48a40000, 0x00ff4500, // orangered
  110. 0xbe434248, 0x00da70d6, // orchid
  111. 0xc02c29df, 0x3085749f, 0x10000000, 0x00eee8aa, // palegoldenrod
  112. 0xc02c29e5, 0x14ae0000, 0x0098fb98, // palegreen
  113. 0xc02c2d2b, 0x4a357a67, 0x14000000, 0x00afeeee, // paleturquoise
  114. 0xc02c2d93, 0x3d85a48b, 0x10000000, 0x00db7093, // palevioletred
  115. 0xc0300e43, 0x5d098000, 0x00ffefd5, // papayawhip
  116. 0xc0a11a21, 0x54c60000, 0x00ffdab9, // peachpuff
  117. 0xc0b2a800, 0x00cd853f, // peru
  118. 0xc12e5800, 0x00ffc0cb, // pink
  119. 0xc1956800, 0x00dda0dd, // plum
  120. 0xc1f72165, 0x09952800, 0x00b0e0e6, // powderblue
  121. 0xc2b2830a, 0x00800080, // purple
  122. 0xc8a40000, 0x00ff0000, // red
  123. 0xc9f3c8a5, 0x3eee0000, 0x00bc8f8f, // rosybrown
  124. 0xc9f90b05, 0x32a50000, 0x004169e1, // royalblue
  125. 0xcc24230b, 0x0a4fbb80, 0x008b4513, // saddlebrown
  126. 0xcc2c6bdc, 0x00fa8072, // salmon
  127. 0xcc2e2645, 0x49f77000, 0x00f4a460, // sandybrown
  128. 0xcca13c8b, 0x15c00000, 0x002e8b57, // seagreen
  129. 0xcca19a0b, 0x31800000, 0x00fff5ee, // seashell
  130. 0xcd257382, 0x00a0522d, // sienna
  131. 0xcd2cb164, 0x00c0c0c0, // silver
  132. 0xcd79132b, 0x14000000, 0x0087ceeb, // skyblue
  133. 0xcd81a145, 0x32a50000, 0x006a5acd, // slateblue
  134. 0xcd81a14f, 0x48390000, 0x00708090, // slategray
  135. 0xcdcfb800, 0x00fffafa, // snow
  136. 0xce124b8f, 0x1e452b80, 0x0000ff7f, // springgreen
  137. 0xce852b05, 0x32a50000, 0x004682b4, // steelblue
  138. 0xd02e0000, 0x00d2b48c, // tan
  139. 0xd0a16000, 0x00008080, // teal
  140. 0xd1099d19, 0x14000000, 0x00d8bfd8, // thistle
  141. 0xd1ed0d1e, 0x00ff6347, // tomato
  142. 0xd2b28d5f, 0x26650000, 0x0040e0d0, // turquoise
  143. 0xd92f6168, 0x00ee82ee, // violet
  144. 0xdd050d00, 0x00f5deb3, // wheat
  145. 0xdd09a140, 0x00ffffff, // white
  146. 0xdd09a167, 0x35eb2800, 0x00f5f5f5, // whitesmoke
  147. 0xe4ac63ee, 0x00ffff00, // yellow
  148. 0xe4ac63ef, 0x1e452b80, 0x009acd32 // yellowgreen
  149. }; // original = 2505 : replacement = 1616
  150. const char* SkParse::FindNamedColor(const char* name, size_t len, SkColor* color) {
  151. const char* namePtr = name;
  152. unsigned int sixMatches[4];
  153. unsigned int* sixMatchPtr = sixMatches;
  154. bool first = true;
  155. bool last = false;
  156. char ch;
  157. do {
  158. unsigned int sixMatch = 0;
  159. for (int chIndex = 0; chIndex < 6; chIndex++) {
  160. sixMatch <<= 5;
  161. ch = *namePtr | 0x20;
  162. if (ch < 'a' || ch > 'z')
  163. ch = 0;
  164. else {
  165. ch = ch - 'a' + 1;
  166. namePtr++;
  167. }
  168. sixMatch |= ch ; // turn 'A' (0x41) into 'a' (0x61);
  169. }
  170. sixMatch <<= 1;
  171. sixMatch |= 1;
  172. if (first) {
  173. sixMatch |= 0x80000000;
  174. first = false;
  175. }
  176. ch = *namePtr | 0x20;
  177. last = ch < 'a' || ch > 'z';
  178. if (last)
  179. sixMatch &= ~1;
  180. len -= 6;
  181. *sixMatchPtr++ = sixMatch;
  182. } while (last == false && len > 0);
  183. const int colorNameSize = sizeof(gColorNames) / sizeof(unsigned int);
  184. int lo = 0;
  185. int hi = colorNameSize - 3; // back off to beginning of yellowgreen
  186. while (lo <= hi) {
  187. int mid = (hi + lo) >> 1;
  188. while ((int) gColorNames[mid] >= 0)
  189. --mid;
  190. sixMatchPtr = sixMatches;
  191. while (gColorNames[mid] == *sixMatchPtr) {
  192. ++mid;
  193. if ((*sixMatchPtr & 1) == 0) { // last
  194. *color = gColorNames[mid] | 0xFF000000;
  195. return namePtr;
  196. }
  197. ++sixMatchPtr;
  198. }
  199. int sixMask = *sixMatchPtr & ~0x80000000;
  200. int midMask = gColorNames[mid] & ~0x80000000;
  201. if (sixMask > midMask) {
  202. lo = mid + 2; // skip color
  203. while ((int) gColorNames[lo] >= 0)
  204. ++lo;
  205. } else if (hi == mid)
  206. return nullptr;
  207. else
  208. hi = mid;
  209. }
  210. return nullptr;
  211. }
  212. // !!! move to char utilities
  213. //static int count_separators(const char* str, const char* sep) {
  214. // char c;
  215. // int separators = 0;
  216. // while ((c = *str++) != '\0') {
  217. // if (strchr(sep, c) == nullptr)
  218. // continue;
  219. // do {
  220. // if ((c = *str++) == '\0')
  221. // goto goHome;
  222. // } while (strchr(sep, c) != nullptr);
  223. // separators++;
  224. // }
  225. //goHome:
  226. // return separators;
  227. //}
  228. static inline unsigned nib2byte(unsigned n)
  229. {
  230. SkASSERT((n & ~0xF) == 0);
  231. return (n << 4) | n;
  232. }
  233. const char* SkParse::FindColor(const char* value, SkColor* colorPtr) {
  234. unsigned int oldAlpha = SkColorGetA(*colorPtr);
  235. if (value[0] == '#') {
  236. uint32_t hex;
  237. const char* end = SkParse::FindHex(value + 1, &hex);
  238. // SkASSERT(end);
  239. if (end == nullptr)
  240. return end;
  241. size_t len = end - value - 1;
  242. if (len == 3 || len == 4) {
  243. unsigned a = len == 4 ? nib2byte(hex >> 12) : oldAlpha;
  244. unsigned r = nib2byte((hex >> 8) & 0xF);
  245. unsigned g = nib2byte((hex >> 4) & 0xF);
  246. unsigned b = nib2byte(hex & 0xF);
  247. *colorPtr = SkColorSetARGB(a, r, g, b);
  248. return end;
  249. } else if (len == 6 || len == 8) {
  250. if (len == 6)
  251. hex |= oldAlpha << 24;
  252. *colorPtr = hex;
  253. return end;
  254. } else {
  255. // SkASSERT(0);
  256. return nullptr;
  257. }
  258. // } else if (strchr(value, ',')) {
  259. // SkScalar array[4];
  260. // int count = count_separators(value, ",") + 1; // !!! count commas, add 1
  261. // SkASSERT(count == 3 || count == 4);
  262. // array[0] = SK_Scalar1 * 255;
  263. // const char* end = SkParse::FindScalars(value, &array[4 - count], count);
  264. // if (end == nullptr)
  265. // return nullptr;
  266. // !!! range check for errors?
  267. // *colorPtr = SkColorSetARGB(SkScalarRoundToInt(array[0]), SkScalarRoundToInt(array[1]),
  268. // SkScalarRoundToInt(array[2]), SkScalarRoundToInt(array[3]));
  269. // return end;
  270. } else
  271. return FindNamedColor(value, strlen(value), colorPtr);
  272. }