mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
grid: reflow: re-insert sixels *after* new grid offset has been set
Also make sure to destroy sixels that are too big to fit in the scrollback. Fixes issues with the sixel list not being sorted correctly.
This commit is contained in:
parent
5a6b96817d
commit
323119a645
1 changed files with 51 additions and 40 deletions
91
grid.c
91
grid.c
|
|
@ -83,9 +83,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) old_sixels = tll_init();
|
tll(struct sixel) untranslated_sixels = tll_init();
|
||||||
|
tll(struct sixel) translated_sixels = tll_init();
|
||||||
tll_foreach(grid->sixel_images, it)
|
tll_foreach(grid->sixel_images, it)
|
||||||
tll_push_back(old_sixels, it->item);
|
tll_push_back(untranslated_sixels, it->item);
|
||||||
tll_free(grid->sixel_images);
|
tll_free(grid->sixel_images);
|
||||||
|
|
||||||
/* Turn cursor coordinates into grid absolute coordinates */
|
/* Turn cursor coordinates into grid absolute coordinates */
|
||||||
|
|
@ -108,7 +109,6 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
for (size_t i = 0; i < tracking_points_count; i++)
|
for (size_t i = 0; i < tracking_points_count; i++)
|
||||||
tll_push_back(tracking_points, _tracking_points[i]);
|
tll_push_back(tracking_points, _tracking_points[i]);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk the old grid
|
* Walk the old grid
|
||||||
*/
|
*/
|
||||||
|
|
@ -122,7 +122,7 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Map sixels on current "old" row to current "new row" */
|
/* Map sixels on current "old" row to current "new row" */
|
||||||
tll_foreach(old_sixels, it) {
|
tll_foreach(untranslated_sixels, it) {
|
||||||
if (it->item.pos.row != old_row_idx)
|
if (it->item.pos.row != old_row_idx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -131,47 +131,17 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
|
|
||||||
/* Make sure it doesn't cross the wrap-around after being re-based */
|
/* Make sure it doesn't cross the wrap-around after being re-based */
|
||||||
int end = (sixel.pos.row + sixel.rows - 1) & (new_rows - 1);
|
int end = (sixel.pos.row + sixel.rows - 1) & (new_rows - 1);
|
||||||
|
|
||||||
if (end < sixel.pos.row) {
|
if (end < sixel.pos.row) {
|
||||||
/* TODO: split instead of destroying */
|
/* TODO: split instead of destroying */
|
||||||
sixel_destroy(&it->item);
|
sixel_destroy(&it->item);
|
||||||
} else {
|
} else {
|
||||||
|
/* Insert sixel into the translated, but *unsorted* list. */
|
||||||
/* Insert sixel into the *sorted* list. */
|
tll_push_back(translated_sixels, sixel);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sixel has been either re-mapped, or destroyed */
|
/* Sixel has been either re-mapped, or destroyed */
|
||||||
tll_remove(old_sixels, it);
|
tll_remove(untranslated_sixels, it);
|
||||||
#undef rebase_row
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define line_wrap() \
|
#define line_wrap() \
|
||||||
|
|
@ -372,9 +342,50 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
grid->saved_cursor.lcf = false;
|
grid->saved_cursor.lcf = false;
|
||||||
|
|
||||||
/* Free sixels we failed to "map" to the new grid */
|
/* Free sixels we failed to "map" to the new grid */
|
||||||
tll_foreach(old_sixels, it)
|
tll_foreach(untranslated_sixels, it)
|
||||||
sixel_destroy(&it->item);
|
sixel_destroy(&it->item);
|
||||||
tll_free(old_sixels);
|
tll_free(untranslated_sixels);
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
|
||||||
|
/* Re-add translated sixels, sorted according to the new grid offset */
|
||||||
|
tll_foreach(translated_sixels, it) {
|
||||||
|
int end_row = rebase_row(term, it->item.pos.row + it->item.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).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (it->item.rows >= new_rows) {
|
||||||
|
sixel_destroy(&it->item);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(it->item.rows < new_rows);
|
||||||
|
|
||||||
|
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, it->item);
|
||||||
|
inserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inserted)
|
||||||
|
tll_push_back(grid->sixel_images, it->item);
|
||||||
|
}
|
||||||
|
tll_free(translated_sixels);
|
||||||
|
#undef rebase_row
|
||||||
|
|
||||||
tll_free(tracking_points);
|
tll_free(tracking_points);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue