[sixel] clean up cells even when under a new sixel #1537

This commit is contained in:
nick black 2021-06-30 23:45:48 -04:00 committed by Nick Black
parent 5cf24d4d2e
commit 0bfa8c33fd
3 changed files with 27 additions and 20 deletions

View File

@ -792,7 +792,7 @@ uint8_t* kitty_trans_auxvec(const struct tinfo* ti);
// these three all use absolute coordinates // these three all use absolute coordinates
void sprixel_invalidate(sprixel* s, int y, int x); void sprixel_invalidate(sprixel* s, int y, int x);
void sprixel_movefrom(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); void sixelmap_free(struct sixelmap *s);
// create an auxiliary vector suitable for a sprixcell, and zero it out. there // 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 static inline int
sprite_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ 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); 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. // returns -1 on error, or the number of bytes written.
static inline int static inline int
sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ 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); 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. // returns -1 on error, or the number of bytes written.
static inline int static inline int
sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ 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){ if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){
return n->tcache.pixel_move(p, s, out); return n->tcache.pixel_move(p, s, out);
}else{ }else{

View File

@ -790,8 +790,12 @@ int sixel_blit(ncplane* n, int linesize, const void* data, int leny, int lenx,
return r; 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){ 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)nc;
(void)out; (void)out;
int starty = s->movedfromy; int starty = s->movedfromy;
@ -800,12 +804,14 @@ 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){ for(int xx = startx ; xx < startx + s->dimx && xx < p->dimx ; ++xx){
int ridx = yy * p->dimx + xx; int ridx = yy * p->dimx + xx;
struct crender *r = &p->crender[ridx]; struct crender *r = &p->crender[ridx];
if(!r->sprixel){ if(r->sprixel){
s = r->sprixel;
}
if(s->n){ if(s->n){
//fprintf(stderr, "CHECKING %d/%d\n", yy - s->movedfromy, xx - s->movedfromx); sprixcell_e state = sprixel_state(s, yy - s->movedfromy,
sprixcell_e state = sprixel_state(s, yy - s->movedfromy + s->n->absy, xx - s->movedfromx);
xx - s->movedfromx + s->n->absx); //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_OPAQUE_SIXEL || state == SPRIXCELL_MIXED_SIXEL){ if(state == SPRIXCELL_TRANSPARENT || state == SPRIXCELL_MIXED_SIXEL){
r->s.damaged = 1; r->s.damaged = 1;
}else if(s->invalidated == SPRIXEL_MOVED){ }else if(s->invalidated == SPRIXEL_MOVED){
// ideally, we wouldn't damage our annihilated sprixcells, but if // ideally, we wouldn't damage our annihilated sprixcells, but if
@ -819,7 +825,6 @@ int sixel_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
} }
} }
} }
}
return 0; return 0;
} }

View File

@ -4,7 +4,7 @@
static atomic_uint_fast32_t sprixelid_nonce; 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", 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->id, s, s->glyphlen, s->dimy, s->dimx, s->pixy, s->pixx,
s->n ? s->n->absy : 0, s->n ? s->n->absx : 0, s->n ? s->n->absy : 0, s->n ? s->n->absx : 0,