diff --git a/image-sixel.c b/image-sixel.c index e23d17f9..8fa02a82 100644 --- a/image-sixel.c +++ b/image-sixel.c @@ -37,8 +37,13 @@ struct sixel_image { u_int xpixel; u_int ypixel; + u_int set_ra; + u_int ra_x; + u_int ra_y; + u_int *colours; u_int ncolours; + u_int p2; u_int dx; u_int dy; @@ -166,6 +171,10 @@ sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end) si->x = x; sixel_parse_expand_lines(si, y); + si->set_ra = 1; + si->ra_x = x; + si->ra_y = y; + return (last); } @@ -268,7 +277,7 @@ sixel_parse_repeat(struct sixel_image *si, const char *cp, const char *end) } struct sixel_image * -sixel_parse(const char *buf, size_t len, u_int xpixel, u_int ypixel) +sixel_parse(const char *buf, size_t len, u_int p2, u_int xpixel, u_int ypixel) { struct sixel_image *si; const char *cp = buf, *end = buf + len; @@ -282,6 +291,7 @@ sixel_parse(const char *buf, size_t len, u_int xpixel, u_int ypixel) si = xcalloc (1, sizeof *si); si->xpixel = xpixel; si->ypixel = ypixel; + si->p2 = p2; while (cp != end) { ch = *cp++; @@ -423,6 +433,18 @@ sixel_scale(struct sixel_image *si, u_int xpixel, u_int ypixel, u_int ox, new = xcalloc (1, sizeof *si); new->xpixel = xpixel; new->ypixel = ypixel; + new->p2 = si->p2; + + new->set_ra = si->set_ra; + /* clamp to slice end */ + new->ra_x = si->ra_x < psx ? si->ra_x : psx; + new->ra_y = si->ra_y < psy ? si->ra_y : psy; + /* subtract slice origin */ + new->ra_x = new->ra_x > pox ? new->ra_x - pox : 0; + new->ra_y = new->ra_y > poy ? new->ra_y - poy : 0; + /* resize */ + new->ra_x = new->ra_x * xpixel / si->xpixel; + new->ra_y = new->ra_y * ypixel / si->ypixel; for (y = 0; y < tsy; y++) { py = poy + ((double)y * psy / tsy); @@ -497,11 +519,15 @@ sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size) len = 8192; buf = xmalloc(len); - sixel_print_add(&buf, &len, &used, "\033Pq", 3); - - tmplen = xsnprintf(tmp, sizeof tmp, "\"1;1;%u;%u", si->x, si->y); + tmplen = xsnprintf(tmp, sizeof tmp, "\033P0;%uq", si->p2); sixel_print_add(&buf, &len, &used, tmp, tmplen); + if (si->set_ra) { + tmplen = xsnprintf(tmp, sizeof tmp, "\"1;1;%u;%u", si->ra_x, + si->ra_y); + sixel_print_add(&buf, &len, &used, tmp, tmplen); + } + for (i = 0; i < ncolours; i++) { c = colours[i]; tmplen = xsnprintf(tmp, sizeof tmp, "#%u;%u;%u;%u;%u", @@ -552,8 +578,7 @@ sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size) if (buf[used - 1] == '$') used--; - if (buf[used - 1] != '-') - sixel_print_add(&buf, &len, &used, "-", 1); + sixel_print_add(&buf, &len, &used, "-", 1); } if (buf[used - 1] == '$' || buf[used - 1] == '-') used--; diff --git a/input.c b/input.c index adf7232b..a046fa8b 100644 --- a/input.c +++ b/input.c @@ -2320,6 +2320,7 @@ input_dcs_dispatch(struct input_ctx *ictx) #ifdef ENABLE_SIXEL struct window *w; struct sixel_image *si; + int p2; #endif if (wp == NULL) @@ -2333,7 +2334,12 @@ input_dcs_dispatch(struct input_ctx *ictx) #ifdef ENABLE_SIXEL w = wp->window; if (buf[0] == 'q') { - si = sixel_parse(buf, len, w->xpixel, w->ypixel); + if (input_split(ictx) != 0) + return (0); + p2 = input_get(ictx, 1, 0, 0); + if (p2 == -1) + p2 = 0; + si = sixel_parse(buf, len, p2, w->xpixel, w->ypixel); if (si != NULL) screen_write_sixelimage(sctx, si, ictx->cell.cell.bg); } diff --git a/tmux.h b/tmux.h index 4db4b670..9ea71e10 100644 --- a/tmux.h +++ b/tmux.h @@ -3493,7 +3493,7 @@ int image_scroll_up(struct screen *, u_int); /* image-sixel.c */ #define SIXEL_COLOUR_REGISTERS 1024 -struct sixel_image *sixel_parse(const char *, size_t, u_int, u_int); +struct sixel_image *sixel_parse(const char *, size_t, u_int, u_int, u_int); void sixel_free(struct sixel_image *); void sixel_log(struct sixel_image *); void sixel_size_in_cells(struct sixel_image *, u_int *, u_int *);