diff --git a/degesch.c b/degesch.c index c840245..3c0ed94 100644 --- a/degesch.c +++ b/degesch.c @@ -2438,20 +2438,47 @@ formatter_parse_mirc (struct formatter *self, const char *s) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +static int * +filter_color_cube_for_acceptable_nick_colors (size_t *len) +{ + static int table[6 * 6 * 6]; + size_t len_counter = 0; + for (int x = 0; x < 6 * 6 * 6; x++) + { + int r = x / 36; + int g = (x / 6) % 6; + int b = (x % 6); + + // Use the luma value of colours within the cube to filter colours that + // look okay-ish on terminals with both black and white backgrounds + double luma = 0.2126 * r / 6. + 0.7152 * g / 6. + 0.0722 * b / 6.; + if (luma >= .3 && luma <= .5) + table[len_counter++] = 16 + x; + } + *len = len_counter; + return table; +} + static void formatter_parse_nick (struct formatter *self, char *s) { char *nick = irc_cut_nickname (s); - int color = siphash_wrapper (nick, strlen (nick)) % 8; + int color = siphash_wrapper (nick, strlen (nick)) % 7; + + // Never use the black colour, could become transparent on black terminals; + // white is similarly excluded from the range + if (color == COLOR_BLACK) + color = -1; + + size_t len; + // TODO: precompute this table + int *colors = filter_color_cube_for_acceptable_nick_colors (&len); + color |= colors[siphash_wrapper (nick, strlen (nick)) % len] << 16; // We always use the default color for ourselves if (self->s && irc_is_this_us (self->s, nick)) color = -1; - // Never use the black colour, could become transparent on black terminals - if (color == COLOR_BLACK) - color = -1; - FORMATTER_ADD_ITEM (self, FG_COLOR, .color = color); char *x = irc_to_utf8 (self->ctx, nick);