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.
This commit is contained in:
Daniel Eklöf 2019-11-30 14:53:22 +01:00
parent 7be98291e1
commit 90bfcc1fbd
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 21 additions and 19 deletions

18
font.c
View file

@ -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);
}

8
font.h
View file

@ -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;

View file

@ -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