From 55e4f1c42e8d1131b01659fad67db5d084780227 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 1 Jun 2021 13:31:38 +0100 Subject: [PATCH] Implement support for strikethrough text. https://defs.ircdocs.horse/info/formatting.html --- src/common/outbound.c | 3 +++ src/common/util.c | 1 + src/fe-gtk/maingui.c | 5 ++++- src/fe-gtk/sexy-spell-entry.c | 20 ++++++++++++++++++++ src/fe-gtk/xtext.c | 17 +++++++++++++++++ src/fe-gtk/xtext.h | 22 ++++++++++++---------- 6 files changed, 57 insertions(+), 11 deletions(-) diff --git a/src/common/outbound.c b/src/common/outbound.c index c39a1d46..70fcd436 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -4434,6 +4434,9 @@ check_special_chars (char *cmd, int do_ascii) /* check for %X */ case 'I': buf[i] = '\035'; break; + case 'S': + buf[i] = '\036'; + break; case 'C': buf[i] = '\003'; break; diff --git a/src/common/util.c b/src/common/util.c index 5b5fb23f..fa0783d4 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -329,6 +329,7 @@ strip_color2 (const char *src, int len, char *dst, int flags) case '\026': /*ATTR_REVERSE: */ case '\002': /*ATTR_BOLD: */ case '\037': /*ATTR_UNDERLINE: */ + case '\036': /*ATTR_STRIKETHROUGH: */ case '\035': /*ATTR_ITALICS: */ if (!(flags & STRIP_ATTRIB)) goto pass_char; break; diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c index 4e5baaa0..b77da59b 100644 --- a/src/fe-gtk/maingui.c +++ b/src/fe-gtk/maingui.c @@ -1394,6 +1394,8 @@ mg_color_insert (GtkWidget *item, gpointer userdata) text = "\037"; break; case 102: text = "\035"; break; + case 103: + text = "\036"; break; default: text = "\017"; break; } @@ -1447,7 +1449,8 @@ mg_create_color_menu (GtkWidget *menu, session *sess) mg_markup_item (submenu, _("Bold"), 100); mg_markup_item (submenu, _("Underline"), 101); mg_markup_item (submenu, _("Italic"), 102); - mg_markup_item (submenu, _("Normal"), 103); + mg_markup_item (submenu, _("Strikethrough"), 103); + mg_markup_item (submenu, _("Normal"), 999); subsubmenu = mg_submenu (submenu, _("Colors 0-7")); diff --git a/src/fe-gtk/sexy-spell-entry.c b/src/fe-gtk/sexy-spell-entry.c index dce19b82..04ff0f8a 100644 --- a/src/fe-gtk/sexy-spell-entry.c +++ b/src/fe-gtk/sexy-spell-entry.c @@ -389,6 +389,17 @@ insert_italic (SexySpellEntry *entry, guint start, gboolean toggle) pango_attr_list_change (entry->priv->attr_list, iattr); } +static void +insert_strikethrough (SexySpellEntry *entry, guint start, gboolean toggle) +{ + PangoAttribute *sattr; + + sattr = pango_attr_strikethrough_new (!toggle); + sattr->start_index = start; + sattr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END; + pango_attr_list_change (entry->priv->attr_list, sattr); +} + static void insert_color (SexySpellEntry *entry, guint start, int fgcolor, int bgcolor) { @@ -429,6 +440,7 @@ insert_reset (SexySpellEntry *entry, guint start) insert_bold (entry, start, TRUE); insert_underline (entry, start, TRUE); insert_italic (entry, start, TRUE); + insert_strikethrough (entry, start, TRUE); insert_color (entry, start, -1, -1); } @@ -918,6 +930,7 @@ check_attributes (SexySpellEntry *entry, const char *text, int len) gboolean bold = FALSE; gboolean italic = FALSE; gboolean underline = FALSE; + gboolean strikethrough = FALSE; int parsing_color = 0; char fg_color[3]; char bg_color[3]; @@ -942,6 +955,12 @@ check_attributes (SexySpellEntry *entry, const char *text, int len) italic = !italic; goto check_color; + case ATTR_STRIKETHROUGH: + insert_hiddenchar (entry, i, i + 1); + insert_strikethrough (entry, i, strikethrough); + strikethrough = !strikethrough; + goto check_color; + case ATTR_UNDERLINE: insert_hiddenchar (entry, i, i + 1); insert_underline (entry, i, underline); @@ -954,6 +973,7 @@ check_attributes (SexySpellEntry *entry, const char *text, int len) bold = FALSE; italic = FALSE; underline = FALSE; + strikethrough = FALSE; goto check_color; case ATTR_HIDDEN: diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index 418bb4da..6a0fccba 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -433,6 +433,7 @@ gtk_xtext_init (GtkXText * xtext) xtext->nc = 0; xtext->pixel_offset = 0; xtext->underline = FALSE; + xtext->strikethrough = FALSE; xtext->hidden = FALSE; xtext->font = NULL; xtext->layout = NULL; @@ -2451,6 +2452,7 @@ gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf, case ATTR_REVERSE: case ATTR_BOLD: case ATTR_UNDERLINE: + case ATTR_STRIKETHROUGH: case ATTR_ITALICS: xtext_do_chunk (&c); if (*text == ATTR_RESET) @@ -2627,6 +2629,13 @@ gtk_xtext_render_flush (GtkXText * xtext, int x, int y, unsigned char *str, g_object_unref (pix); } + if (xtext->strikethrough) + { + /* pango_attr_strikethrough_new does not render in the custom widget so we need to reinvent the wheel */ + y = dest_y + (xtext->fontsize / 2); + gdk_draw_line (xtext->draw_buf, gc, dest_x, y, dest_x + str_width - 1, y); + } + if (xtext->underline) { dounder: @@ -2651,6 +2660,7 @@ gtk_xtext_reset (GtkXText * xtext, int mark, int attribs) if (attribs) { xtext->underline = FALSE; + xtext->strikethrough = FALSE; xtext->hidden = FALSE; } if (!mark) @@ -2961,6 +2971,12 @@ gtk_xtext_render_str (GtkXText * xtext, int y, textentry * ent, pstr += j + 1; j = 0; break; + case ATTR_STRIKETHROUGH: + RENDER_FLUSH; + xtext->strikethrough = !xtext->strikethrough; + pstr += j + 1; + j = 0; + break; case ATTR_ITALICS: RENDER_FLUSH; *emphasis ^= EMPH_ITAL; @@ -3191,6 +3207,7 @@ find_next_wrap (GtkXText * xtext, textentry * ent, unsigned char *str, case ATTR_REVERSE: case ATTR_BOLD: case ATTR_UNDERLINE: + case ATTR_STRIKETHROUGH: case ATTR_ITALICS: if (*str == ATTR_RESET) emphasis = 0; diff --git a/src/fe-gtk/xtext.h b/src/fe-gtk/xtext.h index 12d6f563..18d769fb 100644 --- a/src/fe-gtk/xtext.h +++ b/src/fe-gtk/xtext.h @@ -29,16 +29,17 @@ #define GTK_IS_XTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_XTEXT)) #define GTK_XTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_XTEXT, GtkXTextClass)) -#define ATTR_BOLD '\002' -#define ATTR_COLOR '\003' -#define ATTR_BLINK '\006' -#define ATTR_BEEP '\007' -#define ATTR_HIDDEN '\010' -#define ATTR_ITALICS2 '\011' -#define ATTR_RESET '\017' -#define ATTR_REVERSE '\026' -#define ATTR_ITALICS '\035' -#define ATTR_UNDERLINE '\037' +#define ATTR_BOLD '\002' +#define ATTR_COLOR '\003' +#define ATTR_BLINK '\006' +#define ATTR_BEEP '\007' +#define ATTR_HIDDEN '\010' +#define ATTR_ITALICS2 '\011' +#define ATTR_RESET '\017' +#define ATTR_REVERSE '\026' +#define ATTR_ITALICS '\035' +#define ATTR_STRIKETHROUGH '\036' +#define ATTR_UNDERLINE '\037' /* these match palette.h */ #define XTEXT_MIRC_COLS 32 @@ -207,6 +208,7 @@ struct _GtkXText /* current text states */ unsigned int underline:1; + unsigned int strikethrough:1; unsigned int hidden:1; /* text parsing states */