From be0a52676a9bfa3fbb9b4741a1bf5e48a9247210 Mon Sep 17 00:00:00 2001 From: nick black Date: Mon, 15 Mar 2021 20:02:23 -0400 Subject: [PATCH] [pixel] split annihilators for indirect callback #1401 --- src/lib/internal.h | 3 +++ src/lib/render.c | 59 ++++++++++++++++++++++++++++++---------------- src/lib/terminfo.c | 2 ++ 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/lib/internal.h b/src/lib/internal.h index e7baa1b68..aaaa14c4e 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -313,6 +313,7 @@ typedef struct tinfo { int color_registers; // sixel color registers (post pixel_query_done) int sixel_maxx, sixel_maxy; // sixel size maxima (post pixel_query_done) bool sixel_supported; // do we support sixel (post pixel_query_done)? + int (*pixel_destroy)(struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s); 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) @@ -694,6 +695,8 @@ plane_debug(const ncplane* n, bool details){ void sprixel_free(sprixel* s); void sprixel_hide(sprixel* s); sprixel* sprixel_create(ncplane* n, const char* s, int bytes); +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); static inline void pool_release(egcpool* pool, nccell* c){ diff --git a/src/lib/render.c b/src/lib/render.c index 73f19af92..86c2fd41e 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -922,10 +922,37 @@ 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){ + // FIXME + return 0; +} + +int sprite_sixel_annihilate(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 + const int ycap = nc->stdplane->leny /*s->dimy*/ + nc->margin_t; + const int xcap = nc->stdplane->lenx /*s->dimx*/ + nc->margin_l; +//fprintf(stderr, "yCAP: %d xCAP: %d\n", ycap, xcap); + for(int y = s->y + nc->stdplane->absy ; y < s->y + nc->stdplane->absy + s->dimy && y < ycap ; ++y){ + const int innery = y - nc->stdplane->absy; + for(int x = s->x + nc->stdplane->absx ; x < s->x + nc->stdplane->absx + s->dimx && x < xcap ; ++x){ + const int innerx = x - nc->stdplane->absx; + const size_t damageidx = innery * nc->lfdimx + innerx; +//fprintf(stderr, "DAMAGING %zu %d * %d + %d (max %d/%d)\n", damageidx, innery, nc->lfdimx, innerx, ycap, xcap); + rvec[damageidx].s.damaged = 1; + } + } + return 1; +} + +// returns -1 on error, 0 on success, 1 on success + invalidations requiring +// a subsequent repass by the rasterizer. static int rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){ sprixel* s; sprixel** parent = &nc->sprixelcache; + int ret = 0; while( (s = *parent) ){ if(s->invalidated == SPRIXEL_INVALIDATED){ int y, x; @@ -941,20 +968,11 @@ rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){ parent = &s->next; }else if(s->invalidated == SPRIXEL_HIDE){ //fprintf(stderr, "OUGHT HIDE [%dx%d @ %d/%d] %p\n", s->dimy, s->dimx, s->y, s->x, s); - // FIXME only do this for sixel - struct crender* rvec = p->crender; - // FIXME need to cap by ends minus bottom, right margins also - const int ycap = nc->stdplane->leny /*s->dimy*/ + nc->margin_t; - const int xcap = nc->stdplane->lenx /*s->dimx*/ + nc->margin_l; -//fprintf(stderr, "yCAP: %d xCAP: %d\n", ycap, xcap); - for(int y = s->y + nc->stdplane->absy ; y < s->y + nc->stdplane->absy + s->dimy && y < ycap ; ++y){ - const int innery = y - nc->stdplane->absy; - for(int x = s->x + nc->stdplane->absx ; x < s->x + nc->stdplane->absx + s->dimx && x < xcap ; ++x){ - const int innerx = x - nc->stdplane->absx; - const size_t damageidx = innery * nc->lfdimx + innerx; -//fprintf(stderr, "DAMAGING %zu %d * %d + %d (max %d/%d)\n", damageidx, innery, nc->lfdimx, innerx, ycap, xcap); - rvec[damageidx].s.damaged = 1; - } + int r = nc->tcache.pixel_destroy(nc, p, out, s); + if(r < 0){ + return -1; + }else if(r > 0){ + ret = 1; } // FIXME delete it in kitty *parent = s->next; @@ -964,7 +982,7 @@ rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){ } } // FIXME what effect does emission have on rasterizing style state? - return 0; + return ret; } // Producing the frame requires three steps: @@ -1097,12 +1115,13 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){ if(rasterize_core(nc, p, out)){ return -1; } - if(rasterize_sprixels(nc, p, out)){ - return -1; - } - // FIXME only do this refresh loop if necessary - if(rasterize_core(nc, p, out)){ + int r = rasterize_sprixels(nc, p, out); + if(r < 0){ return -1; + }else if(r > 0){ + if(rasterize_core(nc, p, out)){ + return -1; + } } if(fflush(out)){ return -1; diff --git a/src/lib/terminfo.c b/src/lib/terminfo.c index 5471f5577..3ae80a420 100644 --- a/src/lib/terminfo.c +++ b/src/lib/terminfo.c @@ -60,6 +60,7 @@ apply_term_heuristics(tinfo* ti, const char* termname){ ti->sextants = true; // work since bugfix in 0.19.3 ti->pixel_query_done = true; ti->sixel_supported = true; + ti->pixel_destroy = sprite_kitty_annihilate; set_pixel_blitter(kitty_blit); /*}else if(strstr(termname, "alacritty")){ ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */ @@ -343,6 +344,7 @@ query_sixel(tinfo* ti, int fd){ if(!ti->sixel_supported){ ti->sixel_supported = true; ti->color_registers = 256; // assumed default [shrug] + ti->pixel_destroy = sprite_sixel_annihilate; // ti->sixel_maxx = ti->sixel_maxy = 0; } // FIXME else warning? }