From df2927e088ceb2119264d1a970c22a450f00005b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 14 Jul 2020 16:49:11 +0200 Subject: [PATCH] term: print: write special value CELL_MULT_COL_SPACER to extra cells When printing a multi-column character, write CELL_MULT_COL_SPACER instead of '0' to both padding cells (when character doesn't fit at the end of the line), and to the cells following the actual character. --- render.c | 2 +- selection.c | 8 ++++---- terminal.c | 21 +++++++++------------ terminal.h | 2 ++ 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/render.c b/render.c index d2a278ff..a049ca05 100644 --- a/render.c +++ b/render.c @@ -438,7 +438,7 @@ render_cell(struct terminal *term, pixman_image_t *pix, if (has_cursor && term->cursor_style == CURSOR_BLOCK && term->kbd_focus) draw_cursor(term, cell, font, pix, &fg, &bg, x, y, cell_cols); - if (cell->wc == 0 || cell->attrs.conceal) + if (cell->wc == 0 || cell->wc == CELL_MULT_COL_SPACER || cell->attrs.conceal) goto draw_cursor; pixman_image_t *clr_pix = pixman_image_create_solid_fill(&fg); diff --git a/selection.c b/selection.c index 8dc83906..d5f8721c 100644 --- a/selection.c +++ b/selection.c @@ -134,9 +134,9 @@ foreach_selected_normal( c <= (r == end_row ? end_col : term->cols - 1); c++) { + if (row->cells[c].wc == CELL_MULT_COL_SPACER) + continue; cb(term, row, &row->cells[c], c, data); - c += max(1, wcwidth(row->cells[c].wc)) - 1; - assert(c < term->cols); } start_col = 0; @@ -168,9 +168,9 @@ foreach_selected_block( assert(row != NULL); for (int c = top_left.col; c <= bottom_right.col; c++) { + if (row->cells[c].wc == CELL_MULT_COL_SPACER) + continue; cb(term, row, &row->cells[c], c, data); - c += max(1, wcwidth(row->cells[c].wc)) - 1; - assert(c < term->cols); } } } diff --git a/terminal.c b/terminal.c index eda311da..2a232de3 100644 --- a/terminal.c +++ b/terminal.c @@ -2397,18 +2397,15 @@ term_print(struct terminal *term, wchar_t wc, int width) term->grid->cursor.point.col + width > term->cols) { /* Multi-column character that doesn't fit on current line - - * force a line wrap */ - term->grid->cursor.lcf = 1; + * pad with spacers */ + for (size_t i = term->grid->cursor.point.col; i < term->cols; i++) { + struct cell *cell = &term->grid->cur_row->cells[i]; + cell->wc = CELL_MULT_COL_SPACER; + cell->attrs.clean = 0; + } - /* - * TODO: should we insert place holder values in the remaining - * cells? This would allow e.g. text extraction to simply - * skip these, instead of trying to recognize a sequence of - * empty cells at the end of the line followed by a - * multi-column character... - * - * Might also make text reflow easier, or even more correct. - */ + /* And force a line-wrap */ + term->grid->cursor.lcf = 1; } print_linewrap(term); @@ -2431,7 +2428,7 @@ term_print(struct terminal *term, wchar_t wc, int width) term->grid->cursor.point.col++; struct cell *cell = &row->cells[term->grid->cursor.point.col]; - cell->wc = 0; + cell->wc = CELL_MULT_COL_SPACER; cell->attrs.clean = 0; } diff --git a/terminal.h b/terminal.h index f32f86dc..68259160 100644 --- a/terminal.h +++ b/terminal.h @@ -50,6 +50,8 @@ static_assert(sizeof(struct attributes) == 8, "bad size"); #define CELL_COMB_CHARS_LO 0x40000000ul #define CELL_COMB_CHARS_HI 0x400ffffful +#define CELL_MULT_COL_SPACER 0x40100000ul + struct cell { wchar_t wc; struct attributes attrs;