diff --git a/image.c b/image.c index dcc1edae0..cb73fe902 100644 --- a/image.c +++ b/image.c @@ -530,7 +530,7 @@ image_get_fallback_cell(__unused struct tty *tty, struct image *im, u_int x, void image_set_cell(struct grid_cell *gc, struct image *im, u_int x, u_int y) { - memcpy(gc, &grid_default_cell, sizeof *gc); + /* Keep the cell contents as the underlay for transparent pixels. */ gc->flags |= GRID_FLAG_IMAGE; gc->image_id = im->id; gc->image_x = x; @@ -672,7 +672,9 @@ image_clear(struct screen_write_ctx *ctx, u_int id) if (y >= gd->hsize) image_redraw_area(ctx, x, y - gd->hsize, 1, 1); - grid_set_cell(gd, x, y, &grid_default_cell); + gc.flags &= ~GRID_FLAG_IMAGE; + gc.image_id = gc.image_x = gc.image_y = 0; + grid_set_cell(gd, x, y, &gc); } } } @@ -810,8 +812,8 @@ image_write(struct screen_write_ctx *ctx, struct image *im, u_int bg) for (y = 0; y < sy; y++) { for (x = 0; x < sx; x++) { + grid_view_get_cell(gd, cx + x, cy + y, &gc); image_set_cell(&gc, im, x, origin_y + y); - gc.bg = bg; grid_view_set_cell(gd, cx + x, cy + y, &gc); } } diff --git a/regress/image-support.sh b/regress/image-support.sh index 079680792..aa19fa791 100755 --- a/regress/image-support.sh +++ b/regress/image-support.sh @@ -223,6 +223,18 @@ $TMUX capture-pane -pS0 -E3 >$TMP || exit 1 [ -z "$(sed -n 2p $TMP)" ] || exit 1 [ "$(sed -n 4p $TMP)" = " @@" ] || exit 1 +# Image markers retain the cells beneath them. Deleting a transparent image +# must reveal the original text rather than replacing it with spaces. +PLACEMENT_WINDOW=$($TMUX2 new-window -dP -F '#{window_id}' " + printf 'XY' + printf '\033[H' + printf '\033_Ga=T,q=2,C=1,f=32,s=1,v=1,c=2,r=1,i=13,p=7;////AA==\033\\' + printf '\033_Ga=d,d=i,q=2,i=13,p=7\033\\' + sleep 10") || exit 1 +$TMUX2 select-window -t"$PLACEMENT_WINDOW" || exit 1 +sleep 1 +[ "$($TMUX2 capture-pane -pS0 -E0)" = "XY" ] || exit 1 + # A weighted median at the maximum channel level must still leave colours on # both sides of the split. This skewed black, grey and white image used to stop # palette generation after one colour instead of producing three. diff --git a/tty-draw.c b/tty-draw.c index 6e815cb54..ff3f6148c 100644 --- a/tty-draw.c +++ b/tty-draw.c @@ -29,7 +29,6 @@ enum tty_draw_line_state { TTY_DRAW_LINE_NEW1, TTY_DRAW_LINE_NEW2, TTY_DRAW_LINE_EMPTY, - TTY_DRAW_LINE_IMAGE, TTY_DRAW_LINE_SAME, TTY_DRAW_LINE_DONE }; @@ -39,7 +38,6 @@ static const char* tty_draw_line_states[] = { "NEW1", "NEW2", "EMPTY", - "IMAGE", "SAME", "DONE" }; @@ -132,7 +130,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, struct grid_line *gl; u_int i, j, last_i, cx, ex, width; u_int cellsize, bg; - int flags, empty, skip, wrapped = 0; + int flags, empty, wrapped = 0; char buf[1000]; size_t len; enum tty_draw_line_state current_state, next_state; @@ -237,8 +235,6 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, width = 0; current_state = TTY_DRAW_LINE_FIRST; for (;;) { - skip = 0; - /* Work out the next state. */ if (i == nx) { /* @@ -262,24 +258,22 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, grid_view_get_cell(gd, px + i, py, &gc); #ifdef ENABLE_IMAGES - /* Text terminals render image blocks as ASCII. */ + /* + * Graphical terminals draw the saved cell underlay + * before the image; text terminals use ASCII. + */ if (gc.flags & GRID_FLAG_IMAGE) { im = image_find(gc.image_id); if (image_tty_is_graphical(tty)) { memcpy(&image_gc, &gc, sizeof image_gc); - utf8_set(&image_gc.data, ' '); - image_gc.flags &= - ~GRID_FLAG_IMAGE; - skip = 1; + image_gc.flags &= ~(GRID_FLAG_IMAGE| + GRID_FLAG_SELECTED); } else { image_get_fallback_cell(tty, im, gc.image_x, gc.image_y, &gc, &image_gc, style_ctx); } - if (skip) - image_gc.flags &= - ~GRID_FLAG_SELECTED; gcp = &image_gc; } else gcp = &gc; @@ -288,12 +282,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, #endif /* Work out empty cells. */ - if (skip) - empty = 0; - else - empty = tty_draw_line_get_empty(gcp, - &last, nx - i); - if (empty != 0 || skip) + empty = tty_draw_line_get_empty(gcp, &last, nx - i); + if (empty != 0) ; else { /* Update for codeset if needed. */ @@ -310,9 +300,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, } /* Work out the next state. */ - if (skip) - next_state = TTY_DRAW_LINE_IMAGE; - else if (empty != 0) + if (empty != 0) next_state = TTY_DRAW_LINE_EMPTY; else if (current_state == TTY_DRAW_LINE_FIRST) next_state = TTY_DRAW_LINE_SAME; @@ -359,8 +347,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, } /* Append the cell if it is not empty and not padding. */ - if (next_state != TTY_DRAW_LINE_EMPTY && - next_state != TTY_DRAW_LINE_IMAGE) { + if (next_state != TTY_DRAW_LINE_EMPTY) { memcpy(buf + len, gcp->data.data, gcp->data.size); len += gcp->data.size; width += gcp->data.width;