degesch: color cleanup
This commit is contained in:
parent
b5a7ea63c2
commit
2d040cae73
142
degesch.c
142
degesch.c
@ -1563,40 +1563,6 @@ free_terminal (void)
|
|||||||
del_curterm (cur_term);
|
del_curterm (cur_term);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: commonly terminals have 8 colors (worst), 16 colors (allows brightness
|
|
||||||
// without the bold/blink attributes), 88 colors (the same plus a 4^3 RGB cube
|
|
||||||
// and a few shades of gray), or 256 colors (best)
|
|
||||||
|
|
||||||
static int
|
|
||||||
index_to_terminal_palette (int color)
|
|
||||||
{
|
|
||||||
hard_assert (color >= 0 && color < 256);
|
|
||||||
|
|
||||||
// No conversion
|
|
||||||
if (max_colors == 256)
|
|
||||||
return color;
|
|
||||||
// These colours are the same everywhere
|
|
||||||
if (color < 16 && max_colors > color)
|
|
||||||
return color;
|
|
||||||
|
|
||||||
// Outside the 16-color range, we only support the 88-color palette,
|
|
||||||
// which we can interpolate to from the 256-color one on input
|
|
||||||
if (max_colors != 88)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// 24 -> 8 extra shades of gray
|
|
||||||
if (color >= 232)
|
|
||||||
return 80 + (color - 232) / 3;
|
|
||||||
|
|
||||||
// 6 * 6 * 6 cube -> 4 * 4 * 4 cube
|
|
||||||
int x[6] = { 0, 1, 1, 2, 2, 3 };
|
|
||||||
int index = color - 16;
|
|
||||||
return 16 +
|
|
||||||
( x[ index / 36 ] << 8
|
|
||||||
| x[(index / 6) % 6 ] << 4
|
|
||||||
| x[(index % 6) ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
typedef int (*terminal_printer_fn) (int);
|
typedef int (*terminal_printer_fn) (int);
|
||||||
@ -1726,7 +1692,8 @@ enum
|
|||||||
ATTRIBUTE_BOLD = 1 << 0,
|
ATTRIBUTE_BOLD = 1 << 0,
|
||||||
ATTRIBUTE_ITALIC = 1 << 1,
|
ATTRIBUTE_ITALIC = 1 << 1,
|
||||||
ATTRIBUTE_UNDERLINE = 1 << 2,
|
ATTRIBUTE_UNDERLINE = 1 << 2,
|
||||||
ATTRIBUTE_INVERSE = 1 << 3
|
ATTRIBUTE_INVERSE = 1 << 3,
|
||||||
|
ATTRIBUTE_BLINK = 1 << 4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct attribute_printer
|
struct attribute_printer
|
||||||
@ -1773,50 +1740,94 @@ attribute_printer_apply (struct attribute_printer *self, int attribute)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 256-color output
|
// NOTE: commonly terminals have:
|
||||||
// - 8 color -> maybe bold, maybe inverse (should text be bold now?)
|
// 8 colors (worst, bright fg with BOLD, bg sometimes with BLINK)
|
||||||
// - 16 color -> just use the fallback color
|
// 16 colors (okayish, we have the full basic range guaranteed)
|
||||||
// - 88 color -> use the 256color value if available
|
// 88 colors (the same plus a 4^3 RGB cube and a few shades of gray)
|
||||||
// - 256 color -> use the 256color value if available
|
// 256 colors (best, like above but with a larger cube and more gray)
|
||||||
|
|
||||||
|
/// Interpolate from the 256-color palette to the 88-color one
|
||||||
|
static int
|
||||||
|
attribute_printer_256_to_88 (int color)
|
||||||
|
{
|
||||||
|
// These colours are the same everywhere
|
||||||
|
if (color < 16)
|
||||||
|
return color;
|
||||||
|
|
||||||
|
// 24 -> 8 extra shades of gray
|
||||||
|
if (color >= 232)
|
||||||
|
return 80 + (color - 232) / 3;
|
||||||
|
|
||||||
|
// 6 * 6 * 6 cube -> 4 * 4 * 4 cube
|
||||||
|
int x[6] = { 0, 1, 1, 2, 2, 3 };
|
||||||
|
int index = color - 16;
|
||||||
|
return 16 +
|
||||||
|
( x[ index / 36 ] << 8
|
||||||
|
| x[(index / 6) % 6 ] << 4
|
||||||
|
| x[(index % 6) ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
attribute_printer_decode_color (int color, bool *is_bright)
|
||||||
|
{
|
||||||
|
int16_t c16 = color; hard_assert (c16 < 16);
|
||||||
|
int16_t c256 = color >> 16; hard_assert (c256 < 256);
|
||||||
|
|
||||||
|
*is_bright = false;
|
||||||
|
switch (max_colors)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
if (c16 >= 8)
|
||||||
|
{
|
||||||
|
c16 -= 8;
|
||||||
|
*is_bright = true;
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
return c16;
|
||||||
|
|
||||||
|
case 88:
|
||||||
|
return c256 <= 0 ? c16 : attribute_printer_256_to_88 (c256);
|
||||||
|
case 256:
|
||||||
|
return c256 <= 0 ? c16 : c256;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Unsupported palette
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
attribute_printer_update (struct attribute_printer *self)
|
attribute_printer_update (struct attribute_printer *self)
|
||||||
{
|
{
|
||||||
int fg = 0;
|
bool fg_is_bright;
|
||||||
if ((int16_t) (self->want_foreground >> 16) > 0)
|
int fg = attribute_printer_decode_color
|
||||||
fg = index_to_terminal_palette ((int16_t) (self->want_foreground >> 16));
|
(self->want_foreground, &fg_is_bright);
|
||||||
int bg = 0;
|
bool bg_is_bright;
|
||||||
if ((int16_t) (self->want_background >> 16) > 0)
|
int bg = attribute_printer_decode_color
|
||||||
bg = index_to_terminal_palette ((int16_t) (self->want_background >> 16));
|
(self->want_background, &bg_is_bright);
|
||||||
if (fg <= 0) fg = (int16_t) (self->want_foreground);
|
|
||||||
if (bg <= 0) bg = (int16_t) (self->want_background);
|
|
||||||
|
|
||||||
|
// TODO: (INVERSE | BOLD) should be used for bright backgrounds
|
||||||
|
// when possible, i.e. when the foreground shouldn't be bright as well
|
||||||
|
// and when the BOLD attribute hasn't already been set
|
||||||
int attributes = self->want;
|
int attributes = self->want;
|
||||||
if (max_colors == 8)
|
if (attributes & ATTRIBUTE_INVERSE)
|
||||||
{
|
{
|
||||||
if (fg >= 8)
|
bool tmp = fg_is_bright;
|
||||||
{
|
fg_is_bright = bg_is_bright;
|
||||||
attributes |= ATTRIBUTE_BOLD;
|
bg_is_bright = tmp;
|
||||||
fg -= 8;
|
|
||||||
}
|
|
||||||
if (bg >= 8)
|
|
||||||
{
|
|
||||||
attributes |= ATTRIBUTE_BOLD;
|
|
||||||
bg -= 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute_printer_reset (self);
|
if (fg_is_bright) attributes |= ATTRIBUTE_BOLD;
|
||||||
|
if (bg_is_bright) attributes |= ATTRIBUTE_BLINK;
|
||||||
|
|
||||||
if (fg >= 0) tputs (g_terminal.color_set_fg[fg], 1, self->printer);
|
attribute_printer_reset (self);
|
||||||
if (bg >= 0) tputs (g_terminal.color_set_bg[bg], 1, self->printer);
|
|
||||||
|
|
||||||
if (attributes)
|
if (attributes)
|
||||||
tputs (tparm (set_attributes,
|
tputs (tparm (set_attributes,
|
||||||
0, // standout
|
0, // standout
|
||||||
attributes & ATTRIBUTE_UNDERLINE,
|
attributes & ATTRIBUTE_UNDERLINE,
|
||||||
attributes & ATTRIBUTE_INVERSE,
|
attributes & ATTRIBUTE_INVERSE,
|
||||||
0, // blink
|
attributes & ATTRIBUTE_BLINK,
|
||||||
0, // dim
|
0, // dim
|
||||||
attributes & ATTRIBUTE_BOLD,
|
attributes & ATTRIBUTE_BOLD,
|
||||||
0, // blank
|
0, // blank
|
||||||
@ -1824,6 +1835,11 @@ attribute_printer_update (struct attribute_printer *self)
|
|||||||
0) // acs
|
0) // acs
|
||||||
, 1, self->printer);
|
, 1, self->printer);
|
||||||
|
|
||||||
|
if (fg >= 0)
|
||||||
|
tputs (g_terminal.color_set_fg[fg], 1, self->printer);
|
||||||
|
if (bg >= 0)
|
||||||
|
tputs (g_terminal.color_set_bg[bg], 1, self->printer);
|
||||||
|
|
||||||
self->dirty = true;
|
self->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user