mirror of
https://github.com/tmux/tmux.git
synced 2026-10-15 07:44:24 +00:00
Image resizing code.
This commit is contained in:
88
image-grid.c
88
image-grid.c
@@ -49,6 +49,10 @@ struct image_placement {
|
||||
struct image *image;
|
||||
struct image_spans spans;
|
||||
|
||||
/* Original column and first source column not yet placed. */
|
||||
u_int x;
|
||||
u_int recover_from;
|
||||
|
||||
TAILQ_ENTRY(image_placement) entry;
|
||||
};
|
||||
TAILQ_HEAD(image_placements, image_placement);
|
||||
@@ -73,6 +77,12 @@ struct image_move {
|
||||
u_int source_y;
|
||||
};
|
||||
|
||||
/* One image row to extend after a pane grows. */
|
||||
struct image_recover_row {
|
||||
struct image_line *line;
|
||||
u_int source_y;
|
||||
};
|
||||
|
||||
/* Get the placement store for a grid. */
|
||||
static struct image_store *
|
||||
image_store_get(struct grid *gd)
|
||||
@@ -312,6 +322,7 @@ image_grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
|
||||
moves[n].sx = span_end - start;
|
||||
moves[n].source_x = span->source_x + start - span->x;
|
||||
moves[n].source_y = span->source_y;
|
||||
span->placement->recover_from = 0;
|
||||
n++;
|
||||
}
|
||||
image_line_remove(line, px, nx);
|
||||
@@ -338,6 +349,8 @@ image_copy_placement(struct grid *dst, struct image_placement *src,
|
||||
return (map[i].destination);
|
||||
}
|
||||
plmt = image_placement_create(dst, src->image);
|
||||
plmt->x = src->x;
|
||||
plmt->recover_from = src->recover_from;
|
||||
|
||||
map = xreallocarray(map, n + 1, sizeof *map);
|
||||
map[n].source = src;
|
||||
@@ -413,6 +426,7 @@ image_grid_copy_area(struct grid *dst, u_int dx, u_int dy, struct grid *src,
|
||||
dst_line = image_line_get(&dst->linedata[dy + row]);
|
||||
plmt = image_copy_placement(dst, span->placement, &maps,
|
||||
&nmaps);
|
||||
plmt->recover_from = 0;
|
||||
image_span_add(dst_line, plmt, dx + start - px,
|
||||
span_end - start, span->source_x + start - span->x,
|
||||
span->source_y);
|
||||
@@ -549,6 +563,74 @@ image_add_row(struct image_line *line, struct image_placement *plmt,
|
||||
}
|
||||
}
|
||||
|
||||
/* Add newly visible columns from one image row. */
|
||||
static void
|
||||
image_extend_row(struct image_line *line, struct image_placement *plmt,
|
||||
u_int cx, u_int src_y, u_int from, u_int to)
|
||||
{
|
||||
struct image *im = plmt->image;
|
||||
u_int x, run;
|
||||
|
||||
for (x = from; x < to; x += run) {
|
||||
if (!image_cell_has_visible_pixels(im, x, src_y)) {
|
||||
run = 1;
|
||||
continue;
|
||||
}
|
||||
for (run = 1; x + run < to; run++) {
|
||||
if (!image_cell_has_visible_pixels(im, x + run, src_y))
|
||||
break;
|
||||
}
|
||||
image_span_add(line, plmt, cx + x, run, x, src_y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Extend image rows when grid is resized. */
|
||||
void
|
||||
image_grid_resize_width(struct grid *gd, u_int new_sx)
|
||||
{
|
||||
struct image_placement *plmt;
|
||||
struct image_span *span;
|
||||
struct image_recover_row *rows;
|
||||
u_int image_sx, image_sy, from, to;
|
||||
u_int nrows, i;
|
||||
|
||||
if (gd->images == NULL)
|
||||
return;
|
||||
TAILQ_FOREACH(plmt, &gd->images->placements, entry) {
|
||||
from = plmt->recover_from;
|
||||
if (from == 0 || plmt->x >= new_sx)
|
||||
continue;
|
||||
image_get_size_in_cells(plmt->image, &image_sx, &image_sy);
|
||||
|
||||
to = new_sx - plmt->x;
|
||||
if (to > image_sx)
|
||||
to = image_sx;
|
||||
if (to <= from)
|
||||
continue;
|
||||
|
||||
rows = NULL;
|
||||
nrows = 0;
|
||||
TAILQ_FOREACH(span, &plmt->spans, placement_entry) {
|
||||
for (i = 0; i < nrows; i++) {
|
||||
if (rows[i].line == span->line)
|
||||
break;
|
||||
}
|
||||
if (i != nrows)
|
||||
continue;
|
||||
rows = xreallocarray(rows, nrows + 1, sizeof *rows);
|
||||
rows[nrows].line = span->line;
|
||||
rows[nrows].source_y = span->source_y;
|
||||
nrows++;
|
||||
}
|
||||
for (i = 0; i < nrows; i++) {
|
||||
image_extend_row(rows[i].line, plmt, plmt->x,
|
||||
rows[i].source_y, from, to);
|
||||
}
|
||||
free(rows);
|
||||
plmt->recover_from = (to == image_sx ? 0 : to);
|
||||
}
|
||||
}
|
||||
|
||||
/* Place a SIXEL image at the cursor. */
|
||||
void
|
||||
image_write(struct screen_write_ctx *ctx, struct image *im, u_int bg)
|
||||
@@ -559,10 +641,12 @@ image_write(struct screen_write_ctx *ctx, struct image *im, u_int bg)
|
||||
struct grid_line *gl;
|
||||
struct image_line *line;
|
||||
u_int cx = s->cx, cy = s->cy, y, sx, sy, lines;
|
||||
u_int image_sx;
|
||||
u_int origin_y = 0, h_origin_y, region_height;
|
||||
u_int remaining, n;
|
||||
|
||||
image_get_size_in_cells(im, &sx, &sy);
|
||||
image_sx = sx;
|
||||
if (sx > screen_size_x(s) - cx)
|
||||
sx = screen_size_x(s) - cx;
|
||||
if (sx == 0)
|
||||
@@ -594,6 +678,10 @@ image_write(struct screen_write_ctx *ctx, struct image *im, u_int bg)
|
||||
sy -= origin_y;
|
||||
}
|
||||
plmt = image_placement_create(gd, im);
|
||||
if (sx < image_sx) {
|
||||
plmt->x = cx;
|
||||
plmt->recover_from = sx;
|
||||
}
|
||||
|
||||
/* Attach scrolled image rows to the available history lines. */
|
||||
h_origin_y = origin_y;
|
||||
|
||||
@@ -89,6 +89,7 @@ void image_grid_duplicate_lines(struct grid *, u_int, struct grid *,
|
||||
u_int, u_int);
|
||||
void image_grid_copy_area(struct grid *, u_int, u_int, struct grid *,
|
||||
u_int, u_int, u_int, u_int);
|
||||
void image_grid_resize_width(struct grid *, u_int);
|
||||
int image_grid_line_has_images(struct grid_line *);
|
||||
int image_grid_area_has_images(struct grid *, u_int, u_int, u_int,
|
||||
u_int);
|
||||
|
||||
4
window.c
4
window.c
@@ -1778,6 +1778,10 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
||||
|
||||
log_debug("%s: %%%u resize %ux%u", __func__, wp->id, sx, sy);
|
||||
screen_resize(&wp->base, sx, sy, wp->base.saved_grid == NULL);
|
||||
#ifdef ENABLE_IMAGES
|
||||
if (sx > r->osx)
|
||||
image_grid_resize_width(wp->base.grid, sx);
|
||||
#endif
|
||||
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme != NULL && wme->mode->resize != NULL)
|
||||
|
||||
Reference in New Issue
Block a user