break up opaque/mixed into sixel and kitty states

This commit is contained in:
nick black 2021-04-25 04:56:59 -04:00 committed by Nick Black
parent 8eafcaee5b
commit e9ef4d50f4
5 changed files with 51 additions and 24 deletions

View File

@ -135,8 +135,10 @@ typedef enum {
// ANNIHILATED cells which are no longer ANNIHILATED), or at blittime for
// a new RGBA frame.
typedef enum {
SPRIXCELL_OPAQUE, // no transparent pixels in this cell
SPRIXCELL_MIXED, // this cell has both opaque and transparent pixels
SPRIXCELL_OPAQUE_SIXEL, // no transparent pixels in this cell
SPRIXCELL_OPAQUE_KITTY,
SPRIXCELL_MIXED_SIXEL, // this cell has both opaque and transparent pixels
SPRIXCELL_MIXED_KITTY,
SPRIXCELL_TRANSPARENT, // all pixels are naturally transparent
SPRIXCELL_ANNIHILATED, // this cell has been wiped (all trans)
} sprixcell_e;
@ -981,16 +983,20 @@ scrub_tam_boundaries(sprixcell_e* tam, int leny, int lenx, int cdimy, int cdimx)
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(tam[y * cols + cols - 1] == SPRIXCELL_OPAQUE_KITTY){
tam[y * cols + cols - 1] = SPRIXCELL_MIXED_KITTY;
}else if(tam[y * cols + cols - 1] == SPRIXCELL_OPAQUE_SIXEL){
tam[y * cols + cols - 1] = SPRIXCELL_MIXED_SIXEL;
}
}
}
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;
if(tam[y * cols + x] == SPRIXCELL_OPAQUE_KITTY){
tam[y * cols + x] = SPRIXCELL_MIXED_KITTY;
}else if(tam[y * cols + x] == SPRIXCELL_OPAQUE_SIXEL){
tam[y * cols + x] = SPRIXCELL_MIXED_SIXEL;
}
}
}

View File

