From d562a2eef3f068e2df9cea06df2838369b4c9234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Mon, 13 Feb 2023 02:15:57 +0200 Subject: [PATCH] Implement strikethrough formatting --- dip.c | 50 +++++++++++++++++++++++++++++--------------------- html.c | 12 ++++++++++-- html_gr.c | 1 + html_r.c | 1 + links.h | 8 ++++++-- 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/dip.c b/dip.c index b8acd6a..2c75109 100644 --- a/dip.c +++ b/dip.c @@ -1996,11 +1996,14 @@ bypass_freetype: * at least 1 apart * Otherwise g_print_text will print nonsense (but won't segfault) */ -static void get_underline_pos(int height, int *top, int *bottom) +static void get_line_pos(int height, int *top, int *bottom, unsigned style) { int thickness, baseline; thickness=(height+15)/16; - baseline=height/7; + if (style == FF_STRIKE) + baseline=height/2 - height/12; + else + baseline=height/7; if (baseline<=0) baseline=1; if (thickness>baseline) thickness=baseline; *top=height-baseline; @@ -2010,38 +2013,39 @@ static void get_underline_pos(int height, int *top, int *bottom) /* *width will be advanced by the width of the text */ void g_print_text(struct graphics_device *device, int x, int y, struct style *style, unsigned char *text, int *width) { - int top_underline, bottom_underline, original_width, my_width; - unsigned char original_flags; + int top_line, bottom_line, original_width, my_width; + unsigned char original_flags, line_style; struct rect saved_clip; if (y + style->height <= device->clip.y1 || y >= device->clip.y2) goto o; - if (style->flags & FF_UNDERLINE) { - /* Underline */ + if (style->flags & FF_UNDERLINE || style->flags & FF_STRIKE) { + /* Underline or strike */ if (!width) { width = &my_width; *width = 0; } original_flags = style->flags; original_width = *width; - style->flags &= ~FF_UNDERLINE; - get_underline_pos(style->height, &top_underline, &bottom_underline); - restrict_clip_area(device, &saved_clip, 0, 0, device->size.x2, y + top_underline); + line_style = style->flags & FF_UNDERLINE ? FF_UNDERLINE : FF_STRIKE; + style->flags &= ~line_style; + get_line_pos(style->height, &top_line, &bottom_line, line_style); + restrict_clip_area(device, &saved_clip, 0, 0, device->size.x2, y + top_line); g_print_text(device, x, y, style, text, width); set_clip_area(device, &saved_clip); - if (bottom_underline - top_underline == 1) { + if (bottom_line - top_line == 1) { /* Line */ - drv->draw_hline(device, x, y + top_underline, safe_add(x, *width) - original_width, style->underline_color); + drv->draw_hline(device, x, y + top_line, safe_add(x, *width) - original_width, style->line_color); } else { /* Area */ - drv->fill_area(device, x, y + top_underline, safe_add(x, *width) - original_width, y + bottom_underline, style->underline_color); + drv->fill_area(device, x, y + top_line, safe_add(x, *width) - original_width, y + bottom_line, style->line_color); } - if (bottom_underline < style->height) { - /* Do the bottom half only if the underline is above + if (bottom_line < style->height) { + /* Do the bottom half only if the line is above * the bottom of the letters. */ *width = original_width; - restrict_clip_area(device, &saved_clip, 0, y + bottom_underline, device->size.x2, device->size.y2); + restrict_clip_area(device, &saved_clip, 0, y + bottom_line, device->size.x2, device->size.y2); g_print_text(device, x, y, style, text, width); set_clip_area(device, &saved_clip); } @@ -2275,9 +2279,11 @@ struct style *g_invert_style(struct style *old) #ifdef HAVE_FREETYPE st->ft_face = old->ft_face; #endif - if (st->flags & FF_UNDERLINE) { - /* We have to get a foreground color for underlining */ - st->underline_color = dip_get_color_sRGB((st->r1 << 16) | (st->g1 << 8) | (st->b1)); + if (st->flags & FF_UNDERLINE || st->flags & FF_STRIKE) { + /* We have to get a foreground color for underlining and + * striking + */ + st->line_color = dip_get_color_sRGB((st->r1 << 16) | (st->g1 << 8) | (st->b1)); } st->mono_space = old->mono_space; st->mono_height = old->mono_height; @@ -2323,9 +2329,11 @@ struct style *g_get_style_font(int fg, int bg, int size, int fflags, unsigned ch else st->ft_face = freetype_get_font(font); #endif - if (fflags & FF_UNDERLINE) { - /* We have to get a foreground color for underlining */ - st->underline_color = dip_get_color_sRGB(fg); + if (fflags & FF_UNDERLINE || fflags & FF_STRIKE) { + /* We have to get a foreground color for underlining and + * striking + */ + st->line_color = dip_get_color_sRGB(fg); } if (fflags & FF_MONOSPACED) load_metric(st, ' ', &st->mono_space, &st->mono_height); diff --git a/html.c b/html.c index 1d3c4cd..5d5174f 100644 --- a/html.c +++ b/html.c @@ -967,6 +967,12 @@ static void html_underline(unsigned char *a) format_.attr |= AT_UNDERLINE; } +static void html_strike(unsigned char *a) +{ + get_js_events(a); + format_.attr |= AT_STRIKE; +} + static void html_fixed(unsigned char *a) { get_js_events(a); @@ -2777,8 +2783,10 @@ static struct element_info elements[] = { {"EM", html_italic, 0, 0}, {"ABBR", html_italic, 0, 0}, {"U", html_underline, 0, 0}, - {"S", html_underline, 0, 0}, - {"STRIKE", html_underline, 0, 0}, + {"INS", html_underline, 0, 0}, + {"S", html_strike, 0, 0}, + {"DEL", html_strike, 0, 0}, + {"STRIKE", html_strike, 0, 0}, {"FIXED", html_fixed, 0, 0}, {"CODE", html_fixed, 0, 0}, {"TT", html_fixed, 0, 0}, diff --git a/html_gr.c b/html_gr.c index 2114cdc..e98affe 100644 --- a/html_gr.c +++ b/html_gr.c @@ -113,6 +113,7 @@ static struct style *get_style_by_ta(struct text_attrib *ta) fflags = 0; if (ta->attr & AT_UNDERLINE) fflags |= FF_UNDERLINE; + if (ta->attr & AT_STRIKE) fflags |= FF_STRIKE; if (ta->attr & AT_BOLD) fflags |= FF_BOLD; if (ta->attr & AT_ITALIC) fflags |= FF_ITALIC; if (ta->attr & AT_FIXED) fflags |= FF_MONOSPACED; diff --git a/html_r.c b/html_r.c index af4e48f..8b20b87 100644 --- a/html_r.c +++ b/html_r.c @@ -868,6 +868,7 @@ static void put_chars(void *p_, unsigned char *c, int l) fg = fg_color(fg, bg); if (format_.attr & AT_ITALIC) fg = fg ^ 0x01; if (format_.attr & AT_UNDERLINE) fg = (fg ^ 0x04) | 0x08; + if (format_.attr & AT_STRIKE) fg = (fg ^ 0x06); if (format_.attr & AT_BOLD) fg = fg | 0x08; fg = fg_color(fg, bg); if (format_.attr & AT_GRAPHICS) bg = bg | 0x10; diff --git a/links.h b/links.h index fa25835..47036cd 100644 --- a/links.h +++ b/links.h @@ -2174,9 +2174,11 @@ struct style { /* ?0 are background, ?1 foreground. * These are unrounded 8-bit sRGB space */ - unsigned char flags; /* non-zero means underline */ + unsigned char flags; /* FF_ flags */ int height; - long underline_color; /* Valid only if flags are nonzero */ + long line_color; /* Valid only if flags includes FF_UNDERLINE or + * FF_STRIKE + */ int mono_space; /* -1 if the font is not monospaced * width of the space otherwise */ @@ -2266,6 +2268,7 @@ int hack_rgb(int rgb); #define FF_MONOSPACED 2 #define FF_ITALIC 4 #define FF_UNDERLINE 8 +#define FF_STRIKE 16 #ifndef USE_ITALIC #define FF_SHAPES 4 @@ -4539,6 +4542,7 @@ void init_grview(void); #define AT_FIXED 8 #define AT_GRAPHICS 16 #define AT_INVERT 32 +#define AT_STRIKE 64 #define AL_LEFT 0 #define AL_CENTER 1