mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-06 09:15:57 +02:00
Start work on rewrapping multicells
This commit is contained in:
@@ -84,6 +84,8 @@ typedef struct Rewrap {
|
||||
init_line_func_t init_line;
|
||||
first_dest_line_func_t first_dest_line;
|
||||
next_dest_line_func_t next_dest_line;
|
||||
LineBuf *scratch;
|
||||
bool current_dest_line_has_multiline_cells, current_src_line_has_multline_cells, prev_src_line_ended_with_wrap;
|
||||
} Rewrap;
|
||||
|
||||
static void
|
||||
@@ -93,7 +95,7 @@ copy_range(Line *src, index_type src_at, Line* dest, index_type dest_at, index_t
|
||||
}
|
||||
|
||||
static void
|
||||
init_line(TextCache *tc, index_type xnum, Line *l) {
|
||||
setup_line(TextCache *tc, index_type xnum, Line *l) {
|
||||
l->text_cache = tc;
|
||||
l->xnum = xnum;
|
||||
}
|
||||
@@ -102,6 +104,18 @@ static void
|
||||
next_dest_line(Rewrap *r, bool continued) {
|
||||
r->dest_y = r->next_dest_line(r->dest_buf, r->historybuf, r->as_ansi_buf, &r->src, r->dest_y, &r->dest, continued);
|
||||
r->dest_x = 0;
|
||||
r->current_dest_line_has_multiline_cells = false;
|
||||
if (r->scratch->line_attrs[0].has_dirty_text) {
|
||||
CPUCell *cpu_cells; GPUCell *gpu_cells;
|
||||
linebuf_init_cells(r->scratch, 0, &cpu_cells, &gpu_cells);
|
||||
memcpy(r->dest.cpu_cells, cpu_cells, r->dest_xnum * sizeof(cpu_cells[0]));
|
||||
memcpy(r->dest.gpu_cells, gpu_cells, r->dest_xnum * sizeof(gpu_cells[0]));
|
||||
r->current_dest_line_has_multiline_cells = true;
|
||||
}
|
||||
linebuf_index(r->scratch, 0, r->scratch->ynum - 1);
|
||||
if (r->scratch->line_attrs[r->scratch->ynum - 1].has_dirty_text) {
|
||||
linebuf_clear_line(r->scratch, r->scratch->ynum - 1, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -109,45 +123,52 @@ first_dest_line(Rewrap *r) {
|
||||
r->dest_y = r->first_dest_line(r->dest_buf, r->as_ansi_buf, &r->src, &r->dest);
|
||||
}
|
||||
|
||||
static bool
|
||||
init_src_line(Rewrap *r) {
|
||||
bool newline_needed = !r->prev_src_line_ended_with_wrap;
|
||||
r->init_line(r->src_buf, r->src_y, &r->src);
|
||||
r->src_x_limit = r->src_xnum;
|
||||
if (!r->src.cpu_cells[r->src_xnum-1].next_char_was_wrapped) {
|
||||
// Trim trailing blanks since there is a hard line break at the end of this line
|
||||
while(r->src_x_limit && r->src.cpu_cells[r->src_x_limit - 1].ch_and_idx == BLANK_CHAR) r->src_x_limit--;
|
||||
}
|
||||
r->prev_src_line_ended_with_wrap = r->src.cpu_cells[r->src_xnum - 1].next_char_was_wrapped;
|
||||
r->src.cpu_cells[r->src_xnum - 1].next_char_was_wrapped = false;
|
||||
r->src_x = 0;
|
||||
for (TrackCursor *t = r->cursors; !t->is_sentinel; t++) {
|
||||
if (r->src_y == t->y) {
|
||||
t->is_tracked_line = true;
|
||||
if (t->x >= r->src_x_limit) t->x = MAX(1u, r->src_x_limit) - 1;
|
||||
} else t->is_tracked_line = false;
|
||||
}
|
||||
return newline_needed;
|
||||
}
|
||||
|
||||
static index_type
|
||||
rewrap_inner(Rewrap r) {
|
||||
init_line(r.text_cache, r.src_xnum, &r.src); init_line(r.text_cache, r.dest_xnum, &r.dest);
|
||||
setup_line(r.text_cache, r.src_xnum, &r.src); setup_line(r.text_cache, r.dest_xnum, &r.dest);
|
||||
static TrackCursor tc_end = {.is_sentinel = true };
|
||||
if (!r.cursors) r.cursors = &tc_end;
|
||||
bool is_first_line = true, src_line_is_continued = false;
|
||||
while (r.src_y < r.src_limit) {
|
||||
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) t->is_tracked_line = r.src_y == t->y;
|
||||
r.init_line(r.src_buf, r.src_y, &r.src);
|
||||
r.src_x_limit = r.src.xnum;
|
||||
if (!src_line_is_continued) {
|
||||
if (is_first_line) { is_first_line = false; first_dest_line(&r); }
|
||||
else next_dest_line(&r, false);
|
||||
r.scratch = alloc_linebuf(SCALE_BITS << 1, r.dest_xnum, r.text_cache);
|
||||
if (!r.scratch) fatal("Out of memory");
|
||||
RAII_PyObject(scratch, (PyObject*)r.scratch);
|
||||
for (; r.src_y < r.src_limit; r.src_y++) {
|
||||
if (init_src_line(&r)) {
|
||||
if (r.src_y) next_dest_line(&r, false);
|
||||
else first_dest_line(&r);
|
||||
}
|
||||
src_line_is_continued = r.src.cpu_cells[r.src.xnum-1].next_char_was_wrapped;
|
||||
if (!src_line_is_continued) {
|
||||
// Trim trailing blanks since there is a hard line break at the end of this line
|
||||
while(r.src_x_limit && r.src.cpu_cells[r.src_x_limit - 1].ch_and_idx == BLANK_CHAR) r.src_x_limit--;
|
||||
} else {
|
||||
r.src.cpu_cells[r.src.xnum-1].next_char_was_wrapped = false;
|
||||
}
|
||||
if (r.src_x_limit) {
|
||||
while (r.src_x < r.src_x_limit) {
|
||||
if (r.dest_x >= r.dest_xnum) next_dest_line(&r, true);
|
||||
index_type num = MIN(r.src.xnum - r.src_x, r.dest_xnum - r.dest_x);
|
||||
copy_range(&r.src, r.src_x, &r.dest, r.dest_x, num);
|
||||
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) {
|
||||
if (t->is_tracked_line && t->x >= r.src_x_limit) t->x = MAX(1u, r.src_x_limit) - 1;
|
||||
}
|
||||
while (r.src_x < r.src_x_limit) {
|
||||
if (r.dest_x >= r.dest.xnum) next_dest_line(&r, true);
|
||||
index_type num = MIN(r.src.xnum - r.src_x, r.dest.xnum - r.dest_x);
|
||||
copy_range(&r.src, r.src_x, &r.dest, r.dest_x, num);
|
||||
for (TrackCursor *t = r.cursors; !t->is_sentinel; t++) {
|
||||
if (t->is_tracked_line && r.src_x <= t->x && t->x < r.src_x + num) {
|
||||
t->y = r.dest_y;
|
||||
t->x = r.dest_x + (t->x - r.src_x + (t->x > 0));
|
||||
}
|
||||
if (t->is_tracked_line && r.src_x <= t->x && t->x < r.src_x + num) {
|
||||
t->y = r.dest_y;
|
||||
t->x = r.dest_x + (t->x - r.src_x + (t->x > 0));
|
||||
}
|
||||
r.src_x += num; r.dest_x += num;
|
||||
}
|
||||
r.src_x += num; r.dest_x += num;
|
||||
}
|
||||
r.src_y++; r.src_x = 0;
|
||||
}
|
||||
return r.dest_y;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user