diff --git a/docs/formats.txt b/docs/formats.txt index 2a507a04..b6063857 100644 --- a/docs/formats.txt +++ b/docs/formats.txt @@ -23,6 +23,7 @@ %U Underline on/off %8 Reverse on/off %9 %_ Bold on/off + %I Italic on/off %: Insert newline %| Marks the indentation position %# Monospace font on/off (useful with lists and GUI) diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index 67c95745..25c20109 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -45,16 +45,19 @@ GHashTable *printnicks; -/* convert _underlined_ and *bold* words (and phrases) to use real +/* convert _underlined_, /italics/, and *bold* words (and phrases) to use real underlining or bolding */ char *expand_emphasis(WI_ITEM_REC *item, const char *text) { GString *str; char *ret; int pos; + int emphasis_italics; g_return_val_if_fail(text != NULL, NULL); + emphasis_italics = settings_get_bool("emphasis_italics"); + str = g_string_new(text); for (pos = 0; pos < str->len; pos++) { @@ -62,9 +65,11 @@ char *expand_emphasis(WI_ITEM_REC *item, const char *text) bgn = str->str + pos; - if (*bgn == '*') + if (*bgn == '*') type = 2; /* bold */ - else if (*bgn == '_') + else if (*bgn == '/' && emphasis_italics) + type = 29; /* italics */ + else if (*bgn == '_') type = 31; /* underlined */ else continue; @@ -92,7 +97,7 @@ char *expand_emphasis(WI_ITEM_REC *item, const char *text) found = nicklist_find(CHANNEL(item), bgn) != NULL; end[1] = c; if (found) continue; - + /* check if the whole 'word' (e.g. "_foo_^") is a nick in "_foo_^ ", end will be the second _, end2 the ^ */ end2 = end; @@ -680,6 +685,7 @@ void fe_messages_init(void) settings_add_bool("lookandfeel", "emphasis", TRUE); settings_add_bool("lookandfeel", "emphasis_replace", FALSE); settings_add_bool("lookandfeel", "emphasis_multiword", FALSE); + settings_add_bool("lookandfeel", "emphasis_italics", FALSE); settings_add_bool("lookandfeel", "show_nickmode", TRUE); settings_add_bool("lookandfeel", "show_nickmode_empty", TRUE); settings_add_bool("lookandfeel", "print_active_channel", FALSE); diff --git a/src/fe-common/core/formats.c b/src/fe-common/core/formats.c index 770caaa1..375b00eb 100644 --- a/src/fe-common/core/formats.c +++ b/src/fe-common/core/formats.c @@ -207,6 +207,11 @@ int format_expand_styles(GString *out, const char **format, int *flags) g_string_append_c(out, 4); g_string_append_c(out, FORMAT_STYLE_REVERSE); break; + case 'I': + /* italic */ + g_string_append_c(out, 4); + g_string_append_c(out, FORMAT_STYLE_ITALIC); + break; case ':': /* Newline */ g_string_append_c(out, '\n'); @@ -913,6 +918,14 @@ static const char *get_ansi_color(THEME_REC *theme, const char *str, /* normal */ flags &= ~GUI_PRINT_FLAG_BOLD; break; + case 3: + /* italic */ + flags |= GUI_PRINT_FLAG_ITALIC; + break; + case 23: + /* not italic */ + flags &= ~GUI_PRINT_FLAG_ITALIC; + break; case 4: /* underline */ flags |= GUI_PRINT_FLAG_UNDERLINE; @@ -1085,7 +1098,7 @@ static void get_mirc_color(const char **str, int *fg_ret, int *bg_ret) #define IS_COLOR_CODE(c) \ ((c) == 2 || (c) == 3 || (c) == 4 || (c) == 6 || (c) == 7 || \ - (c) == 15 || (c) == 22 || (c) == 27 || (c) == 31) + (c) == 15 || (c) == 22 || (c) == 27 || (c) == 29 || (c) == 31) /* Return how many characters in `str' must be skipped before `len' characters of text is skipped. */ @@ -1282,6 +1295,9 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) case FORMAT_STYLE_REVERSE: flags ^= GUI_PRINT_FLAG_REVERSE; break; + case FORMAT_STYLE_ITALIC: + flags ^= GUI_PRINT_FLAG_ITALIC; + break; case FORMAT_STYLE_MONOSPACE: flags ^= GUI_PRINT_FLAG_MONOSPACE; break; @@ -1356,6 +1372,11 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text) if (!hide_text_style) flags ^= GUI_PRINT_FLAG_REVERSE; break; + case 29: + /* italic */ + if (!hide_text_style) + flags ^= GUI_PRINT_FLAG_ITALIC; + break; case 31: /* underline */ if (!hide_text_style) diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 037aa424..07e1832c 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -10,6 +10,7 @@ #define GUI_PRINT_FLAG_BLINK 0x0008 #define GUI_PRINT_FLAG_MIRC_COLOR 0x0010 #define GUI_PRINT_FLAG_INDENT 0x0020 +#define GUI_PRINT_FLAG_ITALIC 0x0040 #define GUI_PRINT_FLAG_NEWLINE 0x0080 #define GUI_PRINT_FLAG_CLRTOEOL 0x0100 #define GUI_PRINT_FLAG_MONOSPACE 0x0200 @@ -139,6 +140,7 @@ void format_send_to_gui(TEXT_DEST_REC *dest, const char *text); #define FORMAT_STYLE_BOLD (0x03 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_REVERSE (0x04 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_INDENT (0x05 + FORMAT_STYLE_SPECIAL) +#define FORMAT_STYLE_ITALIC (0x06 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_DEFAULTS (0x07 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_CLRTOEOL (0x08 + FORMAT_STYLE_SPECIAL) #define FORMAT_STYLE_MONOSPACE (0x09 + FORMAT_STYLE_SPECIAL) diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index 380ca114..cf6028b5 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -186,6 +186,7 @@ static void get_colors(int flags, int *fg, int *bg, int *attr) *attr |= (*bg << BG_SHIFT); if (flags & GUI_PRINT_FLAG_REVERSE) *attr |= ATTR_REVERSE; + if (flags & GUI_PRINT_FLAG_ITALIC) *attr |= ATTR_ITALIC; if (flags & GUI_PRINT_FLAG_BOLD) *attr |= ATTR_BOLD; if (flags & GUI_PRINT_FLAG_UNDERLINE) *attr |= ATTR_UNDERLINE; if (flags & GUI_PRINT_FLAG_BLINK) *attr |= ATTR_BLINK; diff --git a/src/fe-text/term-curses.c b/src/fe-text/term-curses.c index fd24bbe3..752edd7f 100644 --- a/src/fe-text/term-curses.c +++ b/src/fe-text/term-curses.c @@ -298,6 +298,9 @@ static int get_attr(int color) if (color & ATTR_UNDERLINE) attr |= A_UNDERLINE; if (color & ATTR_REVERSE) attr |= A_REVERSE; +#ifdef A_ITALIC + if (color & ATTR_ITALIC) attr |= A_ITALIC; +#endif return attr; } diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 9c718aad..a0b257c4 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -346,12 +346,16 @@ void term_set_color(TERM_WINDOW *window, int col) #endif ((col & BG_MASK) >> BG_SHIFT); + if (!term_use_colors && bg > 0) + col |= ATTR_REVERSE; + set_normal = ((col & ATTR_RESETFG) && last_fg != COLOR_RESET) || ((col & ATTR_RESETBG) && last_bg != COLOR_RESET); if (((last_attrs & ATTR_BOLD) && (col & ATTR_BOLD) == 0) || + ((last_attrs & ATTR_REVERSE) && (col & ATTR_REVERSE) == 0) || ((last_attrs & ATTR_BLINK) && (col & ATTR_BLINK) == 0)) { - /* we'll need to get rid of bold/blink - this can only be - done with setting the default color */ + /* we'll need to get rid of bold/blink/reverse - this + can only be done with setting the default color */ set_normal = TRUE; } @@ -361,16 +365,6 @@ void term_set_color(TERM_WINDOW *window, int col) terminfo_set_normal(); } - if (!term_use_colors && bg > 0) - col |= ATTR_REVERSE; - - /* reversed text (use standout) */ - if (col & ATTR_REVERSE) { - if ((last_attrs & ATTR_REVERSE) == 0) - terminfo_set_standout(TRUE); - } else if (last_attrs & ATTR_REVERSE) - terminfo_set_standout(FALSE); - /* set foreground color */ if (fg != last_fg && (fg != 0 || (col & ATTR_RESETFG) == 0)) { @@ -400,6 +394,10 @@ void term_set_color(TERM_WINDOW *window, int col) } } + /* reversed text */ + if (col & ATTR_REVERSE) + terminfo_set_reverse(); + /* bold */ if (window && (term_color256map[fg&0xff]&8) == window->term->TI_colors) col |= ATTR_BOLD; @@ -413,6 +411,13 @@ void term_set_color(TERM_WINDOW *window, int col) } else if (last_attrs & ATTR_UNDERLINE) terminfo_set_uline(FALSE); + /* italic */ + if (col & ATTR_ITALIC) { + if ((last_attrs & ATTR_ITALIC) == 0) + terminfo_set_italic(TRUE); + } else if (last_attrs & ATTR_ITALIC) + terminfo_set_italic(FALSE); + /* update the new attribute settings whilst ignoring color values. */ last_attrs = col & ~( BG_MASK | FG_MASK ); } @@ -516,7 +521,7 @@ void term_clrtoeol(TERM_WINDOW *window) { /* clrtoeol() doesn't necessarily understand colors */ if (last_fg == -1 && last_bg == -1 && - (last_attrs & (ATTR_UNDERLINE|ATTR_REVERSE)) == 0) { + (last_attrs & (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_ITALIC)) == 0) { if (!term_lines_empty[vcy]) { if (vcmove) term_move_real(); terminfo_clrtoeol(); diff --git a/src/fe-text/term.h b/src/fe-text/term.h index 05a31573..cdcc787a 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -14,12 +14,13 @@ typedef struct _TERM_WINDOW TERM_WINDOW; #define ATTR_BLINK ( 0x080000 ) #define ATTR_UNDERLINE ( 0x100000 ) #define ATTR_REVERSE ( 0x200000 ) -#define ATTR_FGCOLOR24 ( 0x400000 ) -#define ATTR_BGCOLOR24 ( 0x800000 ) +#define ATTR_ITALIC ( 0x400000 ) +#define ATTR_FGCOLOR24 ( 0x1000000 ) +#define ATTR_BGCOLOR24 ( 0x2000000 ) #define ATTR_RESET (ATTR_RESETFG|ATTR_RESETBG) -#define ATTR_NOCOLORS (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_BLINK|ATTR_BOLD) +#define ATTR_NOCOLORS (ATTR_UNDERLINE|ATTR_REVERSE|ATTR_BLINK|ATTR_BOLD|ATTR_ITALIC) /* terminal types */ #define TERM_TYPE_8BIT 0 /* normal 8bit text */ diff --git a/src/fe-text/terminfo-core.c b/src/fe-text/terminfo-core.c index ba9256b4..d16987fe 100644 --- a/src/fe-text/terminfo-core.c +++ b/src/fe-text/terminfo-core.c @@ -94,8 +94,11 @@ static TERMINFO_REC tcaps[] = { { "rmul", "ue", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_rmul) }, { "smso", "so", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_smso) }, { "rmso", "se", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_rmso) }, + { "sitm", "ZH", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_sitm) }, + { "ritm", "ZR", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_ritm) }, { "bold", "md", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_bold) }, { "blink", "mb", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_blink) }, + { "rev", "mr", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_rev) }, { "setaf", "AF", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_setaf) }, { "setab", "AB", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_setab) }, { "setf", "Sf", CAP_TYPE_STR, G_STRUCT_OFFSET(TERM_REC, TI_setf) }, @@ -313,6 +316,12 @@ static void _set_blink(TERM_REC *term) tput(tparm(term->TI_blink)); } +/* Reverse on */ +static void _set_reverse(TERM_REC *term) +{ + tput(tparm(term->TI_rev)); +} + /* Bold on */ static void _set_bold(TERM_REC *term) { @@ -331,6 +340,18 @@ static void _set_standout(TERM_REC *term, int set) tput(tparm(set ? term->TI_smso : term->TI_rmso)); } +/* Italic on/off */ +static void _set_italic(TERM_REC *term, int set) +{ + tput(tparm(set ? term->TI_sitm : term->TI_ritm)); +} + +/* Standout on (fallback for reverse) */ +static void _set_standout_on(TERM_REC *term) +{ + _set_standout(term, TRUE); +} + inline static int color256(const TERM_REC *term, const int color) { if (color < term->TI_colors) return color; @@ -609,13 +630,17 @@ static int term_setup(TERM_REC *term) else term->repeat = _repeat_manual; - /* Bold, underline, standout */ + /* Bold, underline, standout, reverse, italics */ term->set_blink = term->TI_blink ? _set_blink : _ignore; term->set_bold = term->TI_bold ? _set_bold : _ignore; + term->set_reverse = term->TI_rev ? _set_reverse : + term->TI_smso ? _set_standout_on : _ignore; term->set_uline = term->TI_smul && term->TI_rmul ? _set_uline : _ignore_parm; term->set_standout = term->TI_smso && term->TI_rmso ? _set_standout : _ignore_parm; + term->set_italic = term->TI_sitm && term->TI_ritm ? + _set_italic : _ignore_parm; /* Create a string to set all attributes off */ str = g_string_new(NULL); @@ -625,6 +650,8 @@ static int term_setup(TERM_REC *term) g_string_append(str, term->TI_rmul); if (term->TI_rmso && (term->TI_sgr0 == NULL || strcmp(term->TI_rmso, term->TI_sgr0) != 0)) g_string_append(str, term->TI_rmso); + if (term->TI_ritm && (term->TI_sgr0 == NULL || strcmp(term->TI_ritm, term->TI_sgr0) != 0)) + g_string_append(str, term->TI_ritm); term->TI_normal = str->str; g_string_free(str, FALSE); term->set_normal = _set_normal; diff --git a/src/fe-text/terminfo-core.h b/src/fe-text/terminfo-core.h index 9e2b76d5..6ab4637d 100644 --- a/src/fe-text/terminfo-core.h +++ b/src/fe-text/terminfo-core.h @@ -16,6 +16,8 @@ #define terminfo_set_bold() current_term->set_bold(current_term) #define terminfo_set_uline(set) current_term->set_uline(current_term, set) #define terminfo_set_standout(set) current_term->set_standout(current_term, set) +#define terminfo_set_reverse() current_term->set_reverse(current_term) +#define terminfo_set_italic(set) current_term->set_italic(current_term, set) #define terminfo_is_colors_set(term) (term->TI_fg != NULL) #define terminfo_beep(term) current_term->beep(current_term) @@ -37,8 +39,10 @@ struct _TERM_REC { void (*set_normal)(TERM_REC *term); void (*set_blink)(TERM_REC *term); void (*set_bold)(TERM_REC *term); + void (*set_reverse)(TERM_REC *term); void (*set_uline)(TERM_REC *term, int set); void (*set_standout)(TERM_REC *term, int set); + void (*set_italic)(TERM_REC *term, int set); void (*beep)(TERM_REC *term); @@ -74,8 +78,9 @@ struct _TERM_REC { int TI_colors; /* numbers of colors in TI_fg[] and TI_bg[] */ const char *TI_sgr0; /* turn off all attributes */ const char *TI_smul, *TI_rmul; /* underline on/off */ - const char *TI_smso, *TI_rmso; /* standout on/off */ - const char *TI_bold, *TI_blink; + const char *TI_smso, *TI_rmso; /* standout on/off */ + const char *TI_sitm, *TI_ritm; /* italic on/off */ + const char *TI_bold, *TI_blink, *TI_rev; const char *TI_setaf, *TI_setab, *TI_setf, *TI_setb; /* Colors - generated and dynamically allocated */ diff --git a/src/fe-text/textbuffer-view.c b/src/fe-text/textbuffer-view.c index b233697c..2197c1df 100644 --- a/src/fe-text/textbuffer-view.c +++ b/src/fe-text/textbuffer-view.c @@ -143,6 +143,9 @@ static void update_cmd_color(unsigned char cmd, int *color) case LINE_CMD_BOLD: *color ^= ATTR_BOLD; break; + case LINE_CMD_ITALIC: + *color ^= ATTR_ITALIC; + break; case LINE_CMD_COLOR0: *color &= BGATTR; *color &= ~ATTR_FGCOLOR24; diff --git a/src/fe-text/textbuffer.c b/src/fe-text/textbuffer.c index ad1b06f6..24ee62bc 100644 --- a/src/fe-text/textbuffer.c +++ b/src/fe-text/textbuffer.c @@ -322,6 +322,10 @@ void textbuffer_line_add_colors(TEXT_BUFFER_REC *buffer, LINE_REC **line, data[pos++] = 0; data[pos++] = LINE_CMD_BOLD; } + if ((flags & GUI_PRINT_FLAG_ITALIC) != (buffer->last_flags & GUI_PRINT_FLAG_ITALIC)) { + data[pos++] = 0; + data[pos++] = LINE_CMD_ITALIC; + } if (flags & GUI_PRINT_FLAG_INDENT) { data[pos++] = 0; data[pos++] = LINE_CMD_INDENT; @@ -501,6 +505,10 @@ void textbuffer_line2text(LINE_REC *line, int coloring, GString *str) g_string_append_printf(str, "\004%c", FORMAT_STYLE_BOLD); break; + case LINE_CMD_ITALIC: + g_string_append_printf(str, "\004%c", + FORMAT_STYLE_ITALIC); + break; case LINE_CMD_COLOR0: g_string_append_printf(str, "\004%c%c", '0', FORMAT_COLOR_NOCHANGE); diff --git a/src/fe-text/textbuffer.h b/src/fe-text/textbuffer.h index 6123ba7a..eacfd447 100644 --- a/src/fe-text/textbuffer.h +++ b/src/fe-text/textbuffer.h @@ -17,6 +17,7 @@ enum { LINE_CMD_INDENT, /* if line is split, indent it at this position */ LINE_CMD_BLINK, /* enable/disable blink */ LINE_CMD_BOLD, /* enable/disable bold */ + LINE_CMD_ITALIC, /* enable/disable italic */ LINE_COLOR_EXT, /* extended color */ LINE_COLOR_EXT_BG, /* extended bg */ #ifdef TERM_TRUECOLOR