From 0a9531ac6caff2ad6abfbb804ec27cade4a92e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 27 May 2021 20:07:28 +0200 Subject: [PATCH] vt: cache grapheme cluster width in composed struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use regular wcswidth() to calculate the width * Explicitly set to ‘2’ if we see a emoji variant selector * Cache the result in the composed struct --- terminal.h | 1 + util.h | 8 -------- vt.c | 14 ++++++++++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/terminal.h b/terminal.h index 45c6c98b..83406f41 100644 --- a/terminal.h +++ b/terminal.h @@ -87,6 +87,7 @@ struct damage { struct composed { wchar_t chars[20]; uint8_t count; + int width; }; struct row_uri_range { diff --git a/util.h b/util.h index af215111..aa9fc8ba 100644 --- a/util.h +++ b/util.h @@ -35,11 +35,3 @@ sdbm_hash(const char *s) return hash; } - -#include -static inline int -my_wcswidth(const wchar_t *s, size_t n) -{ - int ret = wcswidth(s, n); - return max(0, ret); -} diff --git a/vt.c b/vt.c index 496333d7..6ad539d7 100644 --- a/vt.c +++ b/vt.c @@ -716,9 +716,8 @@ action_utf8_print(struct terminal *term, wchar_t wc) if (cc->chars[wanted_count - 1] != wc) continue; - int grapheme_width = my_wcswidth(cc->chars, cc->count); - if (grapheme_width > 0) - term_print(term, CELL_COMB_CHARS_LO + i, grapheme_width); + if (cc->width > 0) + term_print(term, CELL_COMB_CHARS_LO + i, cc->width); return; } @@ -732,11 +731,18 @@ action_utf8_print(struct terminal *term, wchar_t wc) new_cc.chars[wanted_count - 1] = wc; if (term->composed_count < CELL_COMB_CHARS_HI) { + /* TODO: grapheme cluster width */ + int grapheme_width = wcswidth(new_cc.chars, new_cc.count); + if (new_cc.chars[new_cc.count - 1] == 0xfe0f) { + /* Emoji selector */ + grapheme_width = 2; + } + new_cc.width = grapheme_width; + term->composed_count++; term->composed = xrealloc(term->composed, term->composed_count * sizeof(term->composed[0])); term->composed[term->composed_count - 1] = new_cc; - int grapheme_width = my_wcswidth(new_cc.chars, new_cc.count); if (grapheme_width > 0) term_print(term, CELL_COMB_CHARS_LO + term->composed_count - 1, grapheme_width); return;