notcurses_render: simplify using new alpha rules

pull/238/head
nick black 5 years ago
parent c0126b3389
commit db8b99d594
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -1000,24 +1000,23 @@ channels_set_bg_default(uint64_t* channels){
return *channels;
}
// Returns the result of blending two channels.
// Returns the result of blending two channels. 'blends' indicates how heavily
// 'c1' ought be weighed. If 'blends' is 0, 'c1' will be entirely replaced by
// 'c2'. If 'c1' is otherwise the default color, 'c1' will not be touched,
// since we can't blend default colors. Likewise, if 'c2' is a default color,
// it will not be used (unless 'blends' is 0).
static inline unsigned
channels_blend(unsigned c1, unsigned c2, unsigned blends){
if(channel_default_p(c1)){
return c1;
if(blends == 0){
return c2;
}
if(channel_default_p(c2)){
if(blends == 0){
channel_set_default(&c1);
}
return c1;
if(!channel_default_p(c2) && !channel_default_p(c1)){
int rsum = (channel_get_r(c1) * blends + channel_get_r(c2)) / (blends + 1);
int gsum = (channel_get_g(c1) * blends + channel_get_g(c2)) / (blends + 1);
int bsum = (channel_get_b(c1) * blends + channel_get_b(c2)) / (blends + 1);
channel_set_rgb(&c1, rsum, gsum, bsum);
}
int rsum = (channel_get_r(c1) * blends + channel_get_r(c2)) / (blends + 1);
int gsum = (channel_get_g(c1) * blends + channel_get_g(c2)) / (blends + 1);
int bsum = (channel_get_b(c1) * blends + channel_get_b(c2)) / (blends + 1);
unsigned blend = 0;
channel_set_rgb(&blend, rsum, gsum, bsum);
return blend;
return c1;
}
// Extract the 32-bit background channel from a cell.

@ -146,9 +146,9 @@ reshape_shadow_fb(notcurses* nc){
// tail recursion, though, we instead write first, and then recurse, blending
// as we descend. α == 0 is opaque. α == 2 is fully transparent.
static inline ncplane*
dig_visible_cell(cell* c, int y, int x, ncplane* p, int falpha, int balpha){
unsigned fgblends = 1;
unsigned bgblends = 1;
dig_visible_cell(cell* c, int y, int x, ncplane* p){
unsigned fgblends = 0;
unsigned bgblends = 0;
// once we decide on our glyph, it cannot be changed by anything below, so
// lock in this plane for the actual cell return.
ncplane* glyphplane = NULL;
@ -178,30 +178,21 @@ dig_visible_cell(cell* c, int y, int x, ncplane* p, int falpha, int balpha){
c->attrword = vis->attrword;
}
}
if(falpha > CELL_ALPHA_OPAQUE && cell_get_fg_alpha(vis) < CELL_ALPHA_TRANSPARENT){
if(falpha == CELL_ALPHA_BLEND){
cell_blend_fchannel(c, cell_get_fchannel(vis), fgblends);
++fgblends;
}else{
cell_set_fchannel(c, cell_get_fchannel(vis));
}
falpha = cell_get_fg_alpha(vis);
if(cell_get_fg_alpha(c) > CELL_ALPHA_OPAQUE && cell_get_fg_alpha(vis) < CELL_ALPHA_TRANSPARENT){
cell_blend_fchannel(c, cell_get_fchannel(vis), fgblends);
++fgblends;
}
// Background color takes effect independently of whether we have a
// glyph. If we've already locked in the background, it has no effect.
// If it's transparent, it has no effect. Otherwise, update the
// background channel and balpha.
if(balpha > CELL_ALPHA_OPAQUE && cell_get_bg_alpha(vis) < CELL_ALPHA_TRANSPARENT){
if(balpha == CELL_ALPHA_BLEND){
cell_blend_bchannel(c, cell_get_bchannel(vis), bgblends);
++bgblends;
}else{ // balpha == CELL_ALPHA_TRANSPARENT
cell_set_bchannel(c, cell_get_bchannel(vis));
}
balpha = cell_get_bg_alpha(vis);
if(cell_get_bg_alpha(c) > CELL_ALPHA_OPAQUE && cell_get_bg_alpha(vis) < CELL_ALPHA_TRANSPARENT){
cell_blend_bchannel(c, cell_get_bchannel(vis), bgblends);
++bgblends;
}
// if everything's locked in, we're done
if((glyphplane && falpha == CELL_ALPHA_OPAQUE && balpha == CELL_ALPHA_OPAQUE)){
if((glyphplane && cell_get_fg_alpha(c) == CELL_ALPHA_OPAQUE &&
cell_get_bg_alpha(c) == CELL_ALPHA_OPAQUE)){
return glyphplane;
}
}
@ -219,7 +210,9 @@ dig_visible_cell(cell* c, int y, int x, ncplane* p, int falpha, int balpha){
static inline ncplane*
visible_cell(cell* c, int y, int x, ncplane* n){
cell_init(c);
return dig_visible_cell(c, y, x, n, CELL_ALPHA_TRANSPARENT, CELL_ALPHA_TRANSPARENT);
cell_set_fg_alpha(c, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(c, CELL_ALPHA_TRANSPARENT);
return dig_visible_cell(c, y, x, n);
}
// write the cell's UTF-8 grapheme cluster to the provided FILE*. returns the

@ -112,19 +112,25 @@ TEST_CASE("ChannelBlend2") {
CHECK(0x0a == b);
}
// you can't blend into a default color, at any number of blends
// you can't blend into a default color at any positive number of blends
TEST_CASE("ChannelBlendDefaultLeft") {
uint32_t c1 = 0;
uint32_t c2 = 0;
channel_set_rgb(&c2, 0x80, 0x40, 0x20);
uint32_t c = channels_blend(c1, c2, 0);
CHECK(channel_default_p(c));
uint32_t c = channels_blend(c1, c2, 0); // will replace
CHECK(!channel_default_p(c));
unsigned r, g, b;
channel_get_rgb(c, &r, &g, &b);
CHECK(0x80 == r);
CHECK(0x40 == g);
CHECK(0x20 == b);
c = channels_blend(c1, c2, 1); // will not replace
CHECK(channel_default_p(c));
channel_get_rgb(c, &r, &g, &b);
CHECK(0 == r);
CHECK(0 == g);
CHECK(0 == b);
c = channels_blend(c1, c2, 1);
c = channels_blend(c1, c2, 2); // will not replace
CHECK(channel_default_p(c));
channel_get_rgb(c, &r, &g, &b);
CHECK(0 == r);
@ -142,9 +148,9 @@ TEST_CASE("ChannelBlendDefaultRight") {
CHECK(channel_default_p(c));
unsigned r, g, b;
channel_get_rgb(c, &r, &g, &b);
CHECK(0x80 == r);
CHECK(0x40 == g);
CHECK(0x20 == b);
CHECK(0 == r);
CHECK(0 == g);
CHECK(0 == b);
c = channels_blend(c1, c2, 1);
CHECK(!channel_default_p(c));
channel_get_rgb(c, &r, &g, &b);

Loading…
Cancel
Save