mirror of
https://github.com/tmux/tmux.git
synced 2026-10-14 23:34:22 +00:00
Fix some errors from merge.
This commit is contained in:
116
image-grid.c
116
image-grid.c
@@ -206,41 +206,47 @@ image_grid_add(struct grid *gd, struct image *im, u_int x, u_int y,
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the covered part of a span. */
|
||||
/* Remove the covered part of one span. */
|
||||
static void
|
||||
image_span_remove(struct image_span *span, u_int x, u_int end)
|
||||
{
|
||||
u_int span_end = span->x + span->sx;
|
||||
|
||||
if (span_end <= x || span->x >= end)
|
||||
return;
|
||||
if (span->x < x && span_end > end) {
|
||||
span->sx = x - span->x;
|
||||
image_span_add(span->line, span->placement, end, span_end - end,
|
||||
span->source_x + end - span->x, span->source_y);
|
||||
return;
|
||||
}
|
||||
if (span->x < x) {
|
||||
span->sx = x - span->x;
|
||||
return;
|
||||
}
|
||||
if (span_end > end) {
|
||||
span->source_x += end - span->x;
|
||||
span->sx = span_end - end;
|
||||
span->x = end;
|
||||
return;
|
||||
}
|
||||
image_span_free(span);
|
||||
}
|
||||
|
||||
/* Remove a range of cells from every span on a line. */
|
||||
static void
|
||||
image_line_remove(struct image_line *line, u_int x, u_int w)
|
||||
{
|
||||
struct image_span *span, *next;
|
||||
u_int end, span_end, right;
|
||||
u_int end;
|
||||
|
||||
if (line == NULL || w == 0)
|
||||
return;
|
||||
end = x + w;
|
||||
if (end < x)
|
||||
end = UINT_MAX;
|
||||
TAILQ_FOREACH_SAFE(span, &line->spans, line_entry, next) {
|
||||
span_end = span->x + span->sx;
|
||||
if (span_end <= x || span->x >= end)
|
||||
continue;
|
||||
if (span->x < x && span_end > end) {
|
||||
right = span_end - end;
|
||||
span->sx = x - span->x;
|
||||
image_span_add(line, span->placement, end, right,
|
||||
span->source_x + end - span->x, span->source_y);
|
||||
continue;
|
||||
}
|
||||
if (span->x < x) {
|
||||
span->sx = x - span->x;
|
||||
continue;
|
||||
}
|
||||
if (span_end > end) {
|
||||
span->source_x += end - span->x;
|
||||
span->sx = span_end - end;
|
||||
span->x = end;
|
||||
continue;
|
||||
}
|
||||
image_span_free(span);
|
||||
}
|
||||
TAILQ_FOREACH_SAFE(span, &line->spans, line_entry, next)
|
||||
image_span_remove(span, x, end);
|
||||
}
|
||||
|
||||
/* Remove a rectangle of image spans from a grid. */
|
||||
@@ -542,13 +548,69 @@ image_cell_has_visible_pixels(struct image *im, u_int x, u_int y)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return whether a new cell's pixels completely cover an old cell. */
|
||||
static int
|
||||
image_cell_covers(struct image *new, u_int nx, u_int ny, struct image *old,
|
||||
u_int ox, u_int oy)
|
||||
{
|
||||
u_int npx, npy, nsx, nsy, opx, opy, osx, osy, xx, yy;
|
||||
u_int ncw, nch, ocw, och, ncx, ncy, ocx, ocy;
|
||||
const u_char *np, *op, *npixels, *opixels;
|
||||
size_t nstride, ostride;
|
||||
|
||||
image_get_canvas_size(new, &ncw, &nch);
|
||||
image_get_canvas_size(old, &ocw, &och);
|
||||
image_get_size_in_cells(new, &ncx, &ncy);
|
||||
image_get_size_in_cells(old, &ocx, &ocy);
|
||||
if (ncw / ncx != ocw / ocx || nch / ncy != och / ocy)
|
||||
return (0);
|
||||
image_get_pixel_area(new, nx, ny, 1, 1, &npx, &npy, &nsx, &nsy);
|
||||
image_get_pixel_area(old, ox, oy, 1, 1, &opx, &opy, &osx, &osy);
|
||||
|
||||
npixels = image_get_pixels(new, &nstride, NULL);
|
||||
opixels = image_get_pixels(old, &ostride, NULL);
|
||||
for (yy = 0; yy < osy; yy++) {
|
||||
op = opixels + (opy + yy) * ostride + opx * 4;
|
||||
if (yy < nsy) {
|
||||
np = npixels + (npy + yy) * nstride + npx * 4;
|
||||
}
|
||||
for (xx = 0; xx < osx; xx++) {
|
||||
if (op[xx * 4 + 3] == 0)
|
||||
continue;
|
||||
if (yy >= nsy || xx >= nsx || np[xx * 4 + 3] != 255)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Discard cells of older placements fully covered by a new image. */
|
||||
static void
|
||||
image_line_cover(struct image_line *line, struct image_placement *plmt,
|
||||
u_int x, u_int src_x, u_int src_y)
|
||||
{
|
||||
struct image_span *span, *next;
|
||||
struct image_placement *old;
|
||||
|
||||
TAILQ_FOREACH_SAFE(span, &line->spans, line_entry, next) {
|
||||
old = span->placement;
|
||||
if (old == plmt || x < span->x || x >= span->x + span->sx)
|
||||
continue;
|
||||
if (!image_cell_covers(plmt->image, src_x, src_y,
|
||||
old->image, span->source_x + x - span->x,
|
||||
span->source_y))
|
||||
continue;
|
||||
image_span_remove(span, x, x + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach the visible runs from one image row. */
|
||||
static void
|
||||
image_add_row(struct image_line *line, struct image_placement *plmt,
|
||||
u_int cx, u_int src_y, u_int sx)
|
||||
{
|
||||
struct image *im = plmt->image;
|
||||
u_int x, run;
|
||||
u_int x, i, run;
|
||||
|
||||
for (x = 0; x < sx; x += run) {
|
||||
if (!image_cell_has_visible_pixels(im, x, src_y)) {
|
||||
@@ -559,6 +621,8 @@ image_add_row(struct image_line *line, struct image_placement *plmt,
|
||||
if (!image_cell_has_visible_pixels(im, x + run, src_y))
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < run; i++)
|
||||
image_line_cover(line, plmt, cx + x + i, x + i, src_y);
|
||||
image_span_add(line, plmt, cx + x, run, x, src_y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,18 +61,25 @@ struct sixel_image {
|
||||
u_int dy;
|
||||
u_int dc;
|
||||
|
||||
/* Lines of palette indexes. */
|
||||
/* Lines of palette indexes and the bytes allocated for them. */
|
||||
struct sixel_line *lines;
|
||||
size_t allocated;
|
||||
};
|
||||
|
||||
/* Grow a SIXEL image to contain a line. */
|
||||
static int
|
||||
sixel_parse_expand_lines(struct sixel_image *si, u_int y)
|
||||
{
|
||||
u_int height = si->y;
|
||||
|
||||
if (y > height)
|
||||
height = y;
|
||||
if (height > SIXEL_HEIGHT_LIMIT)
|
||||
return (1);
|
||||
if (si->x * height > IMAGE_SIZE_LIMIT / 4)
|
||||
return (1);
|
||||
if (y <= si->y)
|
||||
return (0);
|
||||
if (y > SIXEL_HEIGHT_LIMIT)
|
||||
return (1);
|
||||
si->lines = xrecallocarray(si->lines, si->y, y, sizeof *si->lines);
|
||||
si->y = y;
|
||||
return (0);
|
||||
@@ -82,14 +89,24 @@ sixel_parse_expand_lines(struct sixel_image *si, u_int y)
|
||||
static int
|
||||
sixel_parse_expand_line(struct sixel_image *si, struct sixel_line *sl, u_int x)
|
||||
{
|
||||
u_int width = si->x;
|
||||
size_t added;
|
||||
|
||||
if (x > width)
|
||||
width = x;
|
||||
if (width > SIXEL_WIDTH_LIMIT)
|
||||
return (1);
|
||||
if (width * si->y > IMAGE_SIZE_LIMIT / 4)
|
||||
return (1);
|
||||
if (x <= sl->x)
|
||||
return (0);
|
||||
if (x > SIXEL_WIDTH_LIMIT)
|
||||
added = (width - sl->x) * sizeof *sl->data;
|
||||
if (added > IMAGE_SIZE_LIMIT / 2 - si->allocated)
|
||||
return (1);
|
||||
if (x > si->x)
|
||||
si->x = x;
|
||||
si->x = width;
|
||||
sl->data = xrecallocarray(sl->data, sl->x, si->x, sizeof *sl->data);
|
||||
sl->x = si->x;
|
||||
si->allocated += added;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -204,7 +221,10 @@ sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end)
|
||||
}
|
||||
|
||||
si->x = x;
|
||||
sixel_parse_expand_lines(si, y);
|
||||
if (sixel_parse_expand_lines(si, y) != 0) {
|
||||
log_debug("%s: size limit reached", __func__);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (last);
|
||||
}
|
||||
@@ -320,7 +340,7 @@ sixel_parse_repeat(struct sixel_image *si, const char *cp, const char *end)
|
||||
ch = (*last++) - 0x3f;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (sixel_parse_write(si, ch) != 0) {
|
||||
log_debug("%s: width limit reached", __func__);
|
||||
log_debug("%s: size limit reached", __func__);
|
||||
return (NULL);
|
||||
}
|
||||
si->dx++;
|
||||
@@ -379,7 +399,7 @@ sixel_parse(const char *buf, size_t len, u_int p1, u_int p2, u_int xpixel,
|
||||
if (ch < 0x3f || ch > 0x7e)
|
||||
goto bad;
|
||||
if (sixel_parse_write(si, ch - 0x3f) != 0) {
|
||||
log_debug("%s: width limit reached", __func__);
|
||||
log_debug("%s: size limit reached", __func__);
|
||||
goto bad;
|
||||
}
|
||||
si->dx++;
|
||||
|
||||
@@ -730,6 +730,10 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
|
||||
grid_get_cell(gd, xx, yy, &gc);
|
||||
if (xx + gc.data.width > px + nx)
|
||||
break;
|
||||
#ifdef ENABLE_IMAGES
|
||||
if (ctx->flags & SCREEN_WRITE_INPUT)
|
||||
image_damage_screen(ctx, s->cx, s->cy, 1, 1);
|
||||
#endif
|
||||
grid_view_set_cell(s->grid, s->cx, s->cy, &gc);
|
||||
|
||||
if (!window_position_is_visible(r, xoff + s->cx))
|
||||
|
||||
@@ -5797,6 +5797,9 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
char *expanded;
|
||||
struct format_tree *ft;
|
||||
int current, mode;
|
||||
#ifdef ENABLE_IMAGES
|
||||
int flags;
|
||||
#endif
|
||||
|
||||
width = window_copy_line_number_width(wme);
|
||||
if (width >= sx)
|
||||
@@ -5856,6 +5859,8 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
data->backing->grid, 0, hsize - data->oy + py, content_sx, 1);
|
||||
if (data->image_refresh)
|
||||
image_redraw_area(ctx, width, py, content_sx, 1);
|
||||
flags = ctx->flags;
|
||||
ctx->flags |= SCREEN_WRITE_INPUT;
|
||||
#endif
|
||||
|
||||
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
|
||||
@@ -5877,6 +5882,9 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
screen_write_putc(ctx, &grid_default_cell, '$');
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IMAGES
|
||||
ctx->flags = flags;
|
||||
#endif
|
||||
format_free(ft);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user