diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index d77a4846d..545ff1f6b 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -112,6 +112,7 @@ mbswidth(const char* mbs){ // cell is the left or right side of the glyph can be determined by checking // whether ->gcluster is zero. #define CELL_WIDEASIAN_MASK 0x8000000000000000ull +#define CELL_NOBACKGROUND_MASK 0x0400000000000000ull // if this bit is set, we are *not* using the default background color #define CELL_BGDEFAULT_MASK 0x0000000040000000ull // if this bit is set, we are *not* using the default foreground color @@ -594,7 +595,8 @@ typedef struct cell { // (channels & 0x4000000000000000ull): foreground is *not* "default color" // (channels & 0x3000000000000000ull): foreground alpha (2 bits) // (channels & 0x0800000000000000ull): foreground uses palette index - // (channels & 0x0700000000000000ull): reserved, must be 0 + // (channels & 0x0400000000000000ull): glyph is entirely foreground + // (channels & 0x0300000000000000ull): reserved, must be 0 // (channels & 0x00ffffff00000000ull): foreground in 3x8 RGB (rrggbb) // (channels & 0x0000000080000000ull): reserved, must be 0 // (channels & 0x0000000040000000ull): background is *not* "default color" diff --git a/src/demo/all.c b/src/demo/all.c index 95da75234..d7fa83721 100644 --- a/src/demo/all.c +++ b/src/demo/all.c @@ -15,7 +15,7 @@ allglyphs(struct notcurses* nc, struct ncplane* column, int legendy){ // some of these cause major problems with Kitty, if not others, due to // heavy duty beating on freetype FIXME reenable when reasonable const int valid_planes[] = { - 0, 1, 2, 3, 14, + 0, 1, /*2,*/ 3, 14, /*15, 16,*/ -1 }; struct ncplane* std = notcurses_stdplane(nc); diff --git a/src/lib/internal.h b/src/lib/internal.h index c26fed105..32b07dc7e 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -835,6 +835,13 @@ box_corner_needs(unsigned ctlword){ return (ctlword & NCBOXCORNER_MASK) >> NCBOXCORNER_SHIFT; } +// True if the cell does not generate background pixels (i.e., the cell is a +// solid or shaded block, or certain emoji). +static inline bool +cell_nobackground_p(const cell* c){ + return c->channels & CELL_NOBACKGROUND_MASK; +} + #ifdef __cplusplus } #endif diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 464ef40e2..2001d1657 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1326,16 +1326,12 @@ cell_load_direct(ncplane* n, cell* c, const char* gcluster, int bytes, int cols) return -1; } if(bytes <= 1){ + assert(cols < 2); cell_release(n, c); - c->channels &= ~CELL_WIDEASIAN_MASK; + c->channels &= ~(CELL_WIDEASIAN_MASK | CELL_NOBACKGROUND_MASK); c->gcluster = *gcluster; return bytes; } - if(cols > 1){ - c->channels |= CELL_WIDEASIAN_MASK; - }else{ - c->channels &= ~CELL_WIDEASIAN_MASK; - } if(!cell_simple_p(c)){ if(strcmp(gcluster, cell_extended_gcluster(n, c)) == 0){ return bytes; // reduce, reuse, recycle @@ -1343,6 +1339,17 @@ cell_load_direct(ncplane* n, cell* c, const char* gcluster, int bytes, int cols) cell_release(n, c); } } + if(cols > 1){ + c->channels |= CELL_WIDEASIAN_MASK; + }else{ + c->channels &= ~CELL_WIDEASIAN_MASK; + } + // FIXME also shaded blocks! ░ etc + if(strncmp(gcluster, "\xe2\x96\x88", 3)){ + c->channels &= ~CELL_NOBACKGROUND_MASK; + }else{ + c->channels |= CELL_NOBACKGROUND_MASK; + } int eoffset = egcpool_stash(&n->pool, gcluster, bytes); if(eoffset < 0){ return -1; diff --git a/src/lib/render.c b/src/lib/render.c index b8f34164a..8865b47be 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -756,15 +756,6 @@ stage_cursor(notcurses* nc, FILE* out, int y, int x){ return ret; } -// True if the cell does not generate background pixels. Only the FULL BLOCK -// glyph has this property, AFAIK. -// FIXME also shaded blocks! ░ etc -// FIXME set a bit, doing this at load time -static inline bool -cell_nobackground_p(const egcpool* e, const cell* c){ - return !cell_simple_p(c) && !strcmp(egcpool_extended_gcluster(e, c), "\xe2\x96\x88"); -} - // True if the cell does not generate foreground pixels (i.e., the cell is // entirely whitespace or special characters). // FIXME do this at cell prep time and set a bit in the channels @@ -841,7 +832,7 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec, FILE* out){ // * we are a no-foreground glyph, and the previous was default background, or // * we are a no-background glyph, and the previous was default foreground bool noforeground = cell_noforeground_p(srccell); - bool nobackground = cell_nobackground_p(&nc->pool, srccell); + bool nobackground = cell_nobackground_p(srccell); if((!noforeground && cell_fg_default_p(srccell)) || (!nobackground && cell_bg_default_p(srccell))){ if(!nc->rstate.defaultelidable){ ++nc->stats.defaultemissions; @@ -905,19 +896,17 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec, FILE* out){ nc->rstate.defaultelidable = false; nc->rstate.bgelidable = false; }else if(!cell_bg_default_p(srccell)){ // rgb background - if(!nobackground){ - cell_bg_rgb(srccell, &br, &bg, &bb); - if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){ - ++nc->stats.bgelisions; - }else{ - ret |= term_bg_rgb8(nc->tcache.RGBflag, nc->tcache.setab, nc->tcache.colors, out, br, bg, bb); - ++nc->stats.bgemissions; - nc->rstate.bgelidable = true; - } - nc->rstate.lastbr = br; nc->rstate.lastbg = bg; nc->rstate.lastbb = bb; - nc->rstate.defaultelidable = false; - nc->rstate.bgpalelidable = false; + cell_bg_rgb(srccell, &br, &bg, &bb); + if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){ + ++nc->stats.bgelisions; + }else{ + ret |= term_bg_rgb8(nc->tcache.RGBflag, nc->tcache.setab, nc->tcache.colors, out, br, bg, bb); + ++nc->stats.bgemissions; + nc->rstate.bgelidable = true; } + nc->rstate.lastbr = br; nc->rstate.lastbg = bg; nc->rstate.lastbb = bb; + nc->rstate.defaultelidable = false; + nc->rstate.bgpalelidable = false; } /*if(cell_simple_p(srccell)){ fprintf(stderr, "RAST %u [%c] to %d/%d\n", srccell->gcluster, srccell->gcluster, y, x);