From 90bfcc1fbd8bb53508dc93405add1d8aacb4e7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 30 Nov 2019 14:53:22 +0100 Subject: [PATCH] render: fix underline/strikeout positioning There were two errors: * We subtracted half the line width instead of adding it to the baseline * We rounded the line positioning and thickness before the positioning calculation. In particular, rounding the thickness before using it to adjust the position was wrong. Now we round just before the pixman call. --- font.c | 18 +++++++++--------- font.h | 8 ++++---- render.c | 14 ++++++++------ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/font.c b/font.c index 755727b3..37b2db6d 100644 --- a/font.c +++ b/font.c @@ -70,29 +70,29 @@ underline_strikeout_metrics(struct font *font) LOG_DBG("ft: y-scale: %f, height: %f, descent: %f", y_scale, height, descent); - font->underline.position = round(ft_face->underline_position * y_scale / 64.); - font->underline.thickness = ceil(ft_face->underline_thickness * y_scale / 64.); + font->underline.position = ft_face->underline_position * y_scale / 64.; + font->underline.thickness = ft_face->underline_thickness * y_scale / 64.; if (font->underline.position == 0.) { - font->underline.position = round(descent / 2.); - font->underline.thickness = fabs(round(descent / 5.)); + font->underline.position = descent / 2.; + font->underline.thickness = descent / 5.; } - LOG_DBG("underline: pos=%d, thick=%d", + LOG_DBG("underline: pos=%f, thick=%f", font->underline.position, font->underline.thickness); TT_OS2 *os2 = FT_Get_Sfnt_Table(ft_face, ft_sfnt_os2); if (os2 != NULL) { - font->strikeout.position = round(os2->yStrikeoutPosition * y_scale / 64.); - font->strikeout.thickness = ceil(os2->yStrikeoutSize * y_scale / 64.); + font->strikeout.position = os2->yStrikeoutPosition * y_scale / 64.; + font->strikeout.thickness = os2->yStrikeoutSize * y_scale / 64.; } if (font->strikeout.position == 0.) { - font->strikeout.position = round(height / 2. + descent); + font->strikeout.position = height / 2. + descent; font->strikeout.thickness = font->underline.thickness; } - LOG_DBG("strikeout: pos=%d, thick=%d", + LOG_DBG("strikeout: pos=%f, thick=%f", font->strikeout.position, font->strikeout.thickness); } diff --git a/font.h b/font.h index a01416dc..1a94067a 100644 --- a/font.h +++ b/font.h @@ -53,13 +53,13 @@ struct font { int max_x_advance; struct { - int position; - int thickness; + double position; + double thickness; } underline; struct { - int position; - int thickness; + double position; + double thickness; } strikeout; bool is_fallback; diff --git a/render.c b/render.c index f74c5fac..b90b27e8 100644 --- a/render.c +++ b/render.c @@ -105,12 +105,13 @@ draw_underline(const struct terminal *term, pixman_image_t *pix, const pixman_color_t *color, int x, int y, int cols) { int baseline = y + font_baseline(term); - int width = font->underline.thickness; - int y_under = baseline - font->underline.position - width / 2; + double width = font->underline.thickness; + int y_under = floor(baseline - font->underline.position + width / 2.); pixman_image_fill_rectangles( PIXMAN_OP_SRC, pix, color, - 1, &(pixman_rectangle16_t){x, y_under, cols * term->cell_width, width}); + 1, &(pixman_rectangle16_t){ + x, y_under, cols * term->cell_width, round(max(1., width))}); } static void @@ -119,12 +120,13 @@ draw_strikeout(const struct terminal *term, pixman_image_t *pix, const pixman_color_t *color, int x, int y, int cols) { int baseline = y + font_baseline(term); - int width = font->strikeout.thickness; - int y_strike = baseline - font->strikeout.position - width / 2; + double width = font->strikeout.thickness; + int y_strike = floor(baseline - font->strikeout.position + width / 2.); pixman_image_fill_rectangles( PIXMAN_OP_SRC, pix, color, - 1, &(pixman_rectangle16_t){x, y_strike, cols * term->cell_width, width}); + 1, &(pixman_rectangle16_t){ + x, y_strike, cols * term->cell_width, round(max(1., width))}); } static bool