mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
add ncchannels_reverse, use it in ncmenu, add unit test #1878
This commit is contained in:
parent
0ffa587a68
commit
14a50cfa3f
2
NEWS.md
2
NEWS.md
@ -13,6 +13,8 @@ rearrangements of Notcurses.
|
||||
the number of columns consumed, and makes available the number of bytes
|
||||
used by the EGC.
|
||||
* `ncmenu`s can now be used with any plane, not just the standard plane.
|
||||
* Added `ncchannels_reverse()`, which reverses the color aspects of the
|
||||
two channels, while keeping other elements constant.
|
||||
|
||||
* 2.3.8 (2021-07-04)
|
||||
* Marked all capability functions `__attribute__ ((pure))`. If you were
|
||||
|
13
USAGE.md
13
USAGE.md
@ -2940,6 +2940,19 @@ ncchannels_fchannel(uint64_t channels){
|
||||
return ncchannels_bchannel(channels >> 32u);
|
||||
}
|
||||
|
||||
// Returns the channels with the color information swapped, but not
|
||||
// alpha, nor other housekeeping bits.
|
||||
static inline uint64_t
|
||||
ncchannels_reverse(uint64_t channels){
|
||||
const uint64_t raw = ((uint64_t)ncchannels_bchannel(channels) << 32u) +
|
||||
ncchannels_fchannel(channels);
|
||||
const uint64_t statemask = (CELL_NOBACKGROUND_MASK | CELL_FG_ALPHA_MASK |
|
||||
CELL_BG_ALPHA_MASK | (CELL_NOBACKGROUND_MASK >> 32u));
|
||||
uint64_t ret = raw & ~statemask;
|
||||
ret |= channels & statemask;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Extract 24 bits of foreground RGB from 'channels', shifted to LSBs.
|
||||
static inline unsigned
|
||||
ncchannels_fg_rgb(uint64_t channels){
|
||||
|
@ -83,6 +83,8 @@ notcurses_channels - operations on notcurses channels
|
||||
|
||||
**uint64_t ncchannels_set_bg_default(uint64_t* ***channels***);**
|
||||
|
||||
**uint64_t ncchannels_reverse(uint64_t ***channels***);**
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
||||
@ -93,6 +95,10 @@ always due to invalid inputs. Functions returning `bool` are predicates, and
|
||||
return the requested value. Functions returning `unsigned` forms return the
|
||||
input, modified as requested.
|
||||
|
||||
**ncchannels_reverse** inverts the color components of the two channels,
|
||||
while holding all other elements constant. It's the Notcurses approximation
|
||||
to reverse video.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
**notcurses(3)**,
|
||||
|
@ -118,6 +118,10 @@ API int notcurses_ucs32_to_utf8(const char32_t* ucs32, unsigned ucs32count,
|
||||
#define NCALPHA_BLEND 0x10000000ull
|
||||
#define NCALPHA_OPAQUE 0x00000000ull
|
||||
|
||||
// Does this glyph completely obscure the background? If so, there's no need
|
||||
// to emit a background when rasterizing, a small optimization. These are
|
||||
// also used to track regions into which we must not cellblit.
|
||||
#define CELL_NOBACKGROUND_MASK 0x8700000000000000ull
|
||||
// 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
|
||||
@ -297,6 +301,19 @@ ncchannels_fchannel(uint64_t channels){
|
||||
return ncchannels_bchannel(channels >> 32u);
|
||||
}
|
||||
|
||||
// Returns the channels with the color information swapped, but not
|
||||
// alpha, nor other housekeeping bits.
|
||||
static inline uint64_t
|
||||
ncchannels_reverse(uint64_t channels){
|
||||
const uint64_t raw = ((uint64_t)ncchannels_bchannel(channels) << 32u) +
|
||||
ncchannels_fchannel(channels);
|
||||
const uint64_t statemask = (CELL_NOBACKGROUND_MASK | CELL_FG_ALPHA_MASK |
|
||||
CELL_BG_ALPHA_MASK | (CELL_NOBACKGROUND_MASK >> 32u));
|
||||
uint64_t ret = raw & ~statemask;
|
||||
ret |= channels & statemask;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set the 32-bit background channel of a channel pair.
|
||||
static inline uint64_t
|
||||
ncchannels_set_bchannel(uint64_t* channels, uint32_t channel){
|
||||
|
@ -38,10 +38,6 @@ extern "C" {
|
||||
struct sixelmap;
|
||||
struct ncvisual_details;
|
||||
|
||||
// Does this glyph completely obscure the background? If so, there's no need
|
||||
// to emit a background when rasterizing, a small optimization.
|
||||
#define CELL_NOBACKGROUND_MASK 0x8700000000000000ull
|
||||
|
||||
// Was this glyph drawn as part of an ncvisual? If so, we need to honor
|
||||
// blitter stacking rather than the standard trichannel solver.
|
||||
#define CELL_BLITTERSTACK_MASK CELL_NOBACKGROUND_MASK
|
||||
|
@ -452,10 +452,9 @@ int ncmenu_unroll(ncmenu* n, int sectionidx){
|
||||
ncplane_set_channels(n->ncp, n->disablechannels);
|
||||
}
|
||||
if(i == sec->itemselected){
|
||||
ncplane_set_styles(n->ncp, NCSTYLE_REVERSE);
|
||||
}else{
|
||||
ncplane_set_styles(n->ncp, 0);
|
||||
ncplane_set_channels(n->ncp, ncchannels_reverse(ncplane_channels(n->ncp)));
|
||||
}
|
||||
ncplane_set_styles(n->ncp, 0);
|
||||
int cols = ncplane_putstr_yx(n->ncp, ypos, xpos + 1, sec->items[i].desc);
|
||||
if(cols < 0){
|
||||
return -1;
|
||||
|
@ -170,3 +170,28 @@ TEST_CASE("ChannelBlendDefaultRight") {
|
||||
CHECK(0x20 == b);
|
||||
CHECK(2 == blends);
|
||||
}
|
||||
|
||||
// test that colors are inverted, but nothing else
|
||||
TEST_CASE("ChannelsReverse") {
|
||||
uint64_t channels = 0;
|
||||
uint64_t rev = ncchannels_reverse(channels);
|
||||
CHECK(0 == rev);
|
||||
ncchannels_set_fg_palindex(&channels, 8);
|
||||
rev = ncchannels_reverse(channels);
|
||||
CHECK(8 == ncchannels_bg_palindex(rev));
|
||||
CHECK(0 == ncchannels_fg_palindex(rev));
|
||||
ncchannels_set_fg_palindex(&rev, 63);
|
||||
rev = ncchannels_reverse(rev);
|
||||
CHECK(8 == ncchannels_fg_palindex(rev));
|
||||
CHECK(63 == ncchannels_bg_palindex(rev));
|
||||
ncchannels_set_fg_default(&rev);
|
||||
ncchannels_set_bg_alpha(&rev, NCALPHA_TRANSPARENT);
|
||||
rev = ncchannels_reverse(rev);
|
||||
CHECK(63 == ncchannels_fg_palindex(rev));
|
||||
CHECK(ncchannels_bg_default_p(rev));
|
||||
CHECK(NCALPHA_TRANSPARENT == ncchannels_bg_alpha(rev));
|
||||
ncchannels_set_fg_rgb(&rev, 0x2288cc);
|
||||
rev = ncchannels_reverse(rev);
|
||||
CHECK(0x2288cc == ncchannels_bg_rgb(rev));
|
||||
CHECK(ncchannels_fg_default_p(rev));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user