diff --git a/CMakeLists.txt b/CMakeLists.txt index e3dbb7c..acbfb72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,8 @@ endif () # -lrt is only for glibc < 2.17 # -liconv may or may not be a part of libc -foreach (extra iconv rt) +# -lm may or may not be a part of libc +foreach (extra iconv rt m) find_library (extra_lib_${extra} ${extra}) if (extra_lib_${extra}) list (APPEND project_libraries ${extra_lib_${extra}}) diff --git a/degesch.c b/degesch.c index 3262691..0e70813 100644 --- a/degesch.c +++ b/degesch.c @@ -51,6 +51,7 @@ enum #include "common.c" #include "kike-replies.c" +#include #include #include #include @@ -2108,17 +2109,23 @@ 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 < 6 * 6 * 6; x++) + for (int x = 0; x < N_ELEMENTS (table); x++) { - // FIXME this isn't exactly right, the values aren't linear 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) + // 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; diff --git a/test-nick-colors b/test-nick-colors new file mode 100755 index 0000000..a09f74a --- /dev/null +++ b/test-nick-colors @@ -0,0 +1,23 @@ +#!/bin/sh +# Check whether the terminal colours filtered by our algorithm are legible +export example=$( + tcc "-run -lm" - <<-EOF + #include + #include + #include + + $(perl -0777 -ne 'print $& if /^.*?\nfilter_color(?s:.*?)^}$/m' degesch.c) + + void main () { + size_t len = 0; + int *table = filter_color_cube_for_acceptable_nick_colors (&len); + for (size_t i = 0; i < len; i++) + printf ("<@\\x1b[38;5;%dmIRCuser\\x1b[m> I'm typing!\n", table[i]); + } + EOF +) + +# Both should give acceptable results, +# which results in a bad compromise that the main author himself needs +xterm -bg black -fg white -e 'echo $example; cat' & +xterm -bg white -fg black -e 'echo $example; cat' &