sixel: implement reflow

Move sixel reflow from grid_reflow() to sixel_reflow(). This lets us
use internal sixel functions to update the sixels.

Note that grid_reflow() still needs to remap the sixelss coordinates.
This commit is contained in:
Daniel Eklöf 2020-10-04 13:12:44 +02:00
parent 892730e5b9
commit dbfc636ade
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 51 additions and 54 deletions

55
grid.c
View file

@ -84,7 +84,6 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
int offset = grid->offset + old_screen_rows;
tll(struct sixel) untranslated_sixels = tll_init();
tll(struct sixel) translated_sixels = tll_init();
tll_foreach(grid->sixel_images, it)
tll_push_back(untranslated_sixels, it->item);
tll_free(grid->sixel_images);
@ -129,18 +128,7 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
struct sixel sixel = it->item;
sixel.pos.row = new_row_idx;
/* Make sure it doesn't cross the wrap-around after being re-based */
int end = (sixel.pos.row + sixel.rows - 1) & (new_rows - 1);
if (end < sixel.pos.row) {
/* TODO: split instead of destroying */
sixel_destroy(&it->item);
} else {
/* Insert sixel into the translated, but *unsorted* list. */
tll_push_back(translated_sixels, sixel);
}
/* Sixel has been either re-mapped, or destroyed */
tll_push_back(grid->sixel_images, sixel);
tll_remove(untranslated_sixels, it);
}
@ -346,46 +334,5 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
sixel_destroy(&it->item);
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);
}

48
sixel.c
View file

@ -508,6 +508,54 @@ sixel_cell_size_changed(struct terminal *term)
term->grid = g;
}
void
sixel_reflow(struct terminal *term)
{
struct grid *g = term->grid;
for (size_t i = 0; i < 2; i++) {
struct grid *grid = i == 0 ? &term->normal : &term->alt;
term->grid = grid;
/* Need the “real” list to be empty from the beginning */
tll(struct sixel) copy = tll_init();
tll_foreach(grid->sixel_images, it)
tll_push_back(copy, it->item);
tll_free(grid->sixel_images);
tll_rforeach(copy, it) {
struct sixel *six = &it->item;
int start = six->pos.row;
int end = (start + six->rows - 1) & (grid->num_rows - 1);
if (end < start) {
/* Crosses scrollback wrap-around */
/* TOOD: split image */
sixel_destroy(six);
continue;
}
if (six->rows > grid->num_rows) {
/* Image too large */
/* TODO: keep bottom part? */
sixel_destroy(six);
continue;
}
/* Sixels that didnt overlap may now do so, which isnt
* allowed of course */
_sixel_overwrite_by_rectangle(
term, six->pos.row, six->pos.col, six->rows, six->cols);
sixel_insert(term, it->item);
}
tll_free(copy);
}
term->grid = g;
}
void
sixel_unhook(struct terminal *term)
{

View file

@ -17,6 +17,8 @@ void sixel_scroll_up(struct terminal *term, int rows);
void sixel_scroll_down(struct terminal *term, int rows);
void sixel_cell_size_changed(struct terminal *term);
void sixel_reflow(struct terminal *term);
/*
* Remove sixel data from the specified location. Used when printing
* or erasing characters, and when emitting new sixel images, to