Coverage Report

Created: 2026-08-13 06:07

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