xF: make xC nick colors just work
Colour mapping still suffers, just not as heavily.
This commit is contained in:
+2
-1
@@ -37,7 +37,8 @@ image::xP.webp[align="center"]
|
||||
xF
|
||||
--
|
||||
The hybrid terminal/X11 frontend for 'xC'. It has simplified word wrapping,
|
||||
and X11 doesn't support text selection. This frontend is perfect for testing.
|
||||
limited colour support, and X11 doesn't support text selection.
|
||||
This frontend is perfect for testing.
|
||||
|
||||
xA, xT, xW, xM
|
||||
--------------
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "liberty/liberty.c"
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
static void
|
||||
@@ -108,6 +109,35 @@ tokenize_host_port (char *address, const char **port)
|
||||
return address;
|
||||
}
|
||||
|
||||
static int *
|
||||
filter_color_cube_for_acceptable_nick_colors (size_t *len)
|
||||
{
|
||||
// This is a pure function and we don't use threads, static storage is fine
|
||||
static int table[6 * 6 * 6];
|
||||
size_t len_counter = 0;
|
||||
for (int x = 0; x < (int) N_ELEMENTS (table); x++)
|
||||
{
|
||||
int r = x / 36;
|
||||
int g = (x / 6) % 6;
|
||||
int b = (x % 6);
|
||||
|
||||
// The first step is 95/255, the rest are 40/255,
|
||||
// as an approximation we can double the first step
|
||||
double linear_R = pow ((r + !!r) / 6., 2.2);
|
||||
double linear_G = pow ((g + !!g) / 6., 2.2);
|
||||
double linear_B = pow ((b + !!b) / 6., 2.2);
|
||||
|
||||
// Use the relative luminance of colours within the cube to filter
|
||||
// colours that look okay-ish on terminals with both black and white
|
||||
// backgrounds (use the test-nick-colors script to calibrate)
|
||||
double Y = 0.2126 * linear_R + 0.7152 * linear_G + 0.0722 * linear_B;
|
||||
if (Y >= .25 && Y <= .4)
|
||||
table[len_counter++] = 16 + x;
|
||||
}
|
||||
*len = len_counter;
|
||||
return table;
|
||||
}
|
||||
|
||||
// --- To be moved to liberty --------------------------------------------------
|
||||
|
||||
#define LIST_FOR_EACH_REVERSED(type, iter, tail) \
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ export example=$(
|
||||
#define N_ELEMENTS(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
|
||||
$(perl -0777 -ne 'print $& if /^.*?\nfilter_color(?s:.*?)^}$/m' \
|
||||
"$(dirname "$0")"/xC.c)
|
||||
"$(dirname "$0")"/common.c)
|
||||
|
||||
void main () {
|
||||
size_t len = 0;
|
||||
|
||||
@@ -56,7 +56,6 @@ enum
|
||||
#include "xD-replies.c"
|
||||
#include "xC-proto.c"
|
||||
|
||||
#include <math.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include <pwd.h>
|
||||
@@ -2137,35 +2136,6 @@ static struct ispect_field g_ctx_ispect[] =
|
||||
{}
|
||||
};
|
||||
|
||||
static int *
|
||||
filter_color_cube_for_acceptable_nick_colors (size_t *len)
|
||||
{
|
||||
// This is a pure function and we don't use threads, static storage is fine
|
||||
static int table[6 * 6 * 6];
|
||||
size_t len_counter = 0;
|
||||
for (int x = 0; x < (int) N_ELEMENTS (table); x++)
|
||||
{
|
||||
int r = x / 36;
|
||||
int g = (x / 6) % 6;
|
||||
int b = (x % 6);
|
||||
|
||||
// The first step is 95/255, the rest are 40/255,
|
||||
// as an approximation we can double the first step
|
||||
double linear_R = pow ((r + !!r) / 6., 2.2);
|
||||
double linear_G = pow ((g + !!g) / 6., 2.2);
|
||||
double linear_B = pow ((b + !!b) / 6., 2.2);
|
||||
|
||||
// Use the relative luminance of colours within the cube to filter
|
||||
// colours that look okay-ish on terminals with both black and white
|
||||
// backgrounds (use the test-nick-colors script to calibrate)
|
||||
double Y = 0.2126 * linear_R + 0.7152 * linear_G + 0.0722 * linear_B;
|
||||
if (Y >= .25 && Y <= .4)
|
||||
table[len_counter++] = 16 + x;
|
||||
}
|
||||
*len = len_counter;
|
||||
return table;
|
||||
}
|
||||
|
||||
static bool
|
||||
app_iconv_open (iconv_t *target, const char *to, const char *from)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "xC-proto.c"
|
||||
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WITH_X11
|
||||
#define LIBERTY_XUI_WANT_X11
|
||||
@@ -340,7 +339,8 @@ enum app_attribute
|
||||
ATTRIBUTE_COUNT,
|
||||
};
|
||||
|
||||
static struct attrs g_attrs[ATTRIBUTE_COUNT] =
|
||||
static size_t g_attrs_len = ATTRIBUTE_COUNT;
|
||||
static struct attrs g_attrs[256] =
|
||||
{
|
||||
#define XX(name, fg, bg, attrs_) \
|
||||
[ATTRIBUTE_ ## name] = { fg, bg, attrs_ },
|
||||
@@ -350,6 +350,17 @@ static struct attrs g_attrs[ATTRIBUTE_COUNT] =
|
||||
|
||||
#undef ATTRIBUTE_TABLE
|
||||
|
||||
static void
|
||||
app_init_line_item_colors (void)
|
||||
{
|
||||
size_t colors_len = 0;
|
||||
int *colors = filter_color_cube_for_acceptable_nick_colors (&colors_len);
|
||||
hard_assert (g_attrs_len + colors_len <= N_ELEMENTS (g_attrs));
|
||||
|
||||
for (size_t i = 0; i < colors_len; i++)
|
||||
g_attrs[g_attrs_len++] = (struct attrs) { colors[i], -1, 0 };
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
enum { UNREAD_MARKER_HEIGHT = 1 };
|
||||
@@ -2176,19 +2187,17 @@ app_line_item_color_rgb (int color, int *r, int *g, int *b)
|
||||
static int
|
||||
app_line_item_color (int16_t color)
|
||||
{
|
||||
// These are the closest 256-colour palette matches for the base 16,
|
||||
// using the same RGB estimates as xC and XUI.
|
||||
if (color < 0 || color >= 256)
|
||||
return -1;
|
||||
|
||||
int r = 0, g = 0, b = 0;
|
||||
app_line_item_color_rgb (color, &r, &g, &b);
|
||||
|
||||
int best = 0, best_distance = INT_MAX;
|
||||
for (int i = 0; i < 16; i++)
|
||||
for (size_t i = ATTRIBUTE_IRC_0; i < g_attrs_len; i++)
|
||||
{
|
||||
int rr = 0, gg = 0, bb = 0;
|
||||
app_line_item_color_rgb (g_attrs[ATTRIBUTE_IRC_0 + i].fg,
|
||||
&rr, &gg, &bb);
|
||||
app_line_item_color_rgb (g_attrs[i].fg, &rr, &gg, &bb);
|
||||
int distance =
|
||||
(r - rr) * (r - rr) +
|
||||
(g - gg) * (g - gg) +
|
||||
@@ -2227,20 +2236,20 @@ app_line_item_attrs (chtype attrs, bool leaked,
|
||||
bg = tmp;
|
||||
}
|
||||
|
||||
// XUI attributes use a small, preallocated colour-pair table.
|
||||
// Preserve its common 16-colour palette, approximating extended colours,
|
||||
// and preferring the foreground when both colours are set.
|
||||
// XUI attributes use a preallocated colour-pair table. Quantize colours
|
||||
// to the IRC base palette plus xC's acceptable nickname colours,
|
||||
// preferring the foreground when both colours are set.
|
||||
fg = app_line_item_color (fg);
|
||||
bg = app_line_item_color (bg);
|
||||
if (fg >= 0 && bg < 0)
|
||||
{
|
||||
attrs &= ~A_COLOR;
|
||||
attrs |= g_attrs[ATTRIBUTE_IRC_0 + fg].attrs & A_COLOR;
|
||||
attrs |= g_attrs[fg].attrs & A_COLOR;
|
||||
}
|
||||
else if (bg >= 0 && fg < 0)
|
||||
{
|
||||
attrs &= ~A_COLOR;
|
||||
attrs |= g_attrs[ATTRIBUTE_IRC_0 + bg].attrs & A_COLOR;
|
||||
attrs |= g_attrs[bg].attrs & A_COLOR;
|
||||
attrs ^= A_REVERSE;
|
||||
}
|
||||
else if (item->style & BUFFER_LINE_ITEM_INVERSE)
|
||||
@@ -3851,9 +3860,10 @@ main (int argc, char *argv[])
|
||||
|
||||
xui_preinit ();
|
||||
app_init_bindings ();
|
||||
app_init_line_item_colors ();
|
||||
g_log_message_real = app_log_handler;
|
||||
|
||||
xui_start (&g.poller, requested_gui, g_attrs, ATTRIBUTE_COUNT);
|
||||
xui_start (&g.poller, requested_gui, g_attrs, g_attrs_len);
|
||||
app_select_backend ();
|
||||
xui_invalidate ();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user