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;