mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-07 08:21:02 -04:00
unicode-combining: store seen combining chains "globally" in the term struct
Instead of storing combining data per cell, realize that most combinations are re-occurring and that there's lots of available space left in the unicode range, and store seen base+combining combinations chains in a per-terminal array. When we encounter a combining character, we first try to pre-compose, like before. If that fails, we then search for the current base+combining combo in the list of previously seen combinations. If not found there either, we allocate a new combo and add it to the list. Regardless, the result is an index into this array. We store this index, offsetted by COMB_CHARS_LO=0x40000000ul in the cell. When rendering, we need to check if the cell character is a plain character, or if it's a composed character (identified by checking if the cell character is >= COMB_CHARS_LO). Then we render the grapheme pretty much like before.
This commit is contained in:
parent
ae7383189a
commit
62e0774319
8 changed files with 97 additions and 92 deletions
24
selection.c
24
selection.c
|
|
@ -142,12 +142,7 @@ min_bufsize_for_extraction(const struct terminal *term)
|
|||
{
|
||||
const struct coord *start = &term->selection.start;
|
||||
const struct coord *end = &term->selection.end;
|
||||
const size_t chars_per_cell =
|
||||
#if FOOT_UNICODE_MAX_COMBINING_CHARS > 0
|
||||
1 + ALEN(term->grid->cur_row->comb_chars[0].chars);
|
||||
#else
|
||||
1;
|
||||
#endif
|
||||
const size_t chars_per_cell = 1 + ALEN(term->composed[0].combining);
|
||||
|
||||
switch (term->selection.kind) {
|
||||
case SELECTION_NONE:
|
||||
|
|
@ -239,16 +234,17 @@ extract_one(struct terminal *term, struct row *row, struct cell *cell,
|
|||
ctx->empty_count = 0;
|
||||
|
||||
assert(ctx->idx + 1 <= ctx->size);
|
||||
ctx->buf[ctx->idx++] = cell->wc;
|
||||
|
||||
#if FOOT_UNICODE_MAX_COMBINING_CHARS > 0
|
||||
const struct combining_chars *comb_chars = &row->comb_chars[col];
|
||||
if (cell->wc >= COMB_CHARS_LO && cell->wc < (COMB_CHARS_LO + term->composed_count)) {
|
||||
const struct composed *composed = &term->composed[cell->wc - COMB_CHARS_LO];
|
||||
|
||||
assert(cell->wc != 0);
|
||||
assert(ctx->idx + comb_chars->count <= ctx->size);
|
||||
for (size_t i = 0; i < comb_chars->count; i++)
|
||||
ctx->buf[ctx->idx++] = comb_chars->chars[i];
|
||||
#endif
|
||||
ctx->buf[ctx->idx++] = composed->base;
|
||||
|
||||
assert(ctx->idx + composed->count <= ctx->size);
|
||||
for (size_t i = 0; i < composed->count; i++)
|
||||
ctx->buf[ctx->idx++] = composed->combining[i];
|
||||
} else
|
||||
ctx->buf[ctx->idx++] = cell->wc;
|
||||
|
||||
ctx->last_row = row;
|
||||
ctx->last_cell = cell;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue