vt: utf8: don’t scan *all* previous chains

When checking if we already have a compose chain for the current
sequence of characters, don’t search the list from the beginning,
unless we have to.

Taking the following things into consideration:

* New compose chains are always appended at the end of the list
* If the current sequence is 3 or more characters, it *must* consist
  of an existing compose chain, plus the new character.

Thus, when searching, start at index 0 if we only have two characters,
since then the base cell originally contained a regular base
character, and not a compose chain. I.e. the new chain may be
_anywhere_ in the chain list.

If however we have a sequence of three or more characters, start at
the index the *base* chain was at. If the chain we’re searching for
exists, it *must* have been added *after* the base chain, and thus
it *must* be located *after* the base chain in the chain list.
This commit is contained in:
Daniel Eklöf 2021-06-18 17:53:15 +02:00
parent e81d1845bf
commit 81131e3a87
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

4
vt.c
View file

@ -611,6 +611,7 @@ action_utf8_print(struct terminal *term, wchar_t wc)
xassert(col >= 0 && col < term->cols);
wchar_t base = row->cells[col].wc;
wchar_t UNUSED last = base;
size_t search_start_index = 0;
/* Is base cell already a cluster? */
const struct composed *composed =
@ -620,6 +621,7 @@ action_utf8_print(struct terminal *term, wchar_t wc)
: NULL;
if (composed != NULL) {
search_start_index = base - CELL_COMB_CHARS_LO;
base = composed->chars[0];
last = composed->chars[composed->count - 1];
}
@ -692,7 +694,7 @@ action_utf8_print(struct terminal *term, wchar_t wc)
xassert(wanted_count <= ALEN(composed->chars));
/* Look for existing combining chain */
for (size_t i = 0; i < term->composed_count; i++) {
for (size_t i = search_start_index; i < term->composed_count; i++) {
const struct composed *cc = &term->composed[i];
if (cc->chars[0] != base)