From 37b15adcd8306652ce21804cb6140d1361adc94f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 14 Sep 2021 09:50:49 +0200 Subject: [PATCH] =?UTF-8?q?term:=20turn=20=E2=80=98box-drawings=E2=80=99?= =?UTF-8?q?=20array=20into=20three=20dynamically=20allocated=20arrays?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The box_drawings array is now quite large, and uses up ~4K when *empty*. This patch splits it up into three separate, dynamically allocated arrays; one for the traditional box+line drawing and block elements glyphs, one for braille, and one for the legacy computing symbols. When we need to render a glyph, the *entire* array (that it belongs to) is allocated. I.e this is one step closer to a dynamic glyph cache (like the one fcft uses), but doesn’t go all the way. This is especially nice for people with ‘box-drawings-uses-font-glyphs=yes’; for them, the custom glyphs now uses 3*8 bytes (for the three array pointers), instead of 4K. --- render.c | 60 +++++++++++++++++++++++++++++++----------------------- terminal.c | 42 +++++++++++++++++++++++++++++--------- terminal.h | 27 +++++++++++++++++------- 3 files changed, 87 insertions(+), 42 deletions(-) diff --git a/render.c b/render.c index 684c86e4..b9acc8e1 100644 --- a/render.c +++ b/render.c @@ -513,10 +513,12 @@ render_cell(struct terminal *term, pixman_image_t *pix, if (base != 0) { if (unlikely( /* Classic box drawings */ - (base >= 0x2500 && base <= 0x259f) || + (base >= GLYPH_BOX_DRAWING_FIRST && + base <= GLYPH_BOX_DRAWING_LAST) || /* Braille */ - (base >= 0x2800 && base <= 0x28ff) || + (base >= GLYPH_BRAILLE_FIRST && + base <= GLYPH_BRAILLE_LAST) || /* * Unicode 13 "Symbols for Legacy Computing" @@ -524,42 +526,50 @@ render_cell(struct terminal *term, pixman_image_t *pix, * * Note, the full range is U+1FB00 - U+1FBF9 */ - - /* Unicode 13 sextants */ - (base >= 0x1fb00 && base <= 0x1fb8b) || - (base >= 0x1fb9a && base <= 0x1fb9b)) && + (base >= GLYPH_LEGACY_FIRST && + base <= GLYPH_LEGACY_LAST)) && likely(!term->conf->box_drawings_uses_font_glyphs)) { - /* Box drawing characters */ - size_t idx = base >= 0x1fb00 - ? (base >= 0x1fb9a - ? base - 0x1fb9a + 556 - : base - 0x1fb00 + 416) - : (base >= 0x2800 - ? base - 0x2800 + 160 - : base - 0x2500); + struct fcft_glyph ***arr; + size_t count; + size_t idx; - xassert(idx < ALEN(term->box_drawing)); + if (base >= GLYPH_LEGACY_FIRST) { + arr = &term->custom_glyphs.legacy; + count = GLYPH_LEGACY_COUNT; + idx = base - GLYPH_LEGACY_FIRST; + } else if (base >= GLYPH_BRAILLE_FIRST) { + arr = &term->custom_glyphs.braille; + count = GLYPH_BRAILLE_COUNT; + idx = base - GLYPH_BRAILLE_FIRST; + } else { + arr = &term->custom_glyphs.box_drawing; + count = GLYPH_BOX_DRAWING_COUNT; + idx = base - GLYPH_BOX_DRAWING_FIRST; + } - if (likely(term->box_drawing[idx] != NULL)) - single = term->box_drawing[idx]; + if (unlikely(*arr == NULL)) + *arr = xcalloc(count, sizeof((*arr)[0])); + + if (likely((*arr)[idx] != NULL)) + single = (*arr)[idx]; else { mtx_lock(&term->render.workers.lock); /* Other thread may have instantiated it while we * acquired the lock */ - if (term->box_drawing[idx] == NULL) - term->box_drawing[idx] = box_drawing(term, base); + single = (*arr)[idx]; + if (likely(single == NULL)) + single = (*arr)[idx] = box_drawing(term, base); mtx_unlock(&term->render.workers.lock); - - single = term->box_drawing[idx]; - xassert(single != NULL); } - glyph_count = 1; - glyphs = &single; - cell_cols = single->cols; + if (single != NULL) { + glyph_count = 1; + glyphs = &single; + cell_cols = single->cols; + } } else if (base >= CELL_COMB_CHARS_LO && base <= CELL_COMB_CHARS_HI) diff --git a/terminal.c b/terminal.c index 0138aa15..e6837977 100644 --- a/terminal.c +++ b/terminal.c @@ -626,15 +626,28 @@ err_sem_destroy: } static void -free_box_drawing(struct fcft_glyph **box_drawing) +free_custom_glyph(struct fcft_glyph **glyph) { - if (*box_drawing == NULL) + if (*glyph == NULL) return; - free(pixman_image_get_data((*box_drawing)->pix)); - pixman_image_unref((*box_drawing)->pix); - free(*box_drawing); - *box_drawing = NULL; + free(pixman_image_get_data((*glyph)->pix)); + pixman_image_unref((*glyph)->pix); + free(*glyph); + *glyph = NULL; +} + +static void +free_custom_glyphs(struct fcft_glyph ***glyphs, size_t count) +{ + if (*glyphs == NULL) + return; + + for (size_t i = 0; i < count; i++) + free_custom_glyph(&(*glyphs)[i]); + + free(*glyphs); + *glyphs = NULL; } static bool @@ -647,8 +660,12 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4]) term->fonts[i] = fonts[i]; } - for (size_t i = 0; i < ALEN(term->box_drawing); i++) - free_box_drawing(&term->box_drawing[i]); + free_custom_glyphs( + &term->custom_glyphs.box_drawing, GLYPH_BOX_DRAWING_COUNT); + free_custom_glyphs( + &term->custom_glyphs.braille, GLYPH_BRAILLE_COUNT); + free_custom_glyphs( + &term->custom_glyphs.legacy, GLYPH_LEGACY_COUNT); const int old_cell_width = term->cell_width; const int old_cell_height = term->cell_height; @@ -1590,8 +1607,13 @@ term_destroy(struct terminal *term) for (size_t i = 0; i < 4; i++) free(term->font_sizes[i]); - for (size_t i = 0; i < ALEN(term->box_drawing); i++) - free_box_drawing(&term->box_drawing[i]); + + free_custom_glyphs( + &term->custom_glyphs.box_drawing, GLYPH_BOX_DRAWING_COUNT); + free_custom_glyphs( + &term->custom_glyphs.braille, GLYPH_BRAILLE_COUNT); + free_custom_glyphs( + &term->custom_glyphs.legacy, GLYPH_LEGACY_COUNT); free(term->search.buf); diff --git a/terminal.h b/terminal.h index bfb327e3..028b4844 100644 --- a/terminal.h +++ b/terminal.h @@ -333,13 +333,26 @@ struct terminal { int16_t font_y_ofs; enum fcft_subpixel font_subpixel; - /* - * 0-159: U+02500+0259F - * 160-415: U+02800-028FF - * 416-555: U+1FB00-1FB8B - * 556-557: U+1FB9A-1FB9B - */ - struct fcft_glyph *box_drawing[558]; + struct { + struct fcft_glyph **box_drawing; + struct fcft_glyph **braille; + struct fcft_glyph **legacy; + + #define GLYPH_BOX_DRAWING_FIRST 0x2500 + #define GLYPH_BOX_DRAWING_LAST 0x259F + #define GLYPH_BOX_DRAWING_COUNT \ + (GLYPH_BOX_DRAWING_LAST - GLYPH_BOX_DRAWING_FIRST + 1) + + #define GLYPH_BRAILLE_FIRST 0x2800 + #define GLYPH_BRAILLE_LAST 0x28FF + #define GLYPH_BRAILLE_COUNT \ + (GLYPH_BRAILLE_LAST - GLYPH_BRAILLE_FIRST + 1) + + #define GLYPH_LEGACY_FIRST 0x1FB00 + #define GLYPH_LEGACY_LAST 0x1FB9B + #define GLYPH_LEGACY_COUNT \ + (GLYPH_LEGACY_LAST - GLYPH_LEGACY_FIRST + 1) + } custom_glyphs; bool is_sending_paste_data; ptmx_buffer_list_t ptmx_buffers;