scrub TAM boundaries in sixel+kitty #1553

pull/1567/head
nick black 3 years ago
parent 74862a32b8
commit 3bdd5ce142
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -956,6 +956,31 @@ clamp_to_sixelmax(const tinfo* t, int* y, int* x){
}
}
// any sprixcell which does not cover the entirety of the underlying cell
// cannot be SPRIXCELL_OPAQUE. this postprocesses the TAM, flipping any
// such sprixcells to SPRIXCELL_MIXED.
static inline void
scrub_tam_boundaries(sprixcell_e* tam, int leny, int lenx, int cdimy, int cdimx){
// any sprixcells which don't cover the full cell underneath them cannot
// be SPRIXCELL_OPAQUE
const int cols = (lenx + cdimx - 1) / cdimx;
if(lenx % cdimx){
for(int y = 0 ; y < (leny + cdimy - 1) / cdimy ; ++y){
if(tam[y * cols + cols - 1] == SPRIXCELL_OPAQUE){
tam[y * cols + cols - 1] = SPRIXCELL_MIXED;
}
}
}
if(leny % cdimy){
const int y = (leny + cdimy - 1) / cdimy - 1;
for(int x = 0 ; x < cols ; ++x){
if(tam[y * cols + x] == SPRIXCELL_OPAQUE){
tam[y * cols + x] = SPRIXCELL_MIXED;
}
}
}
}
// get the TAM entry for these (absolute) coordinates
static inline sprixcell_e
sprixel_state(sprixel* s, int y, int x){

@ -307,23 +307,7 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx,
if(fclose(fp) == EOF){
return -1;
}
// any sprixcells which don't cover the full cell underneath them cannot
// be SPRIXCELL_OPAQUE
if(lenx % cdimx){
for(y = 0 ; y < (leny + cdimy - 1) / cdimy ; ++y){
if(tacache[y * cols + cols - 1] == SPRIXCELL_OPAQUE){
tacache[y * cols + cols - 1] = SPRIXCELL_MIXED;
}
}
}
if(leny % cdimy){
y = (leny + cdimy - 1) / cdimy - 1;
for(x = 0 ; x < cols ; ++x){
if(tacache[y * cols + x] == SPRIXCELL_OPAQUE){
tacache[y * cols + x] = SPRIXCELL_MIXED;
}
}
}
scrub_tam_boundaries(tacache, leny, lenx, cdimy, cdimx);
return 0;
}
#undef RGBA_MAXLEN

@ -431,6 +431,8 @@ sixel_blit_inner(int leny, int lenx, const sixeltable* stab, int rows, int cols,
free(buf);
return -1;
}
scrub_tam_boundaries(tacache, leny, lenx, bargs->u.pixel.celldimy,
bargs->u.pixel.celldimx);
// take ownership of buf on success
if(plane_blit_sixel(bargs->u.pixel.spx, buf, size, rows, cols,
bargs->placey, bargs->placex,
@ -514,7 +516,7 @@ int sixel_delete(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){
for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){
struct crender *r = &p->crender[yy * p->dimx + xx];
if(!r->sprixel){
if(!r->sprixel || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE){
r->s.damaged = 1;
}
}
@ -525,12 +527,7 @@ int sixel_delete(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
int sixel_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){
(void)n;
if(s->invalidated == SPRIXEL_MOVED){
for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){
for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){
//fprintf(stderr, "DAMAGING DUE TO MOVE: %d/%d (%d)\n", yy, xx, yy * p->dimx + xx);
p->crender[yy * p->dimx + xx].s.damaged = 1;
}
}
sixel_delete(n, p, out, s);
s->invalidated = SPRIXEL_INVALIDATED;
}else{
if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){

@ -34,6 +34,10 @@ sprixel* sprixel_recycle(ncplane* n){
void sprixel_movefrom(sprixel* s, int y, int x){
if(s->invalidated != SPRIXEL_HIDE){
if(s->invalidated != SPRIXEL_MOVED){
// FIXME if we're Sixel, we need to effect any wipes that were run
// (we normally don't because redisplaying sixel doesn't change
// what's there--you can't "write transparency"). this is probably
// best done by conditionally reblitting the sixel(?).
//fprintf(stderr, "SETTING TO MOVE: %d/%d was: %d\n", y, x, s->invalidated);
s->invalidated = SPRIXEL_MOVED;
s->movedfromy = y;

Loading…
Cancel
Save