mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-07 04:06:07 -05:00
render: cache generated glyphs for regular ASCII characters
To avoid having to re-generate glyphs, cache the glyphs. For now, we only cache ASCII characters, as this allows us to lookup the cache by simply indexing with the character (into a 256-entry array).
This commit is contained in:
parent
c9803a2018
commit
6e55be1557
4 changed files with 47 additions and 8 deletions
2
main.c
2
main.c
|
|
@ -795,6 +795,8 @@ out:
|
|||
for (size_t i = 0; i < sizeof(term.fonts) / sizeof(term.fonts[0]); i++) {
|
||||
if (term.fonts[i].font != NULL)
|
||||
cairo_scaled_font_destroy(term.fonts[i].font);
|
||||
for (size_t j = 0; j < 256; j++)
|
||||
free(term.fonts[i].glyph_cache[j].glyphs);
|
||||
}
|
||||
|
||||
if (term.ptmx != -1)
|
||||
|
|
|
|||
44
render.c
44
render.c
|
|
@ -16,7 +16,7 @@
|
|||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
const struct font *
|
||||
struct font *
|
||||
attrs_to_font(struct terminal *term, const struct attributes *attrs)
|
||||
{
|
||||
int idx = attrs->italic << 1 | attrs->bold;
|
||||
|
|
@ -182,13 +182,43 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
int new_glyphs
|
||||
= sizeof(gseq.glyphs) / sizeof(gseq.glyphs[0]) - gseq.count;
|
||||
|
||||
cairo_status_t status = cairo_scaled_font_text_to_glyphs(
|
||||
attrs_to_font(term, &cell->attrs)->font, x, y + term->fextents.ascent,
|
||||
cell->c, strnlen(cell->c, 4), &gseq.g, &new_glyphs,
|
||||
NULL, NULL, NULL);
|
||||
struct font *font = attrs_to_font(term, &cell->attrs);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return;
|
||||
struct glyph_cache *entry = cell->c[1] == '\0'
|
||||
? &font->glyph_cache[(unsigned char)cell->c[0]]
|
||||
: NULL;
|
||||
|
||||
if (likely(entry != NULL && entry->glyphs != NULL)) {
|
||||
/* Copy cached glyph(s) and upate position */
|
||||
for (size_t i = 0; i < entry->count; i++) {
|
||||
gseq.g[i] = entry->glyphs[i];
|
||||
gseq.g[i].x += x;
|
||||
gseq.g[i].y += y;
|
||||
}
|
||||
|
||||
new_glyphs = entry->count;
|
||||
} else {
|
||||
/* Must generate new glyph(s) */
|
||||
cairo_status_t status = cairo_scaled_font_text_to_glyphs(
|
||||
font->font, x, y + term->fextents.ascent,
|
||||
cell->c, strnlen(cell->c, 4), &gseq.g, &new_glyphs,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
if (entry != NULL) {
|
||||
assert(entry->glyphs == NULL);
|
||||
entry->glyphs = malloc(new_glyphs * sizeof(entry->glyphs[0]));
|
||||
entry->count = new_glyphs;
|
||||
|
||||
for (size_t i = 0; i < new_glyphs; i++) {
|
||||
entry->glyphs[i] = gseq.g[i];
|
||||
entry->glyphs[i].x -= x;
|
||||
entry->glyphs[i].y -= y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gseq.g += new_glyphs;
|
||||
gseq.count += new_glyphs;
|
||||
|
|
|
|||
2
render.h
2
render.h
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "terminal.h"
|
||||
|
||||
const struct font *attrs_to_font(
|
||||
struct font *attrs_to_font(
|
||||
struct terminal *term, const struct attributes *attrs);
|
||||
|
||||
void grid_render(struct terminal *term);
|
||||
|
|
|
|||
|
|
@ -202,6 +202,11 @@ struct primary {
|
|||
uint32_t serial;
|
||||
};
|
||||
|
||||
struct glyph_cache {
|
||||
cairo_glyph_t *glyphs;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct font {
|
||||
cairo_scaled_font_t *font;
|
||||
struct {
|
||||
|
|
@ -212,6 +217,8 @@ struct font {
|
|||
double position;
|
||||
double thickness;
|
||||
} strikeout;
|
||||
|
||||
struct glyph_cache glyph_cache[256];
|
||||
};
|
||||
|
||||
struct terminal {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue