mirror of
https://github.com/tmux/tmux.git
synced 2026-09-05 21:20:45 +00:00
The implementation now distinguishes a newly placed image cell from one later overwritten by text. On a SIXEL terminal, damaged cells are omitted from image output; on Kitty they remain ordinary positional placements.
This commit is contained in:
30
grid.c
30
grid.c
@@ -778,6 +778,10 @@ grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc,
|
||||
struct grid_line *gl;
|
||||
struct grid_cell_entry *gce;
|
||||
struct grid_extd_entry *gee;
|
||||
const struct grid_cell *new_gc;
|
||||
#ifdef ENABLE_IMAGES
|
||||
struct grid_cell old_gc, image_gc;
|
||||
#endif
|
||||
u_int i;
|
||||
|
||||
if (grid_check_y(gd, __func__, py) != 0)
|
||||
@@ -791,11 +795,25 @@ grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc,
|
||||
|
||||
for (i = 0; i < slen; i++) {
|
||||
gce = &gl->celldata[px + i];
|
||||
new_gc = gc;
|
||||
#ifdef ENABLE_IMAGES
|
||||
{
|
||||
u_int old_id = grid_entry_image(gl, gce);
|
||||
u_int new_id = (gc->flags & GRID_FLAG_IMAGE) ?
|
||||
gc->image_id : 0;
|
||||
u_int new_id;
|
||||
|
||||
if (old_id != 0 && (~gc->flags & GRID_FLAG_IMAGE)) {
|
||||
grid_get_cell1(gl, px + i, &old_gc);
|
||||
memcpy(&image_gc, gc, sizeof image_gc);
|
||||
image_gc.flags |= GRID_FLAG_IMAGE|GRID_FLAG_IMAGE_DAMAGED;
|
||||
image_gc.image_id = old_gc.image_id;
|
||||
image_gc.image_x = old_gc.image_x;
|
||||
image_gc.image_y = old_gc.image_y;
|
||||
new_gc = &image_gc;
|
||||
}
|
||||
if (new_gc->flags & GRID_FLAG_IMAGE)
|
||||
new_id = new_gc->image_id;
|
||||
else
|
||||
new_id = 0;
|
||||
|
||||
if (old_id != new_id) {
|
||||
if (old_id != 0)
|
||||
@@ -805,11 +823,11 @@ grid_set_cells(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (grid_need_extended_cell(gce, gc)) {
|
||||
gee = grid_extended_cell(gl, gce, gc);
|
||||
if (grid_need_extended_cell(gce, new_gc)) {
|
||||
gee = grid_extended_cell(gl, gce, new_gc);
|
||||
gee->data = utf8_build_one(s[i]);
|
||||
} else
|
||||
grid_store_cell(gce, gc, s[i]);
|
||||
grid_store_cell(gce, new_gc, s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1322,7 +1340,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
|
||||
#ifdef ENABLE_IMAGES
|
||||
if (gc.flags & GRID_FLAG_IMAGE) {
|
||||
utf8_set(&gc.data, ' ');
|
||||
gc.flags &= ~GRID_FLAG_IMAGE;
|
||||
gc.flags &= ~(GRID_FLAG_IMAGE|GRID_FLAG_IMAGE_DAMAGED);
|
||||
gc.image_id = gc.image_x = gc.image_y = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
19
image.c
19
image.c
@@ -95,7 +95,8 @@ static const struct image_backend image_backend_fallback = {
|
||||
"fallback", IMAGE_BACKEND_SCROLLS, NULL, NULL, NULL
|
||||
};
|
||||
static const struct image_backend image_backend_sixel = {
|
||||
"sixel", IMAGE_BACKEND_GRAPHICAL, sixel_draw_rect,
|
||||
"sixel", IMAGE_BACKEND_GRAPHICAL|IMAGE_BACKEND_TEMPORAL,
|
||||
sixel_draw_rect,
|
||||
sixel_free_output, sixel_geometry_changed
|
||||
};
|
||||
|
||||
@@ -532,9 +533,15 @@ image_get_draw_cell(struct tty *tty, const struct grid_cell *gc,
|
||||
|
||||
if (image_backend_flags(tty) & IMAGE_BACKEND_GRAPHICAL) {
|
||||
memcpy(out, gc, sizeof *out);
|
||||
out->flags &= ~(GRID_FLAG_IMAGE|GRID_FLAG_SELECTED);
|
||||
out->flags &= ~(GRID_FLAG_IMAGE|GRID_FLAG_IMAGE_DAMAGED|
|
||||
GRID_FLAG_SELECTED);
|
||||
return (1);
|
||||
}
|
||||
if (gc->flags & GRID_FLAG_IMAGE_DAMAGED) {
|
||||
memcpy(out, gc, sizeof *out);
|
||||
out->flags &= ~(GRID_FLAG_IMAGE|GRID_FLAG_IMAGE_DAMAGED);
|
||||
return (0);
|
||||
}
|
||||
image_get_fallback_cell(tty, im, gc->image_x, gc->image_y, gc, out,
|
||||
style_ctx);
|
||||
return (0);
|
||||
@@ -545,6 +552,7 @@ void
|
||||
image_set_cell(struct grid_cell *gc, struct image *im, u_int x, u_int y)
|
||||
{
|
||||
/* Keep the cell contents as the underlay for transparent pixels. */
|
||||
gc->flags &= ~GRID_FLAG_IMAGE_DAMAGED;
|
||||
gc->flags |= GRID_FLAG_IMAGE;
|
||||
gc->image_id = im->id;
|
||||
gc->image_x = x;
|
||||
@@ -677,6 +685,11 @@ image_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py,
|
||||
run = 1;
|
||||
continue;
|
||||
}
|
||||
if ((backend->flags & IMAGE_BACKEND_TEMPORAL) &&
|
||||
(gc.flags & GRID_FLAG_IMAGE_DAMAGED)) {
|
||||
run = 1;
|
||||
continue;
|
||||
}
|
||||
im = image_find(gc.image_id);
|
||||
if (im == NULL) {
|
||||
run = 1;
|
||||
@@ -685,6 +698,8 @@ image_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py,
|
||||
for (run = 1; i + run < nx; run++) {
|
||||
grid_view_get_cell(s->grid, px + i + run, py, &next);
|
||||
if (~next.flags & GRID_FLAG_IMAGE ||
|
||||
((backend->flags & IMAGE_BACKEND_TEMPORAL) &&
|
||||
(next.flags & GRID_FLAG_IMAGE_DAMAGED)) ||
|
||||
next.image_id != gc.image_id ||
|
||||
next.image_y != gc.image_y ||
|
||||
next.image_x != gc.image_x + run)
|
||||
|
||||
@@ -2607,6 +2607,9 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
struct grid_line *gl;
|
||||
struct grid_cell_entry *gce;
|
||||
struct grid_cell tmp_gc, now_gc;
|
||||
#ifdef ENABLE_IMAGES
|
||||
struct grid_cell image_gc;
|
||||
#endif
|
||||
struct tty_ctx ttyctx;
|
||||
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
||||
u_int width = ud->width, xx, not_wrap, i, n, vis;
|
||||
@@ -2651,6 +2654,20 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
||||
return;
|
||||
screen_write_initctx(ctx, &ttyctx, 0, 0);
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
/* Update the text underlay without removing an image placement. */
|
||||
grid_view_get_cell(gd, s->cx, s->cy, &now_gc);
|
||||
if ((now_gc.flags & GRID_FLAG_IMAGE) &&
|
||||
(~gc->flags & GRID_FLAG_IMAGE)) {
|
||||
image_redraw_area(ctx, s->cx, s->cy, width, 1);
|
||||
memcpy(&image_gc, gc, sizeof image_gc);
|
||||
image_gc.flags |= GRID_FLAG_IMAGE|GRID_FLAG_IMAGE_DAMAGED;
|
||||
image_gc.image_id = now_gc.image_id;
|
||||
image_gc.image_x = now_gc.image_x;
|
||||
image_gc.image_y = now_gc.image_y;
|
||||
gc = &image_gc;
|
||||
}
|
||||
#endif
|
||||
/* Handle overwriting of UTF-8 characters. */
|
||||
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
|
||||
if (gl->flags & GRID_LINE_EXTENDED) {
|
||||
|
||||
2
tmux.h
2
tmux.h
@@ -810,6 +810,7 @@ struct colour_palette {
|
||||
#define GRID_FLAG_CLEARED 0x40
|
||||
#define GRID_FLAG_TAB 0x80
|
||||
#define GRID_FLAG_IMAGE 0x100
|
||||
#define GRID_FLAG_IMAGE_DAMAGED 0x200
|
||||
|
||||
/* Grid line flags. */
|
||||
#define GRID_LINE_WRAPPED 0x1
|
||||
@@ -4240,6 +4241,7 @@ char *regsub(const char *, const char *, const char *, int);
|
||||
/* image.c */
|
||||
#define IMAGE_BACKEND_GRAPHICAL 0x1
|
||||
#define IMAGE_BACKEND_SCROLLS 0x2
|
||||
#define IMAGE_BACKEND_TEMPORAL 0x4
|
||||
|
||||
struct image *image_create(u_int, u_int, u_int, u_int, u_int, u_int,
|
||||
u_char *);
|
||||
|
||||
Reference in New Issue
Block a user