Track sprite positions in the Cell structure
This commit is contained in:
parent
a8d5ad2c1a
commit
c4680aae2c
@ -59,6 +59,7 @@ typedef uint16_t sprite_index;
|
|||||||
#define UTF8_REJECT 1
|
#define UTF8_REJECT 1
|
||||||
#define UNDERCURL_CODE 6
|
#define UNDERCURL_CODE 6
|
||||||
#define DECORATION_FG_CODE 58
|
#define DECORATION_FG_CODE 58
|
||||||
|
#define CHAR_IS_BLANK(ch) ((ch & CHAR_MASK) == 32 || (ch & CHAR_MASK) == 0)
|
||||||
|
|
||||||
#define CURSOR_BLOCK 1
|
#define CURSOR_BLOCK 1
|
||||||
#define CURSOR_BEAM 2
|
#define CURSOR_BEAM 2
|
||||||
@ -130,6 +131,7 @@ typedef struct {
|
|||||||
char_type ch;
|
char_type ch;
|
||||||
color_type fg, bg, decoration_fg;
|
color_type fg, bg, decoration_fg;
|
||||||
combining_type cc;
|
combining_type cc;
|
||||||
|
sprite_index sprite_x, sprite_y, sprite_z;
|
||||||
} Cell;
|
} Cell;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -288,11 +290,16 @@ typedef struct {
|
|||||||
} ChildMonitor;
|
} ChildMonitor;
|
||||||
PyTypeObject ChildMonitor_Type;
|
PyTypeObject ChildMonitor_Type;
|
||||||
|
|
||||||
|
#define clear_sprite_position(cell) (cell).sprite_x = 0; (cell).sprite_y = 0; (cell).sprite_z = 0;
|
||||||
|
|
||||||
#define left_shift_line(line, at, num) \
|
#define left_shift_line(line, at, num) \
|
||||||
for(index_type __i__ = (at); __i__ < (line)->xnum - (num); __i__++) { \
|
for(index_type __i__ = (at); __i__ < (line)->xnum - (num); __i__++) { \
|
||||||
COPY_CELL(line, __i__ + (num), line, __i__) \
|
COPY_CELL(line, __i__ + (num), line, __i__) \
|
||||||
} \
|
} \
|
||||||
if ((((line)->cells[(at)].ch >> ATTRS_SHIFT) & WIDTH_MASK) != 1) (line)->cells[(at)].ch = (1 << ATTRS_SHIFT) | BLANK_CHAR;
|
if ((((line)->cells[(at)].ch >> ATTRS_SHIFT) & WIDTH_MASK) != 1) { \
|
||||||
|
(line)->cells[(at)].ch = (1 << ATTRS_SHIFT) | BLANK_CHAR; \
|
||||||
|
clear_sprite_position((line)->cells[(at)]); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Global functions
|
// Global functions
|
||||||
@ -324,6 +331,7 @@ Cursor* cursor_copy(Cursor*);
|
|||||||
void cursor_copy_to(Cursor *src, Cursor *dest);
|
void cursor_copy_to(Cursor *src, Cursor *dest);
|
||||||
void cursor_reset_display_attrs(Cursor*);
|
void cursor_reset_display_attrs(Cursor*);
|
||||||
bool update_cell_range_data(ScreenModes *modes, Line *, unsigned int, unsigned int, unsigned int *);
|
bool update_cell_range_data(ScreenModes *modes, Line *, unsigned int, unsigned int, unsigned int *);
|
||||||
|
void set_sprite_position(Cell *cell, Cell *previous_cell);
|
||||||
|
|
||||||
PyObject* line_text_at(char_type, combining_type);
|
PyObject* line_text_at(char_type, combining_type);
|
||||||
void line_clear_text(Line *self, unsigned int at, unsigned int num, int ch);
|
void line_clear_text(Line *self, unsigned int at, unsigned int num, int ch);
|
||||||
|
|||||||
24
kitty/line.c
24
kitty/line.c
@ -219,11 +219,14 @@ width(Line *self, PyObject *val) {
|
|||||||
return PyLong_FromUnsignedLong((unsigned long) (attrs & WIDTH_MASK));
|
return PyLong_FromUnsignedLong((unsigned long) (attrs & WIDTH_MASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define set_sprite_position_at(x) set_sprite_position(self->cells + x, x == 0 ? NULL : self->cells + x - 1);
|
||||||
|
|
||||||
void
|
void
|
||||||
line_add_combining_char(Line *self, uint32_t ch, unsigned int x) {
|
line_add_combining_char(Line *self, uint32_t ch, unsigned int x) {
|
||||||
combining_type c = self->cells[x].cc;
|
combining_type c = self->cells[x].cc;
|
||||||
if (c & CC_MASK) self->cells[x].cc = (c & CC_MASK) | ( (ch & CC_MASK) << CC_SHIFT );
|
if (c & CC_MASK) self->cells[x].cc = (c & CC_MASK) | ( (ch & CC_MASK) << CC_SHIFT );
|
||||||
else self->cells[x].cc = ch & CC_MASK;
|
else self->cells[x].cc = ch & CC_MASK;
|
||||||
|
set_sprite_position_at(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
@ -273,6 +276,7 @@ set_text(Line* self, PyObject *args) {
|
|||||||
self->cells[i].bg = bg;
|
self->cells[i].bg = bg;
|
||||||
self->cells[i].decoration_fg = dfg;
|
self->cells[i].decoration_fg = dfg;
|
||||||
self->cells[i].cc = 0;
|
self->cells[i].cc = 0;
|
||||||
|
set_sprite_position_at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@ -302,9 +306,16 @@ cursor_from(Line* self, PyObject *args) {
|
|||||||
void
|
void
|
||||||
line_clear_text(Line *self, unsigned int at, unsigned int num, int ch) {
|
line_clear_text(Line *self, unsigned int at, unsigned int num, int ch) {
|
||||||
const char_type repl = ((char_type)ch & CHAR_MASK) | (1 << ATTRS_SHIFT);
|
const char_type repl = ((char_type)ch & CHAR_MASK) | (1 << ATTRS_SHIFT);
|
||||||
for (index_type i = at; i < MIN(self->xnum, at + num); i++) {
|
#define PREFIX \
|
||||||
self->cells[i].ch = (self->cells[i].ch & ATTRS_MASK_WITHOUT_WIDTH) | repl;
|
for (index_type i = at; i < MIN(self->xnum, at + num); i++) { \
|
||||||
|
self->cells[i].ch = (self->cells[i].ch & ATTRS_MASK_WITHOUT_WIDTH) | repl; \
|
||||||
self->cells[i].cc = 0;
|
self->cells[i].cc = 0;
|
||||||
|
if (CHAR_IS_BLANK(ch)) {
|
||||||
|
PREFIX
|
||||||
|
clear_sprite_position(self->cells[i]); }
|
||||||
|
} else {
|
||||||
|
PREFIX
|
||||||
|
set_sprite_position_at(i)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,9 +340,11 @@ line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num,
|
|||||||
if (clear_char) {
|
if (clear_char) {
|
||||||
self->cells[i].ch = BLANK_CHAR | attrs;
|
self->cells[i].ch = BLANK_CHAR | attrs;
|
||||||
self->cells[i].cc = 0;
|
self->cells[i].cc = 0;
|
||||||
|
clear_sprite_position(self->cells[i]);
|
||||||
} else {
|
} else {
|
||||||
char_type w = ((self->cells[i].ch >> ATTRS_SHIFT) & WIDTH_MASK) << ATTRS_SHIFT;
|
char_type w = ((self->cells[i].ch >> ATTRS_SHIFT) & WIDTH_MASK) << ATTRS_SHIFT;
|
||||||
self->cells[i].ch = (self->cells[i].ch & CHAR_MASK) | attrs | w;
|
self->cells[i].ch = (self->cells[i].ch & CHAR_MASK) | attrs | w;
|
||||||
|
set_sprite_position_at(i);
|
||||||
}
|
}
|
||||||
self->cells[i].fg = fg; self->cells[i].bg = bg;
|
self->cells[i].fg = fg; self->cells[i].bg = bg;
|
||||||
self->cells[i].decoration_fg = dfg;
|
self->cells[i].decoration_fg = dfg;
|
||||||
@ -355,7 +368,10 @@ void line_right_shift(Line *self, unsigned int at, unsigned int num) {
|
|||||||
}
|
}
|
||||||
// Check if a wide character was split at the right edge
|
// Check if a wide character was split at the right edge
|
||||||
char_type w = (self->cells[self->xnum - 1].ch >> ATTRS_SHIFT) & WIDTH_MASK;
|
char_type w = (self->cells[self->xnum - 1].ch >> ATTRS_SHIFT) & WIDTH_MASK;
|
||||||
if (w != 1) self->cells[self->xnum - 1].ch = (1 << ATTRS_SHIFT) | BLANK_CHAR;
|
if (w != 1) {
|
||||||
|
self->cells[self->xnum - 1].ch = (1 << ATTRS_SHIFT) | BLANK_CHAR;
|
||||||
|
clear_sprite_position(self->cells[self->xnum - 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
@ -399,6 +415,8 @@ line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Curs
|
|||||||
}
|
}
|
||||||
self->cells[at].ch = (ch & CHAR_MASK) | attrs;
|
self->cells[at].ch = (ch & CHAR_MASK) | attrs;
|
||||||
self->cells[at].cc = 0;
|
self->cells[at].cc = 0;
|
||||||
|
if (CHAR_IS_BLANK(ch)) { clear_sprite_position(self->cells[at]); }
|
||||||
|
else set_sprite_position_at(at);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
|||||||
@ -8,12 +8,23 @@
|
|||||||
|
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
update_sprites_in_line(Cell *cells, index_type xnum) {
|
||||||
|
if (LIKELY(xnum > 0)) {
|
||||||
|
set_sprite_position(cells, NULL);
|
||||||
|
for (index_type i = 1; i < xnum; i++) {
|
||||||
|
set_sprite_position(cells + i, cells + i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_attribute_on_line(Cell *cells, uint32_t shift, uint32_t val, index_type xnum) {
|
set_attribute_on_line(Cell *cells, uint32_t shift, uint32_t val, index_type xnum) {
|
||||||
uint32_t mask = shift == DECORATION_SHIFT ? 3 : 1;
|
uint32_t mask = shift == DECORATION_SHIFT ? 3 : 1;
|
||||||
uint32_t aval = (val & mask) << (ATTRS_SHIFT + shift);
|
uint32_t aval = (val & mask) << (ATTRS_SHIFT + shift);
|
||||||
mask = ~(mask << (ATTRS_SHIFT + shift));
|
mask = ~(mask << (ATTRS_SHIFT + shift));
|
||||||
for (index_type i = 0; i < xnum; i++) cells[i].ch = (cells[i].ch & mask) | aval;
|
for (index_type i = 0; i < xnum; i++) cells[i].ch = (cells[i].ch & mask) | aval;
|
||||||
|
if (shift == BOLD_SHIFT || shift == ITALIC_SHIFT) update_sprites_in_line(cells, xnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -28,6 +39,7 @@ copy_line(const Line *src, Line *dest) {
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
clear_chars_in_line(Cell *cells, index_type xnum, char_type ch) {
|
clear_chars_in_line(Cell *cells, index_type xnum, char_type ch) {
|
||||||
|
// Clear only the char part of each cell, the rest must have been cleared by a memset or similar
|
||||||
char_type c = (1 << ATTRS_SHIFT) | ch;
|
char_type c = (1 << ATTRS_SHIFT) | ch;
|
||||||
for (index_type i = 0; i < xnum; i++) cells[i].ch = c;
|
for (index_type i = 0; i < xnum; i++) cells[i].ch = c;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,6 +99,21 @@ sprite_map_position_for(char_type ch, combining_type cc, bool is_second, int *er
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
set_sprite_position(Cell *cell, Cell *previous_cell) {
|
||||||
|
SpritePosition *sp;
|
||||||
|
static int error;
|
||||||
|
if (UNLIKELY(previous_cell != NULL && ((previous_cell->ch >> ATTRS_SHIFT) & WIDTH_MASK) == 2)) {
|
||||||
|
sp = sprite_map_position_for(previous_cell->ch, 0, true, &error);
|
||||||
|
} else {
|
||||||
|
sp = sprite_map_position_for(cell->ch, cell->cc, false, &error);
|
||||||
|
}
|
||||||
|
cell->sprite_x = sp->x;
|
||||||
|
cell->sprite_y = sp->y;
|
||||||
|
cell->sprite_z = sp->z;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
sprite_map_increment() {
|
sprite_map_increment() {
|
||||||
#define increment_doc "Increment the current position and return the old (x, y, z) values"
|
#define increment_doc "Increment the current position and return the old (x, y, z) values"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user