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>
29 * Colour to string conversion functions. Bit 8 of the colour means it is one
30 * of the 256 colour palette.
40 /* 256 colour RGB table, generated on first use. */
41 struct colour_rgb
*colour_rgb_256
;
43 void colour_rgb_generate256(void);
44 double colour_rgb_distance(struct colour_rgb
*, struct colour_rgb
*);
45 int colour_rgb_find(struct colour_rgb
*);
47 /* Generate 256 colour RGB table. */
49 colour_rgb_generate256(void)
51 struct colour_rgb
*rgb
;
55 * Allocate the table. The first 16 colours are often changed by users
56 * and terminals so don't include them.
58 colour_rgb_256
= xcalloc(240, sizeof *colour_rgb_256
);
60 /* Add the colours first. */
62 for (i
= 240; i
> 24; i
--) {
63 rgb
= &colour_rgb_256
[240 - i
];
66 rgb
->r
= (r
* 40) + 55;
68 rgb
->g
= (g
* 40) + 55;
70 rgb
->b
= (b
* 40) + 55;
83 /* Then add the greys. */
84 for (i
= 24; i
> 0; i
--) {
85 rgb
= &colour_rgb_256
[240 - i
];
87 rgb
->r
= 8 + (24 - i
) * 10;
88 rgb
->g
= 8 + (24 - i
) * 10;
89 rgb
->b
= 8 + (24 - i
) * 10;
93 /* Get colour RGB distance. */
95 colour_rgb_distance(struct colour_rgb
*rgb1
, struct colour_rgb
*rgb2
)
99 r
= rgb1
->r
- rgb2
->r
;
100 g
= rgb1
->g
- rgb2
->g
;
101 b
= rgb1
->b
- rgb2
->b
;
102 return (sqrt(r
* r
+ g
* g
+ b
* b
));
105 /* Work out the nearest colour from the 256 colour set. */
107 colour_rgb_find(struct colour_rgb
*rgb
)
109 double distance
, lowest
;
112 if (colour_rgb_256
== NULL
)
113 colour_rgb_generate256();
117 for (i
= 0; i
< 240; i
++) {
118 distance
= colour_rgb_distance(&colour_rgb_256
[i
], rgb
);
119 if (distance
< lowest
) {
127 /* Set grid cell foreground colour. */
129 colour_set_fg(struct grid_cell
*gc
, int c
)
132 gc
->flags
|= GRID_FLAG_FG256
;
136 /* Set grid cell background colour. */
138 colour_set_bg(struct grid_cell
*gc
, int c
)
141 gc
->flags
|= GRID_FLAG_BG256
;
145 /* Convert colour to a string. */
147 colour_tostring(int c
)
152 xsnprintf(s
, sizeof s
, "colour%u", c
& ~0x100);
179 /* Convert colour from string. */
181 colour_fromstring(const char *s
)
185 struct colour_rgb rgb
;
188 if (*s
== '#' && strlen(s
) == 7) {
189 for (cp
= s
+ 1; isxdigit((u_char
) *cp
); cp
++)
193 n
= sscanf(s
+ 1, "%2hhx%2hhx%2hhx", &rgb
.r
, &rgb
.g
, &rgb
.b
);
196 return (colour_rgb_find(&rgb
) | 0x100);
199 if (strncasecmp(s
, "colour", (sizeof "colour") - 1) == 0) {
200 n
= strtonum(s
+ (sizeof "colour") - 1, 0, 255, &errstr
);
206 if (strcasecmp(s
, "black") == 0 || (s
[0] == '0' && s
[1] == '\0'))
208 if (strcasecmp(s
, "red") == 0 || (s
[0] == '1' && s
[1] == '\0'))
210 if (strcasecmp(s
, "green") == 0 || (s
[0] == '2' && s
[1] == '\0'))
212 if (strcasecmp(s
, "yellow") == 0 || (s
[0] == '3' && s
[1] == '\0'))
214 if (strcasecmp(s
, "blue") == 0 || (s
[0] == '4' && s
[1] == '\0'))
216 if (strcasecmp(s
, "magenta") == 0 || (s
[0] == '5' && s
[1] == '\0'))
218 if (strcasecmp(s
, "cyan") == 0 || (s
[0] == '6' && s
[1] == '\0'))
220 if (strcasecmp(s
, "white") == 0 || (s
[0] == '7' && s
[1] == '\0'))
222 if (strcasecmp(s
, "default") == 0 || (s
[0] == '8' && s
[1] == '\0'))
227 /* Convert 256 colour palette to 16. */
229 colour_256to16(u_char c
)
231 static const u_char table
[256] = {
232 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
233 0, 4, 4, 4, 12, 12, 2, 6, 4, 4, 12, 12, 2, 2, 6, 4,
234 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
235 10, 10, 10, 14, 1, 5, 4, 4, 12, 12, 3, 8, 4, 4, 12, 12,
236 2, 2, 6, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10,
237 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 5, 4, 12, 12, 1, 1,
238 5, 4, 12, 12, 3, 3, 8, 4, 12, 12, 2, 2, 2, 6, 12, 12,
239 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 1, 5,
240 12, 12, 1, 1, 1, 5, 12, 12, 1, 1, 1, 5, 12, 12, 3, 3,
241 3, 7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
242 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9,
243 13, 12, 9, 9, 9, 9, 13, 12, 11, 11, 11, 11, 7, 12, 10, 10,
244 10, 10, 10, 14, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13,
245 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9,
246 9, 13, 11, 11, 11, 11, 11, 15, 0, 0, 0, 0, 0, 0, 8, 8,
247 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15
253 /* Convert 256 colour palette to 88. */
255 colour_256to88(u_char c
)
257 static const u_char table
[256] = {
258 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
259 16, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 20, 21, 21, 22,
260 22, 23, 24, 25, 25, 26, 26, 27, 24, 25, 25, 26, 26, 27, 28, 29,
261 29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 36, 37, 37, 38, 38, 39,
262 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43, 40, 41, 41, 42,
263 42, 43, 44, 45, 45, 46, 46, 47, 32, 33, 33, 34, 34, 35, 36, 37,
264 37, 38, 38, 39, 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43,
265 40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 49, 50,
266 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54, 54, 55, 56, 57,
267 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63,
268 48, 49, 49, 50, 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54,
269 54, 55, 56, 57, 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61,
270 61, 62, 62, 63, 64, 65, 65, 66, 66, 67, 68, 69, 69, 70, 70, 71,
271 68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 72, 73, 73, 74,
272 74, 75, 76, 77, 77, 78, 78, 79, 0, 0, 80, 80, 80, 81, 81, 81,
273 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87