From 2fe17aa889a4b0f68475aec03b8eec7288442375 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Tue, 18 Sep 2018 08:49:41 +0900 Subject: [PATCH] cursor_as_sgr now works on GPUCells becomes cell_as_sgr --- kitty/cursor.c | 36 +++++++++++++++++++++++++----------- kitty/data-types.h | 2 +- kitty/line.c | 25 +++++++++++++------------ kitty/screen.c | 9 +++++++-- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/kitty/cursor.c b/kitty/cursor.c index 7c28d1e98..4e3982666 100644 --- a/kitty/cursor.c +++ b/kitty/cursor.c @@ -238,23 +238,37 @@ decoration_as_sgr(uint8_t decoration) { } const char* -cursor_as_sgr(Cursor *self, Cursor *prev) { +cell_as_sgr(GPUCell *cell, GPUCell *prev) { static char buf[128]; #define SZ sizeof(buf) - (p - buf) - 2 #define P(fmt, ...) { p += snprintf(p, SZ, fmt ";", __VA_ARGS__); } char *p = buf; - bool intensity_differs = self->bold != prev->bold || self->dim != prev->dim; +#define CMP(attr) (attr(cell) != attr(prev)) +#define BOLD(cell) (cell->attrs & (1 << BOLD_SHIFT)) +#define DIM(cell) (cell->attrs & (1 << DIM_SHIFT)) +#define ITALIC(cell) (cell->attrs & (1 << ITALIC_SHIFT)) +#define REVERSE(cell) (cell->attrs & (1 << REVERSE_SHIFT)) +#define STRIKETHROUGH(cell) (cell->attrs & (1 << STRIKE_SHIFT)) +#define DECORATION(cell) (cell->attrs & (DECORATION_MASK << DECORATION_SHIFT)) + bool intensity_differs = CMP(BOLD) || CMP(DIM); if (intensity_differs) { - if (!self->bold && !self->dim) { P("%d", 22); } - else { if (self->bold) P("%d", 1); if (self->dim) P("%d", 2); } + if (!BOLD(cell) && !DIM(cell)) { P("%d", 22); } + else { if (BOLD(cell)) P("%d", 1); if (DIM(cell)) P("%d", 2); } } - if (self->italic != prev->italic) P("%d", self->italic ? 3 : 23); - if (self->reverse != prev->reverse) P("%d", self->reverse ? 7 : 27); - if (self->strikethrough != prev->strikethrough) P("%d", self->strikethrough ? 9 : 29); - if (self->decoration != prev->decoration) P("%s", decoration_as_sgr(self->decoration)); - if (self->fg != prev->fg) p += color_as_sgr(p, SZ, self->fg, 30, 90, 38); - if (self->bg != prev->bg) p += color_as_sgr(p, SZ, self->bg, 40, 100, 48); - if (self->decoration_fg != prev->decoration_fg) p += color_as_sgr(p, SZ, self->decoration_fg, 0, 0, DECORATION_FG_CODE); + if (CMP(ITALIC)) P("%d", ITALIC(cell) ? 3 : 23); + if (CMP(REVERSE)) P("%d", REVERSE(cell) ? 7 : 27); + if (CMP(STRIKETHROUGH)) P("%d", STRIKETHROUGH(cell) ? 9 : 29); + if (cell->fg != prev->fg) p += color_as_sgr(p, SZ, cell->fg, 30, 90, 38); + if (cell->bg != prev->bg) p += color_as_sgr(p, SZ, cell->bg, 40, 100, 48); + if (cell->decoration_fg != prev->decoration_fg) p += color_as_sgr(p, SZ, cell->decoration_fg, 0, 0, DECORATION_FG_CODE); + if (CMP(DECORATION)) P("%s", decoration_as_sgr((cell->attrs >> DECORATION_SHIFT) & DECORATION_MASK)); +#undef CMP +#undef BOLD +#undef DIM +#undef ITALIC +#undef REVERSE +#undef STRIKETHROUGH +#undef DECORATION #undef P #undef SZ if (p > buf) *(p - 1) = 0; // remove trailing semi-colon diff --git a/kitty/data-types.h b/kitty/data-types.h index a7519a3ee..c3d5b2c76 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -276,7 +276,7 @@ void cursor_copy_to(Cursor *src, Cursor *dest); void cursor_reset_display_attrs(Cursor*); void cursor_from_sgr(Cursor *self, unsigned int *params, unsigned int count); void apply_sgr_to_cells(GPUCell *first_cell, unsigned int cell_count, unsigned int *params, unsigned int count); -const char* cursor_as_sgr(Cursor*, Cursor*); +const char* cell_as_sgr(GPUCell *, GPUCell *); double monotonic(); PyObject* cm_thread_write(PyObject *self, PyObject *args); diff --git a/kitty/line.c b/kitty/line.c index 7ae5cf7af..74330535b 100644 --- a/kitty/line.c +++ b/kitty/line.c @@ -235,33 +235,34 @@ line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen) { if (limit == 0) return 0; char_type previous_width = 0; - Cursor c1 = {{0}}, c2 = {{0}}; - Cursor *cursor = &c1, *prev_cursor = &c2; - char_type prev_attrs = 0; + GPUCell blank_cell = { 0 }; + GPUCell *cell, *prev_cell = &blank_cell; for (index_type pos=0; pos < limit; pos++) { - bool need_sgr = false; - char_type attrs = self->gpu_cells[pos].attrs, ch = self->cpu_cells[pos].ch; + char_type ch = self->cpu_cells[pos].ch; if (ch == 0) { if (previous_width == 2) { previous_width = 0; continue; } ch = ' '; } - if (attrs != prev_attrs) { ATTRS_TO_CURSOR(attrs, cursor); need_sgr = true; prev_attrs = attrs; } -#define CMPSET(color) if (cursor->color != self->gpu_cells[pos].color) { cursor->color = self->gpu_cells[pos].color; need_sgr = true; } - CMPSET(fg); CMPSET(bg); CMPSET(decoration_fg); - if (need_sgr) { - const char *sgr = cursor_as_sgr(cursor, prev_cursor); - *prev_cursor = *cursor; + cell = &self->gpu_cells[pos]; + +#define CMP_ATTRS (cell->attrs & ATTRS_MASK_WITHOUT_WIDTH) != (prev_cell->attrs & ATTRS_MASK_WITHOUT_WIDTH) +#define CMP(x) cell->x != prev_cell->x + if (CMP_ATTRS || CMP(fg) || CMP(bg) || CMP(decoration_fg)) { + const char *sgr = cell_as_sgr(cell, prev_cell); if (*sgr) WRITE_SGR(sgr); } + prev_cell = cell; WRITE_CH(ch); for(unsigned c = 0; c < arraysz(self->cpu_cells[pos].cc_idx) && self->cpu_cells[pos].cc_idx[c]; c++) { WRITE_CH(codepoint_for_mark(self->cpu_cells[pos].cc_idx[c])); } - previous_width = attrs & WIDTH_MASK; + previous_width = cell->attrs & WIDTH_MASK; } return i; +#undef CMP_ATTRS +#undef CMP #undef WRITE_SGR #undef WRITE_CH } diff --git a/kitty/screen.c b/kitty/screen.c index ec8fdf961..5616a5f80 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1406,7 +1406,6 @@ screen_request_capabilities(Screen *self, char c, PyObject *q) { static char buf[128]; int shape = 0; const char *query; - Cursor blank_cursor = {{0}}; switch(c) { case '+': CALLBACK("request_capabilities", "O", q); @@ -1430,7 +1429,13 @@ screen_request_capabilities(Screen *self, char c, PyObject *q) { shape = snprintf(buf, sizeof(buf), "1$r%d q", shape); } else if (strcmp("m", query) == 0) { // SGR - shape = snprintf(buf, sizeof(buf), "1$r%sm", cursor_as_sgr(self->cursor, &blank_cursor)); + GPUCell blank_cell = { 0 }, cursor_cell = { + .attrs = CURSOR_TO_ATTRS(self->cursor, 1), + .fg = self->cursor->fg & COL_MASK, + .bg = self->cursor->bg & COL_MASK, + .decoration_fg = self->cursor->decoration_fg & COL_MASK, + }; + shape = snprintf(buf, sizeof(buf), "1$r%sm", cell_as_sgr(&cursor_cell, &blank_cell)); } else if (strcmp("r", query) == 0) { shape = snprintf(buf, sizeof(buf), "1$r%u;%ur", self->margin_top + 1, self->margin_bottom + 1); } else {