Crop and scale images as needed when drawing them.

pull/3363/head
Nicholas Marriott 2019-11-28 13:21:40 +00:00
parent e24acc0b5c
commit e01df67ca1
5 changed files with 60 additions and 24 deletions

17
input.c
View File

@ -2151,10 +2151,13 @@ static int
input_dcs_dispatch(struct input_ctx *ictx)
{
struct screen_write_ctx *sctx = &ictx->ctx;
u_char *buf = ictx->input_buf, *pbuf = ictx->param_buf;
size_t len = ictx->input_len, plen = ictx->param_len;
struct window_pane *wp = ictx->wp;
struct window *w = wp->window;
u_char *buf = ictx->input_buf;
size_t len = ictx->input_len;
const char prefix[] = "tmux;";
const u_int prefixlen = (sizeof prefix) - 1;
struct sixel_image *si;
if (ictx->flags & INPUT_DISCARD)
return (0);
@ -2166,10 +2169,12 @@ input_dcs_dispatch(struct input_ctx *ictx)
screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen);
if (buf[0] == 'q') {
screen_write_rawsixel(sctx, (char *)"\033P", 2, 1);
screen_write_rawsixel(sctx, pbuf, plen, 1);
screen_write_rawsixel(sctx, buf, len, 1);
screen_write_rawsixel(sctx, (char *)"\033\\", 2, 0);
si = sixel_parse(buf, len, w->xpixel, w->ypixel);
if (si != NULL) {
sixel_log(si);
screen_write_sixelimage(sctx, si);
sixel_free(si);
}
}
return (0);

View File

@ -1672,17 +1672,14 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
tty_write(tty_cmd_rawstring, &ttyctx);
}
/* Write unmodified SIXEL data. */
/* Write a SIXEL image. */
void
screen_write_rawsixel(struct screen_write_ctx *ctx, u_char *str, u_int len,
int more)
screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si)
{
struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx);
ttyctx.ptr = str;
ttyctx.num = len;
ttyctx.more = more;
ttyctx.ptr = si;
tty_write(tty_cmd_rawsixel, &ttyctx);
tty_write(tty_cmd_sixelimage, &ttyctx);
}

View File

@ -428,7 +428,7 @@ sixel_print_repeat(char **buf, size_t *len, size_t *used, u_int count, char ch)
}
char *
sixel_print(struct sixel_image *si, struct sixel_image *map)
sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size)
{
char *buf, tmp[64], *contains, data, last;
size_t len, used = 0, tmplen;
@ -509,7 +509,10 @@ sixel_print(struct sixel_image *si, struct sixel_image *map)
used--;
sixel_print_add(&buf, &len, &used, "\033\\", 2);
buf[used] = '\0';
if (size != NULL)
*size = used;
free(contains);
return (buf);

9
tmux.h
View File

@ -55,6 +55,7 @@ struct options;
struct options_entry;
struct options_array_item;
struct session;
struct sixel_image;
struct tmuxpeer;
struct tmuxproc;
struct winlink;
@ -1250,7 +1251,6 @@ struct tty_ctx {
u_int num;
void *ptr;
int more;
/*
* Cursor and region position before the screen was updated - this is
@ -1974,7 +1974,7 @@ void tty_cmd_scrolldown(struct tty *, const struct tty_ctx *);
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
void tty_cmd_rawsixel(struct tty *, const struct tty_ctx *);
void tty_cmd_sixelimage(struct tty *, const struct tty_ctx *);
/* tty-term.c */
extern struct tty_terms tty_terms;
@ -2361,7 +2361,7 @@ void screen_write_collect_add(struct screen_write_ctx *,
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawsixel(struct screen_write_ctx *, u_char *, u_int, int);
void screen_write_sixelimage(struct screen_write_ctx *, struct sixel_image *);
/* screen-redraw.c */
void screen_redraw_screen(struct client *);
@ -2711,6 +2711,7 @@ 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);
char *sixel_print(struct sixel_image *, struct sixel_image *);
char *sixel_print(struct sixel_image *, struct sixel_image *,
size_t *);
#endif /* TMUX_H */

42
tty.c
View File

@ -1867,15 +1867,45 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
}
void
tty_cmd_rawsixel(struct tty *tty, const struct tty_ctx *ctx)
tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
{
int flags = (tty->term->flags|tty->term_flags);
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
struct sixel_image *si = ctx->ptr;
struct sixel_image *new;
int flags = (tty->term->flags|tty->term_flags);
char *data;
size_t size;
u_int cx = s->cx, cy = s->cy, sx, sy;
u_int i, j, x, y, rx, ry;
if ((flags & TERM_SIXEL) || tty_term_has(tty->term, TTYC_SXL)) {
tty_add(tty, ctx->ptr, ctx->num);
if (!ctx->more)
tty_invalidate(tty);
if ((~flags & TERM_SIXEL) && tty_term_has(tty->term, TTYC_SXL))
return;
if (tty->xpixel == 0 || tty->ypixel == 0)
return;
sixel_size_in_cells(si, &sx, &sy);
if (sx > wp->sx - cx)
sx = wp->sx - cx;
if (sy > wp->sy - cy)
sy = wp->sy - cy;
if (!tty_clamp_area(tty, ctx, cx, cy, sx, sy, &i, &j, &x, &y, &rx, &ry))
return;
new = sixel_scale(si, tty->xpixel, tty->ypixel, i, j, rx, ry);
if (new == NULL)
return;
data = sixel_print(new, si, &size);
if (data != NULL) {
log_debug("%s: %zu bytes: %s", __func__, size, data);
tty_cursor(tty, x, y);
tty_add(tty, data, size);
tty_invalidate(tty);
free(data);
}
sixel_free(new);
}
static void