mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-31 07:11:09 -04:00
reflow: ensure sixels are correctly sorted when re-inserted
And make sure to remove re-inserted sixels that has wrapped around the scrollback (this may happen when the window size decreases).
This commit is contained in:
parent
6ee76c21f2
commit
a136987678
2 changed files with 63 additions and 32 deletions
|
|
@ -78,6 +78,7 @@
|
||||||
no longer erases the entire image, only the part(s) covered by the
|
no longer erases the entire image, only the part(s) covered by the
|
||||||
new text or image.
|
new text or image.
|
||||||
* Sixel images being erased when printing text next to them.
|
* Sixel images being erased when printing text next to them.
|
||||||
|
* Sixel handling when resizing window.
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
||||||
94
grid.c
94
grid.c
|
|
@ -76,7 +76,10 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
* at the output that is *oldest* */
|
* at the output that is *oldest* */
|
||||||
int offset = grid->offset + old_screen_rows;
|
int offset = grid->offset + old_screen_rows;
|
||||||
|
|
||||||
tll(struct sixel) new_sixels = tll_init();
|
tll(struct sixel) old_sixels = tll_init();
|
||||||
|
tll_foreach(grid->sixel_images, it)
|
||||||
|
tll_push_back(old_sixels, it->item);
|
||||||
|
tll_free(grid->sixel_images);
|
||||||
|
|
||||||
/* Turn cursor coordinates into grid absolute coordinates */
|
/* Turn cursor coordinates into grid absolute coordinates */
|
||||||
struct coord cursor = grid->cursor.point;
|
struct coord cursor = grid->cursor.point;
|
||||||
|
|
@ -106,31 +109,57 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
if (old_row == NULL)
|
if (old_row == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/* Map sixels on current "old" row to current "new row" */
|
||||||
* Update 'row' in all sixels that *begin* at current row
|
tll_foreach(old_sixels, it) {
|
||||||
*
|
if (it->item.pos.row != old_row_idx)
|
||||||
* Since we might end up pushing the sixel down, we can't
|
continue;
|
||||||
* simply update the row inline - we'd then end up pushing the
|
|
||||||
* sixel down again, when we reach the next 'old'
|
struct sixel sixel = it->item;
|
||||||
* row. Instead, copy the sixel (with 'row' updated), to a
|
sixel.pos.row = new_row_idx;
|
||||||
* temporary list and remove the original sixel.
|
|
||||||
*
|
/* Make sure it doesn't cross the wrap-around after being re-based */
|
||||||
* After we've reflowed the grid we'll move the sixels back to
|
int end = (sixel.pos.row + sixel.rows - 1) & (new_rows - 1);
|
||||||
* the "real" sixel list.
|
if (end < sixel.pos.row) {
|
||||||
*/
|
/* TODO: split instead of destroying */
|
||||||
tll_foreach(grid->sixel_images, it) {
|
sixel_destroy(&it->item);
|
||||||
if (it->item.pos.row == old_row_idx) {
|
} else {
|
||||||
struct sixel six = it->item;
|
|
||||||
six.pos.row = new_row_idx;
|
/* Insert sixel into the *sorted* list. */
|
||||||
|
|
||||||
|
/* Based on rebase_row() in sixel.c */
|
||||||
|
/* Uses 'old' offset to ensure old sixels are treated as such */
|
||||||
|
#define rebase_row(t, row) \
|
||||||
|
(((row) - (grid->offset + new_screen_rows) + new_rows) & (new_rows - 1))
|
||||||
|
|
||||||
|
int end_row = rebase_row(term, sixel.pos.row + sixel.rows - 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: this is basically sixel_insert(), except we
|
||||||
|
* cannot use it since:
|
||||||
|
*
|
||||||
|
* a) we don't have a 'term' reference
|
||||||
|
* b) the grid hasn't been fully * updated yet
|
||||||
|
* (e.g. grid->num_rows is invalid etc).
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool inserted = false;
|
||||||
|
tll_foreach(grid->sixel_images, it2) {
|
||||||
|
const struct sixel *s = &it2->item;
|
||||||
|
if (rebase_row(term, s->pos.row + s->rows - 1) < end_row) {
|
||||||
|
tll_insert_before(grid->sixel_images, it2, sixel);
|
||||||
|
inserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inserted)
|
||||||
|
tll_push_back(grid->sixel_images, sixel);
|
||||||
|
|
||||||
int end = (six.pos.row + six.rows - 1) & (new_rows - 1);
|
|
||||||
if (end < six.pos.row) {
|
|
||||||
/* TODO: split sixel instead of removing it... */
|
|
||||||
sixel_destroy(&it->item);
|
|
||||||
} else
|
|
||||||
tll_push_back(new_sixels, six);
|
|
||||||
tll_remove(grid->sixel_images, it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sixel has been either re-mapped, or destroyed */
|
||||||
|
tll_remove(old_sixels, it);
|
||||||
|
#undef rebase_row
|
||||||
}
|
}
|
||||||
|
|
||||||
#define line_wrap() \
|
#define line_wrap() \
|
||||||
|
|
@ -145,6 +174,12 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
} else { \
|
} else { \
|
||||||
memset(new_row->cells, 0, new_cols * sizeof(new_row->cells[0])); \
|
memset(new_row->cells, 0, new_cols * sizeof(new_row->cells[0])); \
|
||||||
new_row->linebreak = false; \
|
new_row->linebreak = false; \
|
||||||
|
tll_foreach(grid->sixel_images, it) { \
|
||||||
|
if (it->item.pos.row == new_row_idx) { \
|
||||||
|
sixel_destroy(&it->item); \
|
||||||
|
tll_remove(grid->sixel_images, it); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
@ -279,15 +314,10 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
grid->cursor.lcf = false;
|
grid->cursor.lcf = false;
|
||||||
grid->saved_cursor.lcf = false;
|
grid->saved_cursor.lcf = false;
|
||||||
|
|
||||||
/* Destroy any non-moved sixels */
|
/* Free sixels we failed to "map" to the new grid */
|
||||||
tll_foreach(grid->sixel_images, it)
|
tll_foreach(old_sixels, it)
|
||||||
sixel_destroy(&it->item);
|
sixel_destroy(&it->item);
|
||||||
tll_free(grid->sixel_images);
|
tll_free(old_sixels);
|
||||||
|
|
||||||
/* Move updated sixels back */
|
|
||||||
tll_foreach(new_sixels, it)
|
|
||||||
tll_push_back(grid->sixel_images, it->item);
|
|
||||||
tll_free(new_sixels);
|
|
||||||
|
|
||||||
tll_free(tracking_points);
|
tll_free(tracking_points);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue