From 0bfa8c33fddda1513e50bcb1fed311e8a2d79779 Mon Sep 17 00:00:00 2001 From: nick black Date: Wed, 30 Jun 2021 23:45:48 -0400 Subject: [PATCH] [sixel] clean up cells even when under a new sixel #1537 --- src/lib/internal.h | 8 +++++--- src/lib/sixel.c | 37 +++++++++++++++++++++---------------- src/lib/sprite.c | 2 +- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/lib/internal.h b/src/lib/internal.h index 2b7cbd561..5ae5f9fa0 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -792,7 +792,7 @@ uint8_t* kitty_trans_auxvec(const struct tinfo* ti); // these three all use absolute coordinates void sprixel_invalidate(sprixel* s, int y, int x); void sprixel_movefrom(sprixel* s, int y, int x); -void sprixel_debug(FILE* out, const sprixel* s); +void sprixel_debug(const sprixel* s, FILE* out); void sixelmap_free(struct sixelmap *s); // create an auxiliary vector suitable for a sprixcell, and zero it out. there @@ -809,6 +809,8 @@ int kitty_blit(ncplane* nc, int linesize, const void* data, int leny, int lenx, static inline int sprite_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ +//fprintf(stderr, "Destroying sprite %u\n", s->id); +//sprixel_debug(s, stderr); return nc->tcache.pixel_destroy(nc, p, out, s); } @@ -816,7 +818,7 @@ sprite_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ // returns -1 on error, or the number of bytes written. static inline int sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ -//sprixel_debug(stderr, s); +//sprixel_debug(s, stderr); return n->tcache.pixel_draw(p, s, out); } @@ -824,7 +826,7 @@ sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ // returns -1 on error, or the number of bytes written. static inline int sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ -//sprixel_debug(stderr, s); +//sprixel_debug(s, stderr); if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){ return n->tcache.pixel_move(p, s, out); }else{ diff --git a/src/lib/sixel.c b/src/lib/sixel.c index 90b13996a..6da773517 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -790,8 +790,12 @@ int sixel_blit(ncplane* n, int linesize, const void* data, int leny, int lenx, return r; } +// to destroy a sixel, we damage all cells underneath it. we might not have +// to, though, if we've got a new sixel ready to go where the old sixel was +// (though we'll still need to if the new sprixcell not opaque, and the +// old and new sprixcell are different in any transparent pixel). int sixel_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ -//fprintf(stderr, "%d] %d %p\n", s->id, s->invalidated, s->n); +//fprintf(stderr, "DESTROYING %d %d %p at %d/%d (%d/%d)\n", s->id, s->invalidated, s->n, s->movedfromy, s->movedfromx, s->dimy, s->dimx); (void)nc; (void)out; int starty = s->movedfromy; @@ -800,23 +804,24 @@ int sixel_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ for(int xx = startx ; xx < startx + s->dimx && xx < p->dimx ; ++xx){ int ridx = yy * p->dimx + xx; struct crender *r = &p->crender[ridx]; - if(!r->sprixel){ - if(s->n){ -//fprintf(stderr, "CHECKING %d/%d\n", yy - s->movedfromy, xx - s->movedfromx); - sprixcell_e state = sprixel_state(s, yy - s->movedfromy + s->n->absy, - xx - s->movedfromx + s->n->absx); - if(state == SPRIXCELL_OPAQUE_SIXEL || state == SPRIXCELL_MIXED_SIXEL){ - r->s.damaged = 1; - }else if(s->invalidated == SPRIXEL_MOVED){ - // ideally, we wouldn't damage our annihilated sprixcells, but if - // we're being annihilated only during this cycle, we need to go - // ahead and damage it. - r->s.damaged = 1; - } - }else{ - // need this to damage cells underneath a sprixel we're removing + if(r->sprixel){ + s = r->sprixel; + } + if(s->n){ + sprixcell_e state = sprixel_state(s, yy - s->movedfromy, + xx - s->movedfromx); +//fprintf(stderr, "CHECKING %d/%d state: %d %d/%d\n", yy - s->movedfromy - s->n->absy, xx - s->movedfromx - s->n->absx, state, yy, xx); + if(state == SPRIXCELL_TRANSPARENT || state == SPRIXCELL_MIXED_SIXEL){ + r->s.damaged = 1; + }else if(s->invalidated == SPRIXEL_MOVED){ + // ideally, we wouldn't damage our annihilated sprixcells, but if + // we're being annihilated only during this cycle, we need to go + // ahead and damage it. r->s.damaged = 1; } + }else{ + // need this to damage cells underneath a sprixel we're removing + r->s.damaged = 1; } } } diff --git a/src/lib/sprite.c b/src/lib/sprite.c index c97077335..8060e06be 100644 --- a/src/lib/sprite.c +++ b/src/lib/sprite.c @@ -4,7 +4,7 @@ static atomic_uint_fast32_t sprixelid_nonce; -void sprixel_debug(FILE* out, const sprixel* s){ +void sprixel_debug(const sprixel* s, FILE* out){ fprintf(out, "Sprixel %d (%p) %dB %dx%d (%dx%d) @%d/%d state: %d\n", s->id, s, s->glyphlen, s->dimy, s->dimx, s->pixy, s->pixx, s->n ? s->n->absy : 0, s->n ? s->n->absx : 0,