diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index a9e7b76f8a..5b41e49c72 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1935,6 +1935,10 @@ int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){ static int calc_gradient_component(unsigned ul, unsigned ur, unsigned ll, unsigned lr, int y, int x, int ylen, int xlen){ + // FIXME bullshit special case. we're subtly broken below somewhere. + if(lr == ll && ll == ul && ul == ur){ + return lr; + } /*fprintf(stderr, "%08x %08x %08x %08x %d %d %d %d -> %08x\n", ul, ur, ll, lr, y, x, ylen, xlen, (((xlen - x) * ul / xlen + x * ur / xlen) * (ylen - y)) / ylen + @@ -1947,30 +1951,33 @@ calc_gradient_component(unsigned ul, unsigned ur, unsigned ll, unsigned lr, unsigned upchuk = ylen * !!(((((xlen - x) * ul + xchuk) / xlen + (x * ur + xchuk) / xlen) * (ylen - y)) % ylen); unsigned downchuk = ylen * !!(((((xlen - x) * ll + xchuk) / xlen + (x * lr + xchuk) / xlen) * y) % ylen); + //fprintf(stderr, "u/d: %u %u t: %u\n", upchuk, downchuk, ylen / 2); + upchuk = downchuk = ylen / 2; - //upchuk = 0; - //downchuk = 0; //fprintf(stderr, "uc: %u dc: %u lc: %u rc: %u\n", upchuk, downchuk, xchuk, xchuk); int up = ((((xlen - x) * ul + xchuk) / xlen + (x * ur + xchuk) / xlen) * (ylen - y) + upchuk) / ylen; int down = ((((xlen - x) * ll + xchuk) / xlen + (x * lr + xchuk) / xlen) * y + downchuk) / ylen; - /* - fprintf(stderr, "UL: (xlen - x) * ul / xlen (%d - %d) * %u / %d (%g)\n", xlen, x, ul, xlen, (((float)xlen - x) * ul + xchuk) / xlen); + /*fprintf(stderr, "UL: (xlen - x) * ul / xlen (%d - %d) * %u / %d (%g)\n", xlen, x, ul, xlen, (((float)xlen - x) * ul + xchuk) / xlen); fprintf(stderr, "UR: x * ur / xlen %d * %u / %d (%g)\n", x, ur, xlen, ((float)x * ur + xchuk) / xlen); fprintf(stderr, "ul: %u ur: %u u: %u\n", (xlen - x) * ul / xlen, - x * ur / xlen, up); -fprintf(stderr, "%u %u %u %u top: %u bottom: %u -> %u\n", + x * ur / xlen, up);*/ +/*fprintf(stderr, "%u %u %u %u top: %u bottom: %u -> %u\n", ul, ur, ll, lr, up, down, up + down);*/ return up + down; } // calculate one of the channels of a gradient at a particular point. -static uint32_t +static inline uint32_t calc_gradient_channel(uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr, int y, int x, int ylen, int xlen){ + if(channel_default_p(ul) || channel_default_p(ll) || channel_default_p(lr) || channel_default_p(ur)){ + return ul; // FIXME speed this up + } uint32_t chan = 0; - channel_set_rgb(&chan, calc_gradient_component(channel_r(ul), channel_r(ur), + channel_set_rgb_clipped(&chan, + calc_gradient_component(channel_r(ul), channel_r(ur), channel_r(ll), channel_r(lr), y, x, ylen, xlen), calc_gradient_component(channel_g(ul), channel_g(ur), @@ -1984,7 +1991,7 @@ calc_gradient_channel(uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr, // calculate both channels of a gradient at a particular point, storing them // into `c`->channels. x and y ought be the location within the gradient. -static void +static inline void calc_gradient_channels(cell* c, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int y, int x, int ylen, int xlen){ cell_set_fchannel(c, calc_gradient_channel(channels_fchannel(ul), diff --git a/tests/fills.cpp b/tests/fills.cpp index aeaaed09a8..05af2f9ccd 100644 --- a/tests/fills.cpp +++ b/tests/fills.cpp @@ -65,30 +65,23 @@ TEST_CASE("Fills") { } SUBCASE("GradientMonochromatic") { - uint64_t ul, ur, ll, lr; - ul = ur = ll = lr = 0; - channels_set_fg(&ul, 0x40f040); - channels_set_bg(&ul, 0x40f040); - channels_set_fg(&ur, 0x40f040); - channels_set_bg(&ur, 0x40f040); - channels_set_fg(&ll, 0x40f040); - channels_set_bg(&ll, 0x40f040); - channels_set_fg(&lr, 0x40f040); - channels_set_bg(&lr, 0x40f040); + uint64_t c = 0; + channels_set_fg(&c, 0x40f040); + channels_set_bg(&c, 0x40f040); int dimy, dimx; ncplane_dim_yx(n_, &dimy, &dimx); - REQUIRE(0 == ncplane_gradient_sized(n_, "M", 0, ul, ur, ll, lr, dimy, dimx)); - cell c = CELL_TRIVIAL_INITIALIZER; + REQUIRE(0 == ncplane_gradient_sized(n_, "M", 0, c, c, c, c, dimy, dimx)); + cell cl = CELL_TRIVIAL_INITIALIZER; uint64_t channels = 0; channels_set_fg(&channels, 0x40f040); channels_set_bg(&channels, 0x40f040); // check all squares for(int y = 0 ; y < dimy ; ++y){ for(int x = 0 ; x < dimx ; ++x){ - REQUIRE(0 <= ncplane_at_yx(n_, y, x, &c)); - CHECK('M' == c.gcluster); - CHECK(0 == c.attrword); - CHECK(channels == c.channels); + REQUIRE(0 <= ncplane_at_yx(n_, y, x, &cl)); + CHECK('M' == cl.gcluster); + CHECK(0 == cl.attrword); + CHECK(channels == cl.channels); } } CHECK(0 == notcurses_render(nc_)); @@ -201,6 +194,50 @@ TEST_CASE("Fills") { CHECK(0 == notcurses_render(nc_)); } + SUBCASE("Ncplane_Format") { + int sbytes; + CHECK(0 == ncplane_set_fg(n_, 0x444444)); + CHECK(1 == ncplane_putegc(n_, "A", &sbytes)); + CHECK(0 == ncplane_set_fg(n_, 0x888888)); + CHECK(1 == ncplane_putegc(n_, "B", &sbytes)); + CHECK(0 == notcurses_render(nc_)); + // attr should change, but not the EGC/color + CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0)); + cell c = CELL_TRIVIAL_INITIALIZER; + cell_styles_on(&c, NCSTYLE_BOLD); + CHECK(0 == ncplane_format(n_, 0, 0, c.attrword)); + cell d = CELL_TRIVIAL_INITIALIZER; + CHECK(1 == ncplane_at_yx(n_, 0, 0, &d)); + CHECK(d.attrword == c.attrword); + CHECK(0x444444 == cell_fg(&d)); + } + + SUBCASE("Ncplane_Stain") { + int sbytes; + CHECK(0 == ncplane_set_fg(n_, 0x444444)); + for(int y = 0 ; y < 8 ; ++y){ + for(int x = 0 ; x < 8 ; ++x){ + CHECK(1 == ncplane_putegc_yx(n_, y, x, "A", &sbytes)); + } + } + CHECK(0 == notcurses_render(nc_)); + // attr should change, but not the EGC/color + CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0)); + uint64_t channels = 0; + channels_set_fg_rgb_clipped(&channels, 0x88, 0x99, 0x77); + REQUIRE(0 == ncplane_stain(n_, 7, 7, channels, channels, channels, channels)); + CHECK(0 == notcurses_render(nc_)); + cell d = CELL_TRIVIAL_INITIALIZER; + for(int y = 0 ; y < 8 ; ++y){ + for(int x = 0 ; x < 8 ; ++x){ + CHECK(1 == ncplane_at_yx(n_, y, x, &d)); + CHECK(channels == d.channels); + REQUIRE(cell_simple_p(&d)); + CHECK('A' == d.gcluster); + } + } + } + CHECK(0 == notcurses_stop(nc_)); CHECK(0 == fclose(outfp_)); diff --git a/tests/ncplane.cpp b/tests/ncplane.cpp index f24994a0c6..925dd46821 100644 --- a/tests/ncplane.cpp +++ b/tests/ncplane.cpp @@ -968,24 +968,6 @@ TEST_CASE("NCPlane") { CHECK(0 == notcurses_render(nc_)); } - SUBCASE("Ncplane_Format") { - int sbytes; - CHECK(0 == ncplane_set_fg(n_, 0x444444)); - CHECK(1 == ncplane_putegc(n_, "A", &sbytes)); - CHECK(0 == ncplane_set_fg(n_, 0x888888)); - CHECK(1 == ncplane_putegc(n_, "B", &sbytes)); - CHECK(0 == notcurses_render(nc_)); - // attr should change, but not the EGC/color - CHECK(0 == ncplane_cursor_move_yx(n_, 0, 0)); - cell c = CELL_TRIVIAL_INITIALIZER; - cell_styles_on(&c, NCSTYLE_BOLD); - CHECK(0 == ncplane_format(n_, 0, 0, c.attrword)); - cell d = CELL_TRIVIAL_INITIALIZER; - CHECK(1 == ncplane_at_yx(n_, 0, 0, &d)); - CHECK(d.attrword == c.attrword); - CHECK(0x444444 == cell_fg(&d)); - } - SUBCASE("EGCStainable") { cell c = CELL_TRIVIAL_INITIALIZER; int sbytes;