|
| 1 | +// (c) Dean McNamee <dean@gmail.com>, 2012. |
| 2 | +// |
| 3 | +// Permission is hereby granted, free of charge, to any person obtaining a copy |
| 4 | +// of this software and associated documentation files (the "Software"), to |
| 5 | +// deal in the Software without restriction, including without limitation the |
| 6 | +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| 7 | +// sell copies of the Software, and to permit persons to whom the Software is |
| 8 | +// furnished to do so, subject to the following conditions: |
| 9 | +// |
| 10 | +// The above copyright notice and this permission notice shall be included in |
| 11 | +// all copies or substantial portions of the Software. |
| 12 | +// |
| 13 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 14 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 15 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 16 | +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 17 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 18 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 19 | +// IN THE SOFTWARE. |
| 20 | + |
| 21 | +// http://www.w3.org/TR/css3-color/ |
| 22 | +var kCSSColorTable = { |
| 23 | + "transparent": [0,0,0,0], "aliceblue": [240,248,255,1], |
| 24 | + "antiquewhite": [250,235,215,1], "aqua": [0,255,255,1], |
| 25 | + "aquamarine": [127,255,212,1], "azure": [240,255,255,1], |
| 26 | + "beige": [245,245,220,1], "bisque": [255,228,196,1], |
| 27 | + "black": [0,0,0,1], "blanchedalmond": [255,235,205,1], |
| 28 | + "blue": [0,0,255,1], "blueviolet": [138,43,226,1], |
| 29 | + "brown": [165,42,42,1], "burlywood": [222,184,135,1], |
| 30 | + "cadetblue": [95,158,160,1], "chartreuse": [127,255,0,1], |
| 31 | + "chocolate": [210,105,30,1], "coral": [255,127,80,1], |
| 32 | + "cornflowerblue": [100,149,237,1], "cornsilk": [255,248,220,1], |
| 33 | + "crimson": [220,20,60,1], "cyan": [0,255,255,1], |
| 34 | + "darkblue": [0,0,139,1], "darkcyan": [0,139,139,1], |
| 35 | + "darkgoldenrod": [184,134,11,1], "darkgray": [169,169,169,1], |
| 36 | + "darkgreen": [0,100,0,1], "darkgrey": [169,169,169,1], |
| 37 | + "darkkhaki": [189,183,107,1], "darkmagenta": [139,0,139,1], |
| 38 | + "darkolivegreen": [85,107,47,1], "darkorange": [255,140,0,1], |
| 39 | + "darkorchid": [153,50,204,1], "darkred": [139,0,0,1], |
| 40 | + "darksalmon": [233,150,122,1], "darkseagreen": [143,188,143,1], |
| 41 | + "darkslateblue": [72,61,139,1], "darkslategray": [47,79,79,1], |
| 42 | + "darkslategrey": [47,79,79,1], "darkturquoise": [0,206,209,1], |
| 43 | + "darkviolet": [148,0,211,1], "deeppink": [255,20,147,1], |
| 44 | + "deepskyblue": [0,191,255,1], "dimgray": [105,105,105,1], |
| 45 | + "dimgrey": [105,105,105,1], "dodgerblue": [30,144,255,1], |
| 46 | + "firebrick": [178,34,34,1], "floralwhite": [255,250,240,1], |
| 47 | + "forestgreen": [34,139,34,1], "fuchsia": [255,0,255,1], |
| 48 | + "gainsboro": [220,220,220,1], "ghostwhite": [248,248,255,1], |
| 49 | + "gold": [255,215,0,1], "goldenrod": [218,165,32,1], |
| 50 | + "gray": [128,128,128,1], "green": [0,128,0,1], |
| 51 | + "greenyellow": [173,255,47,1], "grey": [128,128,128,1], |
| 52 | + "honeydew": [240,255,240,1], "hotpink": [255,105,180,1], |
| 53 | + "indianred": [205,92,92,1], "indigo": [75,0,130,1], |
| 54 | + "ivory": [255,255,240,1], "khaki": [240,230,140,1], |
| 55 | + "lavender": [230,230,250,1], "lavenderblush": [255,240,245,1], |
| 56 | + "lawngreen": [124,252,0,1], "lemonchiffon": [255,250,205,1], |
| 57 | + "lightblue": [173,216,230,1], "lightcoral": [240,128,128,1], |
| 58 | + "lightcyan": [224,255,255,1], "lightgoldenrodyellow": [250,250,210,1], |
| 59 | + "lightgray": [211,211,211,1], "lightgreen": [144,238,144,1], |
| 60 | + "lightgrey": [211,211,211,1], "lightpink": [255,182,193,1], |
| 61 | + "lightsalmon": [255,160,122,1], "lightseagreen": [32,178,170,1], |
| 62 | + "lightskyblue": [135,206,250,1], "lightslategray": [119,136,153,1], |
| 63 | + "lightslategrey": [119,136,153,1], "lightsteelblue": [176,196,222,1], |
| 64 | + "lightyellow": [255,255,224,1], "lime": [0,255,0,1], |
| 65 | + "limegreen": [50,205,50,1], "linen": [250,240,230,1], |
| 66 | + "magenta": [255,0,255,1], "maroon": [128,0,0,1], |
| 67 | + "mediumaquamarine": [102,205,170,1], "mediumblue": [0,0,205,1], |
| 68 | + "mediumorchid": [186,85,211,1], "mediumpurple": [147,112,219,1], |
| 69 | + "mediumseagreen": [60,179,113,1], "mediumslateblue": [123,104,238,1], |
| 70 | + "mediumspringgreen": [0,250,154,1], "mediumturquoise": [72,209,204,1], |
| 71 | + "mediumvioletred": [199,21,133,1], "midnightblue": [25,25,112,1], |
| 72 | + "mintcream": [245,255,250,1], "mistyrose": [255,228,225,1], |
| 73 | + "moccasin": [255,228,181,1], "navajowhite": [255,222,173,1], |
| 74 | + "navy": [0,0,128,1], "oldlace": [253,245,230,1], |
| 75 | + "olive": [128,128,0,1], "olivedrab": [107,142,35,1], |
| 76 | + "orange": [255,165,0,1], "orangered": [255,69,0,1], |
| 77 | + "orchid": [218,112,214,1], "palegoldenrod": [238,232,170,1], |
| 78 | + "palegreen": [152,251,152,1], "paleturquoise": [175,238,238,1], |
| 79 | + "palevioletred": [219,112,147,1], "papayawhip": [255,239,213,1], |
| 80 | + "peachpuff": [255,218,185,1], "peru": [205,133,63,1], |
| 81 | + "pink": [255,192,203,1], "plum": [221,160,221,1], |
| 82 | + "powderblue": [176,224,230,1], "purple": [128,0,128,1], |
| 83 | + "red": [255,0,0,1], "rosybrown": [188,143,143,1], |
| 84 | + "royalblue": [65,105,225,1], "saddlebrown": [139,69,19,1], |
| 85 | + "salmon": [250,128,114,1], "sandybrown": [244,164,96,1], |
| 86 | + "seagreen": [46,139,87,1], "seashell": [255,245,238,1], |
| 87 | + "sienna": [160,82,45,1], "silver": [192,192,192,1], |
| 88 | + "skyblue": [135,206,235,1], "slateblue": [106,90,205,1], |
| 89 | + "slategray": [112,128,144,1], "slategrey": [112,128,144,1], |
| 90 | + "snow": [255,250,250,1], "springgreen": [0,255,127,1], |
| 91 | + "steelblue": [70,130,180,1], "tan": [210,180,140,1], |
| 92 | + "teal": [0,128,128,1], "thistle": [216,191,216,1], |
| 93 | + "tomato": [255,99,71,1], "turquoise": [64,224,208,1], |
| 94 | + "violet": [238,130,238,1], "wheat": [245,222,179,1], |
| 95 | + "white": [255,255,255,1], "whitesmoke": [245,245,245,1], |
| 96 | + "yellow": [255,255,0,1], "yellowgreen": [154,205,50,1]} |
| 97 | + |
| 98 | +function clamp_css_byte(i) { // Clamp to integer 0 .. 255. |
| 99 | + i = i >> 0; |
| 100 | + return i < 0 ? 0 : i > 255 ? 255 : i; |
| 101 | +} |
| 102 | + |
| 103 | +function clamp_css_float(f) { // Clamp to float 0.0 .. 1.0. |
| 104 | + return f < 0 ? 0 : f > 1 ? 1 : f; |
| 105 | +} |
| 106 | + |
| 107 | +function parse_css_int(str) { // int or percentage. |
| 108 | + if (str[str.length - 1] === '%') |
| 109 | + return clamp_css_byte(parseFloat(str) / 100 * 255); |
| 110 | + return clamp_css_byte(parseInt(str)); |
| 111 | +} |
| 112 | + |
| 113 | +function parse_css_float(str) { // float or percentage. |
| 114 | + if (str[str.length - 1] === '%') |
| 115 | + return clamp_css_float(parseFloat(str) / 100); |
| 116 | + return clamp_css_float(parseFloat(str)); |
| 117 | +} |
| 118 | + |
| 119 | +function parseCSSColor(css_str) { |
| 120 | + // Remove all whitespace, not compliant, but should just be more accepting. |
| 121 | + var str = css_str.replace(/ /g, '').toLowerCase(); |
| 122 | + |
| 123 | + // Color keywords (and transparent) lookup. |
| 124 | + if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup. |
| 125 | + |
| 126 | + // #abc and #abc123 syntax. |
| 127 | + if (str[0] === '#') { |
| 128 | + if (str.length === 4) { |
| 129 | + var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. |
| 130 | + if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN. |
| 131 | + return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), |
| 132 | + (iv & 0xf) | ((iv & 0xf) << 4), |
| 133 | + (iv & 0xf0) | ((iv & 0xf0) >> 4), |
| 134 | + 1]; |
| 135 | + } else if (str.length === 7) { |
| 136 | + var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing. |
| 137 | + if (!(iv >= 0 && iv < 0xffffff)) return null; // Covers NaN. |
| 138 | + return [(iv & 0xff0000) >> 16, |
| 139 | + (iv & 0xff00) >> 8, |
| 140 | + iv & 0xff, |
| 141 | + 1]; |
| 142 | + } |
| 143 | + |
| 144 | + return null; |
| 145 | + } |
| 146 | + |
| 147 | + var op = str.indexOf('('), ep = str.indexOf(')'); |
| 148 | + if (op !== -1 && ep + 1 === str.length) { |
| 149 | + var fname = str.substr(0, op); |
| 150 | + var params = str.substr(op+1, ep-(op+1)).split(','); |
| 151 | + switch (fname) { |
| 152 | + case 'rgb': |
| 153 | + if (params.length !== 3) return null; |
| 154 | + return [parse_css_int(params[0]), |
| 155 | + parse_css_int(params[1]), |
| 156 | + parse_css_int(params[2]), |
| 157 | + 1]; |
| 158 | + case 'rgba': |
| 159 | + if (params.length !== 4) return null; |
| 160 | + return [parse_css_int(params[0]), |
| 161 | + parse_css_int(params[1]), |
| 162 | + parse_css_int(params[2]), |
| 163 | + parse_css_float(params[3])]; |
| 164 | + // TODO(deanm): HSL / HSV. |
| 165 | + default: |
| 166 | + return null; |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + return null; |
| 171 | +} |
| 172 | + |
| 173 | +try { exports.parseCSSColor = parseCSSColor } catch(e) { } |
0 commit comments