diff --git a/kitty/data-types.h b/kitty/data-types.h index b01dffa8f..8bbb70f35 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -17,8 +17,7 @@ #define MIN(x, y) (((x) > (y)) ? (y) : (x)) typedef Py_UCS4 char_type; -typedef uint64_t color_type; -typedef uint32_t decoration_type; +typedef uint32_t color_type; typedef uint32_t combining_type; typedef unsigned int index_type; @@ -31,7 +30,8 @@ typedef unsigned int index_type; #define SGR_PROTOCOL 2 #define URXVT_PROTOCOL 3 -#define CELL_SIZE (sizeof(char_type) + sizeof(color_type) + sizeof(decoration_type) + sizeof(combining_type)) +#define CELL_FIELD_COUNT 5 +#define CELL_SIZE (CELL_FIELD_COUNT * 4) // The data cell size must be a multiple of 3 #define DATA_CELL_SIZE 2 * 3 @@ -46,8 +46,6 @@ typedef unsigned int index_type; #define REVERSE_SHIFT 6 #define STRIKE_SHIFT 7 #define COL_MASK 0xFFFFFFFF -#define COL_SHIFT 32 -#define HAS_BG_MASK (0xFF << COL_SHIFT) #define CC_MASK 0xFFFF #define CC_SHIFT 16 #define UTF8_ACCEPT 0 @@ -77,7 +75,8 @@ typedef unsigned int index_type; #define COPY_CELL(src, s, dest, d) \ (dest)->chars[d] = (src)->chars[s]; \ - (dest)->colors[d] = (src)->colors[s]; \ + (dest)->fg_colors[d] = (src)->fg_colors[s]; \ + (dest)->bg_colors[d] = (src)->bg_colors[s]; \ (dest)->decoration_fg[d] = (src)->decoration_fg[s]; \ (dest)->combining_chars[d] = (src)->combining_chars[s]; @@ -85,18 +84,17 @@ typedef unsigned int index_type; #define COPY_LINE(src, dest) \ memcpy((dest)->chars, (src)->chars, sizeof(char_type) * MIN((src)->xnum, (dest)->xnum)); \ - memcpy((dest)->colors, (src)->colors, sizeof(color_type) * MIN((src)->xnum, (dest)->xnum)); \ - memcpy((dest)->decoration_fg, (src)->decoration_fg, sizeof(decoration_type) * MIN((src)->xnum, (dest)->xnum)); \ + memcpy((dest)->fg_colors, (src)->fg_colors, sizeof(color_type) * MIN((src)->xnum, (dest)->xnum)); \ + memcpy((dest)->bg_colors, (src)->bg_colors, sizeof(color_type) * MIN((src)->xnum, (dest)->xnum)); \ + memcpy((dest)->decoration_fg, (src)->decoration_fg, sizeof(color_type) * MIN((src)->xnum, (dest)->xnum)); \ memcpy((dest)->combining_chars, (src)->combining_chars, sizeof(combining_type) * MIN((src)->xnum, (dest)->xnum)); -#define CLEAR_LINE(l, at, num) \ - for (index_type i = (at); i < (num); i++) (l)->chars[i] = (1 << ATTRS_SHIFT) | 32; \ - memset((l)->colors, (at), (num) * sizeof(color_type)); \ - memset((l)->decoration_fg, (at), (num) * sizeof(decoration_type)); \ - memset((l)->combining_chars, (at), (num) * sizeof(combining_type)); - -#define COLORS_TO_CURSOR(col, c) \ - c->fg = col & COL_MASK; c->bg = (col >> COL_SHIFT) +#define CLEAR_LINE(l, num) \ + for (index_type i = 0; i < (num); i++) (l)->chars[i] = (1 << ATTRS_SHIFT) | 32; \ + memset((l)->fg_colors, 0, (num) * sizeof(color_type)); \ + memset((l)->bg_colors, 0, (num) * sizeof(color_type)); \ + memset((l)->decoration_fg, 0, (num) * sizeof(color_type)); \ + memset((l)->combining_chars, 0, (num) * sizeof(combining_type)); #define METHOD(name, arg_type) {#name, (PyCFunction)name, arg_type, name##_doc}, @@ -145,8 +143,9 @@ typedef struct { PyObject_HEAD char_type *chars; - color_type *colors; - decoration_type *decoration_fg; + color_type *fg_colors; + color_type *bg_colors; + color_type *decoration_fg; combining_type *combining_chars; index_type xnum, ynum; bool continued; @@ -166,8 +165,9 @@ typedef struct { // Pointers into buf char_type *chars; - color_type *colors; - decoration_type *decoration_fg; + color_type *fg_colors; + color_type *bg_colors; + color_type *decoration_fg; combining_type *combining_chars; } LineBuf; PyTypeObject LineBuf_Type; diff --git a/kitty/history.c b/kitty/history.c index 41efd7d45..cdec6c1b7 100644 --- a/kitty/history.c +++ b/kitty/history.c @@ -72,8 +72,9 @@ init_line(HistoryBuf *self, index_type num, Line *l) { uint8_t *start_ptr = start_of(self, num); l->continued = *start_ptr; l->chars = (char_type*)(start_ptr + 1); - l->colors = (color_type*)(l->chars + self->xnum); - l->decoration_fg = (decoration_type*)(l->colors + self->xnum); + l->fg_colors = (color_type*)(l->chars + self->xnum); + l->bg_colors = (color_type*)(l->fg_colors + self->xnum); + l->decoration_fg = (color_type*)(l->bg_colors + self->xnum); l->combining_chars = (combining_type*)(l->decoration_fg + self->xnum); } diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 93aa92bc5..2cc953c17 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -63,8 +63,9 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { Py_CLEAR(self); } else { self->chars = (char_type*)self->buf; - self->colors = (color_type*)(self->chars + self->block_size); - self->decoration_fg = (decoration_type*)(self->colors + self->block_size); + self->fg_colors = (color_type*)(self->chars + self->block_size); + self->bg_colors = (color_type*)(self->fg_colors + self->block_size); + self->decoration_fg = (color_type*)(self->bg_colors + self->block_size); self->combining_chars = (combining_type*)(self->decoration_fg + self->block_size); self->line->xnum = xnum; for(index_type i = 0; i < ynum; i++) { @@ -89,7 +90,8 @@ dealloc(LineBuf* self) { #define INIT_LINE(lb, l, ynum) \ (l)->chars = (lb)->chars + (ynum) * (lb)->xnum; \ - (l)->colors = (lb)->colors + (ynum) * (lb)->xnum; \ + (l)->fg_colors = (lb)->fg_colors + (ynum) * (lb)->xnum; \ + (l)->bg_colors = (lb)->bg_colors + (ynum) * (lb)->xnum; \ (l)->decoration_fg = (lb)->decoration_fg + (ynum) * (lb)->xnum; \ (l)->combining_chars = (lb)->combining_chars + (ynum) * (lb)->xnum; @@ -150,19 +152,22 @@ static inline int allocate_line_storage(Line *line, bool initialize) { if (initialize) { line->chars = PyMem_Calloc(line->xnum, sizeof(char_type)); - line->colors = PyMem_Calloc(line->xnum, sizeof(color_type)); - line->decoration_fg = PyMem_Calloc(line->xnum, sizeof(decoration_type)); + line->fg_colors = PyMem_Calloc(line->xnum, sizeof(color_type)); + line->bg_colors = PyMem_Calloc(line->xnum, sizeof(color_type)); + line->decoration_fg = PyMem_Calloc(line->xnum, sizeof(color_type)); line->combining_chars = PyMem_Calloc(line->xnum, sizeof(combining_type)); for (index_type i = 0; i < line->xnum; i++) line->chars[i] = (1 << ATTRS_SHIFT) | 32; } else { line->chars = PyMem_Malloc(line->xnum * sizeof(char_type)); - line->colors = PyMem_Malloc(line->xnum * sizeof(color_type)); - line->decoration_fg = PyMem_Malloc(line->xnum * sizeof(decoration_type)); + line->fg_colors = PyMem_Malloc(line->xnum * sizeof(color_type)); + line->bg_colors = PyMem_Malloc(line->xnum * sizeof(color_type)); + line->decoration_fg = PyMem_Malloc(line->xnum * sizeof(color_type)); line->combining_chars = PyMem_Malloc(line->xnum * sizeof(combining_type)); } - if (line->chars == NULL || line->colors == NULL || line->decoration_fg == NULL || line->combining_chars == NULL) { + if (line->chars == NULL || line->fg_colors == NULL || line->bg_colors == NULL || line->decoration_fg == NULL || line->combining_chars == NULL) { PyMem_Free(line->chars); line->chars = NULL; - PyMem_Free(line->colors); line->colors = NULL; + PyMem_Free(line->fg_colors); line->fg_colors = NULL; + PyMem_Free(line->bg_colors); line->bg_colors = NULL; PyMem_Free(line->decoration_fg); line->decoration_fg = NULL; PyMem_Free(line->combining_chars); line->combining_chars = NULL; PyErr_NoMemory(); @@ -210,7 +215,7 @@ copy_line_to(LineBuf *self, PyObject *args) { void linebuf_clear_line(LineBuf *self, index_type y) { Line l; INIT_LINE(self, &l, self->line_map[y]); - CLEAR_LINE(&l, 0, self->xnum); + CLEAR_LINE(&l, self->xnum); self->continued_map[y] = 0; } @@ -295,7 +300,7 @@ void linebuf_insert_lines(LineBuf *self, unsigned int num, unsigned int y, unsig Line l; for (i = y; i < y + num; i++) { INIT_LINE(self, &l, self->line_map[i]); - CLEAR_LINE(&l, 0, self->xnum); + CLEAR_LINE(&l, self->xnum); self->continued_map[i] = 0; } } @@ -330,7 +335,7 @@ linebuf_delete_lines(LineBuf *self, index_type num, index_type y, index_type bot Line l; for (i = ylimit - num; i < ylimit; i++) { INIT_LINE(self, &l, self->line_map[i]); - CLEAR_LINE(&l, 0, self->xnum); + CLEAR_LINE(&l, self->xnum); self->continued_map[i] = 0; } } diff --git a/kitty/line.c b/kitty/line.c index c4a5ae9fb..b2e449326 100644 --- a/kitty/line.c +++ b/kitty/line.c @@ -17,7 +17,8 @@ static void dealloc(Line* self) { if (self->needs_free) { PyMem_Free(self->chars); - PyMem_Free(self->colors); + PyMem_Free(self->fg_colors); + PyMem_Free(self->bg_colors); PyMem_Free(self->decoration_fg); PyMem_Free(self->combining_chars); } @@ -170,9 +171,8 @@ line_as_ansi(Line *self, Py_UCS4 *buf, index_type buflen) { WRITE_SGR(0); break; } } - color_type col = self->colors[pos]; - CHECK_COLOR(fg, col & COL_MASK, 38); - CHECK_COLOR(bg, col >> COL_SHIFT, 48); + CHECK_COLOR(fg, self->fg_colors[pos], 38); + CHECK_COLOR(bg, self->bg_colors[pos], 48); CHECK_COLOR(decoration_fg, self->decoration_fg[pos], DECORATION_FG_CODE); WRITE_CH(ch); char_type cc = self->combining_chars[pos]; @@ -226,15 +226,6 @@ width(Line *self, PyObject *val) { return PyLong_FromUnsignedLong((unsigned long) (attrs & WIDTH_MASK)); } -static PyObject* -basic_cell_data(Line *self, PyObject *val) { -#define basic_cell_data_doc "basic_cell_data(x) -> ch, attrs, colors" - unsigned long x = PyLong_AsUnsignedLong(val); - if (x >= self->xnum) { PyErr_SetString(PyExc_ValueError, "Out of bounds"); return NULL; } - char_type ch = self->chars[x]; - return Py_BuildValue("IBK", (unsigned int)(ch & CHAR_MASK), (unsigned char)(ch >> ATTRS_SHIFT), (unsigned long long)self->colors[x]); -} - void line_add_combining_char(Line *self, uint32_t ch, unsigned int x) { combining_type c = self->combining_chars[x]; if (c & CC_MASK) self->combining_chars[x] = (c & CC_MASK) | ( (ch & CC_MASK) << CC_SHIFT ); @@ -279,12 +270,13 @@ set_text(Line* self, PyObject *args) { return NULL; } attrs = CURSOR_TO_ATTRS(cursor, 1); - color_type col = (cursor->fg & COL_MASK) | ((color_type)(cursor->bg & COL_MASK) << COL_SHIFT); - decoration_type dfg = cursor->decoration_fg & COL_MASK; + color_type fg = (cursor->fg & COL_MASK), bg = cursor->bg & COL_MASK; + color_type dfg = cursor->decoration_fg & COL_MASK; for (index_type i = cursor->x; offset < limit && i < self->xnum; i++, offset++) { self->chars[i] = (PyUnicode_READ(kind, buf, offset) & CHAR_MASK) | attrs; - self->colors[i] = col; + self->fg_colors[i] = fg; + self->bg_colors[i] = bg; self->decoration_fg[i] = dfg; self->combining_chars[i] = 0; } @@ -307,7 +299,7 @@ cursor_from(Line* self, PyObject *args) { ans->x = x; ans->y = y; char_type attrs = self->chars[x] >> ATTRS_SHIFT; ATTRS_TO_CURSOR(attrs, ans); - COLORS_TO_CURSOR(self->colors[x], ans); + ans->fg = self->fg_colors[x]; ans->bg = self->bg_colors[x]; ans->decoration_fg = self->decoration_fg[x] & COL_MASK; return (PyObject*)ans; @@ -335,8 +327,8 @@ clear_text(Line* self, PyObject *args) { void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char) { char_type attrs = CURSOR_TO_ATTRS(cursor, 1); - color_type col = (cursor->fg & COL_MASK) | ((color_type)(cursor->bg & COL_MASK) << COL_SHIFT); - decoration_type dfg = cursor->decoration_fg & COL_MASK; + color_type fg = (cursor->fg & COL_MASK), bg = (cursor->bg & COL_MASK); + color_type dfg = cursor->decoration_fg & COL_MASK; if (!clear_char) attrs = ((attrs >> ATTRS_SHIFT) & ~WIDTH_MASK) << ATTRS_SHIFT; for (index_type i = at; i < self->xnum && i < at + num; i++) { @@ -347,7 +339,7 @@ line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, char_type w = ((self->chars[i] >> ATTRS_SHIFT) & WIDTH_MASK) << ATTRS_SHIFT; self->chars[i] = (self->chars[i] & CHAR_MASK) | attrs | w; } - self->colors[i] = col; + self->fg_colors[i] = fg; self->bg_colors[i] = bg; self->decoration_fg[i] = dfg; } } @@ -407,7 +399,8 @@ line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Curs attrs = (((self->chars[at] >> ATTRS_SHIFT) & ~3) | (width & 3)) << ATTRS_SHIFT; } else { attrs = CURSOR_TO_ATTRS(cursor, width & 3); - self->colors[at] = (cursor->fg & COL_MASK) | ((color_type)(cursor->bg & COL_MASK) << COL_SHIFT); + self->fg_colors[at] = (cursor->fg & COL_MASK); + self->bg_colors[at] = (cursor->bg & COL_MASK); self->decoration_fg[at] = cursor->decoration_fg & COL_MASK; } self->chars[at] = (ch & CHAR_MASK) | attrs; @@ -449,8 +442,9 @@ __len__(PyObject *self) { static int __eq__(Line *a, Line *b) { return a->xnum == b->xnum && \ memcmp(a->chars, b->chars, sizeof(char_type) * a->xnum) == 0 && \ - memcmp(a->colors, b->colors, sizeof(color_type) * a->xnum) == 0 && \ - memcmp(a->decoration_fg, b->decoration_fg, sizeof(decoration_type) * a->xnum) == 0 && \ + memcmp(a->fg_colors, b->fg_colors, sizeof(color_type) * a->xnum) == 0 && \ + memcmp(a->bg_colors, b->bg_colors, sizeof(color_type) * a->xnum) == 0 && \ + memcmp(a->decoration_fg, b->decoration_fg, sizeof(color_type) * a->xnum) == 0 && \ memcmp(a->combining_chars, b->combining_chars, sizeof(combining_type) * a->xnum) == 0; } @@ -483,7 +477,6 @@ static PyMethodDef methods[] = { METHOD(as_ansi, METH_NOARGS) METHOD(is_continued, METH_NOARGS) METHOD(width, METH_O) - METHOD(basic_cell_data, METH_O) {NULL} /* Sentinel */ }; @@ -522,7 +515,8 @@ copy_char(Line* self, PyObject *args) { return NULL; } to->chars[dest] = self->chars[src]; - to->colors[dest] = self->colors[src]; + to->fg_colors[dest] = self->fg_colors[src]; + to->bg_colors[dest] = self->bg_colors[src]; to->decoration_fg[dest] = self->decoration_fg[src]; to->combining_chars[dest] = self->combining_chars[src]; Py_RETURN_NONE; diff --git a/kitty/rewrap.h b/kitty/rewrap.h index 930b97400..2747cb9e7 100644 --- a/kitty/rewrap.h +++ b/kitty/rewrap.h @@ -43,8 +43,9 @@ static inline void copy_range(Line *src, index_type src_at, Line* dest, index_type dest_at, index_type num) { memcpy(dest->chars + dest_at, src->chars + src_at, num * sizeof(char_type)); - memcpy(dest->colors + dest_at, src->colors + src_at, num * sizeof(color_type)); - memcpy(dest->decoration_fg + dest_at, src->decoration_fg + src_at, num * sizeof(decoration_type)); + memcpy(dest->fg_colors + dest_at, src->fg_colors + src_at, num * sizeof(color_type)); + memcpy(dest->bg_colors + dest_at, src->bg_colors + src_at, num * sizeof(color_type)); + memcpy(dest->decoration_fg + dest_at, src->decoration_fg + src_at, num * sizeof(color_type)); memcpy(dest->combining_chars + dest_at, src->combining_chars + src_at, num * sizeof(combining_type)); } diff --git a/kitty/sprites.c b/kitty/sprites.c index 7b7706c59..7ae1e5845 100644 --- a/kitty/sprites.c +++ b/kitty/sprites.c @@ -160,8 +160,8 @@ update_cell_range_data(ScreenModes *modes, SpriteMap *self, Line *line, unsigned data[offset] = sp->x; data[offset+1] = sp->y; data[offset+2] = sp->z; - data[offset+(reverse ? 4 : 3)] = to_color(color_profile, line->colors[i] & COL_MASK, default_fg); - data[offset+(reverse ? 3 : 4)] = to_color(color_profile, line->colors[i] >> COL_SHIFT, default_bg); + data[offset+(reverse ? 4 : 3)] = to_color(color_profile, line->fg_colors[i] & COL_MASK, default_fg); + data[offset+(reverse ? 3 : 4)] = to_color(color_profile, line->bg_colors[i] & COL_MASK, default_bg); unsigned int decoration_fg = to_color(color_profile, line->decoration_fg[i] & COL_MASK, data[offset+3]); data[offset+5] = (decoration_fg & COL_MASK) | (decoration << 24) | (strikethrough << 26); previous_ch = ch; previous_width = (attrs) & WIDTH_MASK;