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 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 9a76488e..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); @@ -2189,10 +2191,18 @@ 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 glyph_top_y = round((line_height - font_height) / 2.); + const int font_height = font->ascent + font->descent; - 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 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 {