less/backport-makecheck-0028-Handle-fg-and-bg-colors.patch

325 lines
10 KiB
Diff
Raw Normal View History

From 2494a2e0828804eeca0da47d0c35e29c9a5be183 Mon Sep 17 00:00:00 2001
From: Mark Nudelman <markn@greenwoodsoftware.com>
Date: Tue, 18 Oct 2022 16:15:27 -0700
Subject: [PATCH 24/48] Handle fg and bg colors.
---
lesstest/display.c | 46 ++++++++++---------------
lesstest/lesstest.h | 1 +
lesstest/lt_screen.c | 80 ++++++++++++++++++++++++++++++++------------
lesstest/lt_types.h | 3 +-
lesstest/term.c | 1 +
5 files changed, 81 insertions(+), 50 deletions(-)
diff --git a/lesstest/display.c b/lesstest/display.c
index 54ae7c5..2a8f030 100644
--- a/lesstest/display.c
+++ b/lesstest/display.c
@@ -3,16 +3,12 @@
extern TermInfo terminfo;
-static void display_attr(Attr attr) {
- static Attr prev_attr = 0;
- if (prev_attr & ATTR_STANDOUT)
- printf("%s", terminfo.exit_standout);
- if (prev_attr & ATTR_BLINK)
- printf("%s", terminfo.exit_blink);
- if (prev_attr & ATTR_BOLD)
- printf("%s", terminfo.exit_bold);
- if (prev_attr & ATTR_UNDERLINE)
- printf("%s", terminfo.exit_underline);
+static void display_attr_color(Attr attr, Color fg_color, Color bg_color) {
+ printf("%s", terminfo.exit_all_modes);
+ if (fg_color != NULL_COLOR)
+ printf("\33[%dm", fg_color);
+ if (bg_color != NULL_COLOR)
+ printf("\33[%dm", bg_color);
if (attr & ATTR_UNDERLINE)
printf("%s", terminfo.enter_underline);
if (attr & ATTR_BOLD)
@@ -21,14 +17,6 @@ static void display_attr(Attr attr) {
printf("%s", terminfo.enter_blink);
if (attr & ATTR_STANDOUT)
printf("%s", terminfo.enter_standout);
- prev_attr = attr;
-}
-
-static void display_color(Color color) {
- if (color == NULL_COLOR)
- printf("\33[m");
- else
- printf("\33[%dm", color);
}
void display_screen(const byte* img, int imglen, int screen_width, int screen_height) {
@@ -38,7 +26,8 @@ void display_screen(const byte* img, int imglen, int screen_width, int screen_he
int cursor_y = 0;
int literal = 0;
Attr curr_attr = 0;
- Color curr_color = NULL_COLOR;
+ Color curr_fg_color = NULL_COLOR;
+ Color curr_bg_color = NULL_COLOR;
while (imglen-- > 0) {
wchar ch = load_wchar(&img);
if (!literal) {
@@ -48,15 +37,15 @@ void display_screen(const byte* img, int imglen, int screen_width, int screen_he
continue;
case LTS_CHAR_ATTR:
curr_attr = *img++;
- display_attr(curr_attr);
- if (curr_color != NULL_COLOR)
- display_color(curr_color);
+ display_attr_color(curr_attr, curr_fg_color, curr_bg_color);
+ continue;
+ case LTS_CHAR_FG_COLOR:
+ curr_fg_color = *img++;
+ display_attr_color(curr_attr, curr_fg_color, curr_bg_color);
continue;
- case LTS_CHAR_COLOR:
- curr_color = *img++;
- display_color(curr_color);
- if (curr_attr != 0)
- display_attr(curr_attr);
+ case LTS_CHAR_BG_COLOR:
+ curr_bg_color = *img++;
+ display_attr_color(curr_attr, curr_fg_color, curr_bg_color);
continue;
case LTS_CHAR_CURSOR:
cursor_x = x;
@@ -94,7 +83,8 @@ void display_screen_debug(const byte* img, int imglen, int screen_width, int scr
literal = 1;
continue;
case LTS_CHAR_ATTR:
- case LTS_CHAR_COLOR:
+ case LTS_CHAR_FG_COLOR:
+ case LTS_CHAR_BG_COLOR:
x -= 2; // don't count LTS_CHAR or following byte
literal = 1;
break;
diff --git a/lesstest/lesstest.h b/lesstest/lesstest.h
index 93bbed3..dab0fa8 100644
--- a/lesstest/lesstest.h
+++ b/lesstest/lesstest.h
@@ -44,6 +44,7 @@ typedef struct TermInfo {
char* exit_blink;
char* enter_standout;
char* exit_standout;
+ char* exit_all_modes;
char* clear_screen;
char* cursor_move;
char* key_right;
diff --git a/lesstest/lt_screen.c b/lesstest/lt_screen.c
index 2805289..723a0e9 100644
--- a/lesstest/lt_screen.c
+++ b/lesstest/lt_screen.c
@@ -21,7 +21,8 @@ int usage(void) {
typedef struct ScreenChar {
wchar ch;
Attr attr;
- Color color;
+ Color fg_color;
+ Color bg_color;
} ScreenChar;
typedef struct ScreenState {
@@ -31,7 +32,8 @@ typedef struct ScreenState {
int cx;
int cy;
Attr curr_attr;
- Color curr_color;
+ Color curr_fg_color;
+ Color curr_bg_color;
int param_top;
int params[MAX_PARAMS+1];
int in_esc;
@@ -52,15 +54,19 @@ static void screen_init(void) {
screen.cy = 0;
screen.in_esc = 0;
screen.curr_attr = 0;
- screen.curr_color = NULL_COLOR;
+ screen.curr_fg_color = screen.curr_bg_color = NULL_COLOR;
screen.param_top = -1;
screen.params[0] = 0;
}
+static int num_params(void) {
+ return screen.param_top+1;
+}
+
static void param_print(void) {
int i;
fprintf(stderr, "(");
- for (i = 0; i <= screen.param_top; ++i)
+ for (i = 0; i < num_params(); ++i)
fprintf(stderr, "%d ", screen.params[i]);
fprintf(stderr, ")");
}
@@ -76,7 +82,7 @@ static void param_clear(void) {
}
static int param_pop(void){
- if (screen.param_top < 0)
+ if (num_params() == 0)
return -1; // missing param
return screen.params[screen.param_top--];
}
@@ -110,16 +116,17 @@ static int screen_incr(int* px, int* py) {
return 1;
}
-static void screen_char_set(int x, int y, wchar ch, Attr attr, Color color) {
+static void screen_char_set(int x, int y, wchar ch, Attr attr, Color fg_color, Color bg_color) {
ScreenChar* sc = screen_char(x, y);
sc->ch = ch;
sc->attr = attr;
- sc->color = color;
+ sc->fg_color = fg_color;
+ sc->bg_color = bg_color;
}
static int screen_clear(int x, int y, int count) {
while (count-- > 0) {
- screen_char_set(x, y, '_', 0, NULL_COLOR);
+ screen_char_set(x, y, '_', 0, NULL_COLOR, NULL_COLOR);
screen_incr(&x, &y);
}
return 1;
@@ -128,7 +135,8 @@ static int screen_clear(int x, int y, int count) {
static int screen_read(int x, int y, int count) {
//write(ttyout, "$|", 2);
Attr attr = 0;
- int color = NULL_COLOR;
+ int fg_color = NULL_COLOR;
+ int bg_color = NULL_COLOR;
while (count-- > 0) {
byte buf[32];
byte* bufp = buf;
@@ -138,14 +146,19 @@ static int screen_read(int x, int y, int count) {
*bufp++ = LTS_CHAR_ATTR;
*bufp++ = attr;
}
- if (sc->color != color) {
- color = sc->color;
- *bufp++ = LTS_CHAR_COLOR;
- *bufp++ = color;
+ if (sc->fg_color != fg_color) {
+ fg_color = sc->fg_color;
+ *bufp++ = LTS_CHAR_FG_COLOR;
+ *bufp++ = fg_color;
+ }
+ if (sc->bg_color != bg_color) {
+ bg_color = sc->bg_color;
+ *bufp++ = LTS_CHAR_BG_COLOR;
+ *bufp++ = bg_color;
}
if (x == screen.cx && y == screen.cy)
*bufp++ = LTS_CHAR_CURSOR;
- if (sc->ch == '\\' || sc->ch == LTS_CHAR_ATTR || sc->ch == LTS_CHAR_COLOR || sc->ch == LTS_CHAR_CURSOR)
+ if (sc->ch == '\\' || sc->ch == LTS_CHAR_ATTR || sc->ch == LTS_CHAR_FG_COLOR || sc->ch == LTS_CHAR_BG_COLOR || sc->ch == LTS_CHAR_CURSOR)
*bufp++ = '\\';
store_wchar(&bufp, sc->ch);
write(ttyout, buf, bufp-buf);
@@ -199,9 +212,28 @@ static int screen_clear_attr(int attr) {
}
static int screen_set_color(int color) {
- screen.curr_color = (color >= 0) ? color : NULL_COLOR;
- if (verbose) fprintf(stderr, "[%d,%d] set_color(%d)=%d\n", screen.cx, screen.cy, color, screen.curr_color);
- return 1;
+ int ret = 0;
+ switch (color) {
+ case 1: ret = screen_set_attr(ATTR_BOLD); break;
+ case 4: ret = screen_set_attr(ATTR_UNDERLINE); break;
+ case 5:
+ case 6: ret = screen_set_attr(ATTR_BLINK); break;
+ case 7: ret = screen_set_attr(ATTR_STANDOUT); break;
+ case 22: ret = screen_clear_attr(ATTR_BOLD); break;
+ case 24: ret = screen_clear_attr(ATTR_UNDERLINE); break;
+ default:
+ if (color < 0)
+ screen.curr_fg_color = screen.curr_bg_color = NULL_COLOR;
+ else if ((color >= 30 && color <= 37) || (color >= 90 && color <= 97))
+ screen.curr_fg_color = color;
+ else if ((color >= 40 && color <= 47) || (color >= 100 && color <= 107))
+ screen.curr_bg_color = color;
+ else
+ fprintf(stderr, "unrecognized color %d\n", color);
+ if (verbose) fprintf(stderr, "[%d,%d] set_color(%d)=%d/%d\n", screen.cx, screen.cy, color, screen.curr_fg_color, screen.curr_bg_color);
+ break;
+ }
+ return ret;
}
// ------------------------------------------------------------------
@@ -269,7 +301,13 @@ static int exec_esc(wchar ch) {
case 'E': // exit bold/blink
return screen_clear_attr(ATTR_BOLD|ATTR_BLINK);
case 'm': // set color
- return screen_set_color(param_pop());
+ if (num_params() == 0) {
+ screen_set_color(-1);
+ } else {
+ while (num_params() > 0)
+ screen_set_color(param_pop());
+ }
+ return 0;
case '?': // print version string
write(ttyout, version, strlen(version));
return 1;
@@ -280,14 +318,14 @@ static int exec_esc(wchar ch) {
static int add_char(wchar ch) {
//if (verbose) fprintf(stderr, "add (%c) %lx at %d,%d\n", (char)ch, (long)ch, screen.cx, screen.cy);
- screen_char_set(screen.cx, screen.cy, ch, screen.curr_attr, screen.curr_color);
+ screen_char_set(screen.cx, screen.cy, ch, screen.curr_attr, screen.curr_fg_color, screen.curr_bg_color);
int fits = 1;
int zero_width = (is_composing_char(ch) ||
(screen.cx > 0 && is_combining_char(screen_char(screen.cx-1,screen.cy)->ch, ch)));
if (!zero_width) {
fits = screen_incr(&screen.cx, &screen.cy);
if (fits && is_wide_char(ch)) {
- screen_char_set(screen.cx, screen.cy, 0, 0, NULL_COLOR);
+ screen_char_set(screen.cx, screen.cy, 0, 0, NULL_COLOR, NULL_COLOR);
fits = screen_incr(&screen.cx, &screen.cy);
}
}
@@ -303,7 +341,7 @@ static int process_char(wchar ch) {
int ok = 1;
if (screen.in_esc) {
if (ch >= '0' && ch <= '9') {
- int d = (screen.param_top < 0) ? 0 : screen.params[screen.param_top--];
+ int d = (num_params() == 0) ? 0 : screen.params[screen.param_top--];
param_push(10 * d + ch - '0');
} else if (ch == ';') {
param_push(0);
diff --git a/lesstest/lt_types.h b/lesstest/lt_types.h
index 2015582..a2cae31 100644
--- a/lesstest/lt_types.h
+++ b/lesstest/lt_types.h
@@ -21,7 +21,8 @@ typedef unsigned char Color;
#define RUN_ERR 1
#define LTS_CHAR_ATTR '@'
-#define LTS_CHAR_COLOR '$'
+#define LTS_CHAR_FG_COLOR '$'
+#define LTS_CHAR_BG_COLOR '!'
#define LTS_CHAR_CURSOR '#'
#define is_ascii(ch) ((ch) >= ' ' && (ch) < 0x7f)
diff --git a/lesstest/term.c b/lesstest/term.c
index db294a6..b244f3e 100644
--- a/lesstest/term.c
+++ b/lesstest/term.c
@@ -50,6 +50,7 @@ int setup_term(void) {
setup_mode("us", "ue", &terminfo.enter_underline, &terminfo.exit_underline, &sp);
setup_mode("md", "me", &terminfo.enter_bold, &terminfo.exit_bold, &sp);
setup_mode("mb", "me", &terminfo.enter_blink, &terminfo.exit_blink, &sp);
+ terminfo.exit_all_modes = terminfo.exit_bold;
terminfo.cursor_move = tgetstr("cm", &sp);
if (terminfo.cursor_move == NULL) terminfo.cursor_move = "";
terminfo.clear_screen = tgetstr("cl", &sp);
--
2.27.0