aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--degesch.c19
-rwxr-xr-xtest-nick-colors23
3 files changed, 38 insertions, 7 deletions
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 <math.h>
#include <langinfo.h>
#include <locale.h>
#include <pwd.h>
@@ -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 <stddef.h>
+ #include <stdio.h>
+ #include <math.h>
+
+ $(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' &