[paint] invoke sprite_wipe_cell() #1388

This commit is contained in:
nick black 2021-03-20 13:59:08 -04:00 committed by Nick Black
parent 4f4175098a
commit 111bb893f6
5 changed files with 40 additions and 29 deletions

View File

@ -315,11 +315,11 @@ typedef struct tinfo {
int sixel_maxx, sixel_maxy; // sixel size maxima (post pixel_query_done)
bool sixel_supported; // do we support sixel (post pixel_query_done)?
int sprixelnonce; // next sprixel id
int (*pixel_destroy)(struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s);
int (*pixel_destroy)(const struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s);
// wipe out a cell's worth of pixels from within a sprixel. for sixel, this
// means leaving out the pixels (and likely resizes the string). for kitty,
// this means dialing down their alpha to 0 (in equivalent space).
int (*pixel_cell_wipe)(struct notcurses* nc, sprixel* s, int y, int x);
int (*pixel_cell_wipe)(const struct notcurses* nc, sprixel* s, int y, int x);
bool pixel_query_done; // have we yet performed pixel query?
bool sextants; // do we have (good, vetted) Unicode 13 sextant support?
bool braille; // do we have Braille support? (linux console does not)
@ -703,8 +703,9 @@ void sprixel_hide(sprixel* s);
// dimy and dimx are cell geometry, not pixel
sprixel* sprixel_create(ncplane* n, const char* s, int bytes, int sprixelid,
int dimy, int dimx, int pixy, int pixx);
int sprite_kitty_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
int sprite_sixel_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
int sprite_wipe_cell(const notcurses* nc, sprixel* s, int y, int x);
int sprite_kitty_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
int sprite_sixel_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
static inline void
pool_release(egcpool* pool, nccell* c){
@ -1264,8 +1265,8 @@ ncdirect_bg_default_p(const struct ncdirect* nc){
return channels_bg_default_p(ncdirect_channels(nc));
}
int sprite_sixel_cell_wipe(notcurses* nc, sprixel* s, int y, int x);
int sprite_kitty_cell_wipe(notcurses* nc, sprixel* s, int y, int x);
int sprite_sixel_cell_wipe(const notcurses* nc, sprixel* s, int y, int x);
int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int y, int x);
int sixel_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
int leny, int lenx, const blitterargs* bargs);

View File

@ -117,13 +117,7 @@ kitty_null(char* triplet, int skip, int max, int pleft){
}
#define RGBA_MAXLEN 768 // 768 base64-encoded pixels in 4096 bytes
int sprite_kitty_cell_wipe(notcurses* nc, sprixel* s, int ycell, int xcell){
if(ycell >= s->dimy){
return -1;
}
if(xcell >= s->dimx){
return -1;
}
int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell){
const int totalpixels = s->pixy * s->pixx;
const int xpixels = nc->tcache.cellpixx;
const int ypixels = nc->tcache.cellpixy;
@ -145,7 +139,8 @@ int sprite_kitty_cell_wipe(notcurses* nc, sprixel* s, int ycell, int xcell){
int nextpixel = (s->pixx * ycell * ypixels) + (xpixels * xcell);
int thisrow = targx;
int chunkedhandled = 0;
while(targy){ // need to null out |targy| rows of |targx| pixels, track with |thisrow|
const int chunks = totalpixels / RGBA_MAXLEN + !!(totalpixels % RGBA_MAXLEN);
while(targy && chunkedhandled < chunks){ // need to null out |targy| rows of |targx| pixels, track with |thisrow|
//fprintf(stderr, "CHUNK %d NEXTPIXEL: %d\n", chunkedhandled, nextpixel);
while(*c != ';'){
++c;

View File

@ -245,9 +245,6 @@ highcontrast(uint32_t bchannel){
static void
paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
int dstabsy, int dstabsx){
if(p->sprite){
return;
}
int y, x, dimy, dimx, offy, offx;
ncplane_dim_yx(p, &dimy, &dimx);
offy = p->absy - dstabsy;
@ -281,9 +278,22 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
if(cell_wide_right_p(targc)){
continue;
}
const nccell* vis = &p->fb[nfbcellidx(p, y, x)];
// if we're a sprixel, we must not register ourselves as the active
// glyph, but we *do* need to null out any cellregions that we've
// scribbled upon.
if(cell_sprixel_p(vis)){
// if we already have a glyph solved, and we run into a bitmap
// cell, we need to null that cell out.
if(crender->p){
sprite_wipe_cell(ncplane_notcurses_const(p), p->sprite, y, x);
}
continue;
}
if(cell_fg_alpha(targc) > CELL_ALPHA_OPAQUE){
const nccell* vis = &p->fb[nfbcellidx(p, y, x)];
vis = &p->fb[nfbcellidx(p, y, x)];
if(cell_fg_default_p(vis)){
vis = &p->basecell;
}
@ -315,7 +325,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
// background channel and balpha.
// Evaluate the background first, in case we have HIGHCONTRAST fg text.
if(cell_bg_alpha(targc) > CELL_ALPHA_OPAQUE){
const nccell* vis = &p->fb[nfbcellidx(p, y, x)];
vis = &p->fb[nfbcellidx(p, y, x)];
// to be on the blitter stacking path, we need
// 1) crender->s.blittedquads to be non-zero (we're below semigraphics)
// 2) cell_blittedquadrants(vis) to be non-zero (we're semigraphics)
@ -358,7 +368,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
// still use a character we find here, but its color will come entirely
// from cells underneath us.
if(!crender->p){
const nccell* vis = &p->fb[nfbcellidx(p, y, x)];
vis = &p->fb[nfbcellidx(p, y, x)];
if(vis->gcluster == 0 && !cell_double_wide_p(vis)){
vis = &p->basecell;
}
@ -922,7 +932,7 @@ emit_bg_palindex(notcurses* nc, FILE* out, const nccell* srccell){
return 0;
}
int sprite_kitty_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
int sprite_kitty_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
(void)p;
(void)nc;
if(fprintf(out, "\e_Ga=d,d=i,i=%d\e\\", s->id) < 0){
@ -931,7 +941,7 @@ int sprite_kitty_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel*
return 0;
}
int sprite_sixel_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
int sprite_sixel_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
(void)out;
struct crender* rvec = p->crender;
// FIXME need to cap by ends minus bottom, right margins also

View File

@ -6,13 +6,7 @@
// color bands have varying size). le sigh! we work geometrically here,
// blasting through each band and scrubbing the necessary cells therein.
// define a rectangle that will be scrubbed.
int sprite_sixel_cell_wipe(notcurses* nc, sprixel* s, int ycell, int xcell){
if(ycell >= s->dimy){
return -1;
}
if(xcell >= s->dimx){
return -1;
}
int sprite_sixel_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell){
const int xpixels = nc->tcache.cellpixx;
const int ypixels = nc->tcache.cellpixy;
const int top = ypixels * ycell; // start scrubbing on this row

View File

@ -39,3 +39,14 @@ sprixel* sprixel_create(ncplane* n, const char* s, int bytes, int sprixelid,
}
return ret;
}
int sprite_wipe_cell(const notcurses* nc, sprixel* s, int ycell, int xcell){
if(ycell >= s->dimy){
return -1;
}
if(xcell >= s->dimx){
return -1;
}
// FIXME transparency-annihilation cache!
return nc->tcache.pixel_cell_wipe(nc, s, ycell, xcell);
}