mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-13 04:27:47 -05:00
grid: don’t depend on wcwidth()
Calling wcwidth() on every character in the entire scrollback history is slow. We already have the character width encoded in the grid; it’s in the CELL_SPACERs following a multi-column character. Thus, when we see a non-SPACER character, that isn’t in the last column, peek the next character. If it’s a SPACER, get the current characters width from it. The only thing we need the width for, is to be able to print padding SPACERS in the right margin, if the there isn’t enough space on the current row for the current character.
This commit is contained in:
parent
d9e1aefb91
commit
8e05f42a1c
1 changed files with 46 additions and 42 deletions
88
grid.c
88
grid.c
|
|
@ -525,6 +525,17 @@ grid_resize_and_reflow(
|
|||
if (new_cols_left < cols_needed && new_cols_left >= old_cols_left)
|
||||
empty_count = max(0, empty_count - (cols_needed - new_cols_left));
|
||||
|
||||
for (int i = 0; i < empty_count; i++) {
|
||||
if (new_col_idx + 1 > new_cols)
|
||||
line_wrap();
|
||||
|
||||
new_row->cells[new_col_idx] = old_row->cells[c - empty_count + i];
|
||||
new_row->cells[new_col_idx].attrs.clean = 1;
|
||||
new_col_idx++;
|
||||
}
|
||||
|
||||
empty_count = 0;
|
||||
|
||||
wchar_t wc = old_row->cells[c].wc;
|
||||
if (wc >= CELL_COMB_CHARS_LO &&
|
||||
wc < (CELL_COMB_CHARS_LO + compose_count))
|
||||
|
|
@ -532,65 +543,58 @@ grid_resize_and_reflow(
|
|||
wc = composed[wc - CELL_COMB_CHARS_LO].base;
|
||||
}
|
||||
|
||||
int width = max(1, wcwidth(wc));
|
||||
const struct cell *old_cell = &old_row->cells[c];
|
||||
wc = old_cell->wc;
|
||||
|
||||
/* Multi-column characters are never cut in half */
|
||||
xassert(c + width <= old_cols);
|
||||
if (wc == CELL_SPACER)
|
||||
continue;
|
||||
|
||||
for (int i = 0; i < empty_count + 1; i++) {
|
||||
const struct cell *old_cell = &old_row->cells[c - empty_count + i];
|
||||
wc = old_cell->wc;
|
||||
if (wc >= CELL_COMB_CHARS_LO &&
|
||||
wc < (CELL_COMB_CHARS_LO + compose_count))
|
||||
{
|
||||
wc = composed[wc - CELL_COMB_CHARS_LO].base;
|
||||
}
|
||||
|
||||
if (wc >= CELL_SPACER)
|
||||
continue;
|
||||
|
||||
if (wc >= CELL_COMB_CHARS_LO &&
|
||||
wc < (CELL_COMB_CHARS_LO + compose_count))
|
||||
{
|
||||
wc = composed[wc - CELL_COMB_CHARS_LO].base;
|
||||
}
|
||||
if (wc < CELL_SPACER &&
|
||||
c + 1 < old_cols &&
|
||||
old_row->cells[c + 1].wc > CELL_SPACER)
|
||||
{
|
||||
int width = old_row->cells[c + 1].wc - CELL_SPACER + 1;
|
||||
assert(wcwidth(wc) == width);
|
||||
|
||||
/* Out of columns on current row in new grid? */
|
||||
if (new_col_idx + max(1, wcwidth(wc)) > new_cols) {
|
||||
if (new_col_idx + width > new_cols) {
|
||||
/* Pad to end-of-line with spacers, then line-wrap */
|
||||
for (;new_col_idx < new_cols; new_col_idx++)
|
||||
print_spacer(0);
|
||||
line_wrap();
|
||||
}
|
||||
}
|
||||
|
||||
xassert(new_row != NULL);
|
||||
xassert(new_col_idx >= 0);
|
||||
xassert(new_col_idx < new_cols);
|
||||
if (new_col_idx + 1 > new_cols)
|
||||
line_wrap();
|
||||
|
||||
new_row->cells[new_col_idx] = *old_cell;
|
||||
new_row->cells[new_col_idx].attrs.clean = 1;
|
||||
xassert(new_row != NULL);
|
||||
xassert(new_col_idx >= 0);
|
||||
xassert(new_col_idx < new_cols);
|
||||
|
||||
/* Translate tracking point(s) */
|
||||
if (is_tracking_point && i >= empty_count) {
|
||||
tll_foreach(tracking_points, it) {
|
||||
if (it->item->row == old_row_idx && it->item->col == c) {
|
||||
it->item->row = new_row_idx;
|
||||
it->item->col = new_col_idx;
|
||||
tll_remove(tracking_points, it);
|
||||
}
|
||||
new_row->cells[new_col_idx] = *old_cell;
|
||||
new_row->cells[new_col_idx].attrs.clean = 1;
|
||||
|
||||
/* Translate tracking point(s) */
|
||||
if (is_tracking_point) {
|
||||
tll_foreach(tracking_points, it) {
|
||||
if (it->item->row == old_row_idx && it->item->col == c) {
|
||||
it->item->row = new_row_idx;
|
||||
it->item->col = new_col_idx;
|
||||
tll_remove(tracking_points, it);
|
||||
}
|
||||
|
||||
reflow_uri_ranges(old_row, new_row, c, new_col_idx);
|
||||
}
|
||||
new_col_idx++;
|
||||
|
||||
reflow_uri_ranges(old_row, new_row, c, new_col_idx);
|
||||
}
|
||||
|
||||
/* For multi-column characters, insert spacers in the
|
||||
* subsequent cells */
|
||||
const struct cell *old_cell = &old_row->cells[c];
|
||||
for (size_t i = 0; i < width - 1; i++) {
|
||||
xassert(new_col_idx < new_cols);
|
||||
print_spacer(width - i + 1);
|
||||
new_col_idx++;
|
||||
}
|
||||
|
||||
c += width - 1;
|
||||
empty_count = 0;
|
||||
new_col_idx++;
|
||||
}
|
||||
|
||||
if (old_row->linebreak) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue