Skip to content

Commit

Permalink
Start work on rewrapping multicells
Browse files Browse the repository at this point in the history
  • Loading branch information
kovidgoyal committed Dec 28, 2024
1 parent 49c16c2 commit 392cec3
Showing 1 changed file with 52 additions and 31 deletions.
83 changes: 52 additions & 31 deletions kitty/rewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
Expand All @@ -102,52 +104,71 @@ 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
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;
}
Expand Down

0 comments on commit 392cec3

Please sign in to comment.