mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-31 07:11:09 -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
45
render.c
45
render.c
|
|
@ -402,9 +402,20 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
|
||||
struct fcft_font *font = attrs_to_font(term, &cell->attrs);
|
||||
const struct fcft_glyph *glyph = NULL;
|
||||
const struct composed *composed = NULL;
|
||||
|
||||
if (cell->wc != 0)
|
||||
glyph = fcft_glyph_rasterize(font, cell->wc, term->font_subpixel);
|
||||
if (cell->wc != 0) {
|
||||
wchar_t base = cell->wc;
|
||||
|
||||
if (base >= COMB_CHARS_LO &&
|
||||
base < (COMB_CHARS_LO + term->composed_count))
|
||||
{
|
||||
composed = &term->composed[base - COMB_CHARS_LO];
|
||||
base = composed->base;
|
||||
}
|
||||
|
||||
glyph = fcft_glyph_rasterize(font, base, term->font_subpixel);
|
||||
}
|
||||
|
||||
int cell_cols = glyph != NULL ? max(1, glyph->cols) : 1;
|
||||
|
||||
|
|
@ -442,25 +453,25 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
}
|
||||
}
|
||||
|
||||
#if FOOT_UNICODE_MAX_COMBINING_CHARS > 0
|
||||
/* Combining characters */
|
||||
const struct combining_chars *comb_chars = &row->comb_chars[col];
|
||||
for (size_t i = 0; i < comb_chars->count; i++) {
|
||||
const struct fcft_glyph *g = fcft_glyph_rasterize(
|
||||
font, comb_chars->chars[i], term->font_subpixel);
|
||||
if (composed != NULL) {
|
||||
for (size_t i = 0; i < composed->count; i++) {
|
||||
const struct fcft_glyph *g = fcft_glyph_rasterize(
|
||||
font, composed->combining[i], term->font_subpixel);
|
||||
|
||||
if (g == NULL)
|
||||
continue;
|
||||
if (g == NULL)
|
||||
continue;
|
||||
|
||||
pixman_image_composite32(
|
||||
PIXMAN_OP_OVER, clr_pix, g->pix, pix, 0, 0, 0, 0,
|
||||
/* Some fonts use a negative offset, while others use a
|
||||
* "normal" offset */
|
||||
x + (g->x < 0 ? term->cell_width : 0) + g->x,
|
||||
y + font_baseline(term) - g->y,
|
||||
g->width, g->height);
|
||||
pixman_image_composite32(
|
||||
PIXMAN_OP_OVER, clr_pix, g->pix, pix, 0, 0, 0, 0,
|
||||
/* Some fonts use a negative offset, while others use a
|
||||
* "normal" offset */
|
||||
x + (g->x < 0 ? term->cell_width : 0) + g->x,
|
||||
y + font_baseline(term) - g->y,
|
||||
g->width, g->height);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pixman_image_unref(clr_pix);
|
||||
|
||||
/* Underline */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue