diff --git a/csi.c b/csi.c index 4d4fdbf1..a85fb5f6 100644 --- a/csi.c +++ b/csi.c @@ -18,6 +18,7 @@ #define min(x, y) ((x) < (y) ? (x) : (y)) +#if 0 static const struct rgb colors_regular[] = { {0.000000, 0.000000, 0.000000}, /* 0x000000 */ {0.800000, 0.576471, 0.576471}, /* 0xcc9393 */ @@ -41,6 +42,31 @@ static const struct rgb colors_bright[] = { }; static struct rgb colors256[256]; +#else +static const uint32_t colors_regular[] = { + 0x000000, + 0xcc9393, + 0x7f9f7f, + 0xd0bf8f, + 0x6ca0a3, + 0xdc8cc3, + 0x93e0e3, + 0xdcdccc, +}; + +static const uint32_t colors_bright[] = { + 0x000000, + 0xdca3a3, + 0xbfebbf, + 0xf0dfaf, + 0x8cd0d3, + 0xdc8cc3, + 0x93e0e3, + 0xffffff, +}; + +static uint32_t colors256[256]; +#endif static void __attribute__((constructor)) initialize_colors256(void) @@ -53,21 +79,31 @@ initialize_colors256(void) for (size_t r = 0; r < 6; r++) { for (size_t g = 0; g < 6; g++) { for (size_t b = 0; b < 6; b++) { +#if 0 colors256[16 + r * 6 * 6 + g * 6 + b] = (struct rgb) { r * 51 / 255.0, g * 51 / 255.0, b * 51 / 255.0, }; +#else + colors256[16 + r * 6 * 6 + g * 6 + b] + = r * 51 << 16 | g * 51 << 8 | b * 51; +#endif } } } for (size_t i = 0; i < 24; i++){ +#if 0 colors256[232 + i] = (struct rgb) { i * 11 / 255.0, i * 11 / 255.0, i * 11 / 255.0, }; +#else + /* TODO: i + 1? */ + colors256[232 + i] = i * 11 << 16 | i * 11 << 8 | i * 11; +#endif } } @@ -152,8 +188,7 @@ csi_sgr(struct terminal *term) case 35: case 36: case 37: - term->vt.attrs.have_foreground = true; - term->vt.attrs.foreground = colors_regular[param - 30]; + term->vt.attrs.foreground = 1 << 31 | colors_regular[param - 30]; break; case 38: { @@ -161,8 +196,7 @@ csi_sgr(struct terminal *term) term->vt.params.v[i + 1].value == 5) { size_t idx = term->vt.params.v[i + 2].value; - term->vt.attrs.foreground = colors256[idx]; - term->vt.attrs.have_foreground = true; + term->vt.attrs.foreground = 1 << 31 | colors256[idx]; i += 2; } @@ -173,12 +207,7 @@ csi_sgr(struct terminal *term) uint8_t r = term->vt.params.v[i + 2].value; uint8_t g = term->vt.params.v[i + 3].value; uint8_t b = term->vt.params.v[i + 4].value; - term->vt.attrs.foreground = (struct rgb) { - r / 255.0, - g / 255.0, - b / 255.0, - }; - term->vt.attrs.have_foreground = true; + term->vt.attrs.foreground = 1 << 31 | r << 16 | g << 8 | b; i += 4; } @@ -194,12 +223,7 @@ csi_sgr(struct terminal *term) /* 6 - CS tolerance */ /* 7 - color space associated with tolerance */ - term->vt.attrs.foreground = (struct rgb) { - r / 255.0, - g / 255.0, - b / 255.0, - }; - term->vt.attrs.have_foreground = true; + term->vt.attrs.foreground = 1 << 31 | r << 16 | g << 8 | b; } else { LOG_ERR("invalid CSI SGR sequence"); abort(); @@ -214,8 +238,7 @@ csi_sgr(struct terminal *term) } case 39: - term->vt.attrs.foreground = term->foreground; - term->vt.attrs.have_foreground = false; + term->vt.attrs.foreground = 0; break; /* Regular background colors */ @@ -227,8 +250,7 @@ csi_sgr(struct terminal *term) case 45: case 46: case 47: - term->vt.attrs.background = colors_regular[param - 40]; - term->vt.attrs.have_background = true; + term->vt.attrs.background = 1 << 31 | colors_regular[param - 40]; break; case 48: { @@ -236,8 +258,7 @@ csi_sgr(struct terminal *term) term->vt.params.v[i + 1].value == 5) { size_t idx = term->vt.params.v[i + 2].value; - term->vt.attrs.background = colors256[idx]; - term->vt.attrs.have_background = true; + term->vt.attrs.background = 1 << 31 | colors256[idx]; i += 2; } @@ -247,12 +268,7 @@ csi_sgr(struct terminal *term) uint8_t r = term->vt.params.v[i + 2].value; uint8_t g = term->vt.params.v[i + 3].value; uint8_t b = term->vt.params.v[i + 4].value; - term->vt.attrs.background = (struct rgb) { - r / 255.0, - g / 255.0, - b / 255.0, - }; - term->vt.attrs.have_background = true; + term->vt.attrs.background = 1 << 31 | r << 16 | g << 8 | b; i += 4; } @@ -269,12 +285,7 @@ csi_sgr(struct terminal *term) /* 6 - CS tolerance */ /* 7 - color space associated with tolerance */ - term->vt.attrs.background = (struct rgb) { - r / 255.0, - g / 255.0, - b / 255.0, - }; - term->vt.attrs.have_background = true; + term->vt.attrs.background = 1 << 31 | r << 16 | g << 8 | b; } else { LOG_ERR("invalid CSI SGR sequence"); abort(); @@ -289,8 +300,7 @@ csi_sgr(struct terminal *term) break; } case 49: - term->vt.attrs.background = term->background; - term->vt.attrs.have_background = false; + term->vt.attrs.background = 0; break; /* Bright foreground colors */ @@ -302,8 +312,7 @@ csi_sgr(struct terminal *term) case 95: case 96: case 97: - term->vt.attrs.foreground = colors_bright[param - 90]; - term->vt.attrs.have_foreground = true; + term->vt.attrs.foreground = 1 << 31 | colors_bright[param - 90]; break; /* Regular background colors */ @@ -315,8 +324,7 @@ csi_sgr(struct terminal *term) case 105: case 106: case 107: - term->vt.attrs.background = colors_bright[param - 100]; - term->vt.attrs.have_background = true; + term->vt.attrs.background = 1 << 31 | colors_bright[param - 100]; break; default: diff --git a/main.c b/main.c index b88d8000..9dde438a 100644 --- a/main.c +++ b/main.c @@ -33,8 +33,13 @@ #define min(x, y) ((x) < (y) ? (x) : (y)) #define max(x, y) ((x) > (y) ? (x) : (y)) +#if 0 static const struct rgb default_foreground = {0.86, 0.86, 0.86}; static const struct rgb default_background = {0.067, 0.067, 0.067}; +#else +static const uint32_t default_foreground = 0xdcdccc; +static const uint32_t default_background = 0x111111; +#endif static void shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) diff --git a/render.c b/render.c index b0afbe2a..afb39f85 100644 --- a/render.c +++ b/render.c @@ -28,7 +28,11 @@ struct glyph_sequence { int count; struct attributes attrs; +#if 0 struct rgb foreground; +#else + uint32_t foreground; +#endif }; static struct glyph_sequence gseq; @@ -68,22 +72,48 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell, } } +#if 0 const struct rgb *foreground = cell->attrs.have_foreground ? &cell->attrs.foreground : !term->reverse ? &term->foreground : &term->background; const struct rgb *background = cell->attrs.have_background ? &cell->attrs.background : !term->reverse ? &term->background : &term->foreground; +#else + uint32_t _foreground = cell->attrs.foreground >> 31 + ? cell->attrs.foreground + : !term->reverse ? term->foreground : term->background; + uint32_t _background = cell->attrs.background >> 31 + ? cell->attrs.background + : !term->reverse ? term->background : term->foreground; +#endif /* If *one* is set, we reverse */ if (has_cursor ^ cell->attrs.reverse ^ is_selected) { +#if 0 const struct rgb *swap = foreground; - foreground = background; - background = swap; +#else + uint32_t swap = _foreground; +#endif + _foreground = _background; + _background = swap; } +#if 0 + struct rgb foreground = { + ((_foreground >> 16) & 0xff) / 255.0, + ((_foreground >> 8) & 0xff) / 255.0, + ((_foreground >> 0) & 0xff) / 255.0, + }; +#endif + struct rgb background = { + ((_background >> 16) & 0xff) / 255.0, + ((_background >> 8) & 0xff) / 255.0, + ((_background >> 0) & 0xff) / 255.0, + }; + /* Background */ - cairo_set_source_rgb(buf->cairo, background->r, background->g, background->b); + cairo_set_source_rgb(buf->cairo, background.r, background.g, background.b); cairo_rectangle(buf->cairo, x, y, width, height); cairo_fill(buf->cairo); @@ -104,22 +134,30 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell, if (memcmp(&cell->attrs, &gseq.attrs, sizeof(cell->attrs)) != 0 || gseq.count >= sizeof(gseq.glyphs) / sizeof(gseq.glyphs[0]) - 10 || - memcmp(&gseq.foreground, foreground, sizeof(*foreground)) != 0) +#if 0 + memcmp(&gseq.foreground, foreground, sizeof(*foreground)) != 0 +#else + gseq.foreground != _foreground +#endif + ) { if (gseq.count >= sizeof(gseq.glyphs) / sizeof(gseq.glyphs[0]) - 10) LOG_WARN("hit glyph limit"); - cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs)); - cairo_set_source_rgb( - buf->cairo, gseq.foreground.r, gseq.foreground.g, - gseq.foreground.b); + struct rgb fg = { + ((gseq.foreground >> 16) & 0xff) / 255.0, + ((gseq.foreground >> 8) & 0xff) / 255.0, + ((gseq.foreground >> 0) & 0xff) / 255.0, + }; + cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs)); + cairo_set_source_rgb(buf->cairo, fg.r, fg.g, fg.b); cairo_show_glyphs(buf->cairo, gseq.glyphs, gseq.count); gseq.g = gseq.glyphs; gseq.count = 0; gseq.attrs = cell->attrs; - gseq.foreground = *foreground; + gseq.foreground = _foreground; } int new_glyphs @@ -225,9 +263,18 @@ grid_render(struct terminal *term) int rmargin_width = term->width - rmargin; int bmargin_height = term->height - bmargin; +#if 0 const struct rgb *bg = !term->reverse ? &term->background : &term->foreground; - cairo_set_source_rgb(buf->cairo, bg->r, bg->g, bg->b); +#else + uint32_t _bg = !term->reverse ? term->background : term->foreground; + struct rgb bg = { + ((_bg >> 16) & 0xff) / 255.0, + ((_bg >> 8) & 0xff) / 255.0, + ((_bg >> 0) & 0xff) / 255.0, + }; +#endif + cairo_set_source_rgb(buf->cairo, bg.r, bg.g, bg.b); cairo_rectangle(buf->cairo, rmargin, 0, rmargin_width, term->height); cairo_rectangle(buf->cairo, 0, bmargin, term->width, bmargin_height); @@ -332,10 +379,14 @@ grid_render(struct terminal *term) } if (gseq.count > 0) { + struct rgb fg = { + ((gseq.foreground >> 16) & 0xff) / 255.0, + ((gseq.foreground >> 8) & 0xff) / 255.0, + ((gseq.foreground >> 0) & 0xff) / 255.0, + }; + cairo_set_scaled_font(buf->cairo, attrs_to_font(term, &gseq.attrs)); - cairo_set_source_rgb( - buf->cairo, gseq.foreground.r, gseq.foreground.g, - gseq.foreground.b); + cairo_set_source_rgb(buf->cairo, fg.r, fg.g, fg.b); cairo_show_glyphs(buf->cairo, gseq.glyphs, gseq.count); } diff --git a/terminal.c b/terminal.c index 5e0f625f..8871c06f 100644 --- a/terminal.c +++ b/terminal.c @@ -72,10 +72,9 @@ erase_cell_range(struct terminal *term, struct row *row, int start, int end) assert(start < term->cols); assert(end < term->cols); - if (unlikely(term->vt.attrs.have_background)) { + if (unlikely(term->vt.attrs.background >> 31)) { for (int col = start; col <= end; col++) { row->cells[col].c[0] = '\0'; - row->cells[col].attrs.have_background = true; row->cells[col].attrs.background = term->vt.attrs.background; } } else { diff --git a/terminal.h b/terminal.h index b2aaee67..5975be85 100644 --- a/terminal.h +++ b/terminal.h @@ -55,14 +55,12 @@ struct attributes { uint8_t italic:1; uint8_t underline:1; uint8_t strikethrough:1; - //uint8_t blink:1; /* Not supported yet, and removing it means all other attributes fit in a single uint8_t */ + uint8_t blink:1; uint8_t conceal:1; uint8_t reverse:1; - uint8_t have_foreground:1; - uint8_t have_background:1; - struct rgb foreground; /* Only valid when have_foreground == true */ - struct rgb background; /* Only valid when have_background == true */ + uint32_t foreground; + uint32_t background; } __attribute__((packed)); struct cell { @@ -236,8 +234,8 @@ struct terminal { bool print_needs_wrap; struct scroll_region scroll_region; - struct rgb foreground; - struct rgb background; + uint32_t foreground; + uint32_t background; struct { int col;