From 8e31c28f9b7cfb6b8884990bcee34b7e80ab7a2e Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Tue, 23 Jun 2020 23:21:56 +0200 Subject: [PATCH] termptyesc: handle larger sharp-based colors + tests --- src/bin/termptyesc.c | 162 ++++++++++++++++++++++++++---------- tests/tests.results | 1 + tests/xterm-colors-sharp.sh | 79 ++++++++++++++++++ 3 files changed, 197 insertions(+), 45 deletions(-) create mode 100755 tests/xterm-colors-sharp.sh diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 7197956d..932b782a 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -3652,61 +3652,133 @@ _eina_unicode_to_hex(Eina_Unicode u) return -1; } +static int +_xterm_parse_color_sharp(Eina_Unicode *p, + unsigned char *r, unsigned char *g, unsigned char *b, + int len) +{ + int i; + + switch (len) + { + case 3*4+1: + i = _eina_unicode_to_hex(p[0]); + if (i < 0) return -1; + *r = i; + i = _eina_unicode_to_hex(p[1]); + if (i < 0) return -1; + *r = *r * 16 + i; + i = _eina_unicode_to_hex(p[2]); + if (i < 0) return -1; + i = _eina_unicode_to_hex(p[3]); + if (i < 0) return -1; + + i = _eina_unicode_to_hex(p[4]); + if (i < 0) return -1; + *g = i; + i = _eina_unicode_to_hex(p[5]); + if (i < 0) return -1; + *g = *g * 16 + i; + i = _eina_unicode_to_hex(p[6]); + if (i < 0) return -1; + i = _eina_unicode_to_hex(p[7]); + if (i < 0) return -1; + + i = _eina_unicode_to_hex(p[8]); + if (i < 0) return -1; + *b = i; + i = _eina_unicode_to_hex(p[9]); + if (i < 0) return -1; + *b = *b * 16 + i; + i = _eina_unicode_to_hex(p[10]); + if (i < 0) return -1; + i = _eina_unicode_to_hex(p[11]); + if (i < 0) return -1; + break; + case 3*3+1: + i = _eina_unicode_to_hex(p[0]); + if (i < 0) return -1; + *r = i; + i = _eina_unicode_to_hex(p[1]); + if (i < 0) return -1; + *r = *r * 16 + i; + i = _eina_unicode_to_hex(p[3]); + if (i < 0) return -1; + + i = _eina_unicode_to_hex(p[4]); + if (i < 0) return -1; + *g = i; + i = _eina_unicode_to_hex(p[5]); + if (i < 0) return -1; + *g = *g * 16 + i; + i = _eina_unicode_to_hex(p[3]); + if (i < 0) return -1; + + i = _eina_unicode_to_hex(p[7]); + if (i < 0) return -1; + *b = i; + i = _eina_unicode_to_hex(p[8]); + if (i < 0) return -1; + *b = *b * 16 + i; + i = _eina_unicode_to_hex(p[3]); + if (i < 0) return -1; + break; + case 3*2+1: + i = _eina_unicode_to_hex(p[0]); + if (i < 0) return -1; + *r = i; + i = _eina_unicode_to_hex(p[1]); + if (i < 0) return -1; + *r = *r * 16 + i; + + i = _eina_unicode_to_hex(p[2]); + if (i < 0) return -1; + *g = i; + i = _eina_unicode_to_hex(p[3]); + if (i < 0) return -1; + *g = *g * 16 + i; + + i = _eina_unicode_to_hex(p[4]); + if (i < 0) return -1; + *b = i; + i = _eina_unicode_to_hex(p[5]); + if (i < 0) return -1; + *b = *b * 16 + i; + break; + case 3*1+1: + i = _eina_unicode_to_hex(p[0]); + if (i < 0) return -1; + *r = i; + i = _eina_unicode_to_hex(p[1]); + if (i < 0) return -1; + *g = i; + i = _eina_unicode_to_hex(p[2]); + if (i < 0) return -1; + *b = i; + break; + default: + return -1; + } + return 0; +} + + static int _xterm_parse_color(Termpty *ty, Eina_Unicode **ptr, unsigned char *r, unsigned char *g, unsigned char *b, int len) { Eina_Unicode *p = *ptr; - int i; - if (*p != '#') + if (*p == '#') { - WRN("unsupported xterm color"); - ty->decoding_error = EINA_TRUE; - return -1; - } - p++; - len--; - if (len == 7) - { - i = _eina_unicode_to_hex(p[0]); - if (i < 0) goto err; - *r = i; - i = _eina_unicode_to_hex(p[1]); - if (i < 0) goto err; - *r = *r * 16 + i; - - i = _eina_unicode_to_hex(p[2]); - if (i < 0) goto err; - *g = i; - i = _eina_unicode_to_hex(p[3]); - if (i < 0) goto err; - *g = *g * 16 + i; - - i = _eina_unicode_to_hex(p[4]); - if (i < 0) goto err; - *b = i; - i = _eina_unicode_to_hex(p[5]); - if (i < 0) goto err; - *b = *b * 16 + i; - } - else if (len == 4) - { - i = _eina_unicode_to_hex(p[0]); - if (i < 0) goto err; - *r = i; - i = _eina_unicode_to_hex(p[1]); - if (i < 0) goto err; - *g = i; - i = _eina_unicode_to_hex(p[2]); - if (i < 0) goto err; - *b = i; + p++; + len--; + if (_xterm_parse_color_sharp(p, r, g, b, len)) + goto err; } else - { - goto err; - } + goto err; return 0; diff --git a/tests/tests.results b/tests/tests.results index e17f07d2..369da827 100644 --- a/tests/tests.results +++ b/tests/tests.results @@ -145,3 +145,4 @@ color_link_css_hsl.sh fc9bda72bd4eea5e9414ef9755ae176a crash_empty_osc.sh b87272896ce7be9856253b32be1bef14 xterm-osc-10.sh b8c23c9c5482b1e9c30d8a261edc29f0 xterm-osc-11.sh 3e02038964b78d948fb599c996bf370d +xterm-colors-sharp.sh 79d6f72df04237d76a0fa3e722dcec5b diff --git a/tests/xterm-colors-sharp.sh b/tests/xterm-colors-sharp.sh new file mode 100755 index 00000000..f476e2ac --- /dev/null +++ b/tests/xterm-colors-sharp.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# char width: 7 +# char height: 15 + +# set color +printf '\033[0;31;3m' + +# clear screen +printf '\033[2J' + +# move to 0; 0 +printf '\033[0;0H' + +printf 'The purpose of computing is insight, not numbers.\r\n' +printf 'Richard Hamming\r\n' + +# valid colors +# one nibble per color +printf '\033]10;#f0f\007' +# two nibble per color +printf '\033]10;#ff00ff\007' +# three nibble per color +printf '\033]10;#fff000fff\007' +# four nibble per color +printf '\033]10;#FFFF0000FFFF\007' + +## +# invalid +## + +# not hex +# one nibble per color +printf '\033]10;#g0f\007' +printf '\033]10;#fgf\007' +printf '\033]10;#f0g\007' +# two nibble per color +printf '\033]10;#gf00ff\007' +printf '\033]10;#fg00ff\007' +printf '\033]10;#ffg0ff\007' +printf '\033]10;#ff0gff\007' +printf '\033]10;#ff00gf\007' +printf '\033]10;#ff00fg\007' +# three nibble per color +printf '\033]10;#gff000fff\007' +printf '\033]10;#fgf000fff\007' +printf '\033]10;#ffg000fff\007' +printf '\033]10;#fffg00fff\007' +printf '\033]10;#fff0g0fff\007' +printf '\033]10;#fff00gfff\007' +printf '\033]10;#fff000gff\007' +printf '\033]10;#fff000fgf\007' +printf '\033]10;#fff000ffg\007' +# four nibble per color +printf '\033]10;#gFFF0000FFFF\007' +printf '\033]10;#FgFF0000FFFF\007' +printf '\033]10;#FFgF0000FFFF\007' +printf '\033]10;#FFFg0000FFFF\007' +printf '\033]10;#FFFFg000FFFF\007' +printf '\033]10;#FFFF0g00FFFF\007' +printf '\033]10;#FFFF00g0FFFF\007' +printf '\033]10;#FFFF000gFFFF\007' +printf '\033]10;#FFFF0000gFFF\007' +printf '\033]10;#FFFF0000FgFF\007' +printf '\033]10;#FFFF0000FFgF\007' +printf '\033]10;#FFFF0000FFFg\007' + +# too short +printf '\033]10;#FF\007' +#in between +printf '\033]10;#F0FF\007' +printf '\033]10;#FF00F\007' +printf '\033]10;#FFF000F\007' +printf '\033]10;#FFF000FF\007' +printf '\033]10;#FFFF0000F\007' +printf '\033]10;#FFFF0000FF\007' +printf '\033]10;#FFFF0000FFF\007' +# too long +printf '\033]10;#FFFF0000FFFF0000\007'