From 327d749ce03d25897447ec36ed4c46c0da4a72cb Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sun, 16 Mar 2025 15:13:39 +0300 Subject: further improved monochrome terminal support: fixed reverse text on reverse backgrounds * Unfortunately we cannot use `wbkgdset(win, A_REVERSE)` if we plan to use reverse text on this background, i.e. if we want to cancel out the background A_REVERSE. * SciTECO therefore no longer uses background attributes, but only foreground attributes. When setting a reverse text, we XOR A_REVERSE into the previous attributes. * This fixes control characters especially in the info line and popups, as well as rendering of the popup scroll bars. * The command-line should now be rendered properly even on a dark-on-bright color theme (which does not yet exist). --- src/interface-curses/curses-utils.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'src/interface-curses/curses-utils.c') diff --git a/src/interface-curses/curses-utils.c b/src/interface-curses/curses-utils.c index 3fd680b..f94b6dc 100644 --- a/src/interface-curses/curses-utils.c +++ b/src/interface-curses/curses-utils.c @@ -48,9 +48,18 @@ guint teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width) { gint truncate_len = teco_ed & TECO_ED_ICONS ? 1 : 3; - int old_x, old_y; gint chars_added = 0; + /* + * The entire background might be in reverse, especially + * on monochrome terminals. + * In those cases, we have to __remove__ the A_REVERSE flag. + */ + attr_t attrs = A_NORMAL; + short pair = 0; + wattr_get(win, &attrs, &pair, NULL); + + int old_x, old_y; getyx(win, old_y, old_x); if (max_width < 0) @@ -72,37 +81,38 @@ teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width) chars_added++; if (chars_added > max_width) goto truncate; - waddch(win, '$' | A_REVERSE); + wattr_set(win, attrs ^ A_REVERSE, pair, NULL); + waddch(win, '$'); break; case '\r': chars_added += 2; if (chars_added > max_width) goto truncate; - waddch(win, 'C' | A_REVERSE); - waddch(win, 'R' | A_REVERSE); + wattr_set(win, attrs ^ A_REVERSE, pair, NULL); + waddstr(win, "CR"); break; case '\n': chars_added += 2; if (chars_added > max_width) goto truncate; - waddch(win, 'L' | A_REVERSE); - waddch(win, 'F' | A_REVERSE); + wattr_set(win, attrs ^ A_REVERSE, pair, NULL); + waddstr(win, "LF"); break; case '\t': chars_added += 3; if (chars_added > max_width) goto truncate; - waddch(win, 'T' | A_REVERSE); - waddch(win, 'A' | A_REVERSE); - waddch(win, 'B' | A_REVERSE); + wattr_set(win, attrs ^ A_REVERSE, pair, NULL); + waddstr(win, "TAB"); break; default: if (TECO_IS_CTL(*str)) { chars_added += 2; if (chars_added > max_width) goto truncate; - waddch(win, '^' | A_REVERSE); - waddch(win, TECO_CTL_ECHO(*str) | A_REVERSE); + wattr_set(win, attrs ^ A_REVERSE, pair, NULL); + waddch(win, '^'); + waddch(win, TECO_CTL_ECHO(*str)); } else { chars_added++; if (chars_added > max_width) @@ -116,6 +126,8 @@ teco_curses_format_str(WINDOW *win, const gchar *str, gsize len, gint max_width) waddnstr(win, str, clen); } } + /* restore original state of A_REVERSE */ + wattr_set(win, attrs, pair, NULL); str += clen; len -= clen; -- cgit v1.2.3