@ -288,14 +288,14 @@ write_kitty_data(FILE* fp, int linesize, int leny, int lenx,
if(rgba_trans_p(source[e], transcolor)){
if(x % cdimx == 0 && y % cdimy == 0){
tacache[tyx] = SPRIXCELL_TRANSPARENT;
}else if(tacache[tyx] == SPRIXCELL_OPAQUE){
tacache[tyx] = SPRIXCELL_MIXED;
}else if(tacache[tyx] == SPRIXCELL_OPAQUE_KITTY){
tacache[tyx] = SPRIXCELL_MIXED_KITTY;
}
}else{
if(x % cdimx == 0 && y % cdimy == 0){
tacache[tyx] = SPRIXCELL_OPAQUE;
tacache[tyx] = SPRIXCELL_OPAQUE_KITTY;
}else if(tacache[tyx] == SPRIXCELL_TRANSPARENT){
tacache[tyx] = SPRIXCELL_MIXED;
tacache[tyx] = SPRIXCELL_MIXED_KITTY;
}
}
}
@ -396,7 +396,7 @@ int kitty_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
//fprintf(stderr, "CHECKING %d/%d\n", yy - s->movedfromy, xx - s->movedfromx);
sprixcell_e state = sprixel_state(s, yy - s->movedfromy + s->n->absy - stdn->absy,
xx - s->movedfromx + s->n->absx - stdn->absx);
if(state == SPRIXCELL_OPAQUE){
if(state == SPRIXCELL_OPAQUE_KITTY){
r->s.damaged = 1;
}else if(s->invalidated == SPRIXEL_MOVED){
// ideally, we wouldn't damage our annihilated sprixcells, but if

View File

@ -433,7 +433,8 @@ postpaint_cell(nccell* lastframe, int dimx, struct crender* crender,
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc) > 0){
//fprintf(stderr, "damaging due to cmp [%s] %d %d\n", nccell_extended_gcluster(crender->p, &crender->c), y, *x);
if(crender->sprixel){
if(!crender->s.p_beats_sprixel && sprixel_state(crender->sprixel, y, *x) != SPRIXCELL_OPAQUE){
sprixcell_e state = sprixel_state(crender->sprixel, y, *x);
if(!crender->s.p_beats_sprixel && state != SPRIXCELL_OPAQUE_KITTY && state != SPRIXCELL_OPAQUE_SIXEL){
crender->s.damaged = 1;
}
}else{
@ -1077,11 +1078,9 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
// which is only necessary for sixel, not kitty.
if(rvec[damageidx].sprixel){
sprixcell_e scstate = sprixel_state(rvec[damageidx].sprixel, y - nc->stdplane->absy, x - nc->stdplane->absx);
if(scstate != SPRIXCELL_TRANSPARENT
&& scstate != SPRIXCELL_ANNIHILATED && !rvec[damageidx].s.p_beats_sprixel
&& !sprixel_kitty_p(&nc->tcache)){
if((scstate == SPRIXCELL_MIXED_SIXEL || scstate == SPRIXCELL_OPAQUE_SIXEL)
&& !rvec[damageidx].s.p_beats_sprixel){
//fprintf(stderr, "INVALIDATING at %d/%d (%u)\n", y, x, rvec[damageidx].s.p_beats_sprixel);
sprixel_invalidate(rvec[damageidx].sprixel, y, x);
}
}

View File

@ -177,16 +177,16 @@ extract_color_table(const uint32_t* data, int linesize, int cols,
if(rgba_trans_p(*rgb, bargs->transcolor)){
if(sy % cdimy == 0 && visx % cdimx == 0){
tacache[txyidx] = SPRIXCELL_TRANSPARENT;
}else if(tacache[txyidx] == SPRIXCELL_OPAQUE){
tacache[txyidx] = SPRIXCELL_MIXED;
}else if(tacache[txyidx] == SPRIXCELL_OPAQUE_SIXEL){
tacache[txyidx] = SPRIXCELL_MIXED_SIXEL;
}
stab->p2 = SIXEL_P2_TRANS; // even one forces P2=1
continue;
}else{
if(sy % cdimy == 0 && visx % cdimx == 0){
tacache[txyidx] = SPRIXCELL_OPAQUE;
tacache[txyidx] = SPRIXCELL_OPAQUE_SIXEL;
}else if(tacache[txyidx] == SPRIXCELL_TRANSPARENT){
tacache[txyidx] = SPRIXCELL_MIXED;
tacache[txyidx] = SPRIXCELL_MIXED_SIXEL;
}
}
unsigned char comps[RGBSIZE];
@ -724,7 +724,7 @@ int sixel_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){
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 || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE){
if(!r->sprixel || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE_SIXEL){
r->s.damaged = 1;
}
}

View File

@ -423,14 +423,36 @@ TEST_CASE("Bitmaps") {
for(int i = 0 ; i < s->dimy * s->dimx ; ++i){
int py = (i / dimx) * nc_->tcache.cellpixy;
int px = (i % dimx) * nc_->tcache.cellpixx;
// cells with a transparent pixel ought be SPRIXCELL_CONTAINS_TRANS;
// cells with a transparent pixel ought be SPRIXCELL_MIXED;
// cells without one ought be SPRIXCELL_OPAQUE.
CHECK((i % 2) == tam[(i / dimx) + (i % dimx)]);
sprixcell_e state = tam[(i / dimx) + (i % dimx)];
if(i % 2){
if(state == SPRIXCELL_MIXED_SIXEL){
state = SPRIXCELL_MIXED_KITTY;
}
CHECK(SPRIXCELL_MIXED_KITTY == state);
}else{
if(state == SPRIXCELL_OPAQUE_SIXEL){
state = SPRIXCELL_OPAQUE_KITTY;
}
CHECK(SPRIXCELL_OPAQUE_KITTY == state);
}
ncpixel_set_a(&v[py * x + px], 0);
}
for(int yy = vopts.y ; yy < vopts.y + dimy ; ++yy){
for(int xx = vopts.x ; xx < vopts.x + dimx ; ++xx){
CHECK(((yy * dimx + xx) % 2) == sprixel_state(s, yy, xx));
sprixcell_e state = sprixel_state(s, yy, xx);
if((yy * dimx + xx) % 2){
if(state == SPRIXCELL_MIXED_SIXEL){
state = SPRIXCELL_MIXED_KITTY;
}
CHECK(SPRIXCELL_MIXED_KITTY == state);
}else{
if(state == SPRIXCELL_OPAQUE_SIXEL){
state = SPRIXCELL_OPAQUE_KITTY;
}
CHECK(SPRIXCELL_OPAQUE_KITTY == state);
}
}
}
CHECK(0 == ncplane_destroy(n));