1 #include "config.h"
2
3 #include "compat.h"
4
5 #include <stdarg.h>
6 #include <limits.h>
7 #include <ctype.h>
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <assert.h>
11 #include <locale.h>
12 #include <langinfo.h>
13
14 /*
15 Useful string stuff
16 */
17
strconcat(char * dest,size_t maxdestlen,const char * src)18 void strconcat
19 (
20 char * dest,
21 size_t maxdestlen,
22 const char * src
23 )
24 /* appends null-terminated src onto dest, ensuring length of contents
25 of latter (including terminating null) do not exceed maxdestlen. */
26 {
27 const size_t destlen = strlen(dest);
28 size_t srclen = strlen(src);
29 assert(destlen < maxdestlen);
30 if (srclen > maxdestlen - 1 - destlen)
31 {
32 srclen = maxdestlen - 1 - destlen;
33 } /*if*/
34 memcpy(dest + destlen, src, srclen);
35 dest[destlen + srclen] = 0;
36 } /*strconcat*/
37
strtounsigned(const char * s,const char * what)38 unsigned int strtounsigned
39 (
40 const char * s,
41 const char * what /* description of what I'm trying to convert, for error message */
42 )
43 /* parses s as an unsigned decimal integer, returning its value. Aborts the
44 program on error. */
45 {
46 char * s_end;
47 unsigned long result;
48 errno = 0;
49 result = strtoul(s, &s_end, 10);
50 if (errno == 0)
51 {
52 if (*s_end != '\0')
53 {
54 errno = EINVAL;
55 }
56 else if (result > UINT_MAX)
57 {
58 errno = ERANGE;
59 }
60 } /*if*/
61 if (errno != 0)
62 {
63 fprintf(stderr, "ERR: %d converting %s \"%s\" -- %s\n", errno, what, s, strerror(errno));
64 exit(1);
65 } /*if*/
66 return result;
67 } /*strtounsigned*/
68
strtosigned(const char * s,const char * what)69 int strtosigned
70 (
71 const char * s,
72 const char * what /* description of what I'm trying to convert, for error message */
73 )
74 /* parses s as a signed decimal integer, returning its value. Aborts the
75 program on error. */
76 {
77 char * s_end;
78 long result;
79 errno = 0;
80 result = strtol(s, &s_end, 10);
81 if (errno == 0)
82 {
83 if (*s_end != '\0')
84 {
85 errno = EINVAL;
86 }
87 else if (result < -INT_MAX || result > INT_MAX)
88 {
89 errno = ERANGE;
90 }
91 } /*if*/
92 if (errno != 0)
93 {
94 fprintf(stderr, "ERR: %d converting %s \"%s\" -- %s\n", errno, what, s, strerror(errno));
95 exit(1);
96 } /*if*/
97 return result;
98 } /*strtosigned*/
99
100 #ifndef HAVE_STRNDUP
strndup(const char * s,size_t n)101 char * strndup
102 (
103 const char * s,
104 size_t n
105 )
106 {
107 char * result;
108 size_t l = strlen(s);
109 if (l > n)
110 {
111 l = n;
112 } /*if*/
113 result = malloc(l + 1);
114 memcpy(result, s, l);
115 result[l] = 0;
116 return
117 result;
118 } /*strndup*/
119 #endif /*HAVE_STRNDUP*/
120
sprintf_alloc(const char * format,...)121 char * sprintf_alloc
122 (
123 const char * format,
124 ...
125 )
126 /* does the equivalent of sprintf(3) on the args, except the output string buffer
127 is dynamically allocated to be exactly big enough to hold the formatted data.
128 The result is the allocated and filled-in string buffer.
129 On failure, the result will be NULL and errno will contain the error. */
130 {
131 char * result = NULL;
132 size_t result_size = 0;
133 bool allocating = false;
134 for (;;)
135 {
136 va_list args;
137 int nrbytes;
138 va_start(args, format);
139 nrbytes = vsnprintf(result, result_size, format, args) + 1;
140 va_end(args);
141 if (allocating)
142 break;
143 result_size = nrbytes;
144 result = malloc(result_size);
145 if (result == NULL)
146 break;
147 allocating = true;
148 } /*for*/
149 return
150 result;
151 } /*sprintf_alloc*/
152
str_extract_until(const char ** src,const char * delim)153 char * str_extract_until
154 (
155 const char ** src,
156 const char * delim
157 )
158 /* scans *src, looking for the first occurrence of a character in delim. Returns
159 a copy of the prior part of *src if found, and updates *src to point after the
160 delimiter character; else returns a copy of the whole of *src, and sets *src
161 to NULL. Returns NULL iff *src is NULL. */
162 {
163 char * result = NULL; /* to begin with */
164 if (*src != NULL)
165 {
166 const size_t pos = strcspn(*src, delim);
167 if (pos < strlen(*src))
168 {
169 result = strndup(*src, pos);
170 *src = *src + pos + strspn(*src + pos, delim);
171 }
172 else
173 {
174 result = strdup(*src);
175 *src = NULL;
176 } /*if*/
177 } /*if*/
178 return
179 result;
180 } /*str_extract_until*/
181
182 /*
183 locale stuff
184 */
185
186 #ifdef HAVE_ICONV
187
188 const char *
189 default_charset;
190 static char
191 default_charset_buf[32]; /* big enough? */
192 static iconv_t
193 from_locale = ICONV_NULL;
194
195 #endif /*HAVE_ICONV*/
196
init_locale()197 void init_locale()
198 /* does locale initialization and obtains the default character set. */
199 {
200 #ifdef HAVE_ICONV
201 setlocale(LC_ALL, "");
202 strncpy(default_charset_buf, nl_langinfo(CODESET), sizeof default_charset_buf - 1);
203 default_charset_buf[sizeof default_charset_buf - 1] = 0;
204 default_charset = default_charset_buf;
205 // fprintf(stderr, "INFO: default codeset is \"%s\"\n", default_charset); /* debug */
206 setlocale(LC_ALL, "C"); /* don't need locale for anything else */
207 #else
208 // fprintf(stderr, "INFO: all text will be interpreted as UTF-8\n"); /* debug */
209 #endif /*HAVE_ICONV*/
210 } /*init_locale*/
211
locale_decode(const char * localestr)212 char * locale_decode
213 (
214 const char * localestr
215 )
216 /* allocates and returns a string containing the UTF-8 representation of
217 localestr interpreted according to the user's locale settings. */
218 /* not actually used anywhere */
219 {
220 char * result;
221 #ifdef HAVE_ICONV
222 size_t inlen, outlen;
223 char * resultnext;
224 if (from_locale == ICONV_NULL)
225 {
226 from_locale = iconv_open("UTF-8", default_charset);
227 if (from_locale == ICONV_NULL)
228 {
229 fprintf(stderr, "ERR: Cannot convert from charset \"%s\" to UTF-8\n", default_charset);
230 exit(1);
231 } /*if*/
232 } /*if*/
233 inlen = strlen(localestr);
234 outlen = inlen * 5; /* should be enough? */
235 result = malloc(outlen);
236 resultnext = result;
237 if (iconv(from_locale, (char **)&localestr, &inlen, &resultnext, &outlen) < 0)
238 {
239 fprintf
240 (
241 stderr,
242 "ERR: Error %d -- %s decoding string \"%s\"\n",
243 errno, strerror(errno), localestr
244 );
245 exit(1);
246 } /*if*/
247 assert(outlen != 0); /* there will be room for ... */
248 *resultnext++ = 0; /* ... terminating null */
249 result = realloc(result, resultnext - result); /* free unneeded memory */
250 #else
251 result = strdup(localestr);
252 #endif /*HAVE_ICONV*/
253 return result;
254 } /*locale_decode*/
255
256 #if HAVE_ICONV && LOCALIZE_FILENAMES
257
258 static iconv_t
259 to_locale = ICONV_NULL;
260
localize_filename(const char * pathname)261 char * localize_filename(const char * pathname)
262 /* converts a filename from UTF-8 to localized encoding. */
263 {
264 char * result;
265 size_t inlen, outlen;
266 char * resultnext;
267 if (to_locale == ICONV_NULL)
268 {
269 fprintf(stderr, "INFO: Converting filenames to %s\n", default_charset);
270 to_locale = iconv_open(default_charset, "UTF-8");
271 if (to_locale == ICONV_NULL)
272 {
273 fprintf(stderr, "ERR: Cannot convert from UTF-8 to charset \"%s\"\n", default_charset);
274 exit(1);
275 } /*if*/
276 } /*if*/
277 inlen = strlen(pathname);
278 outlen = inlen * 5; /* should be enough? */
279 result = malloc(outlen);
280 resultnext = result;
281 if (iconv(to_locale, (char **)&pathname, &inlen, &resultnext, &outlen) < 0)
282 {
283 fprintf
284 (
285 stderr,
286 "ERR: Error %d -- %s encoding pathname \"%s\"\n",
287 errno, strerror(errno), pathname
288 );
289 exit(1);
290 } /*if*/
291 assert(outlen != 0); /* there will be room for ... */
292 *resultnext++ = 0; /* ... terminating null */
293 result = realloc(result, resultnext - result); /* free unneeded memory */
294 return result;
295 } /*localize_filename*/
296
297 #endif
298
299 /*
300 vfiles
301 */
302
varied_open(const char * fname,int mode,const char * what)303 struct vfile varied_open
304 (
305 const char * fname,
306 int mode, /* either O_RDONLY or O_WRONLY, nothing more */
307 const char * what /* description of what I'm trying to open, for error message */
308 )
309 {
310 struct vfile vf;
311 int fnamelen;
312 if (strcmp(fname, "-") == 0)
313 {
314 vf.ftype = VFTYPE_REDIR;
315 vf.h = mode == O_RDONLY ? stdin : stdout;
316 }
317 else if (fname[0] == '&' && isdigit(fname[1]))
318 {
319 vf.ftype = VFTYPE_FILE;
320 vf.h = fdopen(atoi(fname + 1), mode == O_RDONLY ? "rb" : "wb");
321 }
322 else if (mode == O_WRONLY && fname[0] == '|')
323 {
324 vf.ftype = VFTYPE_PIPE;
325 vf.h = popen(fname + 1, "w");
326 }
327 else if (mode == O_RDONLY && fname[0] != '\0' && fname[fnamelen = strlen(fname) - 1] == '|')
328 {
329 char * const fcopy = strndup(fname, fnamelen);
330 vf.ftype = VFTYPE_PIPE;
331 vf.h = popen(fcopy, "r");
332 free(fcopy);
333 }
334 else
335 {
336 vf.ftype = VFTYPE_FILE;
337 vf.h = fopen(fname, mode == O_RDONLY ? "rb" : "wb");
338 } /*if*/
339 if (vf.h == NULL)
340 {
341 fprintf(stderr, "ERR: %d opening %s \"%s\" -- %s\n", errno, what, fname, strerror(errno));
342 exit(1);
343 } /*if*/
344 vf.mode = mode;
345 return vf;
346 } /*varied_open*/
347
varied_close(struct vfile vf)348 void varied_close(struct vfile vf)
349 {
350 if (vf.mode == O_WRONLY)
351 {
352 /* check for errors on final write before closing */
353 if (fflush(vf.h) != 0)
354 {
355 fprintf(stderr, "ERR: %d on fflush -- %s\n", errno, strerror(errno));
356 exit(1);
357 } /*if*/
358 } /*if*/
359 switch (vf.ftype)
360 {
361 case VFTYPE_FILE:
362 fclose(vf.h);
363 break;
364 case VFTYPE_PIPE:
365 pclose(vf.h);
366 break;
367 case VFTYPE_REDIR:
368 default:
369 /* nothing to do */
370 break;
371 } /*switch*/
372 } /*varied_close*/
373
374 /*
375 parsing of colour specs
376 */
377
378 typedef struct
379 {
380 const char * name; /* null marks end of list */
381 colorspec color;
382 } named_color;
383 const static named_color predefined_color_names[] =
384 /* predefined colour names, copied from <http://www.imagemagick.org/script/color.php> */
385 {
386 {"snow", {255, 250, 250, 255}},
387 {"snow1", {255, 250, 250, 255}},
388 {"snow2", {238, 233, 233, 255}},
389 {"RosyBrown1", {255, 193, 193, 255}},
390 {"RosyBrown2", {238, 180, 180, 255}},
391 {"snow3", {205, 201, 201, 255}},
392 {"LightCoral", {240, 128, 128, 255}},
393 {"IndianRed1", {255, 106, 106, 255}},
394 {"RosyBrown3", {205, 155, 155, 255}},
395 {"IndianRed2", {238, 99, 99, 255}},
396 {"RosyBrown", {188, 143, 143, 255}},
397 {"brown1", {255, 64, 64, 255}},
398 {"firebrick1", {255, 48, 48, 255}},
399 {"brown2", {238, 59, 59, 255}},
400 {"IndianRed", {205, 92, 92, 255}},
401 {"IndianRed3", {205, 85, 85, 255}},
402 {"firebrick2", {238, 44, 44, 255}},
403 {"snow4", {139, 137, 137, 255}},
404 {"brown3", {205, 51, 51, 255}},
405 {"red", {255, 0, 0, 255}},
406 {"red1", {255, 0, 0, 255}},
407 {"RosyBrown4", {139, 105, 105, 255}},
408 {"firebrick3", {205, 38, 38, 255}},
409 {"red2", {238, 0, 0, 255}},
410 {"firebrick", {178, 34, 34, 255}},
411 {"brown", {165, 42, 42, 255}},
412 {"red3", {205, 0, 0, 255}},
413 {"IndianRed4", {139, 58, 58, 255}},
414 {"brown4", {139, 35, 35, 255}},
415 {"firebrick4", {139, 26, 26, 255}},
416 {"DarkRed", {139, 0, 0, 255}},
417 {"red4", {139, 0, 0, 255}},
418 {"maroon", {128, 0, 0, 255}},
419 {"LightPink1", {255, 174, 185, 255}},
420 {"LightPink3", {205, 140, 149, 255}},
421 {"LightPink4", {139, 95, 101, 255}},
422 {"LightPink2", {238, 162, 173, 255}},
423 {"LightPink", {255, 182, 193, 255}},
424 {"pink", {255, 192, 203, 255}},
425 {"crimson", {220, 20, 60, 255}},
426 {"pink1", {255, 181, 197, 255}},
427 {"pink2", {238, 169, 184, 255}},
428 {"pink3", {205, 145, 158, 255}},
429 {"pink4", {139, 99, 108, 255}},
430 {"PaleVioletRed4", {139, 71, 93, 255}},
431 {"PaleVioletRed", {219, 112, 147, 255}},
432 {"PaleVioletRed2", {238, 121, 159, 255}},
433 {"PaleVioletRed1", {255, 130, 171, 255}},
434 {"PaleVioletRed3", {205, 104, 137, 255}},
435 {"LavenderBlush", {255, 240, 245, 255}},
436 {"LavenderBlush1", {255, 240, 245, 255}},
437 {"LavenderBlush3", {205, 193, 197, 255}},
438 {"LavenderBlush2", {238, 224, 229, 255}},
439 {"LavenderBlush4", {139, 131, 134, 255}},
440 {"maroon", {176, 48, 96, 255}},
441 {"HotPink3", {205, 96, 144, 255}},
442 {"VioletRed3", {205, 50, 120, 255}},
443 {"VioletRed1", {255, 62, 150, 255}},
444 {"VioletRed2", {238, 58, 140, 255}},
445 {"VioletRed4", {139, 34, 82, 255}},
446 {"HotPink2", {238, 106, 167, 255}},
447 {"HotPink1", {255, 110, 180, 255}},
448 {"HotPink4", {139, 58, 98, 255}},
449 {"HotPink", {255, 105, 180, 255}},
450 {"DeepPink", {255, 20, 147, 255}},
451 {"DeepPink1", {255, 20, 147, 255}},
452 {"DeepPink2", {238, 18, 137, 255}},
453 {"DeepPink3", {205, 16, 118, 255}},
454 {"DeepPink4", {139, 10, 80, 255}},
455 {"maroon1", {255, 52, 179, 255}},
456 {"maroon2", {238, 48, 167, 255}},
457 {"maroon3", {205, 41, 144, 255}},
458 {"maroon4", {139, 28, 98, 255}},
459 {"MediumVioletRed", {199, 21, 133, 255}},
460 {"VioletRed", {208, 32, 144, 255}},
461 {"orchid2", {238, 122, 233, 255}},
462 {"orchid", {218, 112, 214, 255}},
463 {"orchid1", {255, 131, 250, 255}},
464 {"orchid3", {205, 105, 201, 255}},
465 {"orchid4", {139, 71, 137, 255}},
466 {"thistle1", {255, 225, 255, 255}},
467 {"thistle2", {238, 210, 238, 255}},
468 {"plum1", {255, 187, 255, 255}},
469 {"plum2", {238, 174, 238, 255}},
470 {"thistle", {216, 191, 216, 255}},
471 {"thistle3", {205, 181, 205, 255}},
472 {"plum", {221, 160, 221, 255}},
473 {"violet", {238, 130, 238, 255}},
474 {"plum3", {205, 150, 205, 255}},
475 {"thistle4", {139, 123, 139, 255}},
476 {"fuchsia", {255, 0, 255, 255}},
477 {"magenta", {255, 0, 255, 255}},
478 {"magenta1", {255, 0, 255, 255}},
479 {"plum4", {139, 102, 139, 255}},
480 {"magenta2", {238, 0, 238, 255}},
481 {"magenta3", {205, 0, 205, 255}},
482 {"DarkMagenta", {139, 0, 139, 255}},
483 {"magenta4", {139, 0, 139, 255}},
484 {"purple", {128, 0, 128, 255}},
485 {"MediumOrchid", {186, 85, 211, 255}},
486 {"MediumOrchid1", {224, 102, 255, 255}},
487 {"MediumOrchid2", {209, 95, 238, 255}},
488 {"MediumOrchid3", {180, 82, 205, 255}},
489 {"MediumOrchid4", {122, 55, 139, 255}},
490 {"DarkViolet", {148, 0, 211, 255}},
491 {"DarkOrchid", {153, 50, 204, 255}},
492 {"DarkOrchid1", {191, 62, 255, 255}},
493 {"DarkOrchid3", {154, 50, 205, 255}},
494 {"DarkOrchid2", {178, 58, 238, 255}},
495 {"DarkOrchid4", {104, 34, 139, 255}},
496 {"purple", {160, 32, 240, 255}},
497 {"indigo", { 75, 0, 130, 255}},
498 {"BlueViolet", {138, 43, 226, 255}},
499 {"purple2", {145, 44, 238, 255}},
500 {"purple3", {125, 38, 205, 255}},
501 {"purple4", { 85, 26, 139, 255}},
502 {"purple1", {155, 48, 255, 255}},
503 {"MediumPurple", {147, 112, 219, 255}},
504 {"MediumPurple1", {171, 130, 255, 255}},
505 {"MediumPurple2", {159, 121, 238, 255}},
506 {"MediumPurple3", {137, 104, 205, 255}},
507 {"MediumPurple4", { 93, 71, 139, 255}},
508 {"DarkSlateBlue", { 72, 61, 139, 255}},
509 {"LightSlateBlue", {132, 112, 255, 255}},
510 {"MediumSlateBlue", {123, 104, 238, 255}},
511 {"SlateBlue", {106, 90, 205, 255}},
512 {"SlateBlue1", {131, 111, 255, 255}},
513 {"SlateBlue2", {122, 103, 238, 255}},
514 {"SlateBlue3", {105, 89, 205, 255}},
515 {"SlateBlue4", { 71, 60, 139, 255}},
516 {"GhostWhite", {248, 248, 255, 255}},
517 {"lavender", {230, 230, 250, 255}},
518 {"blue", { 0, 0, 255, 255}},
519 {"blue1", { 0, 0, 255, 255}},
520 {"blue2", { 0, 0, 238, 255}},
521 {"blue3", { 0, 0, 205, 255}},
522 {"MediumBlue", { 0, 0, 205, 255}},
523 {"blue4", { 0, 0, 139, 255}},
524 {"DarkBlue", { 0, 0, 139, 255}},
525 {"MidnightBlue", { 25, 25, 112, 255}},
526 {"navy", { 0, 0, 128, 255}},
527 {"NavyBlue", { 0, 0, 128, 255}},
528 {"RoyalBlue", { 65, 105, 225, 255}},
529 {"RoyalBlue1", { 72, 118, 255, 255}},
530 {"RoyalBlue2", { 67, 110, 238, 255}},
531 {"RoyalBlue3", { 58, 95, 205, 255}},
532 {"RoyalBlue4", { 39, 64, 139, 255}},
533 {"CornflowerBlue", {100, 149, 237, 255}},
534 {"LightSteelBlue", {176, 196, 222, 255}},
535 {"LightSteelBlue1", {202, 225, 255, 255}},
536 {"LightSteelBlue2", {188, 210, 238, 255}},
537 {"LightSteelBlue3", {162, 181, 205, 255}},
538 {"LightSteelBlue4", {110, 123, 139, 255}},
539 {"SlateGray4", {108, 123, 139, 255}},
540 {"SlateGray1", {198, 226, 255, 255}},
541 {"SlateGray2", {185, 211, 238, 255}},
542 {"SlateGray3", {159, 182, 205, 255}},
543 {"LightSlateGray", {119, 136, 153, 255}},
544 {"LightSlateGrey", {119, 136, 153, 255}},
545 {"SlateGray", {112, 128, 144, 255}},
546 {"SlateGrey", {112, 128, 144, 255}},
547 {"DodgerBlue", { 30, 144, 255, 255}},
548 {"DodgerBlue1", { 30, 144, 255, 255}},
549 {"DodgerBlue2", { 28, 134, 238, 255}},
550 {"DodgerBlue4", { 16, 78, 139, 255}},
551 {"DodgerBlue3", { 24, 116, 205, 255}},
552 {"AliceBlue", {240, 248, 255, 255}},
553 {"SteelBlue4", { 54, 100, 139, 255}},
554 {"SteelBlue", { 70, 130, 180, 255}},
555 {"SteelBlue1", { 99, 184, 255, 255}},
556 {"SteelBlue2", { 92, 172, 238, 255}},
557 {"SteelBlue3", { 79, 148, 205, 255}},
558 {"SkyBlue4", { 74, 112, 139, 255}},
559 {"SkyBlue1", {135, 206, 255, 255}},
560 {"SkyBlue2", {126, 192, 238, 255}},
561 {"SkyBlue3", {108, 166, 205, 255}},
562 {"LightSkyBlue", {135, 206, 250, 255}},
563 {"LightSkyBlue4", { 96, 123, 139, 255}},
564 {"LightSkyBlue1", {176, 226, 255, 255}},
565 {"LightSkyBlue2", {164, 211, 238, 255}},
566 {"LightSkyBlue3", {141, 182, 205, 255}},
567 {"SkyBlue", {135, 206, 235, 255}},
568 {"LightBlue3", {154, 192, 205, 255}},
569 {"DeepSkyBlue", { 0, 191, 255, 255}},
570 {"DeepSkyBlue1", { 0, 191, 255, 255}},
571 {"DeepSkyBlue2", { 0, 178, 238, 255}},
572 {"DeepSkyBlue4", { 0, 104, 139, 255}},
573 {"DeepSkyBlue3", { 0, 154, 205, 255}},
574 {"LightBlue1", {191, 239, 255, 255}},
575 {"LightBlue2", {178, 223, 238, 255}},
576 {"LightBlue", {173, 216, 230, 255}},
577 {"LightBlue4", {104, 131, 139, 255}},
578 {"PowderBlue", {176, 224, 230, 255}},
579 {"CadetBlue1", {152, 245, 255, 255}},
580 {"CadetBlue2", {142, 229, 238, 255}},
581 {"CadetBlue3", {122, 197, 205, 255}},
582 {"CadetBlue4", { 83, 134, 139, 255}},
583 {"turquoise1", { 0, 245, 255, 255}},
584 {"turquoise2", { 0, 229, 238, 255}},
585 {"turquoise3", { 0, 197, 205, 255}},
586 {"turquoise4", { 0, 134, 139, 255}},
587 /* {"cadet blue", { 95, 158, 160, 255}}, */ /* don't allow space in name */
588 {"CadetBlue", { 95, 158, 160, 255}},
589 {"DarkTurquoise", { 0, 206, 209, 255}},
590 {"azure", {240, 255, 255, 255}},
591 {"azure1", {240, 255, 255, 255}},
592 {"LightCyan", {224, 255, 255, 255}},
593 {"LightCyan1", {224, 255, 255, 255}},
594 {"azure2", {224, 238, 238, 255}},
595 {"LightCyan2", {209, 238, 238, 255}},
596 {"PaleTurquoise1", {187, 255, 255, 255}},
597 {"PaleTurquoise", {175, 238, 238, 255}},
598 {"PaleTurquoise2", {174, 238, 238, 255}},
599 {"DarkSlateGray1", {151, 255, 255, 255}},
600 {"azure3", {193, 205, 205, 255}},
601 {"LightCyan3", {180, 205, 205, 255}},
602 {"DarkSlateGray2", {141, 238, 238, 255}},
603 {"PaleTurquoise3", {150, 205, 205, 255}},
604 {"DarkSlateGray3", {121, 205, 205, 255}},
605 {"azure4", {131, 139, 139, 255}},
606 {"LightCyan4", {122, 139, 139, 255}},
607 {"aqua", { 0, 255, 255, 255}},
608 {"cyan", { 0, 255, 255, 255}},
609 {"cyan1", { 0, 255, 255, 255}},
610 {"PaleTurquoise4", {102, 139, 139, 255}},
611 {"cyan2", { 0, 238, 238, 255}},
612 {"DarkSlateGray4", { 82, 139, 139, 255}},
613 {"cyan3", { 0, 205, 205, 255}},
614 {"cyan4", { 0, 139, 139, 255}},
615 {"DarkCyan", { 0, 139, 139, 255}},
616 {"teal", { 0, 128, 128, 255}},
617 {"DarkSlateGray", { 47, 79, 79, 255}},
618 {"DarkSlateGrey", { 47, 79, 79, 255}},
619 {"MediumTurquoise", { 72, 209, 204, 255}},
620 {"LightSeaGreen", { 32, 178, 170, 255}},
621 {"turquoise", { 64, 224, 208, 255}},
622 {"aquamarine4", { 69, 139, 116, 255}},
623 {"aquamarine", {127, 255, 212, 255}},
624 {"aquamarine1", {127, 255, 212, 255}},
625 {"aquamarine2", {118, 238, 198, 255}},
626 {"aquamarine3", {102, 205, 170, 255}},
627 {"MediumAquamarine", {102, 205, 170, 255}},
628 {"MediumSpringGreen", { 0, 250, 154, 255}},
629 {"MintCream", {245, 255, 250, 255}},
630 {"SpringGreen", { 0, 255, 127, 255}},
631 {"SpringGreen1", { 0, 255, 127, 255}},
632 {"SpringGreen2", { 0, 238, 118, 255}},
633 {"SpringGreen3", { 0, 205, 102, 255}},
634 {"SpringGreen4", { 0, 139, 69, 255}},
635 {"MediumSeaGreen", { 60, 179, 113, 255}},
636 {"SeaGreen", { 46, 139, 87, 255}},
637 {"SeaGreen3", { 67, 205, 128, 255}},
638 {"SeaGreen1", { 84, 255, 159, 255}},
639 {"SeaGreen4", { 46, 139, 87, 255}},
640 {"SeaGreen2", { 78, 238, 148, 255}},
641 {"MediumForestGreen", { 50, 129, 75, 255}},
642 {"honeydew", {240, 255, 240, 255}},
643 {"honeydew1", {240, 255, 240, 255}},
644 {"honeydew2", {224, 238, 224, 255}},
645 {"DarkSeaGreen1", {193, 255, 193, 255}},
646 {"DarkSeaGreen2", {180, 238, 180, 255}},
647 {"PaleGreen1", {154, 255, 154, 255}},
648 {"PaleGreen", {152, 251, 152, 255}},
649 {"honeydew3", {193, 205, 193, 255}},
650 {"LightGreen", {144, 238, 144, 255}},
651 {"PaleGreen2", {144, 238, 144, 255}},
652 {"DarkSeaGreen3", {155, 205, 155, 255}},
653 {"DarkSeaGreen", {143, 188, 143, 255}},
654 {"PaleGreen3", {124, 205, 124, 255}},
655 {"honeydew4", {131, 139, 131, 255}},
656 {"green1", { 0, 255, 0, 255}},
657 {"lime", { 0, 255, 0, 255}},
658 {"LimeGreen", { 50, 205, 50, 255}},
659 {"DarkSeaGreen4", {105, 139, 105, 255}},
660 {"green2", { 0, 238, 0, 255}},
661 {"PaleGreen4", { 84, 139, 84, 255}},
662 {"green3", { 0, 205, 0, 255}},
663 {"ForestGreen", { 34, 139, 34, 255}},
664 {"green4", { 0, 139, 0, 255}},
665 {"green", { 0, 128, 0, 255}},
666 {"DarkGreen", { 0, 100, 0, 255}},
667 {"LawnGreen", {124, 252, 0, 255}},
668 {"chartreuse", {127, 255, 0, 255}},
669 {"chartreuse1", {127, 255, 0, 255}},
670 {"chartreuse2", {118, 238, 0, 255}},
671 {"chartreuse3", {102, 205, 0, 255}},
672 {"chartreuse4", { 69, 139, 0, 255}},
673 {"GreenYellow", {173, 255, 47, 255}},
674 {"DarkOliveGreen3", {162, 205, 90, 255}},
675 {"DarkOliveGreen1", {202, 255, 112, 255}},
676 {"DarkOliveGreen2", {188, 238, 104, 255}},
677 {"DarkOliveGreen4", {110, 139, 61, 255}},
678 {"DarkOliveGreen", { 85, 107, 47, 255}},
679 {"OliveDrab", {107, 142, 35, 255}},
680 {"OliveDrab1", {192, 255, 62, 255}},
681 {"OliveDrab2", {179, 238, 58, 255}},
682 {"OliveDrab3", {154, 205, 50, 255}},
683 {"YellowGreen", {154, 205, 50, 255}},
684 {"OliveDrab4", {105, 139, 34, 255}},
685 {"ivory", {255, 255, 240, 255}},
686 {"ivory1", {255, 255, 240, 255}},
687 {"LightYellow", {255, 255, 224, 255}},
688 {"LightYellow1", {255, 255, 224, 255}},
689 {"beige", {245, 245, 220, 255}},
690 {"ivory2", {238, 238, 224, 255}},
691 {"LightGoldenrodYellow", {250, 250, 210, 255}},
692 {"LightYellow2", {238, 238, 209, 255}},
693 {"ivory3", {205, 205, 193, 255}},
694 {"LightYellow3", {205, 205, 180, 255}},
695 {"ivory4", {139, 139, 131, 255}},
696 {"LightYellow4", {139, 139, 122, 255}},
697 {"yellow", {255, 255, 0, 255}},
698 {"yellow1", {255, 255, 0, 255}},
699 {"yellow2", {238, 238, 0, 255}},
700 {"yellow3", {205, 205, 0, 255}},
701 {"yellow4", {139, 139, 0, 255}},
702 {"olive", {128, 128, 0, 255}},
703 {"DarkKhaki", {189, 183, 107, 255}},
704 {"khaki2", {238, 230, 133, 255}},
705 {"LemonChiffon4", {139, 137, 112, 255}},
706 {"khaki1", {255, 246, 143, 255}},
707 {"khaki3", {205, 198, 115, 255}},
708 {"khaki4", {139, 134, 78, 255}},
709 {"PaleGoldenrod", {238, 232, 170, 255}},
710 {"LemonChiffon", {255, 250, 205, 255}},
711 {"LemonChiffon1", {255, 250, 205, 255}},
712 {"khaki", {240, 230, 140, 255}},
713 {"LemonChiffon3", {205, 201, 165, 255}},
714 {"LemonChiffon2", {238, 233, 191, 255}},
715 {"MediumGoldenRod", {209, 193, 102, 255}},
716 {"cornsilk4", {139, 136, 120, 255}},
717 {"gold", {255, 215, 0, 255}},
718 {"gold1", {255, 215, 0, 255}},
719 {"gold2", {238, 201, 0, 255}},
720 {"gold3", {205, 173, 0, 255}},
721 {"gold4", {139, 117, 0, 255}},
722 {"LightGoldenrod", {238, 221, 130, 255}},
723 {"LightGoldenrod4", {139, 129, 76, 255}},
724 {"LightGoldenrod1", {255, 236, 139, 255}},
725 {"LightGoldenrod3", {205, 190, 112, 255}},
726 {"LightGoldenrod2", {238, 220, 130, 255}},
727 {"cornsilk3", {205, 200, 177, 255}},
728 {"cornsilk2", {238, 232, 205, 255}},
729 {"cornsilk", {255, 248, 220, 255}},
730 {"cornsilk1", {255, 248, 220, 255}},
731 {"goldenrod", {218, 165, 32, 255}},
732 {"goldenrod1", {255, 193, 37, 255}},
733 {"goldenrod2", {238, 180, 34, 255}},
734 {"goldenrod3", {205, 155, 29, 255}},
735 {"goldenrod4", {139, 105, 20, 255}},
736 {"DarkGoldenrod", {184, 134, 11, 255}},
737 {"DarkGoldenrod1", {255, 185, 15, 255}},
738 {"DarkGoldenrod2", {238, 173, 14, 255}},
739 {"DarkGoldenrod3", {205, 149, 12, 255}},
740 {"DarkGoldenrod4", {139, 101, 8, 255}},
741 {"FloralWhite", {255, 250, 240, 255}},
742 {"wheat2", {238, 216, 174, 255}},
743 {"OldLace", {253, 245, 230, 255}},
744 {"wheat", {245, 222, 179, 255}},
745 {"wheat1", {255, 231, 186, 255}},
746 {"wheat3", {205, 186, 150, 255}},
747 {"orange", {255, 165, 0, 255}},
748 {"orange1", {255, 165, 0, 255}},
749 {"orange2", {238, 154, 0, 255}},
750 {"orange3", {205, 133, 0, 255}},
751 {"orange4", {139, 90, 0, 255}},
752 {"wheat4", {139, 126, 102, 255}},
753 {"moccasin", {255, 228, 181, 255}},
754 {"PapayaWhip", {255, 239, 213, 255}},
755 {"NavajoWhite3", {205, 179, 139, 255}},
756 {"BlanchedAlmond", {255, 235, 205, 255}},
757 {"NavajoWhite", {255, 222, 173, 255}},
758 {"NavajoWhite1", {255, 222, 173, 255}},
759 {"NavajoWhite2", {238, 207, 161, 255}},
760 {"NavajoWhite4", {139, 121, 94, 255}},
761 {"AntiqueWhite4", {139, 131, 120, 255}},
762 {"AntiqueWhite", {250, 235, 215, 255}},
763 {"tan", {210, 180, 140, 255}},
764 {"bisque4", {139, 125, 107, 255}},
765 {"burlywood", {222, 184, 135, 255}},
766 {"AntiqueWhite2", {238, 223, 204, 255}},
767 {"burlywood1", {255, 211, 155, 255}},
768 {"burlywood3", {205, 170, 125, 255}},
769 {"burlywood2", {238, 197, 145, 255}},
770 {"AntiqueWhite1", {255, 239, 219, 255}},
771 {"burlywood4", {139, 115, 85, 255}},
772 {"AntiqueWhite3", {205, 192, 176, 255}},
773 {"DarkOrange", {255, 140, 0, 255}},
774 {"bisque2", {238, 213, 183, 255}},
775 {"bisque", {255, 228, 196, 255}},
776 {"bisque1", {255, 228, 196, 255}},
777 {"bisque3", {205, 183, 158, 255}},
778 {"DarkOrange1", {255, 127, 0, 255}},
779 {"linen", {250, 240, 230, 255}},
780 {"DarkOrange2", {238, 118, 0, 255}},
781 {"DarkOrange3", {205, 102, 0, 255}},
782 {"DarkOrange4", {139, 69, 0, 255}},
783 {"peru", {205, 133, 63, 255}},
784 {"tan1", {255, 165, 79, 255}},
785 {"tan2", {238, 154, 73, 255}},
786 {"tan3", {205, 133, 63, 255}},
787 {"tan4", {139, 90, 43, 255}},
788 {"PeachPuff", {255, 218, 185, 255}},
789 {"PeachPuff1", {255, 218, 185, 255}},
790 {"PeachPuff4", {139, 119, 101, 255}},
791 {"PeachPuff2", {238, 203, 173, 255}},
792 {"PeachPuff3", {205, 175, 149, 255}},
793 {"SandyBrown", {244, 164, 96, 255}},
794 {"seashell4", {139, 134, 130, 255}},
795 {"seashell2", {238, 229, 222, 255}},
796 {"seashell3", {205, 197, 191, 255}},
797 {"chocolate", {210, 105, 30, 255}},
798 {"chocolate1", {255, 127, 36, 255}},
799 {"chocolate2", {238, 118, 33, 255}},
800 {"chocolate3", {205, 102, 29, 255}},
801 {"chocolate4", {139, 69, 19, 255}},
802 {"SaddleBrown", {139, 69, 19, 255}},
803 {"seashell", {255, 245, 238, 255}},
804 {"seashell1", {255, 245, 238, 255}},
805 {"sienna4", {139, 71, 38, 255}},
806 {"sienna", {160, 82, 45, 255}},
807 {"sienna1", {255, 130, 71, 255}},
808 {"sienna2", {238, 121, 66, 255}},
809 {"sienna3", {205, 104, 57, 255}},
810 {"LightSalmon3", {205, 129, 98, 255}},
811 {"LightSalmon", {255, 160, 122, 255}},
812 {"LightSalmon1", {255, 160, 122, 255}},
813 {"LightSalmon4", {139, 87, 66, 255}},
814 {"LightSalmon2", {238, 149, 114, 255}},
815 {"coral", {255, 127, 80, 255}},
816 {"OrangeRed", {255, 69, 0, 255}},
817 {"OrangeRed1", {255, 69, 0, 255}},
818 {"OrangeRed2", {238, 64, 0, 255}},
819 {"OrangeRed3", {205, 55, 0, 255}},
820 {"OrangeRed4", {139, 37, 0, 255}},
821 {"DarkSalmon", {233, 150, 122, 255}},
822 {"salmon1", {255, 140, 105, 255}},
823 {"salmon2", {238, 130, 98, 255}},
824 {"salmon3", {205, 112, 84, 255}},
825 {"salmon4", {139, 76, 57, 255}},
826 {"coral1", {255, 114, 86, 255}},
827 {"coral2", {238, 106, 80, 255}},
828 {"coral3", {205, 91, 69, 255}},
829 {"coral4", {139, 62, 47, 255}},
830 {"tomato4", {139, 54, 38, 255}},
831 {"tomato", {255, 99, 71, 255}},
832 {"tomato1", {255, 99, 71, 255}},
833 {"tomato2", {238, 92, 66, 255}},
834 {"tomato3", {205, 79, 57, 255}},
835 {"MistyRose4", {139, 125, 123, 255}},
836 {"MistyRose2", {238, 213, 210, 255}},
837 {"MistyRose", {255, 228, 225, 255}},
838 {"MistyRose1", {255, 228, 225, 255}},
839 {"salmon", {250, 128, 114, 255}},
840 {"MistyRose3", {205, 183, 181, 255}},
841 {"white", {255, 255, 255, 255}},
842 {"gray100", {255, 255, 255, 255}},
843 {"grey100", {255, 255, 255, 255}},
844 {"grey100", {255, 255, 255, 255}},
845 {"gray99", {252, 252, 252, 255}},
846 {"grey99", {252, 252, 252, 255}},
847 {"gray98", {250, 250, 250, 255}},
848 {"grey98", {250, 250, 250, 255}},
849 {"gray97", {247, 247, 247, 255}},
850 {"grey97", {247, 247, 247, 255}},
851 {"gray96", {245, 245, 245, 255}},
852 {"grey96", {245, 245, 245, 255}},
853 {"WhiteSmoke", {245, 245, 245, 255}},
854 {"gray95", {242, 242, 242, 255}},
855 {"grey95", {242, 242, 242, 255}},
856 {"gray94", {240, 240, 240, 255}},
857 {"grey94", {240, 240, 240, 255}},
858 {"gray93", {237, 237, 237, 255}},
859 {"grey93", {237, 237, 237, 255}},
860 {"gray92", {235, 235, 235, 255}},
861 {"grey92", {235, 235, 235, 255}},
862 {"gray91", {232, 232, 232, 255}},
863 {"grey91", {232, 232, 232, 255}},
864 {"gray90", {229, 229, 229, 255}},
865 {"grey90", {229, 229, 229, 255}},
866 {"gray89", {227, 227, 227, 255}},
867 {"grey89", {227, 227, 227, 255}},
868 {"gray88", {224, 224, 224, 255}},
869 {"grey88", {224, 224, 224, 255}},
870 {"gray87", {222, 222, 222, 255}},
871 {"grey87", {222, 222, 222, 255}},
872 {"gainsboro", {220, 220, 220, 255}},
873 {"gray86", {219, 219, 219, 255}},
874 {"grey86", {219, 219, 219, 255}},
875 {"gray85", {217, 217, 217, 255}},
876 {"grey85", {217, 217, 217, 255}},
877 {"gray84", {214, 214, 214, 255}},
878 {"grey84", {214, 214, 214, 255}},
879 {"gray83", {212, 212, 212, 255}},
880 {"grey83", {212, 212, 212, 255}},
881 {"LightGray", {211, 211, 211, 255}},
882 {"LightGrey", {211, 211, 211, 255}},
883 {"gray82", {209, 209, 209, 255}},
884 {"grey82", {209, 209, 209, 255}},
885 {"gray81", {207, 207, 207, 255}},
886 {"grey81", {207, 207, 207, 255}},
887 {"gray80", {204, 204, 204, 255}},
888 {"grey80", {204, 204, 204, 255}},
889 {"gray79", {201, 201, 201, 255}},
890 {"grey79", {201, 201, 201, 255}},
891 {"gray78", {199, 199, 199, 255}},
892 {"grey78", {199, 199, 199, 255}},
893 {"gray77", {196, 196, 196, 255}},
894 {"grey77", {196, 196, 196, 255}},
895 {"gray76", {194, 194, 194, 255}},
896 {"grey76", {194, 194, 194, 255}},
897 {"silver", {192, 192, 192, 255}},
898 {"gray75", {191, 191, 191, 255}},
899 {"grey75", {191, 191, 191, 255}},
900 {"gray74", {189, 189, 189, 255}},
901 {"grey74", {189, 189, 189, 255}},
902 {"gray73", {186, 186, 186, 255}},
903 {"grey73", {186, 186, 186, 255}},
904 {"gray72", {184, 184, 184, 255}},
905 {"grey72", {184, 184, 184, 255}},
906 {"gray71", {181, 181, 181, 255}},
907 {"grey71", {181, 181, 181, 255}},
908 {"gray70", {179, 179, 179, 255}},
909 {"grey70", {179, 179, 179, 255}},
910 {"gray69", {176, 176, 176, 255}},
911 {"grey69", {176, 176, 176, 255}},
912 {"gray68", {173, 173, 173, 255}},
913 {"grey68", {173, 173, 173, 255}},
914 {"gray67", {171, 171, 171, 255}},
915 {"grey67", {171, 171, 171, 255}},
916 {"DarkGray", {169, 169, 169, 255}},
917 {"DarkGrey", {169, 169, 169, 255}},
918 {"gray66", {168, 168, 168, 255}},
919 {"grey66", {168, 168, 168, 255}},
920 {"gray65", {166, 166, 166, 255}},
921 {"grey65", {166, 166, 166, 255}},
922 {"gray64", {163, 163, 163, 255}},
923 {"grey64", {163, 163, 163, 255}},
924 {"gray63", {161, 161, 161, 255}},
925 {"grey63", {161, 161, 161, 255}},
926 {"gray62", {158, 158, 158, 255}},
927 {"grey62", {158, 158, 158, 255}},
928 {"gray61", {156, 156, 156, 255}},
929 {"grey61", {156, 156, 156, 255}},
930 {"gray60", {153, 153, 153, 255}},
931 {"grey60", {153, 153, 153, 255}},
932 {"gray59", {150, 150, 150, 255}},
933 {"grey59", {150, 150, 150, 255}},
934 {"gray58", {148, 148, 148, 255}},
935 {"grey58", {148, 148, 148, 255}},
936 {"gray57", {145, 145, 145, 255}},
937 {"grey57", {145, 145, 145, 255}},
938 {"gray56", {143, 143, 143, 255}},
939 {"grey56", {143, 143, 143, 255}},
940 {"gray55", {140, 140, 140, 255}},
941 {"grey55", {140, 140, 140, 255}},
942 {"gray54", {138, 138, 138, 255}},
943 {"grey54", {138, 138, 138, 255}},
944 {"gray53", {135, 135, 135, 255}},
945 {"grey53", {135, 135, 135, 255}},
946 {"gray52", {133, 133, 133, 255}},
947 {"grey52", {133, 133, 133, 255}},
948 {"gray51", {130, 130, 130, 255}},
949 {"grey51", {130, 130, 130, 255}},
950 {"fractal", {128, 128, 128, 255}},
951 {"gray50", {127, 127, 127, 255}},
952 {"grey50", {127, 127, 127, 255}},
953 {"gray", {126, 126, 126, 255}},
954 {"gray49", {125, 125, 125, 255}},
955 {"grey49", {125, 125, 125, 255}},
956 {"gray48", {122, 122, 122, 255}},
957 {"grey48", {122, 122, 122, 255}},
958 {"gray47", {120, 120, 120, 255}},
959 {"grey47", {120, 120, 120, 255}},
960 {"gray46", {117, 117, 117, 255}},
961 {"grey46", {117, 117, 117, 255}},
962 {"gray45", {115, 115, 115, 255}},
963 {"grey45", {115, 115, 115, 255}},
964 {"gray44", {112, 112, 112, 255}},
965 {"grey44", {112, 112, 112, 255}},
966 {"gray43", {110, 110, 110, 255}},
967 {"grey43", {110, 110, 110, 255}},
968 {"gray42", {107, 107, 107, 255}},
969 {"grey42", {107, 107, 107, 255}},
970 {"DimGray", {105, 105, 105, 255}},
971 {"DimGrey", {105, 105, 105, 255}},
972 {"gray41", {105, 105, 105, 255}},
973 {"grey41", {105, 105, 105, 255}},
974 {"gray40", {102, 102, 102, 255}},
975 {"grey40", {102, 102, 102, 255}},
976 {"gray39", { 99, 99, 99, 255}},
977 {"grey39", { 99, 99, 99, 255}},
978 {"gray38", { 97, 97, 97, 255}},
979 {"grey38", { 97, 97, 97, 255}},
980 {"gray37", { 94, 94, 94, 255}},
981 {"grey37", { 94, 94, 94, 255}},
982 {"gray36", { 92, 92, 92, 255}},
983 {"grey36", { 92, 92, 92, 255}},
984 {"gray35", { 89, 89, 89, 255}},
985 {"grey35", { 89, 89, 89, 255}},
986 {"gray34", { 87, 87, 87, 255}},
987 {"grey34", { 87, 87, 87, 255}},
988 {"gray33", { 84, 84, 84, 255}},
989 {"grey33", { 84, 84, 84, 255}},
990 {"gray32", { 82, 82, 82, 255}},
991 {"grey32", { 82, 82, 82, 255}},
992 {"gray31", { 79, 79, 79, 255}},
993 {"grey31", { 79, 79, 79, 255}},
994 {"gray30", { 77, 77, 77, 255}},
995 {"grey30", { 77, 77, 77, 255}},
996 {"gray29", { 74, 74, 74, 255}},
997 {"grey29", { 74, 74, 74, 255}},
998 {"gray28", { 71, 71, 71, 255}},
999 {"grey28", { 71, 71, 71, 255}},
1000 {"gray27", { 69, 69, 69, 255}},
1001 {"grey27", { 69, 69, 69, 255}},
1002 {"gray26", { 66, 66, 66, 255}},
1003 {"grey26", { 66, 66, 66, 255}},
1004 {"gray25", { 64, 64, 64, 255}},
1005 {"grey25", { 64, 64, 64, 255}},
1006 {"gray24", { 61, 61, 61, 255}},
1007 {"grey24", { 61, 61, 61, 255}},
1008 {"gray23", { 59, 59, 59, 255}},
1009 {"grey23", { 59, 59, 59, 255}},
1010 {"gray22", { 56, 56, 56, 255}},
1011 {"grey22", { 56, 56, 56, 255}},
1012 {"gray21", { 54, 54, 54, 255}},
1013 {"grey21", { 54, 54, 54, 255}},
1014 {"gray20", { 51, 51, 51, 255}},
1015 {"grey20", { 51, 51, 51, 255}},
1016 {"gray19", { 48, 48, 48, 255}},
1017 {"grey19", { 48, 48, 48, 255}},
1018 {"gray18", { 46, 46, 46, 255}},
1019 {"grey18", { 46, 46, 46, 255}},
1020 {"gray17", { 43, 43, 43, 255}},
1021 {"grey17", { 43, 43, 43, 255}},
1022 {"gray16", { 41, 41, 41, 255}},
1023 {"grey16", { 41, 41, 41, 255}},
1024 {"gray15", { 38, 38, 38, 255}},
1025 {"grey15", { 38, 38, 38, 255}},
1026 {"gray14", { 36, 36, 36, 255}},
1027 {"grey14", { 36, 36, 36, 255}},
1028 {"gray13", { 33, 33, 33, 255}},
1029 {"grey13", { 33, 33, 33, 255}},
1030 {"gray12", { 31, 31, 31, 255}},
1031 {"grey12", { 31, 31, 31, 255}},
1032 {"gray11", { 28, 28, 28, 255}},
1033 {"grey11", { 28, 28, 28, 255}},
1034 {"gray10", { 26, 26, 26, 255}},
1035 {"grey10", { 26, 26, 26, 255}},
1036 {"gray9", { 23, 23, 23, 255}},
1037 {"grey9", { 23, 23, 23, 255}},
1038 {"gray8", { 20, 20, 20, 255}},
1039 {"grey8", { 20, 20, 20, 255}},
1040 {"gray7", { 18, 18, 18, 255}},
1041 {"grey7", { 18, 18, 18, 255}},
1042 {"gray6", { 15, 15, 15, 255}},
1043 {"grey6", { 15, 15, 15, 255}},
1044 {"gray5", { 13, 13, 13, 255}},
1045 {"grey5", { 13, 13, 13, 255}},
1046 {"gray4", { 10, 10, 10, 255}},
1047 {"grey4", { 10, 10, 10, 255}},
1048 {"gray3", { 8, 8, 8, 255}},
1049 {"grey3", { 8, 8, 8, 255}},
1050 {"gray2", { 5, 5, 5, 255}},
1051 {"grey2", { 5, 5, 5, 255}},
1052 {"gray1", { 3, 3, 3, 255}},
1053 {"grey1", { 3, 3, 3, 255}},
1054 {"black", { 0, 0, 0, 255}},
1055 {"gray0", { 0, 0, 0, 255}},
1056 {"grey0", { 0, 0, 0, 255}},
1057 {"opaque", { 0, 0, 0, 255}},
1058 {"none", { 0, 0, 0, 0}},
1059 {"transparent", {0, 0, 0, 0}},
1060 {0, {0, 0, 0, 0}} /* marks end of list */
1061 };
1062
skipseparators(const char ** src,const char * srcend)1063 static void skipseparators
1064 (
1065 const char ** src,
1066 const char * srcend
1067 )
1068 {
1069 unsigned char ch;
1070 for (;;)
1071 {
1072 if (*src == srcend)
1073 break;
1074 ch = **src;
1075 if (ch != ' ' && ch != '\n' && ch != '\t')
1076 break;
1077 ++*src;
1078 } /*for*/
1079 } /*skipseparators*/
1080
parse_color_component(const char ** src,const char * srcend,int maxvalue,int * value)1081 static bool parse_color_component
1082 (
1083 const char ** src,
1084 const char * srcend,
1085 int maxvalue,
1086 int * value
1087 )
1088 /* parses a colour component which can be a number [0 .. maxvalue]
1089 or a percentage of maxvalue. */
1090 {
1091 bool ok;
1092 float fvalue;
1093 int factor;
1094 bool decptseen, percentseen;
1095 unsigned char ch;
1096 decptseen = false;
1097 percentseen = false;
1098 fvalue = 0;
1099 do /*once*/
1100 {
1101 ok = false; /* in case no valid characters seen */
1102 for (;;)
1103 {
1104 if (*src == srcend)
1105 break;
1106 ch = **src;
1107 ++*src;
1108 ok = true; /* if not already set */
1109 if (ch >= '0' && ch <= '9')
1110 {
1111 const int val = ch - '0';
1112 if (decptseen)
1113 {
1114 fvalue += (float)val / factor;
1115 factor *= 10;
1116 }
1117 else
1118 {
1119 fvalue = fvalue * 10 + val;
1120 } /*if*/
1121 }
1122 else if (ch == '.')
1123 {
1124 if (decptseen)
1125 {
1126 ok = false;
1127 break;
1128 } /*if*/
1129 decptseen = true;
1130 factor = 10;
1131 }
1132 else if (ch == '%')
1133 {
1134 percentseen = true;
1135 break;
1136 }
1137 else
1138 {
1139 --*src;
1140 break;
1141 } /*if*/
1142 } /*for*/
1143 if (!ok)
1144 break;
1145 if (fvalue > (percentseen ? 100 : maxvalue))
1146 {
1147 ok = false;
1148 break;
1149 } /*if*/
1150 *value = percentseen ? fvalue * maxvalue / 100 : fvalue;
1151 }
1152 while (false);
1153 return ok;
1154 } /*parse_color_component*/
1155
parse_color(const char * colorstr,const char * what)1156 colorspec parse_color
1157 (
1158 const char * colorstr,
1159 const char * what /* additional explanatory text for error message */
1160 )
1161 /* parses colorstr and returns the resulting colour. Will abort the process
1162 on any errors. */
1163 {
1164 colorspec result;
1165 const char * src;
1166 const char * const srcend = colorstr + strlen(colorstr);
1167 const char * errmsg = 0;
1168 char c;
1169 int colorindex;
1170 bool hex, nonhex, paren;
1171 do /*once*/
1172 {
1173 hex = false;
1174 nonhex = false;
1175 paren = false;
1176 src = colorstr;
1177 for (;;)
1178 {
1179 if (src == srcend)
1180 break;
1181 c = *src;
1182 if (c == '#')
1183 {
1184 if (src != colorstr) /* must occur at start */
1185 {
1186 errmsg = "illegal \"#\"";
1187 break;
1188 } /*if*/
1189 hex = true;
1190 }
1191 else if (c == '(')
1192 {
1193 paren = true;
1194 break;
1195 }
1196 else if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c >= 'A' && c <= 'Z')
1197 {
1198 if (c > 'f' && c <= 'z' || c > 'F' && c <= 'Z')
1199 {
1200 nonhex = true;
1201 } /*if*/
1202 }
1203 else
1204 {
1205 errmsg = "non-alphanumeric character";
1206 break;
1207 } /*if*/
1208 ++src;
1209 } /*for*/
1210 if (errmsg != 0)
1211 break;
1212 if (hex && (nonhex || paren))
1213 {
1214 errmsg = "doesn't make sense";
1215 break;
1216 } /*if*/
1217 if (paren)
1218 {
1219 enum
1220 {
1221 maxspacename = 5, /* max length of all the valid colour space names */
1222 };
1223 char spacename[maxspacename + 1];
1224 int nrcomponents, componentindex, component[4];
1225 bool gotcolors, gothue, gotlightness, gotalpha;
1226 if (src - colorstr > maxspacename)
1227 {
1228 errmsg = "illegal color-space name";
1229 break;
1230 } /*if*/
1231 memcpy(spacename, colorstr, src - colorstr);
1232 spacename[src - colorstr] = 0;
1233 if (strcasecmp(spacename, "rgb") == 0)
1234 {
1235 nrcomponents = 3;
1236 gotcolors = true;
1237 gothue = false;
1238 gotalpha = false;
1239 }
1240 else if (strcasecmp(spacename, "rgba") == 0)
1241 {
1242 nrcomponents = 4;
1243 gotcolors = true;
1244 gothue = false;
1245 gotalpha = true;
1246 }
1247 else if (strcasecmp(spacename, "gray") == 0)
1248 {
1249 nrcomponents = 1;
1250 gotcolors = false;
1251 gothue = false;
1252 gotalpha = false;
1253 }
1254 else if (strcasecmp(spacename, "graya") == 0)
1255 {
1256 nrcomponents = 2;
1257 gotcolors = false;
1258 gothue = false;
1259 gotalpha = true;
1260 }
1261 else if (strcasecmp(spacename, "hsb") == 0 || strcasecmp(spacename, "hsv") == 0)
1262 {
1263 nrcomponents = 3;
1264 gotcolors = true;
1265 gothue = true;
1266 gotlightness = false;
1267 gotalpha = false;
1268 }
1269 else if (strcasecmp(spacename, "hsba") == 0 || strcasecmp(spacename, "hsva") == 0)
1270 {
1271 nrcomponents = 4;
1272 gotcolors = true;
1273 gothue = true;
1274 gotlightness = false;
1275 gotalpha = true;
1276 }
1277 else if (strcasecmp(spacename, "hsl") == 0)
1278 {
1279 nrcomponents = 3;
1280 gotcolors = true;
1281 gothue = true;
1282 gotlightness = true;
1283 gotalpha = false;
1284 }
1285 else if (strcasecmp(spacename, "hsla") == 0)
1286 {
1287 nrcomponents = 4;
1288 gotcolors = true;
1289 gothue = true;
1290 gotlightness = true;
1291 gotalpha = true;
1292 }
1293 else
1294 {
1295 errmsg = "can't recognize color-space name";
1296 break;
1297 } /*if*/
1298 for (componentindex = 0;;)
1299 {
1300 if (componentindex == 0 ? *src != '(' : *src != ',')
1301 {
1302 errmsg = "illegal character in color spec";
1303 break;
1304 } /*if*/
1305 ++src; /* skip parenthesis/comma */
1306 skipseparators(&src, srcend);
1307 if (*src == ')')
1308 {
1309 errmsg = "too few color components";
1310 break;
1311 } /*if*/
1312 if
1313 (
1314 !parse_color_component
1315 (
1316 /*src =*/ &src,
1317 /*srcend =*/ srcend,
1318 /*maxvalue =*/ gothue && componentindex == 0 ? 360 : 255,
1319 /*value =*/ component + componentindex
1320 )
1321 )
1322 {
1323 errmsg = "illegal number for color component";
1324 break;
1325 } /*if*/
1326 ++componentindex;
1327 if (componentindex == nrcomponents)
1328 break;
1329 } /*for*/
1330 if (errmsg != 0)
1331 break;
1332 skipseparators(&src, srcend);
1333 if (*src++ != ')')
1334 {
1335 errmsg = "missing close parenthesis";
1336 break;
1337 } /*if*/
1338 if (src != srcend)
1339 {
1340 errmsg = "junk after close parenthesis";
1341 break;
1342 } /*if*/
1343 if (gothue)
1344 {
1345 component[0] %= 360;
1346 /* convert to RGB using formulas from Wikipedia */
1347 {
1348 const int hue = component[0];
1349 const int chroma =
1350 (gotlightness ?
1351 2
1352 *
1353 (component[2] < 128 ? component[2] : 255 - component[2])
1354 :
1355 component[2]
1356 )
1357 *
1358 component[1]
1359 /
1360 255;
1361 const int second = chroma * (60 - abs(hue % 120 - 60)) / 60;
1362 const int brighten =
1363 gotlightness ?
1364 component[2] - chroma / 2
1365 :
1366 component[2] - chroma;
1367 int * primary, * secondary, * opposite;
1368 if (hue < 60)
1369 {
1370 primary = component + 0;
1371 secondary = component + 1;
1372 opposite = component + 2;
1373 }
1374 else if (hue >= 60 && hue < 120)
1375 {
1376 primary = component + 1;
1377 secondary = component + 0;
1378 opposite = component + 2;
1379 }
1380 else if (hue >= 120 && hue < 180)
1381 {
1382 primary = component + 1;
1383 secondary = component + 2;
1384 opposite = component + 0;
1385 }
1386 else if (hue >= 180 && hue < 240)
1387 {
1388 primary = component + 2;
1389 secondary = component + 1;
1390 opposite = component + 0;
1391 }
1392 else if (hue >= 240 && hue < 300)
1393 {
1394 primary = component + 2;
1395 secondary = component + 0;
1396 opposite = component + 1;
1397 }
1398 else /* hue >= 300 && hue < 360 */
1399 {
1400 primary = component + 0;
1401 secondary = component + 2;
1402 opposite = component + 1;
1403 } /*if*/
1404 *primary = chroma + brighten;
1405 *secondary = second + brighten;
1406 *opposite = brighten;
1407 }
1408 }
1409 else if (!gotcolors)
1410 {
1411 if (gotalpha)
1412 {
1413 component[3] = component[1];
1414 } /*if*/
1415 component[2] = component[1] = component[0];
1416 } /*if*/
1417 if (!gotalpha)
1418 {
1419 component[3] = 255;
1420 } /*if*/
1421 result.r = component[0];
1422 result.g = component[1];
1423 result.b = component[2];
1424 result.a = component[3];
1425 break;
1426 } /*if*/
1427 if (nonhex)
1428 {
1429 bool found;
1430 for (colorindex = 0;;)
1431 {
1432 const named_color * const entry = predefined_color_names + colorindex;
1433 if (entry->name == 0)
1434 {
1435 found = false;
1436 break;
1437 } /*if*/
1438 if (strcasecmp(entry->name, colorstr) == 0)
1439 {
1440 result = entry->color;
1441 found = true;
1442 break;
1443 } /*if*/
1444 ++colorindex;
1445 } /*for*/
1446 if (found)
1447 break;
1448 if (nonhex)
1449 {
1450 errmsg = "unrecognized color name";
1451 break;
1452 } /*if*/
1453 /* allow plain hex string with no preceding "#" for backward compatibility */
1454 } /*if*/
1455 /* must be hex */
1456 {
1457 int componentlength, componentscale, componentindex;
1458 src = colorstr + (colorstr[0] == '#' ? 1 : 0);
1459 if (srcend - src > 12 || (srcend - src) % 3 != 0)
1460 {
1461 errmsg = "bad hex color string";
1462 break;
1463 } /*if*/
1464 componentlength = (srcend - src) / 3;
1465 componentscale = (1 << 4 * componentlength) - 1;
1466 for (componentindex = 0; componentindex < 3; ++componentindex)
1467 {
1468 int component, j;
1469 unsigned char * dest;
1470 component = 0;
1471 for (j = 0; j < componentlength; ++j)
1472 {
1473 const unsigned char ch = *src++;
1474 component =
1475 component * 16
1476 +
1477 (ch >= 'a' && ch <= 'f' ?
1478 ch - 'a' + 10
1479 : ch >= 'A' && ch <= 'F' ?
1480 ch - 'A' + 10
1481 : /* ch >= '0' && ch <= '9' ? */
1482 ch - '0'
1483 );
1484 } /*for*/
1485 switch (componentindex)
1486 {
1487 case 0:
1488 dest = &result.r;
1489 break;
1490 case 1:
1491 dest = &result.g;
1492 break;
1493 case 2:
1494 dest = &result.b;
1495 break;
1496 } /*switch*/
1497 *dest = component * 255 / componentscale;
1498 } /*for*/
1499 result.a = 255;
1500 }
1501 }
1502 while (false);
1503 if (errmsg != 0)
1504 {
1505 fprintf(stderr, "ERR: couldn't parse %s colorspec \"%s\" -- %s\n", what, colorstr, errmsg);
1506 exit(1);
1507 } /*if*/
1508 return result;
1509 } /*parse_color*/
1510