From 06f9495ae2371929f9ffdf962c491ec27486bdbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 16 Jul 2019 15:08:02 +0200 Subject: [PATCH] render: implement strikeout --- main.c | 25 ++++++++++++++++++++++++- render.c | 20 +++++++++++++++++--- terminal.h | 4 ++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 992b1650..1f057812 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -376,11 +377,16 @@ main(int argc, char *const *argv) FT_Face ft_face = cairo_ft_scaled_font_lock_face(f->font); double x_scale = ft_face->size->metrics.x_scale / 65526.; + double height = ft_face->size->metrics.height / 64; + double descent = ft_face->size->metrics.descender / 64; + + LOG_DBG("ft: x-scale: %f, height: %f, descent: %f", + x_scale, height, descent); + f->underline.position = ft_face->underline_position * x_scale / 64.; f->underline.thickness = ft_face->underline_thickness * x_scale / 64.; if (f->underline.position == 0.) { - double descent = ft_face->size->metrics.descender / 64; f->underline.position = descent / 2.; f->underline.thickness = fabs(round(descent / 5.)); } @@ -388,7 +394,24 @@ main(int argc, char *const *argv) LOG_DBG("underline: pos=%f, thick=%f", f->underline.position, f->underline.thickness); + TT_OS2 *os2 = FT_Get_Sfnt_Table(ft_face, ft_sfnt_os2); + if (os2 != NULL) { + f->strikeout.position = os2->yStrikeoutPosition * x_scale / 64.; + f->strikeout.thickness = os2->yStrikeoutSize * x_scale / 64.; + } + + if (f->strikeout.position == 0.) { + assert(false); + /* TODO: fixme */ + f->strikeout.position = height / 2. + descent; + f->strikeout.thickness = f->underline.thickness; + } + + LOG_DBG("strikeout: pos=%f, thick=%f", + f->strikeout.position, f->strikeout.thickness); + cairo_ft_scaled_font_unlock_face(f->font); + } cairo_scaled_font_extents(term.fonts[0].font, &term.fextents); diff --git a/render.c b/render.c index 94c38fc4..da3a37c4 100644 --- a/render.c +++ b/render.c @@ -134,13 +134,27 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell, /* Underline */ if (cell->attrs.underline) { const struct font *font = attrs_to_font(term, &cell->attrs); + double baseline = y + term->fextents.height - term->fextents.descent; double width = font->underline.thickness; - double y_under = y + term->cell_height + font->underline.position + width / 2.; + double y_under = baseline - font->underline.position - width / 2.; cairo_set_source_rgb(buf->cairo, foreground.r, foreground.g, foreground.b); cairo_set_line_width(buf->cairo, width); - cairo_move_to(buf->cairo, x, y_under); - cairo_line_to(buf->cairo, x + term->cell_width, y_under); + cairo_move_to(buf->cairo, x, round(y_under) + 0.5); + cairo_line_to(buf->cairo, x + term->cell_width, round(y_under) + 0.5); + cairo_stroke(buf->cairo); + } + + if (cell->attrs.strikethrough) { + const struct font *font = attrs_to_font(term, &cell->attrs); + double baseline = y + term->fextents.height - term->fextents.descent; + double width = font->strikeout.thickness; + double y_strike = baseline - font->strikeout.position - width / 2.; + + cairo_set_source_rgb(buf->cairo, foreground.r, foreground.g, foreground.b); + cairo_set_line_width(buf->cairo, width); + cairo_move_to(buf->cairo, x, round(y_strike) + 0.5); + cairo_line_to(buf->cairo, x + term->cell_width, round(y_strike) + 0.5); cairo_stroke(buf->cairo); } diff --git a/terminal.h b/terminal.h index daec8667..71a77ddb 100644 --- a/terminal.h +++ b/terminal.h @@ -208,6 +208,10 @@ struct font { double position; double thickness; } underline; + struct { + double position; + double thickness; + } strikeout; }; struct terminal {