gradient: implement + test 1d fills

This commit is contained in:
nick black 2020-02-24 22:54:21 -05:00
parent 5f971a6baa
commit 5b4c6c14e3
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
2 changed files with 68 additions and 8 deletions

View File

@ -2005,14 +2005,21 @@ int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){
static int
calc_gradient_component(unsigned tl, unsigned tr, unsigned bl, unsigned br,
int y, int x, int ylen, int xlen){
assert(xlen >= 2);
assert(ylen >= 2);
assert(y >= 0);
assert(y < ylen);
assert(x >= 0);
assert(x < xlen);
const int avm = (ylen - 1) - y;
const int ahm = (xlen - 1) - x;
if(xlen < 2){
if(ylen < 2){
return tl;
}
return (tl * avm + bl * y) / (ylen - 1);
}
if(ylen < 2){
return (tl * ahm + tr * x) / (xlen - 1);
}
const int tlc = ahm * avm * tl;
const int blc = ahm * y * bl;
const int trc = x * avm * tr;
@ -2066,6 +2073,9 @@ int ncplane_gradient(ncplane* n, const char* egc, uint32_t attrword,
channel_palindex_p(lr) || channel_palindex_p(ur)){
return -1;
}
if(egc == NULL){
return -1;
}
int yoff, xoff, ymax, xmax;
ncplane_cursor_yx(n, &yoff, &xoff);
// must be at least 1x1, with its upper-left corner at the current cursor
@ -2084,14 +2094,18 @@ int ncplane_gradient(ncplane* n, const char* egc, uint32_t attrword,
const int ylen = ystop - yoff + 1;
if(ylen == 1){
if(xlen == 1){
// single cell FIXME
if(ul != ur || ur != lr || lr != ll){
return -1;
}
}else{
// horizontal 1d FIXME
if(ul != ll || ur != lr){
return -1;
}
}
return 0;
}else if(xlen == 1){
// vertical 1d FIXME
return 0;
if(ul != ur || ll != lr){
return -1;
}
}
for(int y = yoff ; y <= ystop ; ++y){
for(int x = xoff ; x <= xstop ; ++x){

View File

@ -219,7 +219,7 @@ TEST_CASE("Fills") {
}
}
CHECK(0 == notcurses_render(nc_));
// attr should change, but not the EGC/color
// EGC/color should change, but nothing else
CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0));
uint64_t channels = 0;
channels_set_fg_rgb(&channels, 0x88, 0x99, 0x77);
@ -237,6 +237,52 @@ TEST_CASE("Fills") {
}
}
// test the single-cell (1x1) special case
SUBCASE("GradientSingleCell") {
int sbytes;
CHECK(0 == ncplane_set_fg(n_, 0x444444));
CHECK(1 == ncplane_putegc_yx(n_, 0, 0, "A", &sbytes));
CHECK(0 == notcurses_render(nc_));
CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0));
uint64_t channels = 0;
channels_set_fg_rgb(&channels, 0x88, 0x99, 0x77);
channels_set_bg(&channels, 0);
REQUIRE(0 == ncplane_gradient(n_, "A", 0, channels, channels, channels, channels, 0, 0));
CHECK(0 == notcurses_render(nc_));
cell d = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == ncplane_at_yx(n_, 0, 0, &d));
CHECK(channels == d.channels);
REQUIRE(cell_simple_p(&d));
CHECK('A' == d.gcluster);
}
// 1d gradients over multiple cells
SUBCASE("Gradient1D") {
int sbytes;
CHECK(0 == ncplane_set_fg(n_, 0x444444));
CHECK(1 == ncplane_putegc_yx(n_, 0, 0, "A", &sbytes));
CHECK(0 == notcurses_render(nc_));
CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0));
uint64_t chan1 = 0, chan2 = 0;
channels_set_fg_rgb(&chan1, 0x88, 0x99, 0x77);
channels_set_fg_rgb(&chan2, 0x77, 0x99, 0x88);
channels_set_bg(&chan1, 0);
channels_set_bg(&chan2, 0);
REQUIRE(0 == ncplane_gradient(n_, "A", 0, chan1, chan2, chan1, chan2, 0, 3));
CHECK(0 == notcurses_render(nc_));
cell d = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == ncplane_at_yx(n_, 0, 0, &d));
CHECK(chan1 == d.channels);
REQUIRE(cell_simple_p(&d));
CHECK('A' == d.gcluster);
CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0));
REQUIRE(0 == ncplane_gradient(n_, "A", 0, chan2, chan1, chan2, chan1, 0, 3));
CHECK(1 == ncplane_at_yx(n_, 0, 0, &d));
REQUIRE(cell_simple_p(&d));
CHECK('A' == d.gcluster);
CHECK(chan2 == d.channels);
}
CHECK(0 == notcurses_stop(nc_));
CHECK(0 == fclose(outfp_));