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

@ -112,19 +112,25 @@ TEST_CASE("ChannelBlend2") {
CHECK(0x0a == b); 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") { TEST_CASE("ChannelBlendDefaultLeft") {
uint32_t c1 = 0; uint32_t c1 = 0;
uint32_t c2 = 0; uint32_t c2 = 0;
channel_set_rgb(&c2, 0x80, 0x40, 0x20); channel_set_rgb(&c2, 0x80, 0x40, 0x20);
uint32_t c = channels_blend(c1, c2, 0); uint32_t c = channels_blend(c1, c2, 0); // will replace
CHECK(channel_default_p(c)); CHECK(!channel_default_p(c));
unsigned r, g, b; unsigned r, g, b;
channel_get_rgb(c, &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 == r);
CHECK(0 == g); CHECK(0 == g);
CHECK(0 == b); CHECK(0 == b);
c = channels_blend(c1, c2, 1); c = channels_blend(c1, c2, 2); // will not replace
CHECK(channel_default_p(c)); CHECK(channel_default_p(c));
channel_get_rgb(c, &r, &g, &b); channel_get_rgb(c, &r, &g, &b);
CHECK(0 == r); CHECK(0 == r);
@ -142,9 +148,9 @@ TEST_CASE("ChannelBlendDefaultRight") {
CHECK(channel_default_p(c)); CHECK(channel_default_p(c));
unsigned r, g, b; unsigned r, g, b;
channel_get_rgb(c, &r, &g, &b); channel_get_rgb(c, &r, &g, &b);
CHECK(0x80 == r); CHECK(0 == r);
CHECK(0x40 == g); CHECK(0 == g);
CHECK(0x20 == b); CHECK(0 == b);
c = channels_blend(c1, c2, 1); c = channels_blend(c1, c2, 1);
CHECK(!channel_default_p(c)); CHECK(!channel_default_p(c));
channel_get_rgb(c, &r, &g, &b); channel_get_rgb(c, &r, &g, &b);

Loading…
Cancel
Save