grid: attributes now track whether we've set a foreground/background color

This means we don't have to explicitly set the foreground/background
to the grid's default colors whenever we reset/clear a cell, and we
can instead simply memset() the entire cell to 0.

This also means the renderer has to get the default color when
rendering a cell without a foreground/background color set.
This commit is contained in:
Daniel Eklöf 2019-06-26 19:44:31 +02:00
parent 97420f13d8
commit 3a97fce6d0
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 25 additions and 21 deletions

26
csi.c
View file

@ -75,14 +75,8 @@ param_get(const struct terminal *term, size_t idx, int default_value)
static void static void
sgr_reset(struct terminal *term) sgr_reset(struct terminal *term)
{ {
term->vt.attrs.bold = false; memset(&term->vt.attrs, 0, sizeof(term->vt.attrs));
term->vt.dim = false; term->vt.dim = false;
term->vt.attrs.italic = false;
term->vt.attrs.underline = false;
term->vt.attrs.strikethrough = false;
term->vt.attrs.blink = false;
term->vt.attrs.conceal = false;
term->vt.attrs.reverse = false;
term->vt.attrs.foreground = term->grid.foreground; term->vt.attrs.foreground = term->grid.foreground;
term->vt.attrs.background = term->grid.background; term->vt.attrs.background = term->grid.background;
} }
@ -130,6 +124,7 @@ csi_sgr(struct terminal *term)
case 35: case 35:
case 36: case 36:
case 37: case 37:
term->vt.attrs.have_foreground = true;
term->vt.attrs.foreground = colors_regular[param - 30]; term->vt.attrs.foreground = colors_regular[param - 30];
break; break;
@ -139,6 +134,7 @@ csi_sgr(struct terminal *term)
{ {
size_t idx = term->vt.params.v[i + 2].value; size_t idx = term->vt.params.v[i + 2].value;
term->vt.attrs.foreground = colors256[idx]; term->vt.attrs.foreground = colors256[idx];
term->vt.attrs.have_foreground = true;
i += 2; i += 2;
} else if (term->vt.params.idx - i - 1 == 4 && } else if (term->vt.params.idx - i - 1 == 4 &&
term->vt.params.v[i + 1].value == 2) term->vt.params.v[i + 1].value == 2)
@ -147,6 +143,7 @@ csi_sgr(struct terminal *term)
uint32_t g = term->vt.params.v[i + 3].value; uint32_t g = term->vt.params.v[i + 3].value;
uint32_t b = term->vt.params.v[i + 4].value; uint32_t b = term->vt.params.v[i + 4].value;
term->vt.attrs.foreground = r << 24 | g << 16 | b << 8 | 0xff; term->vt.attrs.foreground = r << 24 | g << 16 | b << 8 | 0xff;
term->vt.attrs.have_foreground = true;
i += 4; i += 4;
} else { } else {
LOG_ERR("invalid CSI SGR sequence"); LOG_ERR("invalid CSI SGR sequence");
@ -154,7 +151,10 @@ csi_sgr(struct terminal *term)
} }
break; break;
} }
case 39: term->vt.attrs.foreground = term->grid.foreground; break; case 39:
term->vt.attrs.foreground = term->grid.foreground;
term->vt.attrs.have_foreground = false;
break;
/* Regular background colors */ /* Regular background colors */
case 40: case 40:
@ -166,6 +166,7 @@ csi_sgr(struct terminal *term)
case 46: case 46:
case 47: case 47:
term->vt.attrs.background = colors_regular[param - 40]; term->vt.attrs.background = colors_regular[param - 40];
term->vt.attrs.have_background = true;
break; break;
case 48: { case 48: {
@ -174,6 +175,7 @@ csi_sgr(struct terminal *term)
{ {
size_t idx = term->vt.params.v[i + 2].value; size_t idx = term->vt.params.v[i + 2].value;
term->vt.attrs.background = colors256[idx]; term->vt.attrs.background = colors256[idx];
term->vt.attrs.have_background = true;
i += 2; i += 2;
} else if (term->vt.params.idx - i - 1 == 4 && } else if (term->vt.params.idx - i - 1 == 4 &&
term->vt.params.v[i + 1].value == 2) term->vt.params.v[i + 1].value == 2)
@ -182,6 +184,7 @@ csi_sgr(struct terminal *term)
uint32_t g = term->vt.params.v[i + 3].value; uint32_t g = term->vt.params.v[i + 3].value;
uint32_t b = term->vt.params.v[i + 4].value; uint32_t b = term->vt.params.v[i + 4].value;
term->vt.attrs.background = r << 24 | g << 16 | b << 8 | 0xff; term->vt.attrs.background = r << 24 | g << 16 | b << 8 | 0xff;
term->vt.attrs.have_background = true;
i += 4; i += 4;
} else { } else {
LOG_ERR("invalid CSI SGR sequence"); LOG_ERR("invalid CSI SGR sequence");
@ -189,7 +192,10 @@ csi_sgr(struct terminal *term)
} }
break; break;
} }
case 49: term->vt.attrs.background = term->grid.background; break; case 49:
term->vt.attrs.background = term->grid.background;
term->vt.attrs.have_background = false;
break;
/* Bright foreground colors */ /* Bright foreground colors */
case 90: case 90:
@ -201,6 +207,7 @@ csi_sgr(struct terminal *term)
case 96: case 96:
case 97: case 97:
term->vt.attrs.foreground = colors_bright[param - 90]; term->vt.attrs.foreground = colors_bright[param - 90];
term->vt.attrs.have_foreground = true;
break; break;
/* Regular background colors */ /* Regular background colors */
@ -213,6 +220,7 @@ csi_sgr(struct terminal *term)
case 106: case 106:
case 107: case 107:
term->vt.attrs.background = colors_bright[param - 100]; term->vt.attrs.background = colors_bright[param - 100];
term->vt.attrs.have_background = true;
break; break;
default: default:

8
grid.c
View file

@ -187,14 +187,6 @@ grid_erase(struct grid *grid, int start, int end)
{ {
assert(end >= start); assert(end >= start);
memset(&grid->cells[start], 0, (end - start) * sizeof(grid->cells[0])); memset(&grid->cells[start], 0, (end - start) * sizeof(grid->cells[0]));
for (int i = start; i < end; i++) {
struct cell *cell = &grid->cells[i];
cell->attrs.foreground = grid->foreground;
cell->attrs.background = grid->background;
}
grid_damage_erase(grid, start, end - start); grid_damage_erase(grid, start, end - start);
} }

6
main.c
View file

@ -102,8 +102,10 @@ grid_render_update(struct context *c, struct buffer *buf, const struct damage *d
int width = c->term.grid.cell_width; int width = c->term.grid.cell_width;
int height = c->term.grid.cell_height; int height = c->term.grid.cell_height;
uint32_t foreground = cell->attrs.foreground; uint32_t foreground = cell->attrs.have_foreground
uint32_t background = cell->attrs.background; ? cell->attrs.foreground : c->term.grid.foreground;
uint32_t background = cell->attrs.have_background
? cell->attrs.background : c->term.grid.background;
if (has_cursor) { if (has_cursor) {
uint32_t swap = foreground; uint32_t swap = foreground;

View file

@ -19,8 +19,10 @@ struct attributes {
bool blink; bool blink;
bool conceal; bool conceal;
bool reverse; bool reverse;
uint32_t foreground; bool have_foreground;
uint32_t background; bool have_background;
uint32_t foreground; /* Only valid when have_foreground == true */
uint32_t background; /* Only valid when have_background == true */
}; };
struct cell { struct cell {