Home | History | Annotate | Line # | Download | only in dist
colour.c revision 1.14
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      5  * Copyright (c) 2016 Avi Halachmi <avihpit (at) yahoo.com>
      6  *
      7  * Permission to use, copy, modify, and distribute this software for any
      8  * purpose with or without fee is hereby granted, provided that the above
      9  * copyright notice and this permission notice appear in all copies.
     10  *
     11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     16  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     17  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  */
     19 
     20 #include <sys/types.h>
     21 
     22 #include <ctype.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 #include <math.h>
     26 
     27 #include "tmux.h"
     28 
     29 static int
     30 colour_dist_sq(int R, int G, int B, int r, int g, int b)
     31 {
     32 	return ((R - r) * (R - r) + (G - g) * (G - g) + (B - b) * (B - b));
     33 }
     34 
     35 static int
     36 colour_to_6cube(int v)
     37 {
     38 	if (v < 48)
     39 		return (0);
     40 	if (v < 114)
     41 		return (1);
     42 	return ((v - 35) / 40);
     43 }
     44 
     45 /*
     46  * Convert an RGB triplet to the xterm(1) 256 colour palette.
     47  *
     48  * xterm provides a 6x6x6 colour cube (16 - 231) and 24 greys (232 - 255). We
     49  * map our RGB colour to the closest in the cube, also work out the closest
     50  * grey, and use the nearest of the two.
     51  *
     52  * Note that the xterm has much lower resolution for darker colours (they are
     53  * not evenly spread out), so our 6 levels are not evenly spread: 0x0, 0x5f
     54  * (95), 0x87 (135), 0xaf (175), 0xd7 (215) and 0xff (255). Greys are more
     55  * evenly spread (8, 18, 28 ... 238).
     56  */
     57 int
     58 colour_find_rgb(u_char r, u_char g, u_char b)
     59 {
     60 	static const int	q2c[6] = { 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff };
     61 	int			qr, qg, qb, cr, cg, cb, d, idx;
     62 	int			grey_avg, grey_idx, grey;
     63 
     64 	/* Map RGB to 6x6x6 cube. */
     65 	qr = colour_to_6cube(r); cr = q2c[qr];
     66 	qg = colour_to_6cube(g); cg = q2c[qg];
     67 	qb = colour_to_6cube(b); cb = q2c[qb];
     68 
     69 	/* If we have hit the colour exactly, return early. */
     70 	if (cr == r && cg == g && cb == b)
     71 		return ((16 + (36 * qr) + (6 * qg) + qb) | COLOUR_FLAG_256);
     72 
     73 	/* Work out the closest grey (average of RGB). */
     74 	grey_avg = (r + g + b) / 3;
     75 	if (grey_avg > 238)
     76 		grey_idx = 23;
     77 	else
     78 		grey_idx = (grey_avg - 3) / 10;
     79 	grey = 8 + (10 * grey_idx);
     80 
     81 	/* Is grey or 6x6x6 colour closest? */
     82 	d = colour_dist_sq(cr, cg, cb, r, g, b);
     83 	if (colour_dist_sq(grey, grey, grey, r, g, b) < d)
     84 		idx = 232 + grey_idx;
     85 	else
     86 		idx = 16 + (36 * qr) + (6 * qg) + qb;
     87 	return (idx | COLOUR_FLAG_256);
     88 }
     89 
     90 /* Join RGB into a colour. */
     91 int
     92 colour_join_rgb(u_char r, u_char g, u_char b)
     93 {
     94 	return ((((int)((r) & 0xff)) << 16) |
     95 	    (((int)((g) & 0xff)) << 8) |
     96 	    (((int)((b) & 0xff))) | COLOUR_FLAG_RGB);
     97 }
     98 
     99 /* Split colour into RGB. */
    100 void
    101 colour_split_rgb(int c, u_char *r, u_char *g, u_char *b)
    102 {
    103 	*r = (c >> 16) & 0xff;
    104 	*g = (c >> 8) & 0xff;
    105 	*b = c & 0xff;
    106 }
    107 
    108 /* Force colour to RGB if not already. */
    109 int
    110 colour_force_rgb(int c)
    111 {
    112 	if (c & COLOUR_FLAG_RGB)
    113 		return (c);
    114 	if (c & COLOUR_FLAG_256)
    115 		return (colour_256toRGB(c));
    116 	if (c >= 0 && c <= 7)
    117 		return (colour_256toRGB(c));
    118 	if (c >= 90 && c <= 97)
    119 		return (colour_256toRGB(8 + c - 90));
    120 	return (-1);
    121 }
    122 
    123 /* Convert colour to a string. */
    124 const char *
    125 colour_tostring(int c)
    126 {
    127 	static char	s[32];
    128 	u_char		r, g, b;
    129 
    130 	if (c == -1)
    131 		return ("none");
    132 
    133 	if (c & COLOUR_FLAG_RGB) {
    134 		colour_split_rgb(c, &r, &g, &b);
    135 		xsnprintf(s, sizeof s, "#%02x%02x%02x", r, g, b);
    136 		return (s);
    137 	}
    138 
    139 	if (c & COLOUR_FLAG_256) {
    140 		xsnprintf(s, sizeof s, "colour%u", c & 0xff);
    141 		return (s);
    142 	}
    143 
    144 	switch (c) {
    145 	case 0:
    146 		return ("black");
    147 	case 1:
    148 		return ("red");
    149 	case 2:
    150 		return ("green");
    151 	case 3:
    152 		return ("yellow");
    153 	case 4:
    154 		return ("blue");
    155 	case 5:
    156 		return ("magenta");
    157 	case 6:
    158 		return ("cyan");
    159 	case 7:
    160 		return ("white");
    161 	case 8:
    162 		return ("default");
    163 	case 9:
    164 		return ("terminal");
    165 	case 90:
    166 		return ("brightblack");
    167 	case 91:
    168 		return ("brightred");
    169 	case 92:
    170 		return ("brightgreen");
    171 	case 93:
    172 		return ("brightyellow");
    173 	case 94:
    174 		return ("brightblue");
    175 	case 95:
    176 		return ("brightmagenta");
    177 	case 96:
    178 		return ("brightcyan");
    179 	case 97:
    180 		return ("brightwhite");
    181 	}
    182 	return ("invalid");
    183 }
    184 
    185 /* Convert background colour to theme. */
    186 enum client_theme
    187 colour_totheme(int c)
    188 {
    189 	int	r, g, b, brightness;
    190 
    191 	if (c == -1)
    192 		return (THEME_UNKNOWN);
    193 
    194 	if (c & COLOUR_FLAG_RGB) {
    195 		r = (c >> 16) & 0xff;
    196 		g = (c >> 8) & 0xff;
    197 		b = (c >> 0) & 0xff;
    198 
    199 		brightness = r + g + b;
    200 		if (brightness > 382)
    201 			return (THEME_LIGHT);
    202 		return (THEME_DARK);
    203 	}
    204 
    205 	if (c & COLOUR_FLAG_256)
    206 		return (colour_totheme(colour_256toRGB(c)));
    207 
    208 	switch (c) {
    209 	case 0:
    210 	case 90:
    211 		return (THEME_DARK);
    212 	case 7:
    213 	case 97:
    214 		return (THEME_LIGHT);
    215 	default:
    216 		if (c >= 0 && c <= 7)
    217 			return (colour_totheme(colour_256toRGB(c)));
    218 		if (c >= 90 && c <= 97)
    219 			return (colour_totheme(colour_256toRGB(8 + c - 90)));
    220 		break;
    221 	}
    222 	return (THEME_UNKNOWN);
    223 }
    224 
    225 /* Convert colour from string. */
    226 int
    227 colour_fromstring(const char *s)
    228 {
    229 	const char	*errstr;
    230 	const char	*cp;
    231 	int		 n;
    232 	u_char		 r, g, b;
    233 
    234 	if (*s == '#' && strlen(s) == 7) {
    235 		for (cp = s + 1; isxdigit((u_char) *cp); cp++)
    236 			;
    237 		if (*cp != '\0')
    238 			return (-1);
    239 		n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
    240 		if (n != 3)
    241 			return (-1);
    242 		return (colour_join_rgb(r, g, b));
    243 	}
    244 
    245 	if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
    246 		n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
    247 		if (errstr != NULL)
    248 			return (-1);
    249 		return (n | COLOUR_FLAG_256);
    250 	}
    251 	if (strncasecmp(s, "color", (sizeof "color") - 1) == 0) {
    252 		n = strtonum(s + (sizeof "color") - 1, 0, 255, &errstr);
    253 		if (errstr != NULL)
    254 			return (-1);
    255 		return (n | COLOUR_FLAG_256);
    256 	}
    257 
    258 	if (strcasecmp(s, "default") == 0)
    259 		return (8);
    260 	if (strcasecmp(s, "terminal") == 0)
    261 		return (9);
    262 
    263 	if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 0)
    264 		return (0);
    265 	if (strcasecmp(s, "red") == 0 || strcmp(s, "1") == 0)
    266 		return (1);
    267 	if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
    268 		return (2);
    269 	if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
    270 		return (3);
    271 	if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
    272 		return (4);
    273 	if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
    274 		return (5);
    275 	if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
    276 		return (6);
    277 	if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
    278 		return (7);
    279 	if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
    280 		return (90);
    281 	if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
    282 		return (91);
    283 	if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
    284 		return (92);
    285 	if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
    286 		return (93);
    287 	if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
    288 		return (94);
    289 	if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
    290 		return (95);
    291 	if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
    292 		return (96);
    293 	if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
    294 		return (97);
    295 	return (colour_byname(s));
    296 }
    297 
    298 /* Convert 256 colour to RGB colour. */
    299 int
    300 colour_256toRGB(int c)
    301 {
    302 	static const int table[256] = {
    303 		0x000000, 0x800000, 0x008000, 0x808000,
    304 		0x000080, 0x800080, 0x008080, 0xc0c0c0,
    305 		0x808080, 0xff0000, 0x00ff00, 0xffff00,
    306 		0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
    307 		0x000000, 0x00005f, 0x000087, 0x0000af,
    308 		0x0000d7, 0x0000ff, 0x005f00, 0x005f5f,
    309 		0x005f87, 0x005faf, 0x005fd7, 0x005fff,
    310 		0x008700, 0x00875f, 0x008787, 0x0087af,
    311 		0x0087d7, 0x0087ff, 0x00af00, 0x00af5f,
    312 		0x00af87, 0x00afaf, 0x00afd7, 0x00afff,
    313 		0x00d700, 0x00d75f, 0x00d787, 0x00d7af,
    314 		0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f,
    315 		0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff,
    316 		0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af,
    317 		0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f,
    318 		0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff,
    319 		0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af,
    320 		0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f,
    321 		0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff,
    322 		0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af,
    323 		0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f,
    324 		0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff,
    325 		0x870000, 0x87005f, 0x870087, 0x8700af,
    326 		0x8700d7, 0x8700ff, 0x875f00, 0x875f5f,
    327 		0x875f87, 0x875faf, 0x875fd7, 0x875fff,
    328 		0x878700, 0x87875f, 0x878787, 0x8787af,
    329 		0x8787d7, 0x8787ff, 0x87af00, 0x87af5f,
    330 		0x87af87, 0x87afaf, 0x87afd7, 0x87afff,
    331 		0x87d700, 0x87d75f, 0x87d787, 0x87d7af,
    332 		0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f,
    333 		0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff,
    334 		0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af,
    335 		0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f,
    336 		0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff,
    337 		0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af,
    338 		0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f,
    339 		0xafaf87, 0xafafaf, 0xafafd7, 0xafafff,
    340 		0xafd700, 0xafd75f, 0xafd787, 0xafd7af,
    341 		0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f,
    342 		0xafff87, 0xafffaf, 0xafffd7, 0xafffff,
    343 		0xd70000, 0xd7005f, 0xd70087, 0xd700af,
    344 		0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f,
    345 		0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff,
    346 		0xd78700, 0xd7875f, 0xd78787, 0xd787af,
    347 		0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f,
    348 		0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff,
    349 		0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af,
    350 		0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f,
    351 		0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff,
    352 		0xff0000, 0xff005f, 0xff0087, 0xff00af,
    353 		0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f,
    354 		0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff,
    355 		0xff8700, 0xff875f, 0xff8787, 0xff87af,
    356 		0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f,
    357 		0xffaf87, 0xffafaf, 0xffafd7, 0xffafff,
    358 		0xffd700, 0xffd75f, 0xffd787, 0xffd7af,
    359 		0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f,
    360 		0xffff87, 0xffffaf, 0xffffd7, 0xffffff,
    361 		0x080808, 0x121212, 0x1c1c1c, 0x262626,
    362 		0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e,
    363 		0x585858, 0x626262, 0x6c6c6c, 0x767676,
    364 		0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e,
    365 		0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6,
    366 		0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee
    367 	};
    368 
    369 	return (table[c & 0xff] | COLOUR_FLAG_RGB);
    370 }
    371 
    372 /* Convert 256 colour to 16 colour. */
    373 int
    374 colour_256to16(int c)
    375 {
    376 	static const char table[256] = {
    377 		 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    378 		 0,  4,  4,  4, 12, 12,  2,  6,  4,  4, 12, 12,  2,  2,  6,  4,
    379 		12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
    380 		10, 10, 10, 14,  1,  5,  4,  4, 12, 12,  3,  8,  4,  4, 12, 12,
    381 		 2,  2,  6,  4, 12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10,
    382 		14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  5,  4, 12, 12,  1,  1,
    383 		 5,  4, 12, 12,  3,  3,  8,  4, 12, 12,  2,  2,  2,  6, 12, 12,
    384 		10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  1,  5,
    385 		12, 12,  1,  1,  1,  5, 12, 12,  1,  1,  1,  5, 12, 12,  3,  3,
    386 		 3,  7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
    387 		 9,  9,  9,  9, 13, 12,  9,  9,  9,  9, 13, 12,  9,  9,  9,  9,
    388 		13, 12,  9,  9,  9,  9, 13, 12, 11, 11, 11, 11,  7, 12, 10, 10,
    389 		10, 10, 10, 14,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,
    390 		 9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,
    391 		 9, 13, 11, 11, 11, 11, 11, 15,  0,  0,  0,  0,  0,  0,  8,  8,
    392 		 8,  8,  8,  8,  7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15
    393 	};
    394 
    395 	return (table[c & 0xff]);
    396 }
    397 
    398 /* Get colour by X11 colour name. */
    399 int
    400 colour_byname(const char *name)
    401 {
    402 	static const struct {
    403 		const char	*name;
    404 		int		 c;
    405 	} colours[] = {
    406 		{ "AliceBlue", 0xf0f8ff },
    407 		{ "AntiqueWhite", 0xfaebd7 },
    408 		{ "AntiqueWhite1", 0xffefdb },
    409 		{ "AntiqueWhite2", 0xeedfcc },
    410 		{ "AntiqueWhite3", 0xcdc0b0 },
    411 		{ "AntiqueWhite4", 0x8b8378 },
    412 		{ "BlanchedAlmond", 0xffebcd },
    413 		{ "BlueViolet", 0x8a2be2 },
    414 		{ "CadetBlue", 0x5f9ea0 },
    415 		{ "CadetBlue1", 0x98f5ff },
    416 		{ "CadetBlue2", 0x8ee5ee },
    417 		{ "CadetBlue3", 0x7ac5cd },
    418 		{ "CadetBlue4", 0x53868b },
    419 		{ "CornflowerBlue", 0x6495ed },
    420 		{ "DarkBlue", 0x00008b },
    421 		{ "DarkCyan", 0x008b8b },
    422 		{ "DarkGoldenrod", 0xb8860b },
    423 		{ "DarkGoldenrod1", 0xffb90f },
    424 		{ "DarkGoldenrod2", 0xeead0e },
    425 		{ "DarkGoldenrod3", 0xcd950c },
    426 		{ "DarkGoldenrod4", 0x8b6508 },
    427 		{ "DarkGray", 0xa9a9a9 },
    428 		{ "DarkGreen", 0x006400 },
    429 		{ "DarkGrey", 0xa9a9a9 },
    430 		{ "DarkKhaki", 0xbdb76b },
    431 		{ "DarkMagenta", 0x8b008b },
    432 		{ "DarkOliveGreen", 0x556b2f },
    433 		{ "DarkOliveGreen1", 0xcaff70 },
    434 		{ "DarkOliveGreen2", 0xbcee68 },
    435 		{ "DarkOliveGreen3", 0xa2cd5a },
    436 		{ "DarkOliveGreen4", 0x6e8b3d },
    437 		{ "DarkOrange", 0xff8c00 },
    438 		{ "DarkOrange1", 0xff7f00 },
    439 		{ "DarkOrange2", 0xee7600 },
    440 		{ "DarkOrange3", 0xcd6600 },
    441 		{ "DarkOrange4", 0x8b4500 },
    442 		{ "DarkOrchid", 0x9932cc },
    443 		{ "DarkOrchid1", 0xbf3eff },
    444 		{ "DarkOrchid2", 0xb23aee },
    445 		{ "DarkOrchid3", 0x9a32cd },
    446 		{ "DarkOrchid4", 0x68228b },
    447 		{ "DarkRed", 0x8b0000 },
    448 		{ "DarkSalmon", 0xe9967a },
    449 		{ "DarkSeaGreen", 0x8fbc8f },
    450 		{ "DarkSeaGreen1", 0xc1ffc1 },
    451 		{ "DarkSeaGreen2", 0xb4eeb4 },
    452 		{ "DarkSeaGreen3", 0x9bcd9b },
    453 		{ "DarkSeaGreen4", 0x698b69 },
    454 		{ "DarkSlateBlue", 0x483d8b },
    455 		{ "DarkSlateGray", 0x2f4f4f },
    456 		{ "DarkSlateGray1", 0x97ffff },
    457 		{ "DarkSlateGray2", 0x8deeee },
    458 		{ "DarkSlateGray3", 0x79cdcd },
    459 		{ "DarkSlateGray4", 0x528b8b },
    460 		{ "DarkSlateGrey", 0x2f4f4f },
    461 		{ "DarkTurquoise", 0x00ced1 },
    462 		{ "DarkViolet", 0x9400d3 },
    463 		{ "DeepPink", 0xff1493 },
    464 		{ "DeepPink1", 0xff1493 },
    465 		{ "DeepPink2", 0xee1289 },
    466 		{ "DeepPink3", 0xcd1076 },
    467 		{ "DeepPink4", 0x8b0a50 },
    468 		{ "DeepSkyBlue", 0x00bfff },
    469 		{ "DeepSkyBlue1", 0x00bfff },
    470 		{ "DeepSkyBlue2", 0x00b2ee },
    471 		{ "DeepSkyBlue3", 0x009acd },
    472 		{ "DeepSkyBlue4", 0x00688b },
    473 		{ "DimGray", 0x696969 },
    474 		{ "DimGrey", 0x696969 },
    475 		{ "DodgerBlue", 0x1e90ff },
    476 		{ "DodgerBlue1", 0x1e90ff },
    477 		{ "DodgerBlue2", 0x1c86ee },
    478 		{ "DodgerBlue3", 0x1874cd },
    479 		{ "DodgerBlue4", 0x104e8b },
    480 		{ "FloralWhite", 0xfffaf0 },
    481 		{ "ForestGreen", 0x228b22 },
    482 		{ "GhostWhite", 0xf8f8ff },
    483 		{ "GreenYellow", 0xadff2f },
    484 		{ "HotPink", 0xff69b4 },
    485 		{ "HotPink1", 0xff6eb4 },
    486 		{ "HotPink2", 0xee6aa7 },
    487 		{ "HotPink3", 0xcd6090 },
    488 		{ "HotPink4", 0x8b3a62 },
    489 		{ "IndianRed", 0xcd5c5c },
    490 		{ "IndianRed1", 0xff6a6a },
    491 		{ "IndianRed2", 0xee6363 },
    492 		{ "IndianRed3", 0xcd5555 },
    493 		{ "IndianRed4", 0x8b3a3a },
    494 		{ "LavenderBlush", 0xfff0f5 },
    495 		{ "LavenderBlush1", 0xfff0f5 },
    496 		{ "LavenderBlush2", 0xeee0e5 },
    497 		{ "LavenderBlush3", 0xcdc1c5 },
    498 		{ "LavenderBlush4", 0x8b8386 },
    499 		{ "LawnGreen", 0x7cfc00 },
    500 		{ "LemonChiffon", 0xfffacd },
    501 		{ "LemonChiffon1", 0xfffacd },
    502 		{ "LemonChiffon2", 0xeee9bf },
    503 		{ "LemonChiffon3", 0xcdc9a5 },
    504 		{ "LemonChiffon4", 0x8b8970 },
    505 		{ "LightBlue", 0xadd8e6 },
    506 		{ "LightBlue1", 0xbfefff },
    507 		{ "LightBlue2", 0xb2dfee },
    508 		{ "LightBlue3", 0x9ac0cd },
    509 		{ "LightBlue4", 0x68838b },
    510 		{ "LightCoral", 0xf08080 },
    511 		{ "LightCyan", 0xe0ffff },
    512 		{ "LightCyan1", 0xe0ffff },
    513 		{ "LightCyan2", 0xd1eeee },
    514 		{ "LightCyan3", 0xb4cdcd },
    515 		{ "LightCyan4", 0x7a8b8b },
    516 		{ "LightGoldenrod", 0xeedd82 },
    517 		{ "LightGoldenrod1", 0xffec8b },
    518 		{ "LightGoldenrod2", 0xeedc82 },
    519 		{ "LightGoldenrod3", 0xcdbe70 },
    520 		{ "LightGoldenrod4", 0x8b814c },
    521 		{ "LightGoldenrodYellow", 0xfafad2 },
    522 		{ "LightGray", 0xd3d3d3 },
    523 		{ "LightGreen", 0x90ee90 },
    524 		{ "LightGrey", 0xd3d3d3 },
    525 		{ "LightPink", 0xffb6c1 },
    526 		{ "LightPink1", 0xffaeb9 },
    527 		{ "LightPink2", 0xeea2ad },
    528 		{ "LightPink3", 0xcd8c95 },
    529 		{ "LightPink4", 0x8b5f65 },
    530 		{ "LightSalmon", 0xffa07a },
    531 		{ "LightSalmon1", 0xffa07a },
    532 		{ "LightSalmon2", 0xee9572 },
    533 		{ "LightSalmon3", 0xcd8162 },
    534 		{ "LightSalmon4", 0x8b5742 },
    535 		{ "LightSeaGreen", 0x20b2aa },
    536 		{ "LightSkyBlue", 0x87cefa },
    537 		{ "LightSkyBlue1", 0xb0e2ff },
    538 		{ "LightSkyBlue2", 0xa4d3ee },
    539 		{ "LightSkyBlue3", 0x8db6cd },
    540 		{ "LightSkyBlue4", 0x607b8b },
    541 		{ "LightSlateBlue", 0x8470ff },
    542 		{ "LightSlateGray", 0x778899 },
    543 		{ "LightSlateGrey", 0x778899 },
    544 		{ "LightSteelBlue", 0xb0c4de },
    545 		{ "LightSteelBlue1", 0xcae1ff },
    546 		{ "LightSteelBlue2", 0xbcd2ee },
    547 		{ "LightSteelBlue3", 0xa2b5cd },
    548 		{ "LightSteelBlue4", 0x6e7b8b },
    549 		{ "LightYellow", 0xffffe0 },
    550 		{ "LightYellow1", 0xffffe0 },
    551 		{ "LightYellow2", 0xeeeed1 },
    552 		{ "LightYellow3", 0xcdcdb4 },
    553 		{ "LightYellow4", 0x8b8b7a },
    554 		{ "LimeGreen", 0x32cd32 },
    555 		{ "MediumAquamarine", 0x66cdaa },
    556 		{ "MediumBlue", 0x0000cd },
    557 		{ "MediumOrchid", 0xba55d3 },
    558 		{ "MediumOrchid1", 0xe066ff },
    559 		{ "MediumOrchid2", 0xd15fee },
    560 		{ "MediumOrchid3", 0xb452cd },
    561 		{ "MediumOrchid4", 0x7a378b },
    562 		{ "MediumPurple", 0x9370db },
    563 		{ "MediumPurple1", 0xab82ff },
    564 		{ "MediumPurple2", 0x9f79ee },
    565 		{ "MediumPurple3", 0x8968cd },
    566 		{ "MediumPurple4", 0x5d478b },
    567 		{ "MediumSeaGreen", 0x3cb371 },
    568 		{ "MediumSlateBlue", 0x7b68ee },
    569 		{ "MediumSpringGreen", 0x00fa9a },
    570 		{ "MediumTurquoise", 0x48d1cc },
    571 		{ "MediumVioletRed", 0xc71585 },
    572 		{ "MidnightBlue", 0x191970 },
    573 		{ "MintCream", 0xf5fffa },
    574 		{ "MistyRose", 0xffe4e1 },
    575 		{ "MistyRose1", 0xffe4e1 },
    576 		{ "MistyRose2", 0xeed5d2 },
    577 		{ "MistyRose3", 0xcdb7b5 },
    578 		{ "MistyRose4", 0x8b7d7b },
    579 		{ "NavajoWhite", 0xffdead },
    580 		{ "NavajoWhite1", 0xffdead },
    581 		{ "NavajoWhite2", 0xeecfa1 },
    582 		{ "NavajoWhite3", 0xcdb38b },
    583 		{ "NavajoWhite4", 0x8b795e },
    584 		{ "NavyBlue", 0x000080 },
    585 		{ "OldLace", 0xfdf5e6 },
    586 		{ "OliveDrab", 0x6b8e23 },
    587 		{ "OliveDrab1", 0xc0ff3e },
    588 		{ "OliveDrab2", 0xb3ee3a },
    589 		{ "OliveDrab3", 0x9acd32 },
    590 		{ "OliveDrab4", 0x698b22 },
    591 		{ "OrangeRed", 0xff4500 },
    592 		{ "OrangeRed1", 0xff4500 },
    593 		{ "OrangeRed2", 0xee4000 },
    594 		{ "OrangeRed3", 0xcd3700 },
    595 		{ "OrangeRed4", 0x8b2500 },
    596 		{ "PaleGoldenrod", 0xeee8aa },
    597 		{ "PaleGreen", 0x98fb98 },
    598 		{ "PaleGreen1", 0x9aff9a },
    599 		{ "PaleGreen2", 0x90ee90 },
    600 		{ "PaleGreen3", 0x7ccd7c },
    601 		{ "PaleGreen4", 0x548b54 },
    602 		{ "PaleTurquoise", 0xafeeee },
    603 		{ "PaleTurquoise1", 0xbbffff },
    604 		{ "PaleTurquoise2", 0xaeeeee },
    605 		{ "PaleTurquoise3", 0x96cdcd },
    606 		{ "PaleTurquoise4", 0x668b8b },
    607 		{ "PaleVioletRed", 0xdb7093 },
    608 		{ "PaleVioletRed1", 0xff82ab },
    609 		{ "PaleVioletRed2", 0xee799f },
    610 		{ "PaleVioletRed3", 0xcd6889 },
    611 		{ "PaleVioletRed4", 0x8b475d },
    612 		{ "PapayaWhip", 0xffefd5 },
    613 		{ "PeachPuff", 0xffdab9 },
    614 		{ "PeachPuff1", 0xffdab9 },
    615 		{ "PeachPuff2", 0xeecbad },
    616 		{ "PeachPuff3", 0xcdaf95 },
    617 		{ "PeachPuff4", 0x8b7765 },
    618 		{ "PowderBlue", 0xb0e0e6 },
    619 		{ "RebeccaPurple", 0x663399 },
    620 		{ "RosyBrown", 0xbc8f8f },
    621 		{ "RosyBrown1", 0xffc1c1 },
    622 		{ "RosyBrown2", 0xeeb4b4 },
    623 		{ "RosyBrown3", 0xcd9b9b },
    624 		{ "RosyBrown4", 0x8b6969 },
    625 		{ "RoyalBlue", 0x4169e1 },
    626 		{ "RoyalBlue1", 0x4876ff },
    627 		{ "RoyalBlue2", 0x436eee },
    628 		{ "RoyalBlue3", 0x3a5fcd },
    629 		{ "RoyalBlue4", 0x27408b },
    630 		{ "SaddleBrown", 0x8b4513 },
    631 		{ "SandyBrown", 0xf4a460 },
    632 		{ "SeaGreen", 0x2e8b57 },
    633 		{ "SeaGreen1", 0x54ff9f },
    634 		{ "SeaGreen2", 0x4eee94 },
    635 		{ "SeaGreen3", 0x43cd80 },
    636 		{ "SeaGreen4", 0x2e8b57 },
    637 		{ "SkyBlue", 0x87ceeb },
    638 		{ "SkyBlue1", 0x87ceff },
    639 		{ "SkyBlue2", 0x7ec0ee },
    640 		{ "SkyBlue3", 0x6ca6cd },
    641 		{ "SkyBlue4", 0x4a708b },
    642 		{ "SlateBlue", 0x6a5acd },
    643 		{ "SlateBlue1", 0x836fff },
    644 		{ "SlateBlue2", 0x7a67ee },
    645 		{ "SlateBlue3", 0x6959cd },
    646 		{ "SlateBlue4", 0x473c8b },
    647 		{ "SlateGray", 0x708090 },
    648 		{ "SlateGray1", 0xc6e2ff },
    649 		{ "SlateGray2", 0xb9d3ee },
    650 		{ "SlateGray3", 0x9fb6cd },
    651 		{ "SlateGray4", 0x6c7b8b },
    652 		{ "SlateGrey", 0x708090 },
    653 		{ "SpringGreen", 0x00ff7f },
    654 		{ "SpringGreen1", 0x00ff7f },
    655 		{ "SpringGreen2", 0x00ee76 },
    656 		{ "SpringGreen3", 0x00cd66 },
    657 		{ "SpringGreen4", 0x008b45 },
    658 		{ "SteelBlue", 0x4682b4 },
    659 		{ "SteelBlue1", 0x63b8ff },
    660 		{ "SteelBlue2", 0x5cacee },
    661 		{ "SteelBlue3", 0x4f94cd },
    662 		{ "SteelBlue4", 0x36648b },
    663 		{ "VioletRed", 0xd02090 },
    664 		{ "VioletRed1", 0xff3e96 },
    665 		{ "VioletRed2", 0xee3a8c },
    666 		{ "VioletRed3", 0xcd3278 },
    667 		{ "VioletRed4", 0x8b2252 },
    668 		{ "WebGray", 0x808080 },
    669 		{ "WebGreen", 0x008000 },
    670 		{ "WebGrey", 0x808080 },
    671 		{ "WebMaroon", 0x800000 },
    672 		{ "WebPurple", 0x800080 },
    673 		{ "WhiteSmoke", 0xf5f5f5 },
    674 		{ "X11Gray", 0xbebebe },
    675 		{ "X11Green", 0x00ff00 },
    676 		{ "X11Grey", 0xbebebe },
    677 		{ "X11Maroon", 0xb03060 },
    678 		{ "X11Purple", 0xa020f0 },
    679 		{ "YellowGreen", 0x9acd32 },
    680 		{ "alice blue", 0xf0f8ff },
    681 		{ "antique white", 0xfaebd7 },
    682 		{ "aqua", 0x00ffff },
    683 		{ "aquamarine", 0x7fffd4 },
    684 		{ "aquamarine1", 0x7fffd4 },
    685 		{ "aquamarine2", 0x76eec6 },
    686 		{ "aquamarine3", 0x66cdaa },
    687 		{ "aquamarine4", 0x458b74 },
    688 		{ "azure", 0xf0ffff },
    689 		{ "azure1", 0xf0ffff },
    690 		{ "azure2", 0xe0eeee },
    691 		{ "azure3", 0xc1cdcd },
    692 		{ "azure4", 0x838b8b },
    693 		{ "beige", 0xf5f5dc },
    694 		{ "bisque", 0xffe4c4 },
    695 		{ "bisque1", 0xffe4c4 },
    696 		{ "bisque2", 0xeed5b7 },
    697 		{ "bisque3", 0xcdb79e },
    698 		{ "bisque4", 0x8b7d6b },
    699 		{ "black", 0x000000 },
    700 		{ "blanched almond", 0xffebcd },
    701 		{ "blue violet", 0x8a2be2 },
    702 		{ "blue", 0x0000ff },
    703 		{ "blue1", 0x0000ff },
    704 		{ "blue2", 0x0000ee },
    705 		{ "blue3", 0x0000cd },
    706 		{ "blue4", 0x00008b },
    707 		{ "brown", 0xa52a2a },
    708 		{ "brown1", 0xff4040 },
    709 		{ "brown2", 0xee3b3b },
    710 		{ "brown3", 0xcd3333 },
    711 		{ "brown4", 0x8b2323 },
    712 		{ "burlywood", 0xdeb887 },
    713 		{ "burlywood1", 0xffd39b },
    714 		{ "burlywood2", 0xeec591 },
    715 		{ "burlywood3", 0xcdaa7d },
    716 		{ "burlywood4", 0x8b7355 },
    717 		{ "cadet blue", 0x5f9ea0 },
    718 		{ "chartreuse", 0x7fff00 },
    719 		{ "chartreuse1", 0x7fff00 },
    720 		{ "chartreuse2", 0x76ee00 },
    721 		{ "chartreuse3", 0x66cd00 },
    722 		{ "chartreuse4", 0x458b00 },
    723 		{ "chocolate", 0xd2691e },
    724 		{ "chocolate1", 0xff7f24 },
    725 		{ "chocolate2", 0xee7621 },
    726 		{ "chocolate3", 0xcd661d },
    727 		{ "chocolate4", 0x8b4513 },
    728 		{ "coral", 0xff7f50 },
    729 		{ "coral1", 0xff7256 },
    730 		{ "coral2", 0xee6a50 },
    731 		{ "coral3", 0xcd5b45 },
    732 		{ "coral4", 0x8b3e2f },
    733 		{ "cornflower blue", 0x6495ed },
    734 		{ "cornsilk", 0xfff8dc },
    735 		{ "cornsilk1", 0xfff8dc },
    736 		{ "cornsilk2", 0xeee8cd },
    737 		{ "cornsilk3", 0xcdc8b1 },
    738 		{ "cornsilk4", 0x8b8878 },
    739 		{ "crimson", 0xdc143c },
    740 		{ "cyan", 0x00ffff },
    741 		{ "cyan1", 0x00ffff },
    742 		{ "cyan2", 0x00eeee },
    743 		{ "cyan3", 0x00cdcd },
    744 		{ "cyan4", 0x008b8b },
    745 		{ "dark blue", 0x00008b },
    746 		{ "dark cyan", 0x008b8b },
    747 		{ "dark goldenrod", 0xb8860b },
    748 		{ "dark gray", 0xa9a9a9 },
    749 		{ "dark green", 0x006400 },
    750 		{ "dark grey", 0xa9a9a9 },
    751 		{ "dark khaki", 0xbdb76b },
    752 		{ "dark magenta", 0x8b008b },
    753 		{ "dark olive green", 0x556b2f },
    754 		{ "dark orange", 0xff8c00 },
    755 		{ "dark orchid", 0x9932cc },
    756 		{ "dark red", 0x8b0000 },
    757 		{ "dark salmon", 0xe9967a },
    758 		{ "dark sea green", 0x8fbc8f },
    759 		{ "dark slate blue", 0x483d8b },
    760 		{ "dark slate gray", 0x2f4f4f },
    761 		{ "dark slate grey", 0x2f4f4f },
    762 		{ "dark turquoise", 0x00ced1 },
    763 		{ "dark violet", 0x9400d3 },
    764 		{ "deep pink", 0xff1493 },
    765 		{ "deep sky blue", 0x00bfff },
    766 		{ "dim gray", 0x696969 },
    767 		{ "dim grey", 0x696969 },
    768 		{ "dodger blue", 0x1e90ff },
    769 		{ "firebrick", 0xb22222 },
    770 		{ "firebrick1", 0xff3030 },
    771 		{ "firebrick2", 0xee2c2c },
    772 		{ "firebrick3", 0xcd2626 },
    773 		{ "firebrick4", 0x8b1a1a },
    774 		{ "floral white", 0xfffaf0 },
    775 		{ "forest green", 0x228b22 },
    776 		{ "fuchsia", 0xff00ff },
    777 		{ "gainsboro", 0xdcdcdc },
    778 		{ "ghost white", 0xf8f8ff },
    779 		{ "gold", 0xffd700 },
    780 		{ "gold1", 0xffd700 },
    781 		{ "gold2", 0xeec900 },
    782 		{ "gold3", 0xcdad00 },
    783 		{ "gold4", 0x8b7500 },
    784 		{ "goldenrod", 0xdaa520 },
    785 		{ "goldenrod1", 0xffc125 },
    786 		{ "goldenrod2", 0xeeb422 },
    787 		{ "goldenrod3", 0xcd9b1d },
    788 		{ "goldenrod4", 0x8b6914 },
    789 		{ "green yellow", 0xadff2f },
    790 		{ "green", 0x00ff00 },
    791 		{ "green1", 0x00ff00 },
    792 		{ "green2", 0x00ee00 },
    793 		{ "green3", 0x00cd00 },
    794 		{ "green4", 0x008b00 },
    795 		{ "honeydew", 0xf0fff0 },
    796 		{ "honeydew1", 0xf0fff0 },
    797 		{ "honeydew2", 0xe0eee0 },
    798 		{ "honeydew3", 0xc1cdc1 },
    799 		{ "honeydew4", 0x838b83 },
    800 		{ "hot pink", 0xff69b4 },
    801 		{ "indian red", 0xcd5c5c },
    802 		{ "indigo", 0x4b0082 },
    803 		{ "ivory", 0xfffff0 },
    804 		{ "ivory1", 0xfffff0 },
    805 		{ "ivory2", 0xeeeee0 },
    806 		{ "ivory3", 0xcdcdc1 },
    807 		{ "ivory4", 0x8b8b83 },
    808 		{ "khaki", 0xf0e68c },
    809 		{ "khaki1", 0xfff68f },
    810 		{ "khaki2", 0xeee685 },
    811 		{ "khaki3", 0xcdc673 },
    812 		{ "khaki4", 0x8b864e },
    813 		{ "lavender blush", 0xfff0f5 },
    814 		{ "lavender", 0xe6e6fa },
    815 		{ "lawn green", 0x7cfc00 },
    816 		{ "lemon chiffon", 0xfffacd },
    817 		{ "light blue", 0xadd8e6 },
    818 		{ "light coral", 0xf08080 },
    819 		{ "light cyan", 0xe0ffff },
    820 		{ "light goldenrod yellow", 0xfafad2 },
    821 		{ "light goldenrod", 0xeedd82 },
    822 		{ "light gray", 0xd3d3d3 },
    823 		{ "light green", 0x90ee90 },
    824 		{ "light grey", 0xd3d3d3 },
    825 		{ "light pink", 0xffb6c1 },
    826 		{ "light salmon", 0xffa07a },
    827 		{ "light sea green", 0x20b2aa },
    828 		{ "light sky blue", 0x87cefa },
    829 		{ "light slate blue", 0x8470ff },
    830 		{ "light slate gray", 0x778899 },
    831 		{ "light slate grey", 0x778899 },
    832 		{ "light steel blue", 0xb0c4de },
    833 		{ "light yellow", 0xffffe0 },
    834 		{ "lime green", 0x32cd32 },
    835 		{ "lime", 0x00ff00 },
    836 		{ "linen", 0xfaf0e6 },
    837 		{ "magenta", 0xff00ff },
    838 		{ "magenta1", 0xff00ff },
    839 		{ "magenta2", 0xee00ee },
    840 		{ "magenta3", 0xcd00cd },
    841 		{ "magenta4", 0x8b008b },
    842 		{ "maroon", 0xb03060 },
    843 		{ "maroon1", 0xff34b3 },
    844 		{ "maroon2", 0xee30a7 },
    845 		{ "maroon3", 0xcd2990 },
    846 		{ "maroon4", 0x8b1c62 },
    847 		{ "medium aquamarine", 0x66cdaa },
    848 		{ "medium blue", 0x0000cd },
    849 		{ "medium orchid", 0xba55d3 },
    850 		{ "medium purple", 0x9370db },
    851 		{ "medium sea green", 0x3cb371 },
    852 		{ "medium slate blue", 0x7b68ee },
    853 		{ "medium spring green", 0x00fa9a },
    854 		{ "medium turquoise", 0x48d1cc },
    855 		{ "medium violet red", 0xc71585 },
    856 		{ "midnight blue", 0x191970 },
    857 		{ "mint cream", 0xf5fffa },
    858 		{ "misty rose", 0xffe4e1 },
    859 		{ "moccasin", 0xffe4b5 },
    860 		{ "navajo white", 0xffdead },
    861 		{ "navy blue", 0x000080 },
    862 		{ "navy", 0x000080 },
    863 		{ "old lace", 0xfdf5e6 },
    864 		{ "olive drab", 0x6b8e23 },
    865 		{ "olive", 0x808000 },
    866 		{ "orange red", 0xff4500 },
    867 		{ "orange", 0xffa500 },
    868 		{ "orange1", 0xffa500 },
    869 		{ "orange2", 0xee9a00 },
    870 		{ "orange3", 0xcd8500 },
    871 		{ "orange4", 0x8b5a00 },
    872 		{ "orchid", 0xda70d6 },
    873 		{ "orchid1", 0xff83fa },
    874 		{ "orchid2", 0xee7ae9 },
    875 		{ "orchid3", 0xcd69c9 },
    876 		{ "orchid4", 0x8b4789 },
    877 		{ "pale goldenrod", 0xeee8aa },
    878 		{ "pale green", 0x98fb98 },
    879 		{ "pale turquoise", 0xafeeee },
    880 		{ "pale violet red", 0xdb7093 },
    881 		{ "papaya whip", 0xffefd5 },
    882 		{ "peach puff", 0xffdab9 },
    883 		{ "peru", 0xcd853f },
    884 		{ "pink", 0xffc0cb },
    885 		{ "pink1", 0xffb5c5 },
    886 		{ "pink2", 0xeea9b8 },
    887 		{ "pink3", 0xcd919e },
    888 		{ "pink4", 0x8b636c },
    889 		{ "plum", 0xdda0dd },
    890 		{ "plum1", 0xffbbff },
    891 		{ "plum2", 0xeeaeee },
    892 		{ "plum3", 0xcd96cd },
    893 		{ "plum4", 0x8b668b },
    894 		{ "powder blue", 0xb0e0e6 },
    895 		{ "purple", 0xa020f0 },
    896 		{ "purple1", 0x9b30ff },
    897 		{ "purple2", 0x912cee },
    898 		{ "purple3", 0x7d26cd },
    899 		{ "purple4", 0x551a8b },
    900 		{ "rebecca purple", 0x663399 },
    901 		{ "red", 0xff0000 },
    902 		{ "red1", 0xff0000 },
    903 		{ "red2", 0xee0000 },
    904 		{ "red3", 0xcd0000 },
    905 		{ "red4", 0x8b0000 },
    906 		{ "rosy brown", 0xbc8f8f },
    907 		{ "royal blue", 0x4169e1 },
    908 		{ "saddle brown", 0x8b4513 },
    909 		{ "salmon", 0xfa8072 },
    910 		{ "salmon1", 0xff8c69 },
    911 		{ "salmon2", 0xee8262 },
    912 		{ "salmon3", 0xcd7054 },
    913 		{ "salmon4", 0x8b4c39 },
    914 		{ "sandy brown", 0xf4a460 },
    915 		{ "sea green", 0x2e8b57 },
    916 		{ "seashell", 0xfff5ee },
    917 		{ "seashell1", 0xfff5ee },
    918 		{ "seashell2", 0xeee5de },
    919 		{ "seashell3", 0xcdc5bf },
    920 		{ "seashell4", 0x8b8682 },
    921 		{ "sienna", 0xa0522d },
    922 		{ "sienna1", 0xff8247 },
    923 		{ "sienna2", 0xee7942 },
    924 		{ "sienna3", 0xcd6839 },
    925 		{ "sienna4", 0x8b4726 },
    926 		{ "silver", 0xc0c0c0 },
    927 		{ "sky blue", 0x87ceeb },
    928 		{ "slate blue", 0x6a5acd },
    929 		{ "slate gray", 0x708090 },
    930 		{ "slate grey", 0x708090 },
    931 		{ "snow", 0xfffafa },
    932 		{ "snow1", 0xfffafa },
    933 		{ "snow2", 0xeee9e9 },
    934 		{ "snow3", 0xcdc9c9 },
    935 		{ "snow4", 0x8b8989 },
    936 		{ "spring green", 0x00ff7f },
    937 		{ "steel blue", 0x4682b4 },
    938 		{ "tan", 0xd2b48c },
    939 		{ "tan1", 0xffa54f },
    940 		{ "tan2", 0xee9a49 },
    941 		{ "tan3", 0xcd853f },
    942 		{ "tan4", 0x8b5a2b },
    943 		{ "teal", 0x008080 },
    944 		{ "thistle", 0xd8bfd8 },
    945 		{ "thistle1", 0xffe1ff },
    946 		{ "thistle2", 0xeed2ee },
    947 		{ "thistle3", 0xcdb5cd },
    948 		{ "thistle4", 0x8b7b8b },
    949 		{ "tomato", 0xff6347 },
    950 		{ "tomato1", 0xff6347 },
    951 		{ "tomato2", 0xee5c42 },
    952 		{ "tomato3", 0xcd4f39 },
    953 		{ "tomato4", 0x8b3626 },
    954 		{ "turquoise", 0x40e0d0 },
    955 		{ "turquoise1", 0x00f5ff },
    956 		{ "turquoise2", 0x00e5ee },
    957 		{ "turquoise3", 0x00c5cd },
    958 		{ "turquoise4", 0x00868b },
    959 		{ "violet red", 0xd02090 },
    960 		{ "violet", 0xee82ee },
    961 		{ "web gray", 0x808080 },
    962 		{ "web green", 0x008000 },
    963 		{ "web grey", 0x808080 },
    964 		{ "web maroon", 0x800000 },
    965 		{ "web purple", 0x800080 },
    966 		{ "wheat", 0xf5deb3 },
    967 		{ "wheat1", 0xffe7ba },
    968 		{ "wheat2", 0xeed8ae },
    969 		{ "wheat3", 0xcdba96 },
    970 		{ "wheat4", 0x8b7e66 },
    971 		{ "white smoke", 0xf5f5f5 },
    972 		{ "white", 0xffffff },
    973 		{ "x11 gray", 0xbebebe },
    974 		{ "x11 green", 0x00ff00 },
    975 		{ "x11 grey", 0xbebebe },
    976 		{ "x11 maroon", 0xb03060 },
    977 		{ "x11 purple", 0xa020f0 },
    978 		{ "yellow green", 0x9acd32 },
    979 		{ "yellow", 0xffff00 },
    980 		{ "yellow1", 0xffff00 },
    981 		{ "yellow2", 0xeeee00 },
    982 		{ "yellow3", 0xcdcd00 },
    983 		{ "yellow4", 0x8b8b00 }
    984 	};
    985 	u_int		 i;
    986 	int		 c;
    987 	const char	*errstr;
    988 
    989 	if (strncasecmp(name, "grey", 4) == 0 ||
    990 	    strncasecmp(name, "gray", 4) == 0) {
    991 		if (name[4] == '\0')
    992 			return (0xbebebe|COLOUR_FLAG_RGB);
    993 		c = strtonum(name + 4, 0, 100, &errstr);
    994 		if (errstr != NULL)
    995 			return (-1);
    996 		c = round(2.55 * c);
    997 		if (c < 0 || c > 255)
    998 			return (-1);
    999 		return (colour_join_rgb(c, c, c));
   1000 	}
   1001 	for (i = 0; i < nitems(colours); i++) {
   1002 		if (strcasecmp(colours[i].name, name) == 0)
   1003 			return (colours[i].c|COLOUR_FLAG_RGB);
   1004 	}
   1005 	return (-1);
   1006 }
   1007 
   1008 /* Parse colour from an X11 string. */
   1009 int
   1010 colour_parseX11(const char *p)
   1011 {
   1012 	double	 c, m, y, k = 0;
   1013 	u_int	 r, g, b;
   1014 	size_t	 len = strlen(p);
   1015 	int	 colour = -1;
   1016 	char	*copy;
   1017 
   1018 	if ((len == 12 && sscanf(p, "rgb:%02x/%02x/%02x", &r, &g, &b) == 3) ||
   1019 	    (len == 7 && sscanf(p, "#%02x%02x%02x", &r, &g, &b) == 3) ||
   1020 	    sscanf(p, "%d,%d,%d", &r, &g, &b) == 3)
   1021 		colour = colour_join_rgb(r, g, b);
   1022 	else if ((len == 18 &&
   1023 	    sscanf(p, "rgb:%04x/%04x/%04x", &r, &g, &b) == 3) ||
   1024 	    (len == 13 && sscanf(p, "#%04x%04x%04x", &r, &g, &b) == 3))
   1025 		colour = colour_join_rgb(r >> 8, g >> 8, b >> 8);
   1026 	else if ((sscanf(p, "cmyk:%lf/%lf/%lf/%lf", &c, &m, &y, &k) == 4 ||
   1027 	    sscanf(p, "cmy:%lf/%lf/%lf", &c, &m, &y) == 3) &&
   1028 	    c >= 0 && c <= 1 && m >= 0 && m <= 1 &&
   1029 	    y >= 0 && y <= 1 && k >= 0 && k <= 1) {
   1030 		colour = colour_join_rgb(
   1031 		    (1 - c) * (1 - k) * 255,
   1032 		    (1 - m) * (1 - k) * 255,
   1033 		    (1 - y) * (1 - k) * 255);
   1034 	} else {
   1035 		while (len != 0 && *p == ' ') {
   1036 			p++;
   1037 			len--;
   1038 		}
   1039 		while (len != 0 && p[len - 1] == ' ')
   1040 			len--;
   1041 		copy = xstrndup(p, len);
   1042 		colour = colour_byname(copy);
   1043 		free(copy);
   1044 	}
   1045 	log_debug("%s: %s = %s", __func__, p, colour_tostring(colour));
   1046 	return (colour);
   1047 }
   1048 
   1049 /* Initialize palette. */
   1050 void
   1051 colour_palette_init(struct colour_palette *p)
   1052 {
   1053 	p->fg = 8;
   1054 	p->bg = 8;
   1055 	p->palette = NULL;
   1056 	p->default_palette = NULL;
   1057 }
   1058 
   1059 /* Clear palette. */
   1060 void
   1061 colour_palette_clear(struct colour_palette *p)
   1062 {
   1063 	if (p != NULL) {
   1064 		p->fg = 8;
   1065 		p->bg = 8;
   1066  		free(p->palette);
   1067 		p->palette = NULL;
   1068 	}
   1069 }
   1070 
   1071 /* Free a palette. */
   1072 void
   1073 colour_palette_free(struct colour_palette *p)
   1074 {
   1075 	if (p != NULL) {
   1076 		free(p->palette);
   1077 		p->palette = NULL;
   1078 		free(p->default_palette);
   1079 		p->default_palette = NULL;
   1080 	}
   1081 }
   1082 
   1083 /* Get a colour from a palette. */
   1084 int
   1085 colour_palette_get(struct colour_palette *p, int c)
   1086 {
   1087 	if (p == NULL)
   1088 		return (-1);
   1089 
   1090 	if (c >= 90 && c <= 97)
   1091 		c = 8 + c - 90;
   1092 	else if (c & COLOUR_FLAG_256)
   1093 		c &= ~COLOUR_FLAG_256;
   1094 	else if (c >= 8)
   1095 		return (-1);
   1096 
   1097 	if (p->palette != NULL && p->palette[c] != -1)
   1098 		return (p->palette[c]);
   1099 	if (p->default_palette != NULL && p->default_palette[c] != -1)
   1100 		return (p->default_palette[c]);
   1101 	return (-1);
   1102 }
   1103 
   1104 /* Set a colour in a palette. */
   1105 int
   1106 colour_palette_set(struct colour_palette *p, int n, int c)
   1107 {
   1108 	u_int	i;
   1109 
   1110 	if (p == NULL || n > 255)
   1111 		return (0);
   1112 
   1113 	if (c == -1 && p->palette == NULL)
   1114 		return (0);
   1115 
   1116 	if (c != -1 && p->palette == NULL) {
   1117 		if (p->palette == NULL)
   1118 			p->palette = xcalloc(256, sizeof *p->palette);
   1119 		for (i = 0; i < 256; i++)
   1120 			p->palette[i] = -1;
   1121 	}
   1122 	p->palette[n] = c;
   1123 	return (1);
   1124 }
   1125 
   1126 /* Build palette defaults from an option. */
   1127 void
   1128 colour_palette_from_option(struct colour_palette *p, struct options *oo)
   1129 {
   1130 	struct options_entry		*o;
   1131 	struct options_array_item	*a;
   1132 	u_int				 i, n;
   1133 	int				 c;
   1134 
   1135 	if (p == NULL)
   1136 		return;
   1137 
   1138 	o = options_get(oo, "pane-colours");
   1139 	if ((a = options_array_first(o)) == NULL) {
   1140 		if (p->default_palette != NULL) {
   1141 			free(p->default_palette);
   1142 			p->default_palette = NULL;
   1143 		}
   1144 		return;
   1145 	}
   1146 	if (p->default_palette == NULL)
   1147 		p->default_palette = xcalloc(256, sizeof *p->default_palette);
   1148 	for (i = 0; i < 256; i++)
   1149 		p->default_palette[i] = -1;
   1150 	while (a != NULL) {
   1151 		n = options_array_item_index(a);
   1152 		if (n < 256) {
   1153 			c = options_array_item_value(a)->number;
   1154 			p->default_palette[n] = c;
   1155 		}
   1156 		a = options_array_next(a);
   1157 	}
   1158 }
   1159