From 41932287cf046a263ecaca0d8d140d4f57e180f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 10 Oct 2023 10:52:35 +0200 Subject: [PATCH 1/4] Revert "font baseline: use max(font->height, font->ascent + font->descent) when calculating font height" This reverts commit fd813d0e6cfff57cf8a8f55e9a249ddb6fbdb6d6. The intent of the reverted commit was to align font height calculation with cell height calculation. However, it turns out this breaks some fonts. Typically those with large:ish differences in their 'height' attribute, and their ascent+descent value. Closes #1511 --- terminal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terminal.c b/terminal.c index 9a76488e..dd92cd67 100644 --- a/terminal.c +++ b/terminal.c @@ -2189,7 +2189,7 @@ term_font_baseline(const struct terminal *term) { const struct fcft_font *font = term->fonts[0]; const int line_height = term->cell_height; - const int font_height = max(font->height, font->ascent + font->descent); + const int font_height = font->ascent + font->descent; const int glyph_top_y = round((line_height - font_height) / 2.); return term->font_y_ofs + glyph_top_y + font->ascent; From 7d126ff41401ff51bc80227eab319e61d64f13e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 10 Oct 2023 10:55:26 +0200 Subject: [PATCH 2/4] changelog: fixed font baseline calculation --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ae5f985..0e0cc8c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,7 @@ mode ([#1503][1503]). * Crash when a scrollback search match is in the last column. * Scrollback search: grapheme clusters not matching correctly. +* Wrong baseline offset for some fonts ([#1511][1511]). [1436]: https://codeberg.org/dnkl/foot/issues/1436 [1464]: https://codeberg.org/dnkl/foot/issues/1464 @@ -141,6 +142,7 @@ [1493]: https://codeberg.org/dnkl/foot/pulls/1493 [1498]: https://codeberg.org/dnkl/foot/issues/1498 [1503]: https://codeberg.org/dnkl/foot/issues/1503 +[1511]: https://codeberg.org/dnkl/foot/issues/1511 ### Security From 34aa979f460c09a481a02af733737a5925c9b1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 10 Oct 2023 13:52:24 +0200 Subject: [PATCH 3/4] term_font_baseline(): only center glyph when a custom line-height is being used When using the font's own line-height, simply set the baseline 'descent' pixels above the bottom of the cell. This fixes an issue where some fonts appeared "glued" to the top of the cell, and sometimes getting partially clipped. --- terminal.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/terminal.c b/terminal.c index dd92cd67..e517253b 100644 --- a/terminal.c +++ b/terminal.c @@ -2190,9 +2190,17 @@ term_font_baseline(const struct terminal *term) const struct fcft_font *font = term->fonts[0]; const int line_height = term->cell_height; const int font_height = font->ascent + font->descent; - const int glyph_top_y = round((line_height - font_height) / 2.); - return term->font_y_ofs + glyph_top_y + font->ascent; + /* + * Center glyph on the line *if* using a custom line height, + * otherwise the baseline is simply 'descent' pixels above the + * bottom of the cell + */ + const int glyph_top_y = term->font_line_height.px >= 0 + ? round((line_height - font_height) / 2.) + : 0; + + return term->font_y_ofs + line_height - glyph_top_y - font->descent; } void From 4449177517c2d96857483acbc8afd7438fcdfadd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 10 Oct 2023 14:23:33 +0200 Subject: [PATCH 4/4] term: cache font baseline No need to redo the calculation for every single cell we render, every frame... --- box-drawing.c | 2 +- render.c | 16 ++++++++-------- terminal.c | 2 ++ terminal.h | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/box-drawing.c b/box-drawing.c index 07f415cb..cf351b31 100644 --- a/box-drawing.c +++ b/box-drawing.c @@ -3011,7 +3011,7 @@ box_drawing(const struct terminal *term, char32_t wc) .cols = 1, .pix = buf.pix, .x = -term->font_x_ofs, - .y = term_font_baseline(term), + .y = term->font_baseline, .width = width, .height = height, .advance = { diff --git a/render.c b/render.c index 231d2b63..81e9a0a4 100644 --- a/render.c +++ b/render.c @@ -326,7 +326,7 @@ draw_beam_cursor(const struct terminal *term, pixman_image_t *pix, const struct fcft_font *font, const pixman_color_t *color, int x, int y) { - int baseline = y + term_font_baseline(term) - term->fonts[0]->ascent; + int baseline = y + term->font_baseline - term->fonts[0]->ascent; pixman_image_fill_rectangles( PIXMAN_OP_SRC, pix, color, 1, &(pixman_rectangle16_t){ @@ -338,7 +338,7 @@ draw_beam_cursor(const struct terminal *term, pixman_image_t *pix, static int underline_offset(const struct terminal *term, const struct fcft_font *font) { - return term_font_baseline(term) - + return term->font_baseline - (term->conf->use_custom_underline_offset ? -term_pt_or_px_as_pixels(term, &term->conf->underline_offset) : font->underline.position); @@ -392,7 +392,7 @@ draw_strikeout(const struct terminal *term, pixman_image_t *pix, pixman_image_fill_rectangles( PIXMAN_OP_SRC, pix, color, 1, &(pixman_rectangle16_t){ - x, y + term_font_baseline(term) - font->strikeout.position, + x, y + term->font_baseline - font->strikeout.position, cols * term->cell_width, font->strikeout.thickness}); } @@ -776,13 +776,13 @@ render_cell(struct terminal *term, pixman_image_t *pix, pixman_region32_t *damag if (!(cell->attrs.blink && term->blink.state == BLINK_OFF)) { pixman_image_composite32( PIXMAN_OP_OVER, glyph->pix, NULL, pix, 0, 0, 0, 0, - pen_x + letter_x_ofs + g_x, y + term_font_baseline(term) - g_y, + pen_x + letter_x_ofs + g_x, y + term->font_baseline - g_y, glyph->width, glyph->height); } } else { pixman_image_composite32( PIXMAN_OP_OVER, clr_pix, glyph->pix, pix, 0, 0, 0, 0, - pen_x + letter_x_ofs + g_x, y + term_font_baseline(term) - g_y, + pen_x + letter_x_ofs + g_x, y + term->font_baseline - g_y, glyph->width, glyph->height); /* Combining characters */ @@ -822,7 +822,7 @@ render_cell(struct terminal *term, pixman_image_t *pix, pixman_region32_t *damag /* Some fonts use a negative offset, while others use a * "normal" offset */ pen_x + x_ofs + g->x, - y + term_font_baseline(term) - g->y, + y + term->font_baseline - g->y, g->width, g->height); } } @@ -3411,7 +3411,7 @@ render_search_box(struct terminal *term) /* Glyph surface is a pre-rendered image (typically a color emoji...) */ pixman_image_composite32( PIXMAN_OP_OVER, glyph->pix, NULL, buf->pix[0], 0, 0, 0, 0, - x + x_ofs + glyph->x, y + term_font_baseline(term) - glyph->y, + x + x_ofs + glyph->x, y + term->font_baseline - glyph->y, glyph->width, glyph->height); } else { int combining_ofs = width == 0 @@ -3423,7 +3423,7 @@ render_search_box(struct terminal *term) pixman_image_composite32( PIXMAN_OP_OVER, src, glyph->pix, buf->pix[0], 0, 0, 0, 0, x + x_ofs + combining_ofs + glyph->x, - y + term_font_baseline(term) - glyph->y, + y + term->font_baseline - glyph->y, glyph->width, glyph->height); pixman_image_unref(src); } diff --git a/terminal.c b/terminal.c index e517253b..efbbded1 100644 --- a/terminal.c +++ b/terminal.c @@ -774,6 +774,8 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4], term->font_x_ofs = term_pt_or_px_as_pixels(term, &conf->horizontal_letter_offset); term->font_y_ofs = term_pt_or_px_as_pixels(term, &conf->vertical_letter_offset); + term->font_baseline = term_font_baseline(term); + LOG_INFO("cell width=%d, height=%d", term->cell_width, term->cell_height); sixel_cell_size_changed(term); diff --git a/terminal.h b/terminal.h index da873ae6..a8b65198 100644 --- a/terminal.h +++ b/terminal.h @@ -406,6 +406,7 @@ struct terminal { bool font_is_sized_by_dpi; int16_t font_x_ofs; int16_t font_y_ofs; + int16_t font_baseline; enum fcft_subpixel font_subpixel; struct {