4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
28 * Colour to string conversion functions. Bit 8 of the colour means it is one
29 * of the 256 colour palette.
39 /* 256 colour RGB table, generated on first use. */
40 struct colour_rgb
*colour_rgb_256
;
42 void colour_rgb_generate256(void);
43 u_int
colour_rgb_distance(struct colour_rgb
*, struct colour_rgb
*);
44 int colour_rgb_find(struct colour_rgb
*);
46 /* Generate 256 colour RGB table. */
48 colour_rgb_generate256(void)
50 struct colour_rgb
*rgb
;
54 * Allocate the table. The first 16 colours are often changed by users
55 * and terminals so don't include them.
57 colour_rgb_256
= xcalloc(240, sizeof *colour_rgb_256
);
59 /* Add the colours first. */
61 for (i
= 240; i
> 24; i
--) {
62 rgb
= &colour_rgb_256
[240 - i
];
65 rgb
->r
= (r
* 40) + 55;
67 rgb
->g
= (g
* 40) + 55;
69 rgb
->b
= (b
* 40) + 55;
82 /* Then add the greys. */
83 for (i
= 24; i
> 0; i
--) {
84 rgb
= &colour_rgb_256
[240 - i
];
86 rgb
->r
= 8 + (24 - i
) * 10;
87 rgb
->g
= 8 + (24 - i
) * 10;
88 rgb
->b
= 8 + (24 - i
) * 10;
92 /* Get colour RGB distance. */
94 colour_rgb_distance(struct colour_rgb
*rgb1
, struct colour_rgb
*rgb2
)
98 r
= rgb1
->r
- rgb2
->r
;
99 g
= rgb1
->g
- rgb2
->g
;
100 b
= rgb1
->b
- rgb2
->b
;
101 return (r
* r
+ g
* g
+ b
* b
);
104 /* Work out the nearest colour from the 256 colour set. */
106 colour_rgb_find(struct colour_rgb
*rgb
)
108 u_int distance
, lowest
, colour
, i
;
110 if (colour_rgb_256
== NULL
)
111 colour_rgb_generate256();
115 for (i
= 0; i
< 240; i
++) {
116 distance
= colour_rgb_distance(&colour_rgb_256
[i
], rgb
);
117 if (distance
< lowest
) {
125 /* Set grid cell foreground colour. */
127 colour_set_fg(struct grid_cell
*gc
, int c
)
130 gc
->flags
|= GRID_FLAG_FG256
;
134 /* Set grid cell background colour. */
136 colour_set_bg(struct grid_cell
*gc
, int c
)
139 gc
->flags
|= GRID_FLAG_BG256
;
143 /* Convert colour to a string. */
145 colour_tostring(int c
)
150 xsnprintf(s
, sizeof s
, "colour%u", c
& ~0x100);
177 /* Convert colour from string. */
179 colour_fromstring(const char *s
)
183 struct colour_rgb rgb
;
186 if (*s
== '#' && strlen(s
) == 7) {
187 for (cp
= s
+ 1; isxdigit((u_char
) *cp
); cp
++)
191 n
= sscanf(s
+ 1, "%2hhx%2hhx%2hhx", &rgb
.r
, &rgb
.g
, &rgb
.b
);
194 return (colour_rgb_find(&rgb
) | 0x100);
197 if (strncasecmp(s
, "colour", (sizeof "colour") - 1) == 0) {
198 n
= strtonum(s
+ (sizeof "colour") - 1, 0, 255, &errstr
);
204 if (strcasecmp(s
, "black") == 0 || (s
[0] == '0' && s
[1] == '\0'))
206 if (strcasecmp(s
, "red") == 0 || (s
[0] == '1' && s
[1] == '\0'))
208 if (strcasecmp(s
, "green") == 0 || (s
[0] == '2' && s
[1] == '\0'))
210 if (strcasecmp(s
, "yellow") == 0 || (s
[0] == '3' && s
[1] == '\0'))
212 if (strcasecmp(s
, "blue") == 0 || (s
[0] == '4' && s
[1] == '\0'))
214 if (strcasecmp(s
, "magenta") == 0 || (s
[0] == '5' && s
[1] == '\0'))
216 if (strcasecmp(s
, "cyan") == 0 || (s
[0] == '6' && s
[1] == '\0'))
218 if (strcasecmp(s
, "white") == 0 || (s
[0] == '7' && s
[1] == '\0'))
220 if (strcasecmp(s
, "default") == 0 || (s
[0] == '8' && s
[1] == '\0'))
225 /* Convert 256 colour palette to 16. */
227 colour_256to16(u_char c
)
229 static const u_char table
[256] = {
230 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
231 0, 4, 4, 4, 12, 12, 2, 6, 4, 4, 12, 12, 2, 2, 6, 4,
232 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
233 10, 10, 10, 14, 1, 5, 4, 4, 12, 12, 3, 8, 4, 4, 12, 12,
234 2, 2, 6, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10,
235 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 5, 4, 12, 12, 1, 1,
236 5, 4, 12, 12, 3, 3, 8, 4, 12, 12, 2, 2, 2, 6, 12, 12,
237 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 1, 5,
238 12, 12, 1, 1, 1, 5, 12, 12, 1, 1, 1, 5, 12, 12, 3, 3,
239 3, 7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
240 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9,
241 13, 12, 9, 9, 9, 9, 13, 12, 11, 11, 11, 11, 7, 12, 10, 10,
242 10, 10, 10, 14, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13,
243 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9,
244 9, 13, 11, 11, 11, 11, 11, 15, 0, 0, 0, 0, 0, 0, 8, 8,
245 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15
251 /* Convert 256 colour palette to 88. */
253 colour_256to88(u_char c
)
255 static const u_char table
[256] = {
256 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
257 16, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 20, 21, 21, 22,
258 22, 23, 24, 25, 25, 26, 26, 27, 24, 25, 25, 26, 26, 27, 28, 29,
259 29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 36, 37, 37, 38, 38, 39,
260 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43, 40, 41, 41, 42,
261 42, 43, 44, 45, 45, 46, 46, 47, 32, 33, 33, 34, 34, 35, 36, 37,
262 37, 38, 38, 39, 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43,
263 40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 49, 50,
264 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54, 54, 55, 56, 57,
265 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63,
266 48, 49, 49, 50, 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54,
267 54, 55, 56, 57, 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61,
268 61, 62, 62, 63, 64, 65, 65, 66, 66, 67, 68, 69, 69, 70, 70, 71,
269 68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 72, 73, 73, 74,
270 74, 75, 76, 77, 77, 78, 78, 79, 0, 0, 80, 80, 80, 81, 81, 81,
271 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87