diff --git a/image.c b/image.c index a7f566fc..96399806 100644 --- a/image.c +++ b/image.c @@ -37,13 +37,15 @@ image_free(struct image *im) free(im); } -void +int image_free_all(struct screen *s) { struct image *im, *im1; + int redraw = !TAILQ_EMPTY(&s->images); TAILQ_FOREACH_SAFE(im, &s->images, entry, im1) image_free(im); + return (redraw); } void @@ -97,3 +99,35 @@ image_check_area(struct screen *s, u_int px, u_int py, u_int nx, u_int ny) } return (redraw); } + +int +image_scroll_up(struct screen *s, u_int lines) +{ + struct image *im, *im1; + int redraw = 0; + u_int sx, sy; + struct sixel_image *new; + + TAILQ_FOREACH_SAFE(im, &s->images, entry, im1) { + if (im->py >= lines) { + im->py -= lines; + redraw = 1; + continue; + } + if (im->py + im->sy < lines) { + image_free(im); + redraw = 1; + continue; + } + sx = im->sx; + sy = (im->py + im->sy) - lines; + + new = sixel_scale(im->data, 0, 0, 0, im->sy - sy, sx, sy, 1); + sixel_free(im->data); + im->data = new; + + im->py = 0; + redraw = 1; + } + return (redraw); +} diff --git a/sixel.c b/sixel.c index 3d544b83..68ca9a5d 100644 --- a/sixel.c +++ b/sixel.c @@ -350,11 +350,11 @@ sixel_size_in_cells(struct sixel_image *si, u_int *x, u_int *y) struct sixel_image * sixel_scale(struct sixel_image *si, u_int xpixel, u_int ypixel, u_int ox, - u_int oy, u_int sx, u_int sy) + u_int oy, u_int sx, u_int sy, int colours) { struct sixel_image *new; u_int cx, cy, pox, poy, psx, psy, tsx, tsy, px, py; - u_int x, y; + u_int x, y, i; /* * We want to get the section of the image at ox,oy in image cells and @@ -372,6 +372,11 @@ sixel_scale(struct sixel_image *si, u_int xpixel, u_int ypixel, u_int ox, if (oy + sy >= cy) sy = cy - oy; + if (xpixel == 0) + xpixel = si->xpixel; + if (ypixel == 0) + ypixel = si->ypixel; + pox = ox * si->xpixel; poy = oy * si->ypixel; psx = sx * si->xpixel; @@ -391,6 +396,13 @@ sixel_scale(struct sixel_image *si, u_int xpixel, u_int ypixel, u_int ox, sixel_set_pixel(new, x, y, sixel_get_pixel(si, px, py)); } } + + if (colours) { + new->colours = xmalloc(si->ncolours * sizeof *new->colours); + for (i = 0; i < si->ncolours; i++) + new->colours[i] = si->colours[i]; + new->ncolours = si->ncolours; + } return (new); } diff --git a/tmux.h b/tmux.h index 668654e3..48b36354 100644 --- a/tmux.h +++ b/tmux.h @@ -2721,10 +2721,11 @@ struct window_pane *spawn_pane(struct spawn_context *, char **); char *regsub(const char *, const char *, const char *, int); /* image.c */ -void image_free_all(struct screen *); +int image_free_all(struct screen *); void image_store(struct screen *, struct sixel_image *); int image_check_line(struct screen *, u_int, u_int); int image_check_area(struct screen *, u_int, u_int, u_int, u_int); +int image_scroll_up(struct screen *, u_int); /* sixel.c */ struct sixel_image *sixel_parse(const char *, size_t, u_int, u_int); @@ -2732,7 +2733,7 @@ void sixel_free(struct sixel_image *); void sixel_log(struct sixel_image *); void sixel_size_in_cells(struct sixel_image *, u_int *, u_int *); struct sixel_image *sixel_scale(struct sixel_image *, u_int, u_int, u_int, - u_int, u_int, u_int); + u_int, u_int, u_int, int); char *sixel_print(struct sixel_image *, struct sixel_image *, size_t *); struct screen *sixel_to_screen(struct sixel_image *);