mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-15 22:05:24 -05:00
Merge branch 'sixel-left-most-column-overwritten'
This commit is contained in:
commit
7229ddd4ae
2 changed files with 70 additions and 18 deletions
|
|
@ -74,6 +74,8 @@
|
||||||
scaling factor.
|
scaling factor.
|
||||||
* Slow-to-terminate client applications causing other footclient instances to
|
* Slow-to-terminate client applications causing other footclient instances to
|
||||||
freeze when closing a footclient window.
|
freeze when closing a footclient window.
|
||||||
|
* Underlying cell content showing through in the left-most column of
|
||||||
|
sixels.
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
||||||
86
render.c
86
render.c
|
|
@ -439,20 +439,6 @@ draw_cursor(const struct terminal *term, const struct cell *cell,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
render_cell_prepass(struct terminal *term, struct row *row, int col)
|
|
||||||
{
|
|
||||||
for (; col < term->cols - 1; col++) {
|
|
||||||
if (row->cells[col].attrs.confined ||
|
|
||||||
(row->cells[col].attrs.clean == row->cells[col + 1].attrs.clean)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
row->cells[col].attrs.clean = 0;
|
|
||||||
row->cells[col + 1].attrs.clean = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
render_cell(struct terminal *term, pixman_image_t *pix,
|
render_cell(struct terminal *term, pixman_image_t *pix,
|
||||||
struct row *row, int col, int row_no, bool has_cursor)
|
struct row *row, int col, int row_no, bool has_cursor)
|
||||||
|
|
@ -767,10 +753,6 @@ static void
|
||||||
render_row(struct terminal *term, pixman_image_t *pix, struct row *row,
|
render_row(struct terminal *term, pixman_image_t *pix, struct row *row,
|
||||||
int row_no, int cursor_col)
|
int row_no, int cursor_col)
|
||||||
{
|
{
|
||||||
if (term->conf->tweak.overflowing_glyphs)
|
|
||||||
for (int col = term->cols - 1; col >= 0; col--)
|
|
||||||
render_cell_prepass(term, row, col);
|
|
||||||
|
|
||||||
for (int col = term->cols - 1; col >= 0; col--)
|
for (int col = term->cols - 1; col >= 0; col--)
|
||||||
render_cell(term, pix, row, col, row_no, cursor_col == col);
|
render_cell(term, pix, row, col, row_no, cursor_col == col);
|
||||||
}
|
}
|
||||||
|
|
@ -2452,6 +2434,74 @@ grid_render(struct terminal *term)
|
||||||
cursor.row &= term->grid->num_rows - 1;
|
cursor.row &= term->grid->num_rows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (term->conf->tweak.overflowing_glyphs) {
|
||||||
|
/*
|
||||||
|
* Pre-pass to dirty cells affected by overflowing glyphs.
|
||||||
|
*
|
||||||
|
* Given any two pair of cells where the first cell is
|
||||||
|
* overflowing into the second, *both* cells must be
|
||||||
|
* re-rendered if any one of them is dirty.
|
||||||
|
*
|
||||||
|
* Thus, given a string of overflowing glyphs, with a single
|
||||||
|
* dirty cell in the middle, we need to re-render the entire
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
|
for (int r = 0; r < term->rows; r++) {
|
||||||
|
struct row *row = grid_row_in_view(term->grid, r);
|
||||||
|
|
||||||
|
if (!row->dirty)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Loop row from left to right, looking for dirty cells */
|
||||||
|
for (struct cell *cell = &row->cells[0];
|
||||||
|
cell < &row->cells[term->cols];
|
||||||
|
cell++)
|
||||||
|
{
|
||||||
|
if (cell->attrs.clean)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cell is dirty, go back and dirty previous cells, if
|
||||||
|
* they are overflowing.
|
||||||
|
*
|
||||||
|
* As soon as we see a non-overflowing cell we can
|
||||||
|
* stop, since it isn’t affecting the string of
|
||||||
|
* overflowing glyphs that follows it.
|
||||||
|
*
|
||||||
|
* As soon as we see a dirty cell, we can stop, since
|
||||||
|
* that means we’ve already handled it (remember the
|
||||||
|
* outer loop goes from left to right).
|
||||||
|
*/
|
||||||
|
for (struct cell *c = cell - 1; c >= &row->cells[0]; c--) {
|
||||||
|
if (c->attrs.confined)
|
||||||
|
break;
|
||||||
|
if (!c->attrs.clean)
|
||||||
|
break;
|
||||||
|
c->attrs.clean = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now move forward, dirtying all cells until we hit a
|
||||||
|
* non-overflowing cell.
|
||||||
|
*
|
||||||
|
* Note that the first non-overflowing cell must be
|
||||||
|
* re-rendered as well, but any cell *after* that is
|
||||||
|
* unaffected by the string of overflowing glyphs
|
||||||
|
* we’re dealing with right now.
|
||||||
|
*
|
||||||
|
* For performance, this iterates the *outer* loop’s
|
||||||
|
* cell pointer - no point in re-checking all these
|
||||||
|
* glyphs again, in the outer loop.
|
||||||
|
*/
|
||||||
|
for (; cell < &row->cells[term->cols]; cell++) {
|
||||||
|
cell->attrs.clean = false;
|
||||||
|
if (cell->attrs.confined)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render_sixel_images(term, buf->pix[0], &cursor);
|
render_sixel_images(term, buf->pix[0], &cursor);
|
||||||
|
|
||||||
if (term->render.workers.count > 0) {
|
if (term->render.workers.count > 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue