mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-04 07:15:29 -04:00
term: rename CELL_MULT_COL_SPACER -> CELL_SPACER, and change its definition
Instead of using CELL_SPACER for *all* cells that previously used CELL_MULT_COL_SPACER, include the remaining number of spacers following, and including, itself. This is encoded by adding to the CELL_SPACER value. So, a double width character will now store the character itself in the first cell (just like before), and CELL_SPACER+1 in the second cell. A three-cell character would store the character itself, then CELL_SPACER+2, and finally CELL_SPACER+1. In other words, the last spacer is always CELL_SPACER+1. CELL_SPACER+0 is used when padding at the right margin. I.e. when writing e.g. a double width character in the last column, we insert a CELL_SPACER+0 pad character, and then write the double width character in the first column on the next row.
This commit is contained in:
parent
5bec83c406
commit
d9e1aefb91
9 changed files with 34 additions and 34 deletions
|
|
@ -113,7 +113,7 @@ extract_one(const struct terminal *term, const struct row *row,
|
||||||
{
|
{
|
||||||
struct extraction_context *ctx = context;
|
struct extraction_context *ctx = context;
|
||||||
|
|
||||||
if (cell->wc == CELL_MULT_COL_SPACER)
|
if (cell->wc >= CELL_SPACER)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (ctx->last_row != NULL && row != ctx->last_row) {
|
if (ctx->last_row != NULL && row != ctx->last_row) {
|
||||||
|
|
|
||||||
10
grid.c
10
grid.c
|
|
@ -473,9 +473,9 @@ grid_resize_and_reflow(
|
||||||
grid, new_grid, new_row, &new_row_idx, &new_col_idx, \
|
grid, new_grid, new_row, &new_row_idx, &new_col_idx, \
|
||||||
new_rows, new_cols)
|
new_rows, new_cols)
|
||||||
|
|
||||||
#define print_spacer() \
|
#define print_spacer(remaining) \
|
||||||
do { \
|
do { \
|
||||||
new_row->cells[new_col_idx].wc = CELL_MULT_COL_SPACER; \
|
new_row->cells[new_col_idx].wc = CELL_SPACER + (remaining); \
|
||||||
new_row->cells[new_col_idx].attrs = old_cell->attrs; \
|
new_row->cells[new_col_idx].attrs = old_cell->attrs; \
|
||||||
new_row->cells[new_col_idx].attrs.clean = 1; \
|
new_row->cells[new_col_idx].attrs.clean = 1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
@ -541,7 +541,7 @@ grid_resize_and_reflow(
|
||||||
const struct cell *old_cell = &old_row->cells[c - empty_count + i];
|
const struct cell *old_cell = &old_row->cells[c - empty_count + i];
|
||||||
wc = old_cell->wc;
|
wc = old_cell->wc;
|
||||||
|
|
||||||
if (wc == CELL_MULT_COL_SPACER)
|
if (wc >= CELL_SPACER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wc >= CELL_COMB_CHARS_LO &&
|
if (wc >= CELL_COMB_CHARS_LO &&
|
||||||
|
|
@ -554,7 +554,7 @@ grid_resize_and_reflow(
|
||||||
if (new_col_idx + max(1, wcwidth(wc)) > new_cols) {
|
if (new_col_idx + max(1, wcwidth(wc)) > new_cols) {
|
||||||
/* Pad to end-of-line with spacers, then line-wrap */
|
/* Pad to end-of-line with spacers, then line-wrap */
|
||||||
for (;new_col_idx < new_cols; new_col_idx++)
|
for (;new_col_idx < new_cols; new_col_idx++)
|
||||||
print_spacer();
|
print_spacer(0);
|
||||||
line_wrap();
|
line_wrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -585,7 +585,7 @@ grid_resize_and_reflow(
|
||||||
const struct cell *old_cell = &old_row->cells[c];
|
const struct cell *old_cell = &old_row->cells[c];
|
||||||
for (size_t i = 0; i < width - 1; i++) {
|
for (size_t i = 0; i < width - 1; i++) {
|
||||||
xassert(new_col_idx < new_cols);
|
xassert(new_col_idx < new_cols);
|
||||||
print_spacer();
|
print_spacer(width - i + 1);
|
||||||
new_col_idx++;
|
new_col_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
ime.c
4
ime.c
|
|
@ -199,7 +199,7 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
||||||
|
|
||||||
for (int j = 1; j < width; j++) {
|
for (int j = 1; j < width; j++) {
|
||||||
cell = &seat->ime.preedit.cells[cell_idx + j];
|
cell = &seat->ime.preedit.cells[cell_idx + j];
|
||||||
cell->wc = CELL_MULT_COL_SPACER;
|
cell->wc = CELL_SPACER + width - j;
|
||||||
cell->attrs = (struct attributes){.clean = 1};
|
cell->attrs = (struct attributes){.clean = 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +280,7 @@ done(void *data, struct zwp_text_input_v3 *zwp_text_input_v3,
|
||||||
|
|
||||||
/* Expand cursor end to end of glyph */
|
/* Expand cursor end to end of glyph */
|
||||||
while (cell_end > cell_begin && cell_end < cell_count &&
|
while (cell_end > cell_begin && cell_end < cell_count &&
|
||||||
seat->ime.preedit.cells[cell_end].wc == CELL_MULT_COL_SPACER)
|
seat->ime.preedit.cells[cell_end].wc >= CELL_SPACER)
|
||||||
{
|
{
|
||||||
cell_end++;
|
cell_end++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
render.c
10
render.c
|
|
@ -594,7 +594,7 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
||||||
if (has_cursor && term->cursor_style == CURSOR_BLOCK && term->kbd_focus)
|
if (has_cursor && term->cursor_style == CURSOR_BLOCK && term->kbd_focus)
|
||||||
draw_cursor(term, cell, font, pix, &fg, &bg, x, y, cell_cols);
|
draw_cursor(term, cell, font, pix, &fg, &bg, x, y, cell_cols);
|
||||||
|
|
||||||
if (cell->wc == 0 || cell->wc == CELL_MULT_COL_SPACER ||
|
if (cell->wc == 0 || cell->wc >= CELL_SPACER ||
|
||||||
(unlikely(cell->attrs.conceal) && !is_selected))
|
(unlikely(cell->attrs.conceal) && !is_selected))
|
||||||
{
|
{
|
||||||
goto draw_cursor;
|
goto draw_cursor;
|
||||||
|
|
@ -1237,7 +1237,7 @@ render_ime_preedit_for_seat(struct terminal *term, struct seat *seat,
|
||||||
|
|
||||||
/* Make sure we don't start in the middle of a character */
|
/* Make sure we don't start in the middle of a character */
|
||||||
while (ime_ofs < cells_needed &&
|
while (ime_ofs < cells_needed &&
|
||||||
seat->ime.preedit.cells[ime_ofs].wc == CELL_MULT_COL_SPACER)
|
seat->ime.preedit.cells[ime_ofs].wc >= CELL_SPACER)
|
||||||
{
|
{
|
||||||
ime_ofs++;
|
ime_ofs++;
|
||||||
}
|
}
|
||||||
|
|
@ -1249,7 +1249,7 @@ render_ime_preedit_for_seat(struct terminal *term, struct seat *seat,
|
||||||
struct row *row = grid_row_in_view(term->grid, row_idx);
|
struct row *row = grid_row_in_view(term->grid, row_idx);
|
||||||
|
|
||||||
/* Don't start pre-edit text in the middle of a double-width character */
|
/* Don't start pre-edit text in the middle of a double-width character */
|
||||||
while (col_idx > 0 && row->cells[col_idx].wc == CELL_MULT_COL_SPACER) {
|
while (col_idx > 0 && row->cells[col_idx].wc >= CELL_SPACER) {
|
||||||
cells_used++;
|
cells_used++;
|
||||||
col_idx--;
|
col_idx--;
|
||||||
}
|
}
|
||||||
|
|
@ -1268,11 +1268,11 @@ render_ime_preedit_for_seat(struct terminal *term, struct seat *seat,
|
||||||
row->dirty = true;
|
row->dirty = true;
|
||||||
|
|
||||||
/* Render pre-edit text */
|
/* Render pre-edit text */
|
||||||
xassert(seat->ime.preedit.cells[ime_ofs].wc != CELL_MULT_COL_SPACER);
|
xassert(seat->ime.preedit.cells[ime_ofs].wc < CELL_SPACER);
|
||||||
for (int i = 0, idx = ime_ofs; idx < seat->ime.preedit.count; i++, idx++) {
|
for (int i = 0, idx = ime_ofs; idx < seat->ime.preedit.count; i++, idx++) {
|
||||||
const struct cell *cell = &seat->ime.preedit.cells[idx];
|
const struct cell *cell = &seat->ime.preedit.cells[idx];
|
||||||
|
|
||||||
if (cell->wc == CELL_MULT_COL_SPACER)
|
if (cell->wc >= CELL_SPACER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int width = max(1, wcwidth(cell->wc));
|
int width = max(1, wcwidth(cell->wc));
|
||||||
|
|
|
||||||
4
search.c
4
search.c
|
|
@ -337,7 +337,7 @@ search_find_next(struct terminal *term)
|
||||||
row = term->grid->rows[end_row];
|
row = term->grid->rows[end_row];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row->cells[end_col].wc == CELL_MULT_COL_SPACER) {
|
if (row->cells[end_col].wc >= CELL_SPACER) {
|
||||||
end_col++;
|
end_col++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -461,7 +461,7 @@ search_match_to_end_of_word(struct terminal *term, bool spaces_only)
|
||||||
bool done = false;
|
bool done = false;
|
||||||
for (; end_col < term->cols; end_col++) {
|
for (; end_col < term->cols; end_col++) {
|
||||||
wchar_t wc = row->cells[end_col].wc;
|
wchar_t wc = row->cells[end_col].wc;
|
||||||
if (wc == CELL_MULT_COL_SPACER)
|
if (wc >= CELL_SPACER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const struct composed *composed = NULL;
|
const struct composed *composed = NULL;
|
||||||
|
|
|
||||||
26
selection.c
26
selection.c
|
|
@ -234,7 +234,7 @@ find_word_boundary_left(struct terminal *term, struct coord *pos,
|
||||||
const struct row *r = grid_row_in_view(term->grid, pos->row);
|
const struct row *r = grid_row_in_view(term->grid, pos->row);
|
||||||
wchar_t c = r->cells[pos->col].wc;
|
wchar_t c = r->cells[pos->col].wc;
|
||||||
|
|
||||||
while (c == CELL_MULT_COL_SPACER) {
|
while (c >= CELL_SPACER) {
|
||||||
xassert(pos->col > 0);
|
xassert(pos->col > 0);
|
||||||
if (pos->col == 0)
|
if (pos->col == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -268,7 +268,7 @@ find_word_boundary_left(struct terminal *term, struct coord *pos,
|
||||||
const struct row *row = grid_row_in_view(term->grid, next_row);
|
const struct row *row = grid_row_in_view(term->grid, next_row);
|
||||||
|
|
||||||
c = row->cells[next_col].wc;
|
c = row->cells[next_col].wc;
|
||||||
while (c == CELL_MULT_COL_SPACER) {
|
while (c >= CELL_SPACER) {
|
||||||
xassert(next_col > 0);
|
xassert(next_col > 0);
|
||||||
if (--next_col < 0)
|
if (--next_col < 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -306,7 +306,7 @@ find_word_boundary_right(struct terminal *term, struct coord *pos,
|
||||||
const struct row *r = grid_row_in_view(term->grid, pos->row);
|
const struct row *r = grid_row_in_view(term->grid, pos->row);
|
||||||
wchar_t c = r->cells[pos->col].wc;
|
wchar_t c = r->cells[pos->col].wc;
|
||||||
|
|
||||||
while (c == CELL_MULT_COL_SPACER) {
|
while (c >= CELL_SPACER) {
|
||||||
xassert(pos->col > 0);
|
xassert(pos->col > 0);
|
||||||
if (pos->col == 0)
|
if (pos->col == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -340,7 +340,7 @@ find_word_boundary_right(struct terminal *term, struct coord *pos,
|
||||||
const struct row *row = grid_row_in_view(term->grid, next_row);
|
const struct row *row = grid_row_in_view(term->grid, next_row);
|
||||||
|
|
||||||
c = row->cells[next_col].wc;
|
c = row->cells[next_col].wc;
|
||||||
while (c == CELL_MULT_COL_SPACER) {
|
while (c >= CELL_SPACER) {
|
||||||
if (++next_col >= term->cols) {
|
if (++next_col >= term->cols) {
|
||||||
next_col = 0;
|
next_col = 0;
|
||||||
if (++next_row >= term->rows)
|
if (++next_row >= term->rows)
|
||||||
|
|
@ -554,7 +554,7 @@ set_pivot_point_for_block_and_char_wise(struct terminal *term,
|
||||||
const struct row *row = term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)];
|
const struct row *row = term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)];
|
||||||
const struct cell *cell = &row->cells[pivot_start->col];
|
const struct cell *cell = &row->cells[pivot_start->col];
|
||||||
|
|
||||||
if (cell->wc != CELL_MULT_COL_SPACER)
|
if (cell->wc < CELL_SPACER)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Multi-column chars don’t cross rows */
|
/* Multi-column chars don’t cross rows */
|
||||||
|
|
@ -579,7 +579,7 @@ set_pivot_point_for_block_and_char_wise(struct terminal *term,
|
||||||
const struct row *row = term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)];
|
const struct row *row = term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)];
|
||||||
const wchar_t wc = row->cells[pivot_end->col].wc;
|
const wchar_t wc = row->cells[pivot_end->col].wc;
|
||||||
|
|
||||||
keep_going = wc == CELL_MULT_COL_SPACER;
|
keep_going = wc >= CELL_SPACER;
|
||||||
|
|
||||||
if (pivot_end->col == 0) {
|
if (pivot_end->col == 0) {
|
||||||
if (pivot_end->row - term->grid->view <= 0)
|
if (pivot_end->row - term->grid->view <= 0)
|
||||||
|
|
@ -596,7 +596,7 @@ set_pivot_point_for_block_and_char_wise(struct terminal *term,
|
||||||
const wchar_t wc = pivot_start->col < term->cols - 1
|
const wchar_t wc = pivot_start->col < term->cols - 1
|
||||||
? row->cells[pivot_start->col + 1].wc : 0;
|
? row->cells[pivot_start->col + 1].wc : 0;
|
||||||
|
|
||||||
keep_going = wc == CELL_MULT_COL_SPACER;
|
keep_going = wc >= CELL_SPACER;
|
||||||
|
|
||||||
if (pivot_start->col >= term->cols - 1) {
|
if (pivot_start->col >= term->cols - 1) {
|
||||||
if (pivot_start->row - term->grid->view >= term->rows - 1)
|
if (pivot_start->row - term->grid->view >= term->rows - 1)
|
||||||
|
|
@ -609,9 +609,9 @@ set_pivot_point_for_block_and_char_wise(struct terminal *term,
|
||||||
}
|
}
|
||||||
|
|
||||||
xassert(term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)]->
|
xassert(term->grid->rows[pivot_start->row & (term->grid->num_rows - 1)]->
|
||||||
cells[pivot_start->col].wc != CELL_MULT_COL_SPACER);
|
cells[pivot_start->col].wc < CELL_SPACER);
|
||||||
xassert(term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)]->
|
xassert(term->grid->rows[pivot_end->row & (term->grid->num_rows - 1)]->
|
||||||
cells[pivot_end->col].wc != CELL_MULT_COL_SPACER);
|
cells[pivot_end->col].wc < CELL_SPACER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -743,17 +743,17 @@ selection_update(struct terminal *term, int col, int row)
|
||||||
(new_start.row == new_end.row && new_start.col <= new_end.col))
|
(new_start.row == new_end.row && new_start.col <= new_end.col))
|
||||||
{
|
{
|
||||||
while (new_start.col >= 1 &&
|
while (new_start.col >= 1 &&
|
||||||
row_start->cells[new_start.col].wc == CELL_MULT_COL_SPACER)
|
row_start->cells[new_start.col].wc >= CELL_SPACER)
|
||||||
new_start.col--;
|
new_start.col--;
|
||||||
while (new_end.col < term->cols - 1 &&
|
while (new_end.col < term->cols - 1 &&
|
||||||
row_end->cells[new_end.col + 1].wc == CELL_MULT_COL_SPACER)
|
row_end->cells[new_end.col + 1].wc >= CELL_SPACER)
|
||||||
new_end.col++;
|
new_end.col++;
|
||||||
} else {
|
} else {
|
||||||
while (new_end.col >= 1 &&
|
while (new_end.col >= 1 &&
|
||||||
row_end->cells[new_end.col].wc == CELL_MULT_COL_SPACER)
|
row_end->cells[new_end.col].wc >= CELL_SPACER)
|
||||||
new_end.col--;
|
new_end.col--;
|
||||||
while (new_start.col < term->cols - 1 &&
|
while (new_start.col < term->cols - 1 &&
|
||||||
row_start->cells[new_start.col + 1].wc == CELL_MULT_COL_SPACER)
|
row_start->cells[new_start.col + 1].wc >= CELL_SPACER)
|
||||||
new_start.col++;
|
new_start.col++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2764,12 +2764,12 @@ print_insert(struct terminal *term, int width)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_spacer(struct terminal *term, int col)
|
print_spacer(struct terminal *term, int col, int remaining)
|
||||||
{
|
{
|
||||||
struct row *row = term->grid->cur_row;
|
struct row *row = term->grid->cur_row;
|
||||||
struct cell *cell = &row->cells[col];
|
struct cell *cell = &row->cells[col];
|
||||||
|
|
||||||
cell->wc = CELL_MULT_COL_SPACER;
|
cell->wc = CELL_SPACER + remaining;
|
||||||
cell->attrs = term->vt.attrs;
|
cell->attrs = term->vt.attrs;
|
||||||
cell->attrs.clean = 0;
|
cell->attrs.clean = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2803,7 +2803,7 @@ term_print(struct terminal *term, wchar_t wc, int width)
|
||||||
/* Multi-column character that doesn't fit on current line -
|
/* Multi-column character that doesn't fit on current line -
|
||||||
* pad with spacers */
|
* pad with spacers */
|
||||||
for (size_t i = term->grid->cursor.point.col; i < term->cols; i++)
|
for (size_t i = term->grid->cursor.point.col; i < term->cols; i++)
|
||||||
print_spacer(term, i);
|
print_spacer(term, i, 0);
|
||||||
|
|
||||||
/* And force a line-wrap */
|
/* And force a line-wrap */
|
||||||
term->grid->cursor.lcf = 1;
|
term->grid->cursor.lcf = 1;
|
||||||
|
|
@ -2826,7 +2826,7 @@ term_print(struct terminal *term, wchar_t wc, int width)
|
||||||
/* Advance cursor the 'additional' columns while dirty:ing the cells */
|
/* Advance cursor the 'additional' columns while dirty:ing the cells */
|
||||||
for (int i = 1; i < width && term->grid->cursor.point.col < term->cols - 1; i++) {
|
for (int i = 1; i < width && term->grid->cursor.point.col < term->cols - 1; i++) {
|
||||||
term->grid->cursor.point.col++;
|
term->grid->cursor.point.col++;
|
||||||
print_spacer(term, term->grid->cursor.point.col);
|
print_spacer(term, term->grid->cursor.point.col, width - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advance cursor */
|
/* Advance cursor */
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ static_assert(sizeof(struct attributes) == 8, "VT attribute struct too large");
|
||||||
|
|
||||||
#define CELL_COMB_CHARS_LO 0x40000000ul
|
#define CELL_COMB_CHARS_LO 0x40000000ul
|
||||||
#define CELL_COMB_CHARS_HI 0x400ffffful
|
#define CELL_COMB_CHARS_HI 0x400ffffful
|
||||||
#define CELL_MULT_COL_SPACER 0x40100000ul
|
#define CELL_SPACER 0x40100000ul
|
||||||
|
|
||||||
struct cell {
|
struct cell {
|
||||||
wchar_t wc;
|
wchar_t wc;
|
||||||
|
|
|
||||||
2
vt.c
2
vt.c
|
|
@ -569,7 +569,7 @@ action_utf8_print(struct terminal *term, wchar_t wc)
|
||||||
if (!term->grid->cursor.lcf)
|
if (!term->grid->cursor.lcf)
|
||||||
base_col--;
|
base_col--;
|
||||||
|
|
||||||
while (row->cells[base_col].wc == CELL_MULT_COL_SPACER && base_col > 0)
|
while (row->cells[base_col].wc >= CELL_SPACER && base_col > 0)
|
||||||
base_col--;
|
base_col--;
|
||||||
|
|
||||||
xassert(base_col >= 0 && base_col < term->cols);
|
xassert(base_col >= 0 && base_col < term->cols);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue