From 50543983ad109b7a48b3c4dc0ff114702e09cb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 1 May 2020 20:17:37 +0200 Subject: [PATCH] unicode-combine: only compose if we don't have any other combining characters If the client sent the sequence SAB, where SA does NOT have a composed representation, but SB does, the old code would compose SB and throw away A. This patch fixes this by only allowing a compose if there aren't any pre-existing combining characters. --- vt.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/vt.c b/vt.c index 8abba1da..f6711bce 100644 --- a/vt.c +++ b/vt.c @@ -575,27 +575,35 @@ action_utf8_print(struct terminal *term, uint8_t c) if (base != 0 && base_width > 0) { /* - * First, see if there's a pre-composed character of this - * combo, with the same column width as the base - * character. If there is, replace the base character with - * the pre-composed character, as that is likely to - * produce a better looking result. + * If this is the *first* combining characger, see if + * there's a pre-composed character of this combo, with + * the same column width as the base character. + * + * If there is, replace the base character with the + * pre-composed character, as that is likely to produce a + * better looking result. + * + * TODO: we could perhaps remove this is we improve our + * positioning of the combining characters when rendering + * the glyph. */ - wchar_t composed[] = {base, wc}; - ssize_t composed_length = utf8proc_normalize_utf32( - composed, ALEN(composed), UTF8PROC_COMPOSE | UTF8PROC_STABLE); - int composed_width = wcwidth(composed[0]); - - if (composed_length == 1 && composed_width == base_width) { - term->grid->cursor.point.col = base_col; - term->grid->cursor.lcf = false; - term_print(term, composed[0], composed_width); - return; - } - struct combining_chars *comb_chars = &row->comb_chars[base_col]; + if (comb_chars->count == 0) { + wchar_t composed[] = {base, wc}; + ssize_t composed_length = utf8proc_normalize_utf32( + composed, ALEN(composed), UTF8PROC_COMPOSE | UTF8PROC_STABLE); + int composed_width = wcwidth(composed[0]); + + if (composed_length == 1 && composed_width == base_width) { + term->grid->cursor.point.col = base_col; + term->grid->cursor.lcf = false; + term_print(term, composed[0], composed_width); + return; + } + } + if (comb_chars->count < ALEN(comb_chars->chars)) comb_chars->chars[comb_chars->count++] = wc; else {