From 1181f74d19f6f9e881b539ed9fdb8cc17d03f7bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 24 Jan 2025 09:52:57 +0100 Subject: [PATCH] composed: re-factor: break out key calculation from vt.c --- composed.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ composed.h | 3 +++ vt.c | 24 ++---------------------- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/composed.c b/composed.c index 442325ea..7a36275e 100644 --- a/composed.c +++ b/composed.c @@ -4,6 +4,52 @@ #include #include "debug.h" +#include "terminal.h" + +uint32_t +composed_key_from_chars(const uint32_t chars[], size_t count) +{ + if (count == 0) + return 0; + + uint32_t key = chars[0]; + for (size_t i = 1; i < count; i++) + key = composed_key_from_key(key, chars[i]); + + return key; +} + +uint32_t +composed_key_from_key(uint32_t prev_key, uint32_t next_char) +{ + unsigned bits = 32 - __builtin_clz(CELL_COMB_CHARS_HI - CELL_COMB_CHARS_LO); + + /* Rotate old key 8 bits */ + uint32_t new_key = (prev_key << 8) | (prev_key >> (bits - 8)); + + /* xor with new char */ + new_key ^= next_char; + + /* Multiply with magic hash constant */ + new_key *= 2654435761ul; + + /* And mask, to ensure the new value is within range */ + new_key &= CELL_COMB_CHARS_HI - CELL_COMB_CHARS_LO; + return new_key; +} + +UNITTEST +{ + const char32_t chars[] = U"abcdef"; + + uint32_t k1 = composed_key_from_key(chars[0], chars[1]); + uint32_t k2 = composed_key_from_chars(chars, 2); + xassert(k1 == k2); + + uint32_t k3 = composed_key_from_key(k2, chars[2]); + uint32_t k4 = composed_key_from_chars(chars, 3); + xassert(k3 == k4); +} struct composed * composed_lookup(struct composed *root, uint32_t key) diff --git a/composed.h b/composed.h index 17158407..fcaf87d4 100644 --- a/composed.h +++ b/composed.h @@ -12,6 +12,9 @@ struct composed { uint8_t width; }; +uint32_t composed_key_from_chars(const uint32_t chars[], size_t count); +uint32_t composed_key_from_key(uint32_t prev_key, uint32_t next_char); + struct composed *composed_lookup(struct composed *root, uint32_t key); void composed_insert(struct composed **root, struct composed *node); diff --git a/vt.c b/vt.c index bd1cf4ca..8f5d27d9 100644 --- a/vt.c +++ b/vt.c @@ -647,26 +647,6 @@ action_put(struct terminal *term, uint8_t c) dcs_put(term, c); } -static inline uint32_t -chain_key(uint32_t old_key, uint32_t new_wc) -{ - unsigned bits = 32 - __builtin_clz(CELL_COMB_CHARS_HI - CELL_COMB_CHARS_LO); - - /* Rotate old key 8 bits */ - uint32_t new_key = (old_key << 8) | (old_key >> (bits - 8)); - - /* xor with new char */ - new_key ^= new_wc; - - /* Multiply with magic hash constant */ - new_key *= 2654435761ul; - - /* And mask, to ensure the new value is within range */ - new_key &= CELL_COMB_CHARS_HI - CELL_COMB_CHARS_LO; - - return new_key; -} - #if defined(FOOT_GRAPHEME_CLUSTERING) static int emoji_vs_compare(const void *_key, const void *_entry) @@ -738,9 +718,9 @@ action_utf8_print(struct terminal *term, char32_t wc) if (composed != NULL) { base = composed->chars[0]; last = composed->chars[composed->count - 1]; - key = chain_key(composed->key, wc); + key = composed_key_from_key(composed->key, wc); } else - key = chain_key(base, wc); + key = composed_key_from_key(base, wc); #if defined(FOOT_GRAPHEME_CLUSTERING) if (grapheme_clustering) {