rename cell->nccell, keep alias #1200

pull/1208/head
nick black 4 years ago committed by Nick Black
parent e66f1a03ad
commit fd2acde1b1

@ -1,6 +1,10 @@
This document attempts to list user-visible changes and any major internal
rearrangements of Notcurses.
* 2.1.0 (not yet released)
* `cell` has been renamed `nccell`. The old name has been kept as an alias,
but ought be considered deprecated. It will be removed in Notcurses 3.0.
* 2.0.12 (2020-12-12)
* `ncplane_resize_maximize()` has been added, suitable for use as a
`resizecb`. It resizes the plane to the visual area's size, and is

@ -52,7 +52,7 @@ const char* notcurses_version(void);
// library we loaded, not what we compile against.
void notcurses_version_components(int* major, int* minor, int* patch, int* tweak);
struct cell; // a coordinate on an ncplane: an EGC plus styling
struct nccell; // a coordinate on an ncplane: an EGC plus styling
struct ncplane; // a drawable Notcurses surface, composed of cells
struct notcurses; // Notcurses state for a given terminal, composed of ncplanes
@ -629,11 +629,11 @@ Fundamental to Notcurses is a z-buffer of rectilinear virtual screens, known
as `ncplane`s. An `ncplane` can be larger than the physical screen, or smaller,
or the same size; it can be entirely contained within the physical screen, or
overlap in part, or lie wholly beyond the boundaries, never to be rendered.
In addition to its framebuffer--a rectilinear matrix of cells
In addition to its framebuffer--a rectilinear matrix of `nccell`s
(see [Cells](#cells))--an `ncplane` is defined by:
* a base cell, used for any cell on the plane without a glyph,
* the egcpool backing its cells,
* a base `nccell`, used for any cell on the plane without a glyph,
* the egcpool backing its `nccell`s,
* a current cursor location,
* a current style, foreground channel, and background channel,
* its geometry,
@ -643,7 +643,7 @@ In addition to its framebuffer--a rectilinear matrix of cells
* an optional resize callback,
* a name (used only for debugging).
If opaque, a `cell` on a higher `ncplane` completely obstructs a corresponding
If opaque, a `nccell` on a higher `ncplane` completely obstructs a corresponding
`cell` from a lower `ncplane` from being seen. An `ncplane` corresponds loosely
to an [NCURSES Panel](https://invisible-island.net/ncurses/ncurses-intro.html#panels),
but is the primary drawing surface of notcurses—there is no object
@ -847,7 +847,7 @@ void ncplane_off_styles(struct ncplane* n, unsigned stylebits);
// Set the ncplane's base cell to this cell. It will be used for purposes of
// rendering anywhere that the ncplane's gcluster is 0. Erasing the ncplane
// does not reset the base cell; this function must be called with a zero 'c'.
int ncplane_set_base_cell(struct ncplane* ncp, const cell* c);
int ncplane_set_base_cell(struct ncplane* ncp, const nccell* c);
// Set the ncplane's base cell to this cell. It will be used for purposes of
// rendering anywhere that the ncplane's gcluster is 0. Erasing the ncplane
@ -858,7 +858,7 @@ int ncplane_set_base(struct ncplane* ncp, const char* egc,
// Extract the ncplane's base cell into 'c'. The reference is invalidated if
// 'ncp' is destroyed.
int ncplane_base(struct ncplane* ncp, cell* c);
int ncplane_base(struct ncplane* ncp, nccell* c);
```
`ncplane`s are completely ordered along an imaginary z-axis. Newly-created
@ -904,7 +904,7 @@ char* ncplane_at_cursor(struct ncplane* n, uint16_t* styles, uint64_t* channels)
// Retrieve the current contents of the cell under the cursor into 'c'. This
// cell is invalidated if the associated plane is destroyed.
int ncplane_at_cursor_cell(struct ncplane* n, cell* c);
int ncplane_at_cursor_cell(struct ncplane* n, nccell* c);
// Retrieve the current contents of the specified cell. The EGC is returned, or
// NULL on error. This EGC must be free()d by the caller. The styles and
@ -914,7 +914,7 @@ char* ncplane_at_yx(const struct ncplane* n, int y, int x,
// Retrieve the current contents of the specified cell into 'c'. This cell is
// invalidated if the associated plane is destroyed.
int ncplane_at_yx_cell(struct ncplane* n, int y, int x, cell* c);
int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c);
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
@ -953,20 +953,20 @@ void ncplane_cursor_yx(const struct ncplane* n, int* restrict y, int* restrict x
// and advance the cursor by the width of the cell (but not past the end of the
// plane). On success, returns the number of columns the cursor was advanced.
// On failure, -1 is returned.
int ncplane_putc_yx(struct ncplane* n, int y, int x, const cell* c);
int ncplane_putc_yx(struct ncplane* n, int y, int x, const nccell* c);
// Call ncplane_putc_yx() for the current cursor location.
static inline int
ncplane_putc(struct ncplane* n, const cell* c){
ncplane_putc(struct ncplane* n, const nccell* c){
return ncplane_putc_yx(n, -1, -1, c);
}
// Replace the cell at the specified coordinates with the provided 7-bit char
// Replace the nccell at the specified coordinates with the provided 7-bit char
// 'c'. Advance the cursor by 1. On success, returns 1. On failure, returns -1.
// This works whether the underlying char is signed or unsigned.
static inline int
ncplane_putchar_yx(struct ncplane* n, int y, int x, char c){
cell ce = CELL_INITIALIZER(c, ncplane_attr(n), ncplane_channels(n));
nccell ce = CELL_INITIALIZER(c, ncplane_attr(n), ncplane_channels(n));
return ncplane_putc_yx(n, y, x, &ce);
}
@ -980,7 +980,7 @@ ncplane_putchar(struct ncplane* n, char c){
// of the plane will not be changed.
int ncplane_putchar_stained(struct ncplane* n, char c);
// Replace the cell at the specified coordinates with the provided wide char
// Replace the nccell at the specified coordinates with the provided wide char
// 'w'. Advance the cursor by the character's width as reported by wcwidth().
// On success, returns 1. On failure, returns -1.
static inline int
@ -1196,19 +1196,19 @@ on both sides. Boxes allow fairly detailed specification of how they're drawn.
// lines), just as if ncplane_putc() was called at that spot. Return the
// number of cells drawn on success. On error, return the negative number of
// cells drawn.
int ncplane_hline_interp(struct ncplane* n, const cell* c, int len,
int ncplane_hline_interp(struct ncplane* n, const nccell* c, int len,
uint64_t c1, uint64_t c2);
static inline int
ncplane_hline(struct ncplane* n, const cell* c, int len){
ncplane_hline(struct ncplane* n, const nccell* c, int len){
return ncplane_hline_interp(n, c, len, c->channels, c->channels);
}
int ncplane_vline_interp(struct ncplane* n, const cell* c, int len,
int ncplane_vline_interp(struct ncplane* n, const nccell* c, int len,
uint64_t c1, uint64_t c2);
static inline int
ncplane_vline(struct ncplane* n, const cell* c, int len){
ncplane_vline(struct ncplane* n, const nccell* c, int len){
return ncplane_vline_interp(n, c, len, c->channels, c->channels);
}
@ -1242,17 +1242,17 @@ ncplane_vline(struct ncplane* n, const cell* c, int len){
#define NCBOXCORNER_MASK 0x0300
#define NCBOXCORNER_SHIFT 8u
int ncplane_box(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
int ncplane_box(struct ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hline,
const cell* vline, int ystop, int xstop, unsigned ctlword);
// Draw a box with its upper-left corner at the current cursor position, having
// dimensions 'ylen'x'xlen'. See ncplane_box() for more information. The
// minimum box size is 2x2, and it cannot be drawn off-screen.
static inline int
ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, int ylen, int xlen, unsigned ctlword){
ncplane_box_sized(struct ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hline,
const nccell* vline, int ylen, int xlen, unsigned ctlword){
int y, x;
ncplane_cursor_yx(n, &y, &x);
return ncplane_box(n, ul, ur, ll, lr, hline, vline, y + ylen - 1,
@ -1260,9 +1260,9 @@ ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur,
}
static inline int
ncplane_perimeter(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, unsigned ctlword){
ncplane_perimeter(struct ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hline,
const nccell* vline, unsigned ctlword){
if(ncplane_cursor_move_yx(n, 0, 0)){
return -1;
}
@ -1275,9 +1275,9 @@ static inline int
ncplane_rounded_box(struct ncplane* n, uint32_t attr, uint64_t channels,
int ystop, int xstop, unsigned ctlword){
int ret = 0;
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if((ret = cells_rounded_box(n, attr, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
ret = ncplane_box(n, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
}
@ -1300,9 +1300,9 @@ static inline int
ncplane_double_box(struct ncplane* n, uint32_t attr, uint64_t channels,
int ystop, int xstop, unsigned ctlword){
int ret = 0;
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if((ret = cells_double_box(n, attr, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
ret = ncplane_box(n, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
}
@ -1330,7 +1330,7 @@ Similarly, areas can be filled with a cell.
// target. We do the same to all cardinally-connected cells having this same
// fill target. Returns the number of cells polyfilled. An invalid initial y, x
// is an error. Returns the number of cells filled, or -1 on error.
int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const nccell* c);
// Draw a gradient with its upper-left corner at the current cursor position,
// stopping at 'ystop'x'xstop'. The glyph composed of 'egc' and 'styles' is
@ -1545,15 +1545,16 @@ int ncplane_set_bg_palindex(struct ncplane* n, int idx);
## Cells
Unlike the `notcurses` or `ncplane` objects, the definition of `cell` is
Unlike the `notcurses` or `ncplane` objects, the definition of `nccell` is
available to the user. It is somewhat ironic, then, that the user typically
needn't (and shouldn't) use `cell`s directly. Use a `cell` when the EGC being
output is used several times. In this case, time otherwise spent running
needn't (and shouldn't) use `nccell`s directly. Use an `nccell` when the EGC
being output is used several times. In this case, time otherwise spent running
`cell_load()` (which tokenizes and verifies EGCs) can be saved. It can also be
useful to use a `cell` when the same styling is used in a discontinuous manner.
useful to use an `ncell` when the same styling is used in a discontinuous
manner.
```c
// A cell corresponds to a single character cell on some plane, which can be
// An nccell corresponds to a single character cell on some plane, which can be
// occupied by a single grapheme cluster (some root spacing glyph, along with
// possible combining characters, which might span multiple columns). At any
// cell, we can have a theoretically arbitrarily long UTF-8 string, a foreground
@ -1567,7 +1568,7 @@ useful to use a `cell` when the same styling is used in a discontinuous manner.
//
// Multi-column characters can only have a single style/color throughout.
//
// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
// Each nccell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB.
// Dynamic requirements can add up to 16MB to an ncplane, but such large pools
// are unlikely in common use.
@ -1589,9 +1590,9 @@ useful to use a `cell` when the same styling is used in a discontinuous manner.
// meaningfully set transparency, but it can be mixed into a cascading color.
// RGB is used if neither default terminal colors nor palette indexing are in
// play, and fully supports all transparency options.
typedef struct cell {
typedef struct nccell {
// These 32 bits, together with the associated plane's associated egcpool,
// completely define this cell's EGC. Unless the EGC requires more than four
// completely define this nccell's EGC. Unless the EGC requires more than four
// bytes to encode as UTF-8, it will be inlined here. If more than four bytes
// are required, it will be spilled into the egcpool. In either case, there's
// a NUL-terminated string available without copying, because (1) the egcpool
@ -1605,7 +1606,7 @@ typedef struct cell {
// index into the egcpool. These pools may thus be up to 16MB.
//
// The cost of this scheme is that the character 0x01 (SOH) cannot be encoded
// in a cell, which is absolutely fine because what 70s horseshit is SOH? It
// in a nccell, which is absolutely fine because what 70s horseshit is SOH? It
// must not be allowed through the API, or havoc will result.
uint32_t gcluster; // 4B → 4B
uint8_t gcluster_backstop; // 1B → 5B (8 bits of zero)
@ -1630,7 +1631,7 @@ typedef struct cell {
// best explained by color(3NCURSES). ours is the same concept. until the
// "not default color" bit is set, any color you load will be ignored.
uint64_t channels; // + 8B == 16B
} cell;
} nccell;
#define CELL_WIDEASIAN_MASK 0x8000000000000000ull
#define CELL_BGDEFAULT_MASK 0x0000000040000000ull
@ -1646,9 +1647,9 @@ typedef struct cell {
#define CELL_ALPHA_OPAQUE 0x00000000ull
```
`cell`s must be initialized with an initialization macro or `cell_init()`
`nccell`s must be initialized with an initialization macro or `cell_init()`
before any other use. `cell_init()` and `CELL_TRIVIAL_INITIALIZER` both
simply zero out the `cell`.
simply zero out the `nccell`.
```c
#define CELL_TRIVIAL_INITIALIZER { }
@ -1656,18 +1657,18 @@ simply zero out the `cell`.
#define CELL_INITIALIZER(c, s, chan) { .gcluster = (c), .gcluster_backstop = 0, .reserved = 0, .stylemask = (s), .channels = (chan), }
static inline void
cell_init(cell* c){
cell_init(nccell* c){
memset(c, 0, sizeof(*c));
}
```
A `cell` has three fundamental elements:
An `nccell` has three fundamental elements:
* The EGC displayed at this coordinate, encoded in UTF-8. If the EGC is a
single ASCII character (value less than 0x80), it is stored inline in
the `cell`'s `gcluster` field. Otherwise, `gcluster`'s top 24 bits
the `nccell`'s `gcluster` field. Otherwise, `gcluster`'s top 24 bits
are a 128-biased offset into the associated `ncplane`'s egcpool. This
implies that `cell`s are associated with `ncplane`s once prepared.
implies that `nccell`s are associated with `ncplane`s once prepared.
* The Curses-style attributes of the text.
* The 52 bits of foreground and background RGBA (2x8/8/8/2), plus a few flags.
@ -1675,19 +1676,19 @@ The EGC should be loaded using `cell_load()`. Either a single NUL-terminated
EGC can be provided, or a string composed of multiple EGCs. In the latter case,
the first EGC from the string is loaded. Remember, backing storage for the EGC
is provided by the `ncplane` passed to `cell_load()`; if this `ncplane` is
destroyed (or even erased), the `cell` cannot safely be used. If you're done
using the `cell` before being done with the `ncplane`, call `cell_release()`
destroyed (or even erased), the `nccell` cannot safely be used. If you're done
using the `nccell` before being done with the `ncplane`, call `cell_release()`
to free up the EGC resources.
```c
// Breaks the UTF-8 string in 'gcluster' down, setting up the cell 'c'. Returns
// the number of bytes copied out of 'gcluster', or -1 on failure. The styling
// of the cell is left untouched, but any resources are released.
int cell_load(struct ncplane* n, cell* c, const char* gcluster);
// Breaks the UTF-8 string in 'gcluster' down, setting up the nccell 'c'.
// Returns the number of bytes copied out of 'gcluster', or -1 on failure. The
// styling of the cell is left untouched, but any resources are released.
int cell_load(struct ncplane* n, nccell* c, const char* gcluster);
// cell_load(), plus blast the styling with 'attr' and 'channels'.
static inline int
cell_prime(struct ncplane* n, cell* c, const char* gcluster,
cell_prime(struct ncplane* n, nccell* c, const char* gcluster,
uint32_t stylemask, uint64_t channels){
c->stylemask = stylemask;
c->channels = channels;
@ -1697,10 +1698,10 @@ cell_prime(struct ncplane* n, cell* c, const char* gcluster,
// Duplicate 'c' into 'targ'. Not intended for external use; exposed for the
// benefit of unit tests.
int cell_duplicate(struct ncplane* n, cell* targ, const cell* c);
int cell_duplicate(struct ncplane* n, nccell* targ, const cell* c);
// Release resources held by the cell 'c'.
void cell_release(struct ncplane* n, cell* c);
void cell_release(struct ncplane* n, nccell* c);
#define NCSTYLE_MASK 0x03fful
#define NCSTYLE_STANDOUT 0x0080ul
@ -1717,45 +1718,45 @@ void cell_release(struct ncplane* n, cell* c);
// copy the UTF8-encoded EGC out of the cell, whether simple or complex. the
// result is not tied to the ncplane, and persists across erases / destruction.
static inline char*
cell_strdup(const struct ncplane* n, const cell* c){
cell_strdup(const struct ncplane* n, const nccell* c){
return strdup(cell_extended_gcluster(n, c));
}
// Set the specified style bits for the cell 'c', whether they're actively
// supported or not. Only the lower 16 bits are meaningful.
static inline void
cell_styles_set(cell* c, unsigned stylebits){
cell_styles_set(nccell* c, unsigned stylebits){
c->stylemask = stylebits & NCSTYLE_MASK;
}
// Extract the style bits from the cell.
static inline unsigned
cell_styles(const cell* c){
cell_styles(const nccell* c){
return c->stylemask;
}
// Add the specified styles (in the LSBs) to the cell's existing spec, whether
// they're actively supported or not.
static inline void
cell_on_styles(cell* c, unsigned stylebits){
cell_on_styles(nccell* c, unsigned stylebits){
c->stylemask |= (stylebits & NCSTYLE_MASK);
}
// Remove the specified styles (in the LSBs) from the cell's existing spec.
static inline void
cell_off_styles(cell* c, unsigned stylebits){
cell_off_styles(nccell* c, unsigned stylebits){
c->stylemask &= ~(stylebits & NCSTYLE_MASK);
}
// does the cell contain an East Asian Wide codepoint?
static inline bool
cell_double_wide_p(const cell* c){
cell_double_wide_p(const nccell* c){
return (c->channels & CELL_WIDEASIAN_MASK);
}
// Load a 7-bit char 'ch' into the cell 'c'.
static inline int
cell_load_char(struct ncplane* n, cell* c, char ch){
cell_load_char(struct ncplane* n, nccell* c, char ch){
cell_release(n, c);
c->channels &= ~(CELL_WIDEASIAN_MASK | CELL_NOBACKGROUND_MASK);
c->gcluster = ch;
@ -1764,7 +1765,7 @@ cell_load_char(struct ncplane* n, cell* c, char ch){
// Load a UTF-8 encoded EGC of up to 4 bytes into the cell 'c'.
static inline int
cell_load_egc32(struct ncplane* n, cell* c, uint32_t egc){
cell_load_egc32(struct ncplane* n, nccell* c, uint32_t egc){
cell_release(n, c);
c->channels &= ~(CELL_WIDEASIAN_MASK | CELL_NOBACKGROUND_MASK);
c->gcluster = htole(egc);
@ -1773,7 +1774,7 @@ cell_load_egc32(struct ncplane* n, cell* c, uint32_t egc){
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
// is invalidated by any further operation on the plane 'n', so...watch out!
const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
const char* cell_extended_gcluster(const struct ncplane* n, const nccell* c);
// load up six cells with the EGCs necessary to draw a box. returns 0 on
// success, -1 on error. on error, any cells this function might
@ -1781,8 +1782,8 @@ const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
// six EGCs in gcluster.
static inline int
cells_load_box(struct ncplane* n, uint32_t style, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr,
cell* hl, cell* vl, const char* gclusters){
nccell* ul, nccell* ur, nccell* ll, nccell* lr,
nccell* hl, nccell* vl, const char* gclusters){
int ulen;
if((ulen = cell_prime(n, ul, gclusters, style, channels)) > 0){
if((ulen = cell_prime(n, ur, gclusters += ulen, style, channels)) > 0){
@ -1808,122 +1809,122 @@ cells_load_box(struct ncplane* n, uint32_t style, uint64_t channels,
static inline int
cells_rounded_box(struct ncplane* n, uint32_t attr, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl){
nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){
return cells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, "╭╮╰╯─│");
}
static inline int
cells_double_box(struct ncplane* n, uint32_t attr, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl){
nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){
return cells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, "╔╗╚╝═║");
}
```
### Cell channels API
Helpers are provided to manipulate a `cell`'s `channels` member. They are all
implemented in terms of the lower-level [Channels API](#channels).
Helpers are provided to manipulate an `nccell`'s `channels` member. They are
all implemented in terms of the lower-level [Channels API](#channels).
```c
// Extract the 32-bit background channel from a cell.
static inline uint32_t
cell_bchannel(const cell* cl){
cell_bchannel(const nccell* cl){
return channels_bchannel(cl->channels);
}
// Extract the 32-bit foreground channel from a cell.
static inline uint32_t
cell_fchannel(const cell* cl){
cell_fchannel(const nccell* cl){
return channels_fchannel(cl->channels);
}
// Extract 24 bits of foreground RGB from 'cell', shifted to LSBs.
// Extract 24 bits of foreground RGB from 'cl', shifted to LSBs.
static inline uint32_t
cell_fg_rgb(const cell* cl){
cell_fg_rgb(const nccell* cl){
return channels_fg_rgb(cl->channels);
}
// Extract 24 bits of background RGB from 'cell', shifted to LSBs.
// Extract 24 bits of background RGB from 'cl', shifted to LSBs.
static inline uint32_t
cell_bg_rgb(const cell* cl){
cell_bg_rgb(const nccell* cl){
return channels_bg_rgb(cl->channels);
}
// Extract 2 bits of foreground alpha from 'cell', shifted to LSBs.
// Extract 2 bits of foreground alpha from 'cl', shifted to LSBs.
static inline unsigned
cell_fg_alpha(const cell* cl){
cell_fg_alpha(const nccell* cl){
return channels_fg_alpha(cl->channels);
}
// Extract 2 bits of background alpha from 'cell', shifted to LSBs.
// Extract 2 bits of background alpha from 'cl', shifted to LSBs.
static inline unsigned
cell_bg_alpha(const cell* cl){
cell_bg_alpha(const nccell* cl){
return channels_bg_alpha(cl->channels);
}
// Extract 24 bits of foreground RGB from 'cell', split into subcell.
// Extract 24 bits of foreground RGB from 'cl', split into subcell.
static inline uint32_t
cell_fg_rgb8(const cell* cl, unsigned* r, unsigned* g, unsigned* b){
cell_fg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
return channels_fg_rgb8(cl->channels, r, g, b);
}
// Extract 24 bits of background RGB from 'cell', split into subcell.
// Extract 24 bits of background RGB from 'cl', split into subcell.
static inline uint32_t
cell_bg_rgb8(const cell* cl, unsigned* r, unsigned* g, unsigned* b){
cell_bg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
return channels_bg_rgb8(cl->channels, r, g, b);
}
// Set the r, g, and b cell for the foreground component of this 64-bit
// 'cell' variable, and mark it as not using the default color.
static inline int
cell_set_fg_rgb8(cell* cl, int r, int g, int b){
cell_set_fg_rgb8(nccell* cl, int r, int g, int b){
return channels_set_fg_rgb8(&cl->channels, r, g, b);
}
// Same, but clipped to [0..255].
static inline void
cell_set_fg_rgb8_clipped(cell* cl, int r, int g, int b){
cell_set_fg_rgb8_clipped(nccell* cl, int r, int g, int b){
channels_set_fg_rgb8_clipped(&cl->channels, r, g, b);
}
// Same, but with an assembled 24-bit RGB value.
static inline int
cell_set_fg_rgb(cell* c, uint32_t channel){
cell_set_fg_rgb(nccell* c, uint32_t channel){
return channels_set_fg_rgb(&c->channels, channel);
}
// Set the r, g, and b cell for the background component of this 64-bit
// 'cell' variable, and mark it as not using the default color.
static inline int
cell_set_bg_rgb8(cell* cl, int r, int g, int b){
cell_set_bg_rgb8(nccell* cl, int r, int g, int b){
return channels_set_bg_rgb8(&cl->channels, r, g, b);
}
// Same, but clipped to [0..255].
static inline void
cell_set_bg_rgb8_clipped(cell* cl, int r, int g, int b){
cell_set_bg_rgb8_clipped(nccell* cl, int r, int g, int b){
channels_set_bg_rgb8_clipped(&cl->channels, r, g, b);
}
// Same, but with an assembled 24-bit RGB value.
static inline int
cell_set_bg_rgb(cell* c, uint32_t channel){
cell_set_bg_rgb(nccell* c, uint32_t channel){
return channels_set_bg_rgb(&c->channels, channel);
}
static inline int
cell_set_fg_alpha(cell* c, unsigned alpha){
cell_set_fg_alpha(nccell* c, unsigned alpha){
return channels_set_fg_alpha(&c->channels, alpha);
}
static inline int
cell_set_bg_alpha(cell* c, unsigned alpha){
cell_set_bg_alpha(nccell* c, unsigned alpha){
return channels_set_bg_alpha(&c->channels, alpha);
}
// Is the foreground using the "default foreground color"?
static inline bool
cell_fg_default_p(const cell* cl){
cell_fg_default_p(const nccell* cl){
return channels_fg_default_p(cl->channels);
}
@ -1931,19 +1932,19 @@ cell_fg_default_p(const cell* cl){
// background color" must generally be used to take advantage of
// terminal-effected transparency.
static inline bool
cell_bg_default_p(const cell* cl){
cell_bg_default_p(const nccell* cl){
return channels_bg_default_p(cl->channels);
}
// Use the default color for the foreground.
static inline void
cell_set_fg_default(cell* c){
cell_set_fg_default(nccell* c){
channels_set_fg_default(&c->channels);
}
// Use the default color for the background.
static inline void
cell_set_bg_default(cell* c){
cell_set_bg_default(nccell* c){
channels_set_bg_default(&c->channels);
}
@ -2373,13 +2374,13 @@ additionally provides 2 bits of alpha channel, a bit for selecting terminal
default colors, and a bit to indicate whether it describes a Wide East Asian
character. The remaining four bits are reserved. Typically two channels are
bound together in a 64-bit unsigned integer (`uint64_t`), with eight bits
currently going unused. There is such a double-channel in every `cell` and
currently going unused. There is such a double-channel in every `nccell` and
`ncplane` object.
Usually, the higher-level `ncplane` and `cell` functionality ought be used. It
Usually, the higher-level `ncplane` and `nccell` functionality ought be used. It
will sometimes be necessary, however, to muck with channels at their lowest
level. The channel API facilitates such muckery. All channel-related `ncplane`
and `cell` functionality is implemented in terms of this API.
and `nccell` functionality is implemented in terms of this API.
```c
// Extract the 8-bit red component from a 32-bit channel.
@ -2626,6 +2627,7 @@ graphics) plane using a variety of blitting methods:
* Unicode upper- and lower-half blocks (▀ and ▄, respectively). 2:1 pixels
map losslessly to 2:1 cells. The default blitting mode.
* Unicode half blocks plus quadrants. 2x2 pixels map to 2:1 cells.
* Unicode sextants. 3x2 pixels map to 2:1 cells.
* Braille. 4:2 pixels map to 2:1 cells. Useful when only two colors are needed
in a small area, due to high resolution.

@ -41,7 +41,7 @@
<div style="float:left">
<h3>C library (section 3)</h3>
<a href="notcurses_capabilities.3.html">notcurses_capabilities</a>—runtime capability detection<br/>
<a href="notcurses_cell.3.html">notcurses_cell</a>—operations on <tt>cell</tt> objects<br/>
<a href="notcurses_nccell.3.html">notcurses_nccell</a>—operations on <tt>nccell</tt> objects<br/>
<a href="notcurses_channels.3.html">notcurses_channels</a>—operations on the <tt>channel</tt> type<br/>
<a href="notcurses_directmode.3.html">notcurses_directmode</a>—minimal notcurses instances for styling text<br/>
<a href="notcurses_fade.3.html">notcurses_fade</a>—fading and pulsing for <tt>ncplane</tt>s<br/>

@ -73,21 +73,21 @@ is assumed to be 80x24 cells). Further ncplanes can be created with
**ncplane_new(3)**. A total z-ordering always exists on the set of ncplanes,
and new ncplanes are placed at the top of the z-buffer. Ncplanes can be larger,
smaller, or the same size as the physical screen, and can be placed anywhere
relative to it (including entirely off-screen). Ncplanes are made up of cells
(see [Cells][] below). Information on ncplanes is available at
relative to it (including entirely off-screen). Ncplanes are made up of
`nccell`s (see [NcCells][] below). Information on ncplanes is available at
**notcurses_plane(3)**.
## Cells
## NcCells
Cells make up the framebuffers backing each ncplane, one cell per coordinate,
one extended grapheme cluster (see **unicode(7)**) per cell. A cell consists of
a gcluster (either a directly-encoded 7-bit ASCII character (see **ascii(7)**), or
a 25-bit index into the ncplane's egcpool), a set of attributes, and two
channels (one for the foreground, and one for the background—see
**notcurses_channels(3)**). Information on cells is available at
**notcurses_cell(3)**.
`nccell`s make up the framebuffers backing each ncplane, one cell per
coordinate, one extended grapheme cluster (see **unicode(7)**) per cell. An
`nccell` consists of a gcluster (either a directly-encoded 7-bit ASCII
character (see **ascii(7)**), or a 25-bit index into the ncplane's egcpool), a
set of attributes, and two channels (one for the foreground, and one for the
background—see **notcurses_channels(3)**). Information on cells is available at
**notcurses_nccell(3)**.
It is not usually necessary for users to interact directly with cells. They
It is not usually necessary for users to interact directly with `nccell`s. They
are typically encountered when retrieving data from ncplanes or the rendered
scene (see e.g. **ncplane_at_yx(3)**), or to achieve peak performance when a
particular EGC is heavily reused within a plane.
@ -142,7 +142,7 @@ order to turn most error returns into exceptions.
**notcurses-demo(1)**,
**notcurses-input(1)**,
**notcurses_capabilities(3)**,
**notcurses_cell(3)**,
**notcurses_nccell(3)**,
**notcurses_channels(3)**,
**notcurses_directmode(3)**,
**notcurses_fade(3)**,

@ -1,161 +0,0 @@
% notcurses_cell(3)
% nick black <nickblack@linux.com>
% v2.0.12
# NAME
notcurses_cell - operations on notcurses cells
# SYNOPSIS
**#include <notcurses/notcurses.h>**
```c
// See DESCRIPTION below for information on EGC encoding
typedef struct cell {
uint32_t gcluster; // 4B → 4B
uint8_t gcluster_backstop; // 1B → 5B (8 bits of zero)
uint8_t reserved; // 1B → 6B (8 reserved bits, ought be zero)
uint16_t stylemask; // 2B → 8B (16 bits of NCSTYLE_* attributes)
uint64_t channels;
} cell;
#define CELL_TRIVIAL_INITIALIZER \
{ .gcluster = '\0', .stylemask = 0, .channels = 0, }
#define CELL_SIMPLE_INITIALIZER(c) \
{ .gcluster = (c), .stylemask = 0, .channels = 0, }
#define CELL_INITIALIZER(c, s, chan) \
{ .gcluster = (c), .stylemask = (s), .channels = (chan), }
#define CELL_WIDEASIAN_MASK 0x8000000080000000ull
#define CELL_BGDEFAULT_MASK 0x0000000040000000ull
#define CELL_FGDEFAULT_MASK (CELL_BGDEFAULT_MASK << 32u)
#define CELL_BG_RGB_MASK 0x0000000000ffffffull
#define CELL_FG_RGB_MASK (CELL_BG_MASK << 32u)
#define CELL_BG_PALETTE 0x0000000008000000ull
#define CELL_FG_PALETTE (CELL_BG_PALETTE << 32u)
#define CHANNEL_ALPHA_MASK 0x30000000ull
#define CELL_ALPHA_HIGHCONTRAST 0x30000000ull
#define CELL_ALPHA_TRANSPARENT 0x2.0.12000ull
#define CELL_ALPHA_BLEND 0x10000000ull
#define CELL_ALPHA_OPAQUE 0x00000000ull
```
**void cell_init(cell* ***c***);**
**int cell_load(struct ncplane* ***n***, cell* ***c***, const char* ***gcluster***);**
**int cell_prime(struct ncplane* ***n***, cell* ***c***, const char* ***gcluster***,
uint32_t ***stylemask***, uint64_t ***channels***);**
**int cell_duplicate(struct ncplane* ***n***, cell* ***targ***, const cell* ***c***);**
**void cell_release(struct ncplane* ***n***, cell* ***c***);**
**void cell_styles_set(cell* ***c***, unsigned ***stylebits***);**
**unsigned cell_styles(const cell* ***c***);**
**void cell_on_styles(cell* ***c***, unsigned ***stylebits***);**
**void cell_off_styles(cell* ***c***, unsigned ***stylebits***);**
**void cell_set_fg_default(cell* ***c***);**
**void cell_set_bg_default(cell* ***c***);**
**int cell_set_fg_alpha(cell* ***c***, unsigned ***alpha***);**
**int cell_set_bg_alpha(cell* ***c***, unsigned ***alpha***);**
**bool cell_double_wide_p(const cell* ***c***);**
**const char* cell_extended_gcluster(const struct ncplane* ***n***, const cell* ***c***);**
**char* cell_strdup(const struct ncplane* ***n***, const cell* ***c***);**
**int cell_load_char(struct ncplane* ***n***, cell* ***c***, char ***ch***);**
**int cell_load_egc32(struct ncplane* ***n***, cell* ***c***, uint32_t ***egc***);**
**char* cell_extract(const struct ncplane* ***n***, const cell* ***c***, uint16_t* ***stylemask***, uint64_t* ***channels***);**
**uint32_t cell_bchannel(const cell* ***c***);**
**uint32_t cell_fchannel(const cell* ***c***);**
**uint64_t cell_set_bchannel(cell* ***c***, uint32_t ***channel***);**
**uint64_t cell_set_fchannel(cell* ***c***, uint32_t ***channel***);**
**uint32_t cell_fg_rgb(const cell* ***c***);**
**uint32_t cell_bg_rgb(const cell* ***c***);**
**unsigned cell_fg_alpha(const cell* ***c***);**
**unsigned cell_bg_alpha(const cell* ***c***);**
**unsigned cell_fg_rgb8(const cell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);**
**unsigned cell_bg_rgb8(const cell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);**
**int cell_set_fg_rgb8(cell* ***c***, int ***r***, int ***g***, int ***b***);**
**int cell_set_bg_rgb8(cell* ***c***, int ***r***, int ***g***, int ***b***);**
**void cell_set_fg_rgb8_clipped(cell* ***c***, int ***r***, int ***g***, int ***b***);**
**void cell_set_bg_rgb8_clipped(cell* ***c***, int ***r***, int ***g***, int ***b***);**
**int cell_set_fg_rgb(cell* ***c***, uint32_t ***channel***);**
**int cell_set_bg_rgb(cell* ***c***, uint32_t ***channel***);**
**bool cell_fg_default_p(const cell* ***c***);**
**bool cell_bg_default_p(const cell* ***c***);**
**int ncstrwidth(const char* ***text***)**;
# DESCRIPTION
Cells make up the framebuffer associated with each plane, with one cell per
addressable coordinate. You should not usually need to interact directly
with cells.
Each **cell** contains exactly one extended grapheme cluster. If the EGC
is encoded in UTF-8 with four or fewer bytes (all Unicode codepoints as of
Unicode 13 can be encoded in no more than four UTF-8 bytes), it is encoded
directly into the **cell**'s **gcluster** field, and no additional storage
is necessary. Otherwise, the EGC is stored as a nul-terminated UTF-8 string in
some backing egcpool. Egcpools are associated with **ncplane**s, so **cell**s
must be considered associated with **ncplane**s. Indeed, **ncplane_erase()**
destroys the backing storage for all a plane's cells, invalidating them. This
association is formed at the time of **cell_load()**, **cell_prime()**, or
**cell_duplicate()**. All of these functions first call **cell_release()**, as
does **cell_load_simple()**. When done using a **cell** entirely, call
**cell_release()**. **ncplane_destroy()** will free up the memory used by the
**cell**, but the backing egcpool has a maximum size of 16MiB, and failure to
release **cell**s can eventually block new output.
**cell_extended_gcluster** provides a nul-terminated handle to the EGC. This
ought be considered invalidated by changes to the **cell** or **egcpool**.
The handle is **not** heap-allocated; do **not** attempt to **free(3)** it.
A heap-allocated copy can be acquired with **cell_strdup**.
# RETURN VALUES
**cell_load()** and similar functions return the number of bytes loaded from the
EGC, or -1 on failure. They can fail due to either an invalid UTF-8 input, or the
backing egcpool reaching its maximum size.
**cell_set_fg_rgb8()** and similar functions will return -1 if provided invalid
inputs, and 0 otherwise.
# SEE ALSO
**notcurses(3)**,
**notcurses_channels(3)**,
**notcurses_plane(3)**,
**notcurses_output(3)**

@ -10,13 +10,13 @@ notcurses_lines - operations on lines and boxes
**#include <notcurses/notcurses.h>**
**int ncplane_hline_interp(struct ncplane* ***n***, const cell* ***c***, int ***len***, uint64_t ***c1***, uint64_t ***c2***);**
**int ncplane_hline_interp(struct ncplane* ***n***, const nccell* ***c***, int ***len***, uint64_t ***c1***, uint64_t ***c2***);**
**static inline int ncplane_hline(struct ncplane* ***n***, const cell* ***c***, int ***len***);**
**static inline int ncplane_hline(struct ncplane* ***n***, const nccell* ***c***, int ***len***);**
**int ncplane_vline_interp(struct ncplane* ***n***, const cell* ***c***, int ***len***, uint64_t ***c1***, uint64_t ***c2***);**
**int ncplane_vline_interp(struct ncplane* ***n***, const nccell* ***c***, int ***len***, uint64_t ***c1***, uint64_t ***c2***);**
**static inline int ncplane_vline(struct ncplane* ***n***, const cell* ***c***, int ***len***);**
**static inline int ncplane_vline(struct ncplane* ***n***, const nccell* ***c***, int ***len***);**
```c
#define NCBOXMASK_TOP 0x0001
@ -31,27 +31,27 @@ notcurses_lines - operations on lines and boxes
#define NCBOXCORNER_SHIFT 8u
```
**int ncplane_box(struct ncplane* ***n***, const cell* ***ul***, const cell* ***ur***, const cell* ***ll***, const cell* ***lr***, const cell* ***hline***, const cell* ***vline***, int ***ystop***, int ***xstop***, unsigned ***ctlword***);**
**int ncplane_box(struct ncplane* ***n***, const nccell* ***ul***, const nccell* ***ur***, const nccell* ***ll***, const nccell* ***lr***, const nccell* ***hline***, const nccell* ***vline***, int ***ystop***, int ***xstop***, unsigned ***ctlword***);**
**static inline int ncplane_box_sized(struct ncplane* ***n***, const cell* ***ul***, const cell* ***ur***, const cell* ***ll***, const cell* ***lr***, const cell* ***hline***, const cell* ***vline***, int ***ylen***, int ***xlen***, unsigned ***ctlword***);**
**static inline int ncplane_box_sized(struct ncplane* ***n***, const nccell* ***ul***, const nccell* ***ur***, const nccell* ***ll***, const nccell* ***lr***, const nccell* ***hline***, const nccell* ***vline***, int ***ylen***, int ***xlen***, unsigned ***ctlword***);**
**static inline int ncplane_perimeter(struct ncplane* ***n***, const cell* ***ul***, const cell* ***ur***, const cell* ***ll***, const cell* ***lr***, const cell* ***hline***, const cell* ***vline***, unsigned ***ctlword***)**
**static inline int ncplane_perimeter(struct ncplane* ***n***, const nccell* ***ul***, const nccell* ***ur***, const nccell* ***ll***, const nccell* ***lr***, const nccell* ***hline***, const nccell* ***vline***, unsigned ***ctlword***)**
**static inline int cells_load_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, cell* ***ul***, cell* ***ur***, cell* ***ll***, cell* ***lr***, cell* ***hl***, cell* ***vl***, const char* ***gclusters***);**
**static inline int cells_load_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, nccell* ***ul***, nccell* ***ur***, nccell* ***ll***, nccell* ***lr***, nccell* ***hl***, nccell* ***vl***, const char* ***gclusters***);**
**static inline int cells_rounded_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, cell* ***ul***, cell* ***ur***, cell* ***ll***, cell* ***lr***, cell* ***hl***, cell* ***vl***);**
**static inline int cells_rounded_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, nccell* ***ul***, nccell* ***ur***, nccell* ***ll***, nccell* ***lr***, nccell* ***hl***, nccell* ***vl***);**
**static inline int ncplane_rounded_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, int ***ystop***, int ***xstop***, unsigned ***ctlword***);**
**static inline int ncplane_rounded_box_sized(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, int ***ylen***, int ***xlen***, unsigned ***ctlword***);**
**static inline int cells_double_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, cell* ***ul***, cell* ***ur***, cell* ***ll***, cell* ***lr***, cell* ***hl***, cell* ***vl***);**
**static inline int cells_double_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, nccell* ***ul***, nccell* ***ur***, nccell* ***ll***, nccell* ***lr***, nccell* ***hl***, nccell* ***vl***);**
**static inline int ncplane_double_box(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, int ***ystop***, int ***xstop***, unsigned ***ctlword***);**
**static inline int ncplane_double_box_sized(struct ncplane* ***n***, uint32_t ***styles***, uint64_t ***channels***, int ***ylen***, int ***xlen***, unsigned ***ctlword***);**
**int ncplane_polyfill_yx(struct ncplane* ***n***, int ***y***, int ***x***, const cell* ***c***);**
**int ncplane_polyfill_yx(struct ncplane* ***n***, int ***y***, int ***x***, const nccell* ***c***);**
**int ncplane_gradient(struct ncplane* ***n***, const char* ***egc***, uint32_t ***stylemask***, uint64_t ***ul***, uint64_t ***ur***, uint64_t ***ll***, uint64_t ***lr***, int ***ystop***, int ***xstop***);**
@ -81,5 +81,5 @@ current equivalent position, otherwise 0.
# SEE ALSO
**notcurses(3)**,
**notcurses_cell(3)**,
**notcurses_nccell(3)**,
**notcurses_plane(3)**

@ -0,0 +1,167 @@
% notcurses_nccell(3)
% nick black <nickblack@linux.com>
% v2.0.12
# NAME
notcurses_nccell - operations on notcurses cells
# SYNOPSIS
**#include <notcurses/notcurses.h>**
```c
// See DESCRIPTION below for information on EGC encoding
typedef struct nccell {
uint32_t gcluster; // 4B → 4B
uint8_t gcluster_backstop; // 1B → 5B (8 bits of zero)
uint8_t reserved; // 1B → 6B (8 reserved bits, ought be zero)
uint16_t stylemask; // 2B → 8B (16 bits of NCSTYLE_* attributes)
uint64_t channels;
} nccell;
#define CELL_TRIVIAL_INITIALIZER \
{ .gcluster = '\0', .stylemask = 0, .channels = 0, }
#define CELL_SIMPLE_INITIALIZER(c) \
{ .gcluster = (c), .stylemask = 0, .channels = 0, }
#define CELL_INITIALIZER(c, s, chan) \
{ .gcluster = (c), .stylemask = (s), .channels = (chan), }
#define CELL_WIDEASIAN_MASK 0x8000000080000000ull
#define CELL_BGDEFAULT_MASK 0x0000000040000000ull
#define CELL_FGDEFAULT_MASK (CELL_BGDEFAULT_MASK << 32u)
#define CELL_BG_RGB_MASK 0x0000000000ffffffull
#define CELL_FG_RGB_MASK (CELL_BG_MASK << 32u)
#define CELL_BG_PALETTE 0x0000000008000000ull
#define CELL_FG_PALETTE (CELL_BG_PALETTE << 32u)
#define CHANNEL_ALPHA_MASK 0x30000000ull
#define CELL_ALPHA_HIGHCONTRAST 0x30000000ull
#define CELL_ALPHA_TRANSPARENT 0x2.0.12000ull
#define CELL_ALPHA_BLEND 0x10000000ull
#define CELL_ALPHA_OPAQUE 0x00000000ull
```
**void cell_init(nccell* ***c***);**
**int cell_load(struct ncplane* ***n***, nccell* ***c***, const char* ***gcluster***);**
**int cell_prime(struct ncplane* ***n***, nccell* ***c***, const char* ***gcluster***,
uint32_t ***stylemask***, uint64_t ***channels***);**
**int cell_duplicate(struct ncplane* ***n***, nccell* ***targ***, const nccell* ***c***);**
**void cell_release(struct ncplane* ***n***, nccell* ***c***);**
**void cell_styles_set(nccell* ***c***, unsigned ***stylebits***);**
**unsigned cell_styles(const nccell* ***c***);**
**void cell_on_styles(nccell* ***c***, unsigned ***stylebits***);**
**void cell_off_styles(nccell* ***c***, unsigned ***stylebits***);**
**void cell_set_fg_default(nccell* ***c***);**
**void cell_set_bg_default(nccell* ***c***);**
**int cell_set_fg_alpha(nccell* ***c***, unsigned ***alpha***);**
**int cell_set_bg_alpha(nccell* ***c***, unsigned ***alpha***);**
**bool cell_double_wide_p(const nccell* ***c***);**
**const char* cell_extended_gcluster(const struct ncplane* ***n***, const nccell* ***c***);**
**char* cell_strdup(const struct ncplane* ***n***, const nccell* ***c***);**
**int cell_load_char(struct ncplane* ***n***, nccell* ***c***, char ***ch***);**
**int cell_load_egc32(struct ncplane* ***n***, nccell* ***c***, uint32_t ***egc***);**
**char* cell_extract(const struct ncplane* ***n***, const nccell* ***c***, uint16_t* ***stylemask***, uint64_t* ***channels***);**
**uint32_t cell_bchannel(const nccell* ***c***);**
**uint32_t cell_fchannel(const nccell* ***c***);**
**uint64_t cell_set_bchannel(nccell* ***c***, uint32_t ***channel***);**
**uint64_t cell_set_fchannel(nccell* ***c***, uint32_t ***channel***);**
**uint32_t cell_fg_rgb(const nccell* ***c***);**
**uint32_t cell_bg_rgb(const nccell* ***c***);**
**unsigned cell_fg_alpha(const nccell* ***c***);**
**unsigned cell_bg_alpha(const nccell* ***c***);**
**unsigned cell_fg_rgb8(const nccell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);**
**unsigned cell_bg_rgb8(const ncell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);**
**int cell_set_fg_rgb8(nccell* ***c***, int ***r***, int ***g***, int ***b***);**
**int cell_set_bg_rgb8(nccell* ***c***, int ***r***, int ***g***, int ***b***);**
**void cell_set_fg_rgb8_clipped(nccell* ***c***, int ***r***, int ***g***, int ***b***);**
**void cell_set_bg_rgb8_clipped(nccell* ***c***, int ***r***, int ***g***, int ***b***);**
**int cell_set_fg_rgb(nccell* ***c***, uint32_t ***channel***);**
**int cell_set_bg_rgb(nccell* ***c***, uint32_t ***channel***);**
**bool cell_fg_default_p(const nccell* ***c***);**
**bool cell_bg_default_p(const nccell* ***c***);**
**int ncstrwidth(const char* ***text***)**;
# DESCRIPTION
Cells make up the framebuffer associated with each plane, with one cell per
addressable coordinate. You should not usually need to interact directly
with **nccell**s.
Each **nccell** contains exactly one extended grapheme cluster. If the EGC
is encoded in UTF-8 with four or fewer bytes (all Unicode codepoints as of
Unicode 13 can be encoded in no more than four UTF-8 bytes), it is encoded
directly into the **nccell**'s **gcluster** field, and no additional storage
is necessary. Otherwise, the EGC is stored as a nul-terminated UTF-8 string in
some backing egcpool. Egcpools are associated with **ncplane**s, so **nccell**s
must be considered associated with **ncplane**s. Indeed, **ncplane_erase()**
destroys the backing storage for all a plane's cells, invalidating them. This
association is formed at the time of **cell_load()**, **cell_prime()**, or
**cell_duplicate()**. All of these functions first call **cell_release()**, as
does **cell_load_simple()**. When done using a **nccell** entirely, call
**cell_release()**. **ncplane_destroy()** will free up the memory used by the
**nccell**, but the backing egcpool has a maximum size of 16MiB, and failure to
release **nccell**s can eventually block new output.
**cell_extended_gcluster** provides a nul-terminated handle to the EGC. This
ought be considered invalidated by changes to the **nccell** or **egcpool**.
The handle is **not** heap-allocated; do **not** attempt to **free(3)** it.
A heap-allocated copy can be acquired with **cell_strdup**.
# RETURN VALUES
**cell_load()** and similar functions return the number of bytes loaded from the
EGC, or -1 on failure. They can fail due to either an invalid UTF-8 input, or the
backing egcpool reaching its maximum size.
**cell_set_fg_rgb8()** and similar functions will return -1 if provided invalid
inputs, and 0 otherwise.
# NOTES
**cell** was renamed to **nccell** in Notcurses 2.1.0, so as not to bleed such
a common term into the (single, global) C namespace. **cell** will be retained
as an alias until Notcurses 3.0.
# SEE ALSO
**notcurses(3)**,
**notcurses_channels(3)**,
**notcurses_plane(3)**,
**notcurses_output(3)**

@ -10,9 +10,9 @@ notcurses_output - output to ncplanes
**#include <notcurses/notcurses.h>**
**static inline int ncplane_putc(struct ncplane* ***n***, const cell* ***c***);**
**static inline int ncplane_putc(struct ncplane* ***n***, const nccell* ***c***);**
**int ncplane_putc_yx(struct ncplane* ***n***, int ***y***, int ***x***, const cell* ***c***);**
**int ncplane_putc_yx(struct ncplane* ***n***, int ***y***, int ***x***, const nccell* ***c***);**
**static inline int ncplane_putchar(struct ncplane* ***n***, char ***c***);**
@ -81,7 +81,7 @@ notcurses_output - output to ncplanes
These functions write EGCs (Extended Grapheme Clusters) to the specified
**struct ncplane**s. The following inputs are supported:
* **ncplane_putc()**: writes a single cell (see **notcurses_cell(3)**)
* **ncplane_putc()**: writes a single **nccell** (see **notcurses_nccell(3)**)
* **ncplane_putchar()**: writes a single 7-bit ASCII character
* **ncplane_putwc()**: writes a single **wchar_t** (following UTF-8 conversion)
* **ncplane_putwegc()**: writes a single EGC from an array of **wchar_t**
@ -93,7 +93,7 @@ These functions write EGCs (Extended Grapheme Clusters) to the specified
* **ncplane_puttext()**: multi-line, line-broken, aligned text
All of these use the **ncplane**'s active styling, save **notcurses_putc()**,
which uses the cell's styling. Functions accepting a single EGC expect a series
which uses the **nccell**'s styling. Functions accepting a single EGC expect a series
of **wchar_t** terminated by **L'\0'** or a series of UTF-8 **char** terminated
by **'\0'**. The EGC must be well-formed, and must not contain any cluster
breaks. For more information, consult [Unicode® Standard Annex #29](https://unicode.org/reports/tr29/).
@ -134,7 +134,7 @@ EGCs.
**fprintf(3)**
**notcurses(3)**,
**notcurses_cell(3)**,
**notcurses_nccell(3)**,
**notcurses_plane(3)**,
**stdarg(3)**,
**ascii(7)**,

@ -53,7 +53,7 @@ input, modified as requested.
# SEE ALSO
**notcurses(3)**,
**notcurses_cell(3)**,
**notcurses_nccell(3)**,
**notcurses_channels(3)**,
**notcurses_output(3)**,
**notcurses_plane(3)**

@ -65,11 +65,11 @@ typedef struct ncplane_options {
**const struct ncplane* ncplane_parent_const(const struct ncplane* ***n***);**
**int ncplane_set_base_cell(struct ncplane* ***ncp***, const cell* ***c***);**
**int ncplane_set_base_cell(struct ncplane* ***ncp***, const nccell* ***c***);**
**int ncplane_set_base(struct ncplane* ***ncp***, const char* ***egc***, uint32_t ***stylemask***, uint64_t ***channels***);**
**int ncplane_base(struct ncplane* ***ncp***, cell* ***c***);**
**int ncplane_base(struct ncplane* ***ncp***, nccell* ***c***);**
**int ncplane_move_top(struct ncplane* ***n***);**
@ -85,11 +85,11 @@ typedef struct ncplane_options {
**char* ncplane_at_cursor(struct ncplane* ***n***, uint16_t* ***stylemask***, uint64_t* ***channels***);**
**int ncplane_at_cursor_cell(struct ncplane* ***n***, cell* ***c***);**
**int ncplane_at_cursor_cell(struct ncplane* ***n***, nccell* ***c***);**
**char* ncplane_at_yx(const struct ncplane* ***n***, int ***y***, int ***x***, uint16_t* ***stylemask***, uint64_t* ***channels***);**
**int ncplane_at_yx_cell(struct ncplane* ***n***, int ***y***, int ***x***, cell* ***c***);**
**int ncplane_at_yx_cell(struct ncplane* ***n***, int ***y***, int ***x***, nccell* ***c***);**
**uint32_t* ncplane_rgba(const struct ncplane* ***nc***, int ***begy***, int ***begx***, int ***leny***, int ***lenx***);**
@ -189,11 +189,11 @@ typedef struct ncplane_options {
Ncplanes are the fundamental drawing object of notcurses. All output functions
take a **struct ncplane** as an argument. They can be any size, and placed
anywhere. In addition to its framebuffer--a rectilinear matrix of cells
(see **notcurses_cell(3)**)--an ncplane is defined by:
anywhere. In addition to its framebuffer--a rectilinear matrix of **nccell**s
(see **notcurses_nccell(3)**)--an ncplane is defined by:
* a base cell, used for any cell on the plane without a glyph,
* the egcpool backing its cells,
* a base **nccell**, used for any cell on the plane without a glyph,
* the egcpool backing its **nccell**s,
* a current cursor location,
* a current style, foreground channel, and background channel,
* its geometry,
@ -315,10 +315,10 @@ respectively, of the pile containing their argument. **notcurses_top** and
**notcurses_bottom** do the same for the standard pile.
**ncplane_at_yx** and **ncplane_at_cursor** return a heap-allocated copy of the
EGC at the relevant cell, or NULL if the cell is invalid. The caller should free
EGC at the relevant cell, or **NULL** if the cell is invalid. The caller should free
this result. **ncplane_at_yx_cell** and **ncplane_at_cursor_cell** instead load
these values into a **cell**, which is invalidated if the associated plane is
destroyed. The caller should release this cell with **cell_release**.
destroyed. The caller should release this **nccell** with **cell_release**.
Functions returning **int** return 0 on success, and non-zero on error.
@ -331,5 +331,5 @@ It should not be used in new code.
# SEE ALSO
**notcurses(3)**, **notcurses_cell(3)**, **notcurses_output(3)**,
**notcurses(3)**, **notcurses_nccell(3)**, **notcurses_output(3)**,
**notcurses_stdplane(3)**

@ -25,8 +25,8 @@ notcurses_render - sync the physical display to the virtual ncplanes
# DESCRIPTION
Rendering reduces a pile of **ncplane**s to a single plane, proceeding from the
top to the bottom along a pile's z-axis. The result is a matrix of **cell**s
(see **notcurses_cell**). Rasterizing takes this matrix, together with the
top to the bottom along a pile's z-axis. The result is a matrix of **nccell**s
(see **notcurses_nccell**). Rasterizing takes this matrix, together with the
current state of the visual area, and produces a stream of optimized control
sequences and EGCs for the terminal. By writing this stream to the terminal,
the physical display is synced to some pile's planes.
@ -115,7 +115,7 @@ purposes of color blending.
# SEE ALSO
**notcurses(3)**,
**notcurses_cell(3)**,
**notcurses_nccell(3)**,
**notcurses_input(3)**,
**notcurses_output(3)**,
**notcurses_plane(3)**,

@ -46,17 +46,17 @@ namespace ncpp
_cell = CELL_INITIALIZER (c, a, chan);
}
operator cell* () noexcept
operator nccell* () noexcept
{
return &_cell;
}
operator cell const* () const noexcept
operator nccell const* () const noexcept
{
return &_cell;
}
cell& get () noexcept
nccell& get () noexcept
{
return _cell;
}
@ -222,7 +222,7 @@ namespace ncpp
}
private:
cell _cell;
nccell _cell;
};
}

@ -42,7 +42,6 @@ API void notcurses_version_components(int* major, int* minor, int* patch, int* t
struct notcurses; // Notcurses state for a given terminal, composed of ncplanes
struct ncplane; // a drawable Notcurses surface, composed of cells
struct cell; // a coordinate on an ncplane: an EGC plus styling
struct ncvisual; // a visual bit of multimedia opened with LibAV|OIIO
struct ncuplot; // a histogram, bound to a plane (uint64_ts)
struct ncdplot; // a histogram, bound to a plane (non-negative doubles)
@ -486,7 +485,7 @@ channels_set_bg_default(uint64_t* channels){
return *channels;
}
// A cell corresponds to a single character cell on some plane, which can be
// An nccell corresponds to a single character cell on some plane, which can be
// occupied by a single grapheme cluster (some root spacing glyph, along with
// possible combining characters, which might span multiple columns). At any
// cell, we can have a theoretically arbitrarily long UTF-8 string, a foreground
@ -511,7 +510,7 @@ channels_set_bg_default(uint64_t* channels){
// a single column. BiDi text is too complicated for me to even get into here.
// Be assured there are no easy answers; ours is indeed a disturbing Universe.
//
// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
// Each nccell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB.
// Dynamic requirements (the egcpool) can add up to 16MB to an ncplane, but
// such large pools are unlikely in common use.
@ -533,7 +532,7 @@ channels_set_bg_default(uint64_t* channels){
// meaningfully set transparency, but it can be mixed into a cascading color.
// RGB is used if neither default terminal colors nor palette indexing are in
// play, and fully supports all transparency options.
typedef struct cell {
typedef struct nccell {
// These 32 bits, together with the associated plane's associated egcpool,
// completely define this cell's EGC. Unless the EGC requires more than four
// bytes to encode as UTF-8, it will be inlined here. If more than four bytes
@ -561,8 +560,8 @@ typedef struct cell {
// index into the egcpool. These pools may thus be up to 16MB.
//
// The cost of this scheme is that the character 0x01 (SOH) cannot be encoded
// in a cell, which is absolutely fine because what 70s horseshit is SOH? It
// must not be allowed through the API, or havoc will result.
// in a nccell, which is absolutely fine because what 70s horseshit is SOH?
// It must not be allowed through the API, or havoc will result.
uint32_t gcluster; // 4B → 4B little endian EGC
uint8_t gcluster_backstop; // 1B → 5B (8 bits of zero)
// we store the column width minus 1 in this field. this is necessary to
@ -590,7 +589,9 @@ typedef struct cell {
// best explained by color(3NCURSES). ours is the same concept. until the
// "not default color" bit is set, any color you load will be ignored.
uint64_t channels; // + 8B == 16B
} cell;
} nccell;
typedef nccell cell; // FIXME backwards-compat, remove in 3.0
#define CELL_TRIVIAL_INITIALIZER { .gcluster = 0, .gcluster_backstop = 0, .width = 0, .stylemask = 0, .channels = 0, }
// do *not* load control characters, wide EGCs, nor invalid EGCs using these
@ -600,18 +601,18 @@ typedef struct cell {
#define CELL_INITIALIZER(c, s, chan) { .gcluster = (htole(c)), .gcluster_backstop = 0, .width = 0, .stylemask = (s), .channels = (chan), }
static inline void
cell_init(cell* c){
cell_init(nccell* c){
memset(c, 0, sizeof(*c));
}
// Breaks the UTF-8 string in 'gcluster' down, setting up the cell 'c'. Returns
// the number of bytes copied out of 'gcluster', or -1 on failure. The styling
// of the cell is left untouched, but any resources are released.
API int cell_load(struct ncplane* n, cell* c, const char* gcluster);
// Breaks the UTF-8 string in 'gcluster' down, setting up the nccell 'c'.
// Returns the number of bytes copied out of 'gcluster', or -1 on failure. The
// styling of the cell is left untouched, but any resources are released.
API int cell_load(struct ncplane* n, nccell* c, const char* gcluster);
// cell_load(), plus blast the styling with 'attr' and 'channels'.
static inline int
cell_prime(struct ncplane* n, cell* c, const char* gcluster,
cell_prime(struct ncplane* n, nccell* c, const char* gcluster,
uint32_t stylemask, uint64_t channels){
c->stylemask = stylemask;
c->channels = channels;
@ -620,10 +621,10 @@ cell_prime(struct ncplane* n, cell* c, const char* gcluster,
}
// Duplicate 'c' into 'targ'; both must be/will be bound to 'n'.
API int cell_duplicate(struct ncplane* n, cell* targ, const cell* c);
API int cell_duplicate(struct ncplane* n, nccell* targ, const nccell* c);
// Release resources held by the cell 'c'.
API void cell_release(struct ncplane* n, cell* c);
// Release resources held by the nccell 'c'.
API void cell_release(struct ncplane* n, nccell* c);
#define NCSTYLE_MASK 0x03ffu
#define NCSTYLE_STANDOUT 0x0080u
@ -638,86 +639,86 @@ API void cell_release(struct ncplane* n, cell* c);
#define NCSTYLE_STRUCK 0x0200u
#define NCSTYLE_NONE 0
// Set the specified style bits for the cell 'c', whether they're actively
// Set the specified style bits for the nccell 'c', whether they're actively
// supported or not. Only the lower 16 bits are meaningful.
static inline void
cell_set_styles(cell* c, unsigned stylebits){
cell_set_styles(nccell* c, unsigned stylebits){
c->stylemask = stylebits & NCSTYLE_MASK;
}
// Extract the style bits from the cell.
// Extract the style bits from the nccell.
static inline unsigned
cell_styles(const cell* c){
cell_styles(const nccell* c){
return c->stylemask;
}
// Add the specified styles (in the LSBs) to the cell's existing spec, whether
// they're actively supported or not.
// Add the specified styles (in the LSBs) to the nccell's existing spec,
// whether they're actively supported or not.
static inline void
cell_on_styles(cell* c, unsigned stylebits){
cell_on_styles(nccell* c, unsigned stylebits){
c->stylemask |= (stylebits & NCSTYLE_MASK);
}
// Remove the specified styles (in the LSBs) from the cell's existing spec.
// Remove the specified styles (in the LSBs) from the nccell's existing spec.
static inline void
cell_off_styles(cell* c, unsigned stylebits){
cell_off_styles(nccell* c, unsigned stylebits){
c->stylemask &= ~(stylebits & NCSTYLE_MASK);
}
// Use the default color for the foreground.
static inline void
cell_set_fg_default(cell* c){
cell_set_fg_default(nccell* c){
channels_set_fg_default(&c->channels);
}
// Use the default color for the background.
static inline void
cell_set_bg_default(cell* c){
cell_set_bg_default(nccell* c){
channels_set_bg_default(&c->channels);
}
static inline int
cell_set_fg_alpha(cell* c, int alpha){
cell_set_fg_alpha(nccell* c, int alpha){
return channels_set_fg_alpha(&c->channels, alpha);
}
static inline int
cell_set_bg_alpha(cell* c, int alpha){
cell_set_bg_alpha(nccell* c, int alpha){
return channels_set_bg_alpha(&c->channels, alpha);
}
// Does the cell contain an East Asian Wide codepoint?
// Does the nccell contain an East Asian Wide codepoint?
static inline bool
cell_double_wide_p(const cell* c){
cell_double_wide_p(const nccell* c){
return (c->channels & CELL_WIDEASIAN_MASK);
}
// Is this the right half of a wide character?
static inline bool
cell_wide_right_p(const cell* c){
cell_wide_right_p(const nccell* c){
return cell_double_wide_p(c) && c->gcluster == 0;
}
// Is this the left half of a wide character?
static inline bool
cell_wide_left_p(const cell* c){
cell_wide_left_p(const nccell* c){
return cell_double_wide_p(c) && c->gcluster;
}
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
// can be invalidated by any further operation on the plane 'n', so...watch out!
API const char* cell_extended_gcluster(const struct ncplane* n, const cell* c);
API const char* cell_extended_gcluster(const struct ncplane* n, const nccell* c);
// copy the UTF8-encoded EGC out of the cell. the result is not tied to any
// copy the UTF8-encoded EGC out of the nccell. the result is not tied to any
// ncplane, and persists across erases / destruction.
static inline char*
cell_strdup(const struct ncplane* n, const cell* c){
cell_strdup(const struct ncplane* n, const nccell* c){
return strdup(cell_extended_gcluster(n, c));
}
// Extract the three elements of a cell.
// Extract the three elements of a nccell.
static inline char*
cell_extract(const struct ncplane* n, const cell* c,
cell_extract(const struct ncplane* n, const nccell* c,
uint16_t* stylemask, uint64_t* channels){
if(stylemask){
*stylemask = c->stylemask;
@ -728,13 +729,13 @@ cell_extract(const struct ncplane* n, const cell* c,
return cell_strdup(n, c);
}
// Returns true if the two cells are distinct EGCs, attributes, or channels.
// Returns true if the two nccells are distinct EGCs, attributes, or channels.
// The actual egcpool index needn't be the same--indeed, the planes needn't even
// be the same. Only the expanded EGC must be equal. The EGC must be bit-equal;
// it would probably be better to test whether they're Unicode-equal FIXME.
static inline bool
cellcmp(const struct ncplane* n1, const cell* RESTRICT c1,
const struct ncplane* n2, const cell* RESTRICT c2){
cellcmp(const struct ncplane* n1, const nccell* RESTRICT c1,
const struct ncplane* n2, const nccell* RESTRICT c2){
if(c1->stylemask != c2->stylemask){
return true;
}
@ -744,20 +745,20 @@ cellcmp(const struct ncplane* n1, const cell* RESTRICT c1,
return strcmp(cell_extended_gcluster(n1, c1), cell_extended_gcluster(n2, c2));
}
// Load a 7-bit char 'ch' into the cell 'c'. Returns the number of bytes used,
// or -1 on error.
// Load a 7-bit char 'ch' into the nccell 'c'. Returns the number of bytes
// used, or -1 on error.
static inline int
cell_load_char(struct ncplane* n, cell* c, char ch){
cell_load_char(struct ncplane* n, nccell* c, char ch){
char gcluster[2];
gcluster[0] = ch;
gcluster[1] = '\0';
return cell_load(n, c, gcluster);
}
// Load a UTF-8 encoded EGC of up to 4 bytes into the cell 'c'. Returns the
// Load a UTF-8 encoded EGC of up to 4 bytes into the nccell 'c'. Returns the
// number of bytes used, or -1 on error.
static inline int
cell_load_egc32(struct ncplane* n, cell* c, uint32_t egc){
cell_load_egc32(struct ncplane* n, nccell* c, uint32_t egc){
char gcluster[sizeof(egc) + 1];
egc = htole(egc);
memcpy(gcluster, &egc, sizeof(egc));
@ -1256,21 +1257,21 @@ ncplane_resize_simple(struct ncplane* n, int ylen, int xlen){
// the standard plane.
API int ncplane_destroy(struct ncplane* n);
// Set the ncplane's base cell to this cell. It will be used for purposes of
// rendering anywhere that the ncplane's gcluster is 0. Erasing the ncplane
// Set the ncplane's base nccell to this nccell. It will be used for purposes
// of rendering anywhere that the ncplane's gcluster is 0. Erasing the ncplane
// does not reset the base cell; this function must be called with a zero 'c'.
API int ncplane_set_base_cell(struct ncplane* n, const cell* c);
API int ncplane_set_base_cell(struct ncplane* n, const nccell* c);
// Set the ncplane's base cell to this cell. It will be used for purposes of
// Set the ncplane's base nccell to this cell. It will be used for purposes of
// rendering anywhere that the ncplane's gcluster is 0. Erasing the ncplane
// does not reset the base cell; this function must be called with an empty
// 'egc'. 'egc' must be a single extended grapheme cluster.
API int ncplane_set_base(struct ncplane* n, const char* egc,
uint32_t stylemask, uint64_t channels);
// Extract the ncplane's base cell into 'c'. The reference is invalidated if
// Extract the ncplane's base nccell into 'c'. The reference is invalidated if
// 'ncp' is destroyed.
API int ncplane_base(struct ncplane* n, cell* c);
API int ncplane_base(struct ncplane* n, nccell* c);
// Move this plane relative to the standard plane, or the plane to which it is
// bound (if it is bound to a plane). It is an error to attempt to move the
@ -1335,7 +1336,7 @@ API char* ncplane_at_cursor(struct ncplane* n, uint16_t* stylemask, uint64_t* ch
// Retrieve the current contents of the cell under the cursor into 'c'. This
// cell is invalidated if the associated plane is destroyed.
static inline int
ncplane_at_cursor_cell(struct ncplane* n, cell* c){
ncplane_at_cursor_cell(struct ncplane* n, nccell* c){
char* egc = ncplane_at_cursor(n, &c->stylemask, &c->channels);
if(!egc){
return -1;
@ -1354,7 +1355,7 @@ API char* ncplane_at_yx(const struct ncplane* n, int y, int x,
// Retrieve the current contents of the specified cell into 'c'. This cell is
// invalidated if the associated plane is destroyed.
static inline int
ncplane_at_yx_cell(struct ncplane* n, int y, int x, cell* c){
ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c){
char* egc = ncplane_at_yx(n, y, x, &c->stylemask, &c->channels);
if(!egc){
return -1;
@ -1433,11 +1434,11 @@ API uint16_t ncplane_styles(const struct ncplane* n);
// and advance the cursor by the width of the cell (but not past the end of the
// plane). On success, returns the number of columns the cursor was advanced.
// 'c' must already be associated with 'n'. On failure, -1 is returned.
API int ncplane_putc_yx(struct ncplane* n, int y, int x, const cell* c);
API int ncplane_putc_yx(struct ncplane* n, int y, int x, const nccell* c);
// Call ncplane_putc_yx() for the current cursor location.
static inline int
ncplane_putc(struct ncplane* n, const cell* c){
ncplane_putc(struct ncplane* n, const nccell* c){
return ncplane_putc_yx(n, -1, -1, c);
}
@ -1446,7 +1447,7 @@ ncplane_putc(struct ncplane* n, const cell* c){
// This works whether the underlying char is signed or unsigned.
static inline int
ncplane_putchar_yx(struct ncplane* n, int y, int x, char c){
cell ce = CELL_INITIALIZER((uint32_t)c, ncplane_styles(n), ncplane_channels(n));
nccell ce = CELL_INITIALIZER((uint32_t)c, ncplane_styles(n), ncplane_channels(n));
return ncplane_putc_yx(n, y, x, &ce);
}
@ -1705,19 +1706,19 @@ API int ncplane_puttext(struct ncplane* n, int y, ncalign_e align,
// lines), just as if ncplane_putc() was called at that spot. Return the
// number of cells drawn on success. On error, return the negative number of
// cells drawn.
API int ncplane_hline_interp(struct ncplane* n, const cell* c, int len,
API int ncplane_hline_interp(struct ncplane* n, const nccell* c, int len,
uint64_t c1, uint64_t c2);
static inline int
ncplane_hline(struct ncplane* n, const cell* c, int len){
ncplane_hline(struct ncplane* n, const nccell* c, int len){
return ncplane_hline_interp(n, c, len, c->channels, c->channels);
}
API int ncplane_vline_interp(struct ncplane* n, const cell* c, int len,
API int ncplane_vline_interp(struct ncplane* n, const nccell* c, int len,
uint64_t c1, uint64_t c2);
static inline int
ncplane_vline(struct ncplane* n, const cell* c, int len){
ncplane_vline(struct ncplane* n, const nccell* c, int len){
return ncplane_vline_interp(n, c, len, c->channels, c->channels);
}
@ -1750,18 +1751,18 @@ ncplane_vline(struct ncplane* n, const cell* c, int len){
// and are interpreted as the number of connecting edges necessary to draw a
// given corner. At 0 (the default), corners are always drawn. At 3, corners
// are never drawn (since at most 2 edges can touch a box's corner).
API int ncplane_box(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, int ystop, int xstop,
API int ncplane_box(struct ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hline,
const nccell* vline, int ystop, int xstop,
unsigned ctlword);
// Draw a box with its upper-left corner at the current cursor position, having
// dimensions 'ylen'x'xlen'. See ncplane_box() for more information. The
// minimum box size is 2x2, and it cannot be drawn off-screen.
static inline int
ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, int ylen, int xlen, unsigned ctlword){
ncplane_box_sized(struct ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hline,
const nccell* vline, int ylen, int xlen, unsigned ctlword){
int y, x;
ncplane_cursor_yx(n, &y, &x);
return ncplane_box(n, ul, ur, ll, lr, hline, vline, y + ylen - 1,
@ -1769,9 +1770,9 @@ ncplane_box_sized(struct ncplane* n, const cell* ul, const cell* ur,
}
static inline int
ncplane_perimeter(struct ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hline,
const cell* vline, unsigned ctlword){
ncplane_perimeter(struct ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hline,
const nccell* vline, unsigned ctlword){
if(ncplane_cursor_move_yx(n, 0, 0)){
return -1;
}
@ -1785,7 +1786,7 @@ ncplane_perimeter(struct ncplane* n, const cell* ul, const cell* ur,
// target. We do the same to all cardinally-connected cells having this same
// fill target. Returns the number of cells polyfilled. An invalid initial y, x
// is an error. Returns the number of cells filled, or -1 on error.
API int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);
API int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const nccell* c);
// Draw a gradient with its upper-left corner at the current cursor position,
// stopping at 'ystop'x'xstop'. The glyph composed of 'egc' and 'stylemask' is
@ -1872,135 +1873,135 @@ API void ncplane_erase(struct ncplane* n);
// Extract the 32-bit background channel from a cell.
static inline uint32_t
cell_bchannel(const cell* cl){
cell_bchannel(const nccell* cl){
return channels_bchannel(cl->channels);
}
// Extract the 32-bit foreground channel from a cell.
static inline uint32_t
cell_fchannel(const cell* cl){
cell_fchannel(const nccell* cl){
return channels_fchannel(cl->channels);
}
// Set the 32-bit background channel of a cell.
// Set the 32-bit background channel of an nccell.
static inline uint64_t
cell_set_bchannel(cell* cl, uint32_t channel){
cell_set_bchannel(nccell* cl, uint32_t channel){
return channels_set_bchannel(&cl->channels, channel);
}
// Set the 32-bit foreground channel of a cell.
// Set the 32-bit foreground channel of an nccell.
static inline uint64_t
cell_set_fchannel(cell* cl, uint32_t channel){
cell_set_fchannel(nccell* cl, uint32_t channel){
return channels_set_fchannel(&cl->channels, channel);
}
// Extract 24 bits of foreground RGB from 'cell', shifted to LSBs.
// Extract 24 bits of foreground RGB from 'cl', shifted to LSBs.
static inline uint32_t
cell_fg_rgb(const cell* cl){
cell_fg_rgb(const nccell* cl){
return channels_fg_rgb(cl->channels);
}
// Extract 24 bits of background RGB from 'cell', shifted to LSBs.
// Extract 24 bits of background RGB from 'cl', shifted to LSBs.
static inline uint32_t
cell_bg_rgb(const cell* cl){
cell_bg_rgb(const nccell* cl){
return channels_bg_rgb(cl->channels);
}
// Extract 2 bits of foreground alpha from 'cell', shifted to LSBs.
// Extract 2 bits of foreground alpha from 'cl', shifted to LSBs.
static inline uint32_t
cell_fg_alpha(const cell* cl){
cell_fg_alpha(const nccell* cl){
return channels_fg_alpha(cl->channels);
}
// Extract 2 bits of background alpha from 'cell', shifted to LSBs.
// Extract 2 bits of background alpha from 'cl', shifted to LSBs.
static inline uint32_t
cell_bg_alpha(const cell* cl){
cell_bg_alpha(const nccell* cl){
return channels_bg_alpha(cl->channels);
}
// Extract 24 bits of foreground RGB from 'cell', split into components.
// Extract 24 bits of foreground RGB from 'cl', split into components.
static inline uint32_t
cell_fg_rgb8(const cell* cl, unsigned* r, unsigned* g, unsigned* b){
cell_fg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
return channels_fg_rgb8(cl->channels, r, g, b);
}
// Extract 24 bits of background RGB from 'cell', split into components.
// Extract 24 bits of background RGB from 'cl', split into components.
static inline uint32_t
cell_bg_rgb8(const cell* cl, unsigned* r, unsigned* g, unsigned* b){
cell_bg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
return channels_bg_rgb8(cl->channels, r, g, b);
}
// Set the r, g, and b cell for the foreground component of this 64-bit
// 'cell' variable, and mark it as not using the default color.
// 'cl' variable, and mark it as not using the default color.
static inline int
cell_set_fg_rgb8(cell* cl, int r, int g, int b){
cell_set_fg_rgb8(nccell* cl, int r, int g, int b){
return channels_set_fg_rgb8(&cl->channels, r, g, b);
}
// Same, but clipped to [0..255].
static inline void
cell_set_fg_rgb8_clipped(cell* cl, int r, int g, int b){
cell_set_fg_rgb8_clipped(nccell* cl, int r, int g, int b){
channels_set_fg_rgb8_clipped(&cl->channels, r, g, b);
}
// Same, but with an assembled 24-bit RGB value.
static inline int
cell_set_fg_rgb(cell* c, uint32_t channel){
cell_set_fg_rgb(nccell* c, uint32_t channel){
return channels_set_fg_rgb(&c->channels, channel);
}
// Set the cell's foreground palette index, set the foreground palette index
// bit, set it foreground-opaque, and clear the foreground default color bit.
static inline int
cell_set_fg_palindex(cell* cl, int idx){
cell_set_fg_palindex(nccell* cl, int idx){
return channels_set_fg_palindex(&cl->channels, idx);
}
static inline uint32_t
cell_fg_palindex(const cell* cl){
cell_fg_palindex(const nccell* cl){
return (cl->channels & 0xff00000000ull) >> 32u;
}
// Set the r, g, and b cell for the background component of this 64-bit
// 'cell' variable, and mark it as not using the default color.
// 'cl' variable, and mark it as not using the default color.
static inline int
cell_set_bg_rgb8(cell* cl, int r, int g, int b){
cell_set_bg_rgb8(nccell* cl, int r, int g, int b){
return channels_set_bg_rgb8(&cl->channels, r, g, b);
}
// Same, but clipped to [0..255].
static inline void
cell_set_bg_rgb8_clipped(cell* cl, int r, int g, int b){
cell_set_bg_rgb8_clipped(nccell* cl, int r, int g, int b){
channels_set_bg_rgb8_clipped(&cl->channels, r, g, b);
}
// Same, but with an assembled 24-bit RGB value. A value over 0xffffff
// will be rejected, with a non-zero return value.
static inline int
cell_set_bg_rgb(cell* c, uint32_t channel){
cell_set_bg_rgb(nccell* c, uint32_t channel){
return channels_set_bg_rgb(&c->channels, channel);
}
// Set the cell's background palette index, set the background palette index
// bit, set it background-opaque, and clear the background default color bit.
static inline int
cell_set_bg_palindex(cell* cl, int idx){
cell_set_bg_palindex(nccell* cl, int idx){
return channels_set_bg_palindex(&cl->channels, idx);
}
static inline uint32_t
cell_bg_palindex(const cell* cl){
cell_bg_palindex(const nccell* cl){
return (cl->channels & 0xff);
}
// Is the foreground using the "default foreground color"?
static inline bool
cell_fg_default_p(const cell* cl){
cell_fg_default_p(const nccell* cl){
return channels_fg_default_p(cl->channels);
}
static inline bool
cell_fg_palindex_p(const cell* cl){
cell_fg_palindex_p(const nccell* cl){
return channels_fg_palindex_p(cl->channels);
}
@ -2008,12 +2009,12 @@ cell_fg_palindex_p(const cell* cl){
// background color" must generally be used to take advantage of
// terminal-effected transparency.
static inline bool
cell_bg_default_p(const cell* cl){
cell_bg_default_p(const nccell* cl){
return channels_bg_default_p(cl->channels);
}
static inline bool
cell_bg_palindex_p(const cell* cl){
cell_bg_palindex_p(const nccell* cl){
return channels_bg_palindex_p(cl->channels);
}
@ -2183,8 +2184,8 @@ API void ncfadectx_free(struct ncfadectx* nctx);
// six EGCs in gcluster.
static inline int
cells_load_box(struct ncplane* n, uint32_t styles, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr,
cell* hl, cell* vl, const char* gclusters){
nccell* ul, nccell* ur, nccell* ll, nccell* lr,
nccell* hl, nccell* vl, const char* gclusters){
int ulen;
if((ulen = cell_prime(n, ul, gclusters, styles, channels)) > 0){
if((ulen = cell_prime(n, ur, gclusters += ulen, styles, channels)) > 0){
@ -2208,16 +2209,16 @@ cells_load_box(struct ncplane* n, uint32_t styles, uint64_t channels,
}
API int cells_rounded_box(struct ncplane* n, uint32_t styles, uint64_t channels,
cell* ul, cell* ur, cell* ll,
cell* lr, cell* hl, cell* vl);
nccell* ul, nccell* ur, nccell* ll,
nccell* lr, nccell* hl, nccell* vl);
static inline int
ncplane_rounded_box(struct ncplane* n, uint32_t styles, uint64_t channels,
int ystop, int xstop, unsigned ctlword){
int ret = 0;
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if((ret = cells_rounded_box(n, styles, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
ret = ncplane_box(n, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
}
@ -2235,12 +2236,12 @@ ncplane_perimeter_rounded(struct ncplane* n, uint32_t stylemask,
}
int dimy, dimx;
ncplane_dim_yx(n, &dimy, &dimx);
cell ul = CELL_TRIVIAL_INITIALIZER;
cell ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER;
cell lr = CELL_TRIVIAL_INITIALIZER;
cell vl = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER;
nccell ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER;
nccell lr = CELL_TRIVIAL_INITIALIZER;
nccell vl = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER;
if(cells_rounded_box(n, stylemask, channels, &ul, &ur, &ll, &lr, &hl, &vl)){
return -1;
}
@ -2261,16 +2262,16 @@ ncplane_rounded_box_sized(struct ncplane* n, uint32_t styles, uint64_t channels,
}
API int cells_double_box(struct ncplane* n, uint32_t styles, uint64_t channels,
cell* ul, cell* ur, cell* ll,
cell* lr, cell* hl, cell* vl);
nccell* ul, nccell* ur, nccell* ll,
nccell* lr, nccell* hl, nccell* vl);
static inline int
ncplane_double_box(struct ncplane* n, uint32_t styles, uint64_t channels,
int ystop, int xstop, unsigned ctlword){
int ret = 0;
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if((ret = cells_double_box(n, styles, channels, &ul, &ur, &ll, &lr, &hl, &vl)) == 0){
ret = ncplane_box(n, &ul, &ur, &ll, &lr, &hl, &vl, ystop, xstop, ctlword);
}
@ -2288,12 +2289,12 @@ ncplane_perimeter_double(struct ncplane* n, uint32_t stylemask,
}
int dimy, dimx;
ncplane_dim_yx(n, &dimy, &dimx);
cell ul = CELL_TRIVIAL_INITIALIZER;
cell ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER;
cell lr = CELL_TRIVIAL_INITIALIZER;
cell vl = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER;
nccell ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER;
nccell lr = CELL_TRIVIAL_INITIALIZER;
nccell vl = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER;
if(cells_double_box(n, stylemask, channels, &ul, &ur, &ll, &lr, &hl, &vl)){
return -1;
}

@ -3,7 +3,7 @@
#include "demo.h"
static int
reload_corners(struct ncplane* n, cell* ul, cell* ur, cell* ll, cell* lr){
reload_corners(struct ncplane* n, nccell* ul, nccell* ur, nccell* ll, nccell* lr){
int dimy, dimx;
ncplane_dim_yx(n, &dimy, &dimx);
char* egc;
@ -82,9 +82,9 @@ int box_demo(struct notcurses* nc){
int ylen, xlen;
struct ncplane* n = notcurses_stddim_yx(nc, &ylen, &xlen);
ncplane_erase(n);
cell ul = CELL_TRIVIAL_INITIALIZER, ll = CELL_TRIVIAL_INITIALIZER;
cell lr = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ll = CELL_TRIVIAL_INITIALIZER;
nccell lr = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if(cells_double_box(n, 0, 0, &ul, &ur, &ll, &lr, &hl, &vl)){
return -1;
}
@ -92,7 +92,7 @@ int box_demo(struct notcurses* nc){
const int targx = 7;
const int targy = 7;
int ytargbase = (ylen - targy) / 2;
cell c = CELL_CHAR_INITIALIZER(' ');
nccell c = CELL_CHAR_INITIALIZER(' ');
cell_set_bg_default(&c);
ncplane_set_base_cell(n, &c);
cell_release(n, &c);

@ -9,7 +9,7 @@ typedef struct chunli {
} chunli;
static int
chunli_draw(struct notcurses* nc, const char* ext, int count, const cell* b){
chunli_draw(struct notcurses* nc, const char* ext, int count, const nccell* b){
chunli chuns[CHUNS];
char file[20];
int dimx, dimy;
@ -51,7 +51,7 @@ int chunli_demo(struct notcurses* nc){
timespec_div(&demodelay, 10, &iterdelay);
int ret, dimx, dimy;
notcurses_refresh(nc, &dimy, &dimx);
cell b = CELL_TRIVIAL_INITIALIZER;
nccell b = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_alpha(&b, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(&b, CELL_ALPHA_TRANSPARENT);
if( (ret = chunli_draw(nc, "bmp", CHUNS, &b)) ){

@ -218,7 +218,7 @@ ext_demos(struct notcurses* nc, const char* spec, bool ignore_failures){
// set the standard plane's base character to an opaque black, but don't
// erase the plane (we let one demo bleed through to the next, an effect
// we exploit in a few transitions).
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_rgb8(&c, 0, 0, 0);
cell_set_bg_rgb8(&c, 0, 0, 0);
ncplane_set_base_cell(n, &c);

@ -114,7 +114,7 @@ zoom_map(struct notcurses* nc, const char* map, int* ret){
static int
draw_eagle(struct ncplane* n, const char* sprite){
cell bgc = CELL_TRIVIAL_INITIALIZER;
nccell bgc = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_alpha(&bgc, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(&bgc, CELL_ALPHA_TRANSPARENT);
ncplane_set_base_cell(n, &bgc);

@ -146,8 +146,8 @@ int fallin_demo(struct notcurses* nc){
ncplane_resize_simple(n, newy, newx);
continue;
}
cell c = CELL_TRIVIAL_INITIALIZER;
cell stdc = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
nccell stdc = CELL_TRIVIAL_INITIALIZER;
if(ncplane_at_yx_cell(stdn, usey, usex, &stdc) < 0){
goto err;
}

@ -3,7 +3,7 @@
// clip and set
static int
ccell_set_fg_rgb8(cell* c, int r, int g, int b){
ccell_set_fg_rgb8(nccell* c, int r, int g, int b){
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
@ -11,7 +11,7 @@ ccell_set_fg_rgb8(cell* c, int r, int g, int b){
}
static int
ccell_set_bg_rgb8(cell* c, int r, int g, int b){
ccell_set_bg_rgb8(nccell* c, int r, int g, int b){
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
@ -20,9 +20,9 @@ ccell_set_bg_rgb8(cell* c, int r, int g, int b){
static void
release_cells(struct ncplane* n,
cell* ul, cell* uc, cell* ur,
cell* cl, cell* cc, cell* cr,
cell* ll, cell* lc, cell* lr){
nccell* ul, nccell* uc, nccell* ur,
nccell* cl, nccell* cc, nccell* cr,
nccell* ll, nccell* lc, nccell* lr){
cell_release(n, ul);
cell_release(n, uc);
cell_release(n, ur);
@ -36,9 +36,9 @@ release_cells(struct ncplane* n,
static int
prep_cells2(struct ncplane* n,
cell* ul, cell* uc, cell* ur,
cell* cl, cell* cc, cell* cr,
cell* ll, cell* lc, cell* lr){
nccell* ul, nccell* uc, nccell* ur,
nccell* cl, nccell* cc, nccell* cr,
nccell* ll, nccell* lc, nccell* lr){
cell_init(ul);
cell_init(uc);
cell_init(cl);
@ -63,9 +63,9 @@ prep_cells2(struct ncplane* n,
static int
prep_cells(struct ncplane* n,
cell* ul, cell* uc, cell* ur,
cell* cl, cell* cc, cell* cr,
cell* ll, cell* lc, cell* lr){
nccell* ul, nccell* uc, nccell* ur,
nccell* cl, nccell* cc, nccell* cr,
nccell* ll, nccell* lc, nccell* lr){
cell_init(ul);
cell_init(uc);
cell_init(cl);
@ -89,7 +89,7 @@ prep_cells(struct ncplane* n,
}
static int
bgnext(cell* c, int* r, int* g, int* b){
bgnext(nccell* c, int* r, int* g, int* b){
int ret = ccell_set_bg_rgb8(c, *r, *g, *b);
if(*g % 2){
if(--*b <= 0){
@ -112,7 +112,7 @@ bgnext(cell* c, int* r, int* g, int* b){
static int
gridinv_demo(struct notcurses* nc, struct ncplane *n){
ncplane_erase(n);
cell ul, ll, cl, cr, lc, lr, ur, uc, cc;
nccell ul, ll, cl, cr, lc, lr, ur, uc, cc;
prep_cells2(n, &ul, &uc, &ur, &cl, &cc, &cr, &ll, &lc, &lr);
for(int i = 0 ; i < 256 ; ++i){
int maxx, maxy;
@ -176,7 +176,7 @@ gridswitch_demo(struct notcurses* nc, struct ncplane *n){
ncplane_erase(n);
int ret = 0;
int maxx, maxy;
cell ul, ll, cl, cr, lc, lr, ur, uc, cc;
nccell ul, ll, cl, cr, lc, lr, ur, uc, cc;
prep_cells(n, &ul, &uc, &ur, &cl, &cc, &cr, &ll, &lc, &lr);
for(int i = 0 ; i < 256 ; ++i){
notcurses_term_dim_yx(nc, &maxy, &maxx);
@ -249,9 +249,9 @@ int grid_demo(struct notcurses* nc){
int y, x;
struct ncplane* n = notcurses_stdplane(nc);
ncplane_erase(n);
cell ul, uc, ur;
cell ll, lc, lr;
cell cl, cc, cr;
nccell ul, uc, ur;
nccell ll, lc, lr;
nccell cl, cc, cr;
prep_cells(n, &ul, &uc, &ur, &cl, &cc, &cr, &ll, &lc, &lr);
int ret = 0;

@ -74,7 +74,7 @@ int highcontrast_demo(struct notcurses* nc){
return -1;
}
const char motto[] = " high contrast text is evaluated relative to the solved background";
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST);
unsigned total = 0, r = 0, g = 0, b = 0;
for(int out = 0 ; out < totcells ; ++out){ // build up the initial screen

@ -162,9 +162,9 @@ about_toggle(struct notcurses* nc){
ncplane_printf_aligned(n, 4, NCALIGN_RIGHT, "restart Ctrl+R ");
ncplane_printf_aligned(n, 5, NCALIGN_CENTER, "q quit");
ncplane_putstr_aligned(n, 7, NCALIGN_CENTER, "\u00a9 nick black <nickblack@linux.com>");
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell lr = CELL_TRIVIAL_INITIALIZER, ll = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell lr = CELL_TRIVIAL_INITIALIZER, ll = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
channels = 0;
channels_set_fg_rgb(&channels, 0xc020c0);
channels_set_bg_rgb(&channels, 0);
@ -319,9 +319,9 @@ struct ncmenu* menu_create(struct notcurses* nc){
static int
hud_refresh(struct ncplane* n){
ncplane_erase(n);
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell lr = CELL_TRIVIAL_INITIALIZER, ll = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell lr = CELL_TRIVIAL_INITIALIZER, ll = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if(cells_rounded_box(n, NCSTYLE_NONE, 0, &ul, &ur, &ll, &lr, &hl, &vl)){
return -1;
}
@ -364,7 +364,7 @@ hud_print_finished(elem* list){
break;
}
if(hud){
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_base(hud, &c);
ncplane_set_bg_rgb(hud, cell_bg_rgb(&c));
ncplane_set_bg_alpha(hud, CELL_ALPHA_BLEND);
@ -577,7 +577,7 @@ int demo_render(struct notcurses* nc){
}
uint64_t ns = timespec_to_ns(&ts) - elems->startns;
++elems->frames;
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_base(hud, &c);
ncplane_set_bg_rgb(hud, cell_bg_rgb(&c));
ncplane_set_bg_alpha(hud, CELL_ALPHA_BLEND);

@ -36,12 +36,12 @@ int intro(struct notcurses* nc){
if(ncplane_highgradient_sized(ncp, ccul, ccur, ccll, cclr, rows, cols) <= 0){
return -1;
}
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_set_bg_rgb8(&c, 0x20, 0x20, 0x20);
ncplane_set_base_cell(ncp, &c);
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if(ncplane_cursor_move_yx(ncp, 1, 0)){
return -1;
}

@ -26609,7 +26609,7 @@ int jungle_demo(struct notcurses* nc){
const int xoff = (dimx - ORIGWIDTH / xiter) / 2;
const int yoff = (dimy - ORIGHEIGHT / yiter) / 4;
ncplane_erase(n);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_load(n, &c, "\xe2\x96\x80"); // upper half block
for(size_t y = 0 ; y < ORIGHEIGHT ; y += (yiter * 2)){
if(ncplane_cursor_move_yx(n, yoff + y / (yiter * 2), xoff)){

@ -3526,7 +3526,7 @@ makegroup(struct ncplane* title, int y, const char* emoji, const char* name){
if(n == NULL){
return NULL;
}
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
y = 1;
int x = 1;
while(*emoji){

@ -157,7 +157,7 @@ int normal_demo(struct notcurses* nc){
int r = -1;
struct ncplane* nstd = notcurses_stddim_yx(nc, &dy, &dx);
ncplane_erase(nstd);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_rgb8(&c, 0x0, 0x0, 0x0);
cell_set_bg_rgb8(&c, 0x0, 0x0, 0x0);
ncplane_set_base_cell(nstd, &c);

@ -63,7 +63,7 @@ kill_active_tablet(struct ncreel* pr, tabletctx** tctx){
static int
tabletdraw(struct ncplane* w, int maxy, tabletctx* tctx, unsigned rgb){
char cchbuf[2];
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
int y;
int maxx = ncplane_dim_x(w) - 1;
if(maxy > tctx->lines){

@ -39,7 +39,7 @@ legend(struct notcurses* nc, const char* msg){
if(n == NULL){
return NULL;
}
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_rgb8(&c, 0, 0, 0); // darken surrounding characters by half
cell_set_fg_alpha(&c, CELL_ALPHA_BLEND);
cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT); // don't touch background
@ -120,7 +120,7 @@ slidepanel(struct notcurses* nc, struct ncplane* stdn){
// no glyph, we should show underlying glyphs in the default colors. The
// background default might be transparent, at the window level (i.e. a copy
// of the underlying desktop).
cell c = CELL_CHAR_INITIALIZER(' ');
nccell c = CELL_CHAR_INITIALIZER(' ');
struct timespec cur;
ncplane_set_base_cell(n, &c);
clock_gettime(CLOCK_MONOTONIC, &cur);

@ -24,9 +24,9 @@ static int
draw_block(struct ncplane* nn, uint32_t blockstart){
int dimx, dimy;
ncplane_dim_yx(nn, &dimy, &dimx);
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
cells_rounded_box(nn, 0, 0, &ul, &ur, &ll, &lr, &hl, &vl);
cell_set_bg_alpha(&ul, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(&ur, CELL_ALPHA_TRANSPARENT);

@ -48,7 +48,7 @@ mathplane(struct notcurses* nc){
// the closer the coordinate is (lower distance), the more we lighten the cell
static inline int
lighten(struct ncplane* n, cell* c, int distance, int y, int x){
lighten(struct ncplane* n, nccell* c, int distance, int y, int x){
if(cell_wide_right_p(c)){ // not really a character
return 0;
}
@ -62,14 +62,14 @@ lighten(struct ncplane* n, cell* c, int distance, int y, int x){
}
static inline int
lightup_surrounding_cells(struct ncplane* n, cell* lightup, int y, int x){
lightup_surrounding_cells(struct ncplane* n, nccell* lightup, int y, int x){
lighten(n, lightup, 0, y, x);
cell_release(n, lightup);
return 0;
}
typedef struct worm {
cell lightup;
nccell lightup;
int x, y;
int prevx, prevy;
} worm;
@ -184,7 +184,7 @@ message(struct ncplane* n, int maxy, int maxx, int num, int total,
ncplane_putegc_yx(n, 4, 17, "", NULL);
ncplane_putegc_yx(n, 5, 17, "", NULL);
ncplane_putegc_yx(n, 6, 17, "", NULL);
cell hl = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER;
cell_load(n, &hl, "");
cell_set_fg_rgb8(&hl, 255, 255, 255);
cell_set_bg_rgb8(&hl, 32, 64, 32);
@ -459,7 +459,7 @@ int witherworm_demo(struct notcurses* nc){
ncplane_erase(n);
for(i = 0 ; i < screens ; ++i){
wchar_t key = NCKEY_INVALID;
cell c;
nccell c;
struct timespec screenend;
clock_gettime(CLOCK_MONOTONIC, &screenend);
ns_to_timespec(timespec_to_ns(&screenend) + timespec_to_ns(&demodelay), &screenend);

@ -350,7 +350,7 @@ infoplane(struct ncdirect* ncd, const fetched_info* fi){
ncplane_printf_aligned(infop, 3, NCALIGN_RIGHT, "Shell: %s ", fi->shell);
if(notcurses_cantruecolor(nc)){
ncplane_printf_aligned(infop, 4, NCALIGN_LEFT, " RGB TERM: %s", fi->term);
cell c = CELL_CHAR_INITIALIZER('R');
nccell c = CELL_CHAR_INITIALIZER('R');
cell_set_styles(&c, NCSTYLE_BOLD);
cell_set_fg_rgb8(&c, 0xd0, 0, 0);
ncplane_putc_yx(infop, 4, 1, &c);
@ -369,9 +369,9 @@ infoplane(struct ncdirect* ncd, const fetched_info* fi){
ncplane_printf_aligned(infop, 5, NCALIGN_RIGHT, "UID: %ju ", (uintmax_t)getuid());
ncplane_set_styles(infop, NCSTYLE_ITALIC);
ncplane_printf_aligned(infop, 6, NCALIGN_CENTER, "%s (%d cores)", fi->cpu_model, fi->core_count);
cell ul = CELL_TRIVIAL_INITIALIZER; cell ur = CELL_TRIVIAL_INITIALIZER;
cell ll = CELL_TRIVIAL_INITIALIZER; cell lr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER; cell vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell ll = CELL_TRIVIAL_INITIALIZER, lr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
if(cells_rounded_box(infop, 0, 0, &ul, &ur, &ll, &lr, &hl, &vl)){
return -1;
}

@ -63,7 +63,7 @@ tria_blit_ascii(ncplane* nc, int placey, int placex, int linesize,
for(x = placex ; visx < (begx + lenx) && x < dimx ; ++x, ++visx){
const unsigned char* rgbbase_up = dat + (linesize * visy) + (visx * bpp / CHAR_BIT);
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
cell* c = ncplane_cell_ref_yx(nc, y, x);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
// use the default for the background, as that's the only way it's
// effective in that case anyway
c->channels = 0;
@ -114,7 +114,7 @@ tria_blit(ncplane* nc, int placey, int placex, int linesize,
rgbbase_down = dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT);
}
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
cell* c = ncplane_cell_ref_yx(nc, y, x);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
// use the default for the background, as that's the only way it's
// effective in that case anyway
c->channels = 0;
@ -286,7 +286,7 @@ quadrant_solver(uint32_t tl, uint32_t tr, uint32_t bl, uint32_t br,
// FIXME we ought be able to just build up a bitstring and use it as an index!
// FIXME pass in rgbas as array of uint32_t ala sexblitter
static inline const char*
qtrans_check(cell* c, bool blendcolors,
qtrans_check(nccell* c, bool blendcolors,
const unsigned char* rgbbase_tl, const unsigned char* rgbbase_tr,
const unsigned char* rgbbase_bl, const unsigned char* rgbbase_br){
uint32_t tl = 0, tr = 0, bl = 0, br = 0;
@ -411,7 +411,7 @@ quadrant_blit(ncplane* nc, int placey, int placex, int linesize,
rgbbase_bl = dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT);
}
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_tl[0], rgbbase_tr[1], rgbbase_bl[2], rgbbase_br[3]);
cell* c = ncplane_cell_ref_yx(nc, y, x);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
c->channels = 0;
c->stylemask = 0;
const char* egc = qtrans_check(c, blendcolors, rgbbase_tl, rgbbase_tr, rgbbase_bl, rgbbase_br);
@ -625,7 +625,7 @@ sextant_blit(ncplane* nc, int placey, int placex, int linesize,
memcpy(&rgbas[4], (dat + (linesize * (visy + 2)) + (visx * bpp / CHAR_BIT)), sizeof(*rgbas));
}
}
cell* c = ncplane_cell_ref_yx(nc, y, x);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
c->channels = 0;
c->stylemask = 0;
const char* egc = sex_trans_check(rgbas, &c->channels, blendcolors);
@ -742,7 +742,7 @@ braille_blit(ncplane* nc, int placey, int placex, int linesize,
fold_rgb8(&r, &g, &b, rgbbase_r3, &blends);
}
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
cell* c = ncplane_cell_ref_yx(nc, y, x);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
// use the default for the background, as that's the only way it's
// effective in that case anyway
c->channels = 0;

@ -224,7 +224,6 @@ egcpool_check_validity(const egcpool* pool, int offset){
static inline void
egcpool_release(egcpool* pool, int offset){
size_t freed = 1; // account for free(d) NUL terminator
assert(egcpool_check_validity(pool, offset));
while(pool->pool[offset]){
pool->pool[offset] = '\0';
++freed;
@ -247,19 +246,19 @@ egcpool_dump(egcpool* pool){
// get the offset into the egcpool for this cell's EGC. returns meaningless and
// unsafe results if called on a simple cell.
static inline uint32_t
cell_egc_idx(const cell* c){
cell_egc_idx(const nccell* c){
return (htole(c->gcluster) & 0x00fffffflu);
}
// Is the cell simple (a UTF8-encoded EGC of four bytes or fewer)?
static inline bool
cell_simple_p(const cell* c){
cell_simple_p(const nccell* c){
return (htole(c->gcluster) & htole(0xff000000ul)) != htole(0x01000000ul);
}
// only applies to complex cells, do not use on simple cells
__attribute__ ((__returns_nonnull__)) static inline const char*
egcpool_extended_gcluster(const egcpool* pool, const cell* c) {
egcpool_extended_gcluster(const egcpool* pool, const nccell* c) {
assert(!cell_simple_p(c));
uint32_t idx = cell_egc_idx(c);
return pool->pool + idx;

@ -119,7 +119,7 @@ int ncplane_fadein_iteration(ncplane* n, ncfadectx* nctx, int iter,
channels_fg_rgb8(nctx->channels[nctx->cols * y + x], &r, &g, &b);
unsigned br, bg, bb;
channels_bg_rgb8(nctx->channels[nctx->cols * y + x], &br, &bg, &bb);
cell* c = &n->fb[dimx * y + x];
nccell* c = &n->fb[dimx * y + x];
if(!cell_fg_default_p(c)){
r = r * iter / nctx->maxsteps;
g = g * iter / nctx->maxsteps;
@ -182,7 +182,7 @@ int ncplane_fadeout_iteration(ncplane* n, ncfadectx* nctx, int iter,
ncplane_dim_yx(n, &dimy, &dimx);
for(y = 0 ; y < nctx->rows && y < dimy ; ++y){
for(x = 0 ; x < nctx->cols && x < dimx; ++x){
cell* c = &n->fb[dimx * y + x];
nccell* c = &n->fb[dimx * y + x];
if(!cell_fg_default_p(c)){
channels_fg_rgb8(nctx->channels[nctx->cols * y + x], &r, &g, &b);
r = r * (nctx->maxsteps - iter) / nctx->maxsteps;
@ -199,7 +199,7 @@ int ncplane_fadeout_iteration(ncplane* n, ncfadectx* nctx, int iter,
}
}
}
cell* c = &n->basecell;
nccell* c = &n->basecell;
if(!cell_fg_default_p(c)){
channels_fg_rgb8(nctx->channels[nctx->cols * y], &r, &g, &b);
r = r * (nctx->maxsteps - iter) / nctx->maxsteps;

@ -3,7 +3,7 @@
void ncplane_greyscale(ncplane *n){
for(int y = 0 ; y < n->leny ; ++y){
for(int x = 0 ; x < n->lenx ; ++x){
cell* c = &n->fb[nfbcellidx(n, y, x)];
nccell* c = &n->fb[nfbcellidx(n, y, x)];
unsigned r, g, b;
cell_fg_rgb8(c, &r, &g, &b);
int gy = rgb_greyscale(r, g, b);
@ -20,14 +20,14 @@ void ncplane_greyscale(ncplane *n){
// success. so a return of 0 means there's no work to be done here, and N means
// we did some work here, filling everything we could reach. out-of-plane is 0.
static int
ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c, const char* filltarg){
ncplane_polyfill_recurse(ncplane* n, int y, int x, const nccell* c, const char* filltarg){
if(y >= n->leny || x >= n->lenx){
return 0; // not fillable
}
if(y < 0 || x < 0){
return 0; // not fillable
}
cell* cur = &n->fb[nfbcellidx(n, y, x)];
nccell* cur = &n->fb[nfbcellidx(n, y, x)];
const char* glust = cell_extended_gcluster(n, cur);
//fprintf(stderr, "checking %d/%d (%s) for [%s]\n", y, x, glust, filltarg);
if(strcmp(glust, filltarg)){
@ -58,7 +58,7 @@ ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c, const char* fi
}
// at the initial step only, invalid y, x is an error, so explicitly check.
int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){
int ncplane_polyfill_yx(ncplane* n, int y, int x, const nccell* c){
int ret = -1;
if(y < n->leny && x < n->lenx){
if(y >= 0 && x >= 0){
@ -68,7 +68,7 @@ int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){
if(y < 0 || x < 0){
return -1; // not fillable
}
const cell* cur = &n->fb[nfbcellidx(n, y, x)];
const nccell* cur = &n->fb[nfbcellidx(n, y, x)];
const char* targ = cell_extended_gcluster(n, cur);
const char* fillegc = cell_extended_gcluster(n, c);
//fprintf(stderr, "checking %d/%d (%s) for [%s]\n", y, x, targ, fillegc);
@ -131,7 +131,7 @@ check_gradient_args(uint64_t ul, uint64_t ur, uint64_t bl, uint64_t br){
// calculate both channels of a gradient at a particular point, knowing that
// we're using double halfblocks, into `c`->channels.
static inline void
calc_highgradient(cell* c, uint32_t ul, uint32_t ur, uint32_t ll,
calc_highgradient(nccell* c, 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)){
cell_set_fchannel(c, calc_gradient_channel(ul, ur, ll, lr,
@ -176,7 +176,7 @@ int ncplane_highgradient(ncplane* n, uint32_t ul, uint32_t ur,
int total = 0;
for(int y = yoff ; y <= ystop ; ++y){
for(int x = xoff ; x <= xstop ; ++x){
cell* targc = ncplane_cell_ref_yx(n, y, x);
nccell* targc = ncplane_cell_ref_yx(n, y, x);
targc->channels = 0;
if(cell_load(n, targc, "") < 0){
return -1;
@ -249,7 +249,7 @@ int ncplane_gradient(ncplane* n, const char* egc, uint32_t stylemask,
int total = 0;
for(int y = yoff ; y <= ystop ; ++y){
for(int x = xoff ; x <= xstop ; ++x){
cell* targc = ncplane_cell_ref_yx(n, y, x);
nccell* targc = ncplane_cell_ref_yx(n, y, x);
targc->channels = 0;
if(cell_load(n, targc, egc) < 0){
return -1;
@ -291,7 +291,7 @@ int ncplane_stain(ncplane* n, int ystop, int xstop,
int total = 0;
for(int y = yoff ; y <= ystop ; ++y){
for(int x = xoff ; x <= xstop ; ++x){
cell* targc = ncplane_cell_ref_yx(n, y, x);
nccell* targc = ncplane_cell_ref_yx(n, y, x);
if(targc->gcluster){
calc_gradient_channels(&targc->channels, tl, tr, bl, br,
y - yoff, x - xoff, ylen, xlen);
@ -320,7 +320,7 @@ int ncplane_format(ncplane* n, int ystop, int xstop, uint32_t stylemask){
int total = 0;
for(int y = yoff ; y < ystop + 1 ; ++y){
for(int x = xoff ; x < xstop + 1 ; ++x){
cell* targc = ncplane_cell_ref_yx(n, y, x);
nccell* targc = ncplane_cell_ref_yx(n, y, x);
targc->stylemask = stylemask;
++total;
}
@ -331,7 +331,7 @@ int ncplane_format(ncplane* n, int ystop, int xstop, uint32_t stylemask){
// if we're a half block, reverse the channels. if we're a space, set both to
// the background. if we're a full block, set both to the foreground.
static int
rotate_channels(ncplane* src, const cell* c, uint32_t* fchan, uint32_t* bchan){
rotate_channels(ncplane* src, const nccell* c, uint32_t* fchan, uint32_t* bchan){
const char* egc = cell_extended_gcluster(src, c);
if(egc[0] == ' ' || egc[0] == 0){
*fchan = *bchan;
@ -392,8 +392,8 @@ rotate_output(ncplane* dst, uint32_t tchan, uint32_t bchan){
// lower?) having the two channels as fore- and background.
static int
rotate_2x1_cw(ncplane* src, ncplane* dst, int srcy, int srcx, int dsty, int dstx){
cell c1 = CELL_TRIVIAL_INITIALIZER;
cell c2 = CELL_TRIVIAL_INITIALIZER;
nccell c1 = CELL_TRIVIAL_INITIALIZER;
nccell c2 = CELL_TRIVIAL_INITIALIZER;
if(ncplane_at_yx_cell(src, srcy, srcx, &c1) < 0){
return -1;
}
@ -433,8 +433,8 @@ rotate_2x1_cw(ncplane* src, ncplane* dst, int srcy, int srcx, int dsty, int dstx
static int
rotate_2x1_ccw(ncplane* src, ncplane* dst, int srcy, int srcx, int dsty, int dstx){
cell c1 = CELL_TRIVIAL_INITIALIZER;
cell c2 = CELL_TRIVIAL_INITIALIZER;
nccell c1 = CELL_TRIVIAL_INITIALIZER;
nccell c2 = CELL_TRIVIAL_INITIALIZER;
if(ncplane_at_yx_cell(src, srcy, srcx, &c1) < 0){
return -1;
}
@ -464,8 +464,8 @@ rotate_merge(ncplane* n, ncplane* newp){
if(ret == 0){
for(int y = 0 ; y < dimy ; ++y){
for(int x = 0 ; x < dimx ; ++x){
const cell* src = &newp->fb[fbcellidx(y, dimx, x)];
cell* targ = &n->fb[fbcellidx(y, dimx, x)];
const nccell* src = &newp->fb[fbcellidx(y, dimx, x)];
nccell* targ = &n->fb[fbcellidx(y, dimx, x)];
if(cell_duplicate_far(&n->pool, targ, newp, src) < 0){
return -1;
}

@ -60,7 +60,7 @@ struct esctrie;
// circular buffer of rows. 'logrow' is the index of the row at the logical top
// of the plane. It only changes from 0 if the plane is scrollable.
typedef struct ncplane {
cell* fb; // "framebuffer" of character cells
nccell* fb; // "framebuffer" of character cells
int logrow; // logical top row, starts at 0, add one for each scroll
int x, y; // current cursor location within this plane
// ncplane_yx() etc. use coordinates relative to the plane to which this
@ -88,7 +88,7 @@ typedef struct ncplane {
void* userptr; // slot for the user to stick some opaque pointer
int (*resizecb)(struct ncplane*); // callback after parent is resized
cell basecell; // cell written anywhere that fb[i].gcluster == 0
nccell basecell; // cell written anywhere that fb[i].gcluster == 0
char* name; // used only for debugging
ncalign_e align; // relative to parent plane, for automatic realignment
uint16_t stylemask; // same deal as in a cell
@ -323,7 +323,7 @@ typedef struct notcurses {
// we keep a copy of the last rendered frame. this facilitates O(1)
// notcurses_at_yx() and O(1) damage detection (at the cost of some memory).
cell* lastframe;// last rasterized framebuffer, NULL until first rasterization
nccell* lastframe;// last rasterized framebuffer, NULL until first raster
egcpool pool; // egcpool for lastframe
int lfdimx; // dimensions of lastframe, unchanged by screen resize
@ -577,20 +577,20 @@ term_fg_palindex(const notcurses* nc, FILE* out, unsigned pal){
}
static inline const char*
pool_extended_gcluster(const egcpool* pool, const cell* c){
pool_extended_gcluster(const egcpool* pool, const nccell* c){
if(cell_simple_p(c)){
return (const char*)&c->gcluster;
}
return egcpool_extended_gcluster(pool, c);
}
static inline cell*
static inline nccell*
ncplane_cell_ref_yx(ncplane* n, int y, int x){
return &n->fb[nfbcellidx(n, y, x)];
}
static inline void
cell_set_wide(cell* c){
cell_set_wide(nccell* c){
c->channels |= CELL_WIDEASIAN_MASK;
}
@ -609,7 +609,7 @@ ns_to_timespec(uint64_t ns, struct timespec* ts){
}
static inline void
cell_debug(const egcpool* p, const cell* c){
cell_debug(const egcpool* p, const nccell* c){
fprintf(stderr, "gcluster: %u %s style: 0x%04x chan: 0x%016jx\n",
c->gcluster, egcpool_extended_gcluster(p, c), c->stylemask, c->channels);
}
@ -622,7 +622,7 @@ plane_debug(const ncplane* n, bool details){
if(details){
for(int y = 0 ; y < 1 ; ++y){
for(int x = 0 ; x < 10 ; ++x){
const cell* c = &n->fb[fbcellidx(y, dimx, x)];
const nccell* c = &n->fb[fbcellidx(y, dimx, x)];
fprintf(stderr, "[%03d/%03d] ", y, x);
cell_debug(&n->pool, c);
}
@ -631,22 +631,22 @@ plane_debug(const ncplane* n, bool details){
}
static inline void
pool_release(egcpool* pool, cell* c){
pool_release(egcpool* pool, nccell* c){
if(!cell_simple_p(c)){
egcpool_release(pool, cell_egc_idx(c));
}
c->gcluster = 0; // don't subject ourselves to double-release problems
}
// set the cell 'c' to point into the egcpool at location 'eoffset'
// set the nccell 'c' to point into the egcpool at location 'eoffset'
static inline void
set_gcluster_egc(cell* c, int eoffset){
set_gcluster_egc(nccell* c, int eoffset){
c->gcluster = htole(0x01000000ul) + htole(eoffset);
}
// Duplicate one cell onto another, possibly crossing ncplanes.
// Duplicate one nccell onto another, possibly crossing ncplanes.
static inline int
cell_duplicate_far(egcpool* tpool, cell* targ, const ncplane* splane, const cell* c){
cell_duplicate_far(egcpool* tpool, nccell* targ, const ncplane* splane, const nccell* c){
pool_release(tpool, targ);
targ->stylemask = c->stylemask;
targ->channels = c->channels;
@ -878,7 +878,7 @@ box_corner_needs(unsigned ctlword){
// True if the cell does not generate background pixels (i.e., the cell is a
// solid or shaded block, or certain emoji).
static inline bool
cell_nobackground_p(const cell* c){
cell_nobackground_p(const nccell* c){
return c->channels & CELL_NOBACKGROUND_MASK;
}
@ -921,12 +921,12 @@ channels_blend(unsigned c1, unsigned c2, unsigned* blends){
// do not pass palette-indexed channels!
static inline uint64_t
cell_blend_fchannel(cell* cl, unsigned channel, unsigned* blends){
cell_blend_fchannel(nccell* cl, unsigned channel, unsigned* blends){
return cell_set_fchannel(cl, channels_blend(cell_fchannel(cl), channel, blends));
}
static inline uint64_t
cell_blend_bchannel(cell* cl, unsigned channel, unsigned* blends){
cell_blend_bchannel(nccell* cl, unsigned channel, unsigned* blends){
return cell_set_bchannel(cl, channels_blend(cell_bchannel(cl), channel, blends));
}
@ -961,7 +961,7 @@ egc_rtl(const char* egc, int* bytes){
// CELL_WIDEASIAN_MASK and CELL_NOBACKGROUND_MASK ought be set however they're
// going to be set.
static inline int
pool_blit_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int cols){
pool_blit_direct(egcpool* pool, nccell* c, const char* gcluster, int bytes, int cols){
pool_release(pool, c);
if(bytes < 0 || cols < 0){
return -1;
@ -980,7 +980,7 @@ pool_blit_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int co
}
static inline int
pool_load_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int cols){
pool_load_direct(egcpool* pool, nccell* c, const char* gcluster, int bytes, int cols){
char* rtl = NULL;
c->width = cols - 1;
if(cols < 2){
@ -1006,12 +1006,12 @@ pool_load_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int co
}
static inline int
cell_load_direct(ncplane* n, cell* c, const char* gcluster, int bytes, int cols){
cell_load_direct(ncplane* n, nccell* c, const char* gcluster, int bytes, int cols){
return pool_load_direct(&n->pool, c, gcluster, bytes, cols);
}
static inline int
pool_load(egcpool* pool, cell* c, const char* gcluster){
pool_load(egcpool* pool, nccell* c, const char* gcluster){
int cols;
int bytes = utf8_egc_len(gcluster, &cols);
return pool_load_direct(pool, c, gcluster, bytes, cols);
@ -1037,12 +1037,12 @@ iswordbreak(wchar_t wchar){
return uc_is_general_category_withtable(wchar, mask);
}
// the heart of damage detection. compare two cells (from two different planes)
// for equality. if they are equal, return 0. otherwise, dup the second onto
// the first and return non-zero.
// the heart of damage detection. compare two nccells (from two different
// planes) for equality. if they are equal, return 0. otherwise, dup the second
// onto the first and return non-zero.
static inline int
cellcmp_and_dupfar(egcpool* dampool, cell* damcell,
const ncplane* srcplane, const cell* srccell){
cellcmp_and_dupfar(egcpool* dampool, nccell* damcell,
const ncplane* srcplane, const nccell* srccell){
if(damcell->stylemask == srccell->stylemask){
if(damcell->channels == srccell->channels){
const char* srcegc = cell_extended_gcluster(srcplane, srccell);

@ -241,7 +241,7 @@ write_header(ncmenu* ncm){
if(ncplane_cursor_move_yx(ncm->ncp, ypos, 0)){
return -1;
}
cell c = CELL_INITIALIZER(' ', 0, ncm->headerchannels);
nccell c = CELL_INITIALIZER(' ', 0, ncm->headerchannels);
ncplane_set_styles(ncm->ncp, 0);
if(ncplane_putc(ncm->ncp, &c) < 0){
return -1;
@ -274,7 +274,7 @@ write_header(ncmenu* ncm){
return -1;
}
if(ncm->sections[i].shortcut_offset >= 0){
cell cl = CELL_TRIVIAL_INITIALIZER;
nccell cl = CELL_TRIVIAL_INITIALIZER;
if(ncplane_at_yx_cell(ncm->ncp, ypos, xoff + ncm->sections[i].shortcut_offset, &cl) < 0){
return -1;
}
@ -357,7 +357,7 @@ ncmenu* ncmenu_create(ncplane* n, const ncmenu_options* opts){
ret->sectionchannels = opts->sectionchannels;
ret->disablechannels = ret->sectionchannels;
channels_set_fg_rgb(&ret->disablechannels, 0xdddddd);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_alpha(&c, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT);
ncplane_set_base_cell(ret->ncp, &c);
@ -454,7 +454,7 @@ int ncmenu_unroll(ncmenu* n, int sectionidx){
}
}
if(sec->items[i].shortcut_offset >= 0){
cell cl = CELL_TRIVIAL_INITIALIZER;
nccell cl = CELL_TRIVIAL_INITIALIZER;
if(ncplane_at_yx_cell(n->ncp, ypos, xpos + 1 + sec->items[i].shortcut_offset, &cl) < 0){
return -1;
}

@ -597,8 +597,8 @@ int ncplane_resize_internal(ncplane* n, int keepy, int keepx, int keepleny,
// we've shrunk, we will be filling the new structure.
int keptarea = keepleny * keeplenx;
int newarea = ylen * xlen;
size_t fbsize = sizeof(cell) * newarea;
cell* fb = malloc(fbsize);
size_t fbsize = sizeof(nccell) * newarea;
nccell* fb = malloc(fbsize);
if(fb == NULL){
return -1;
}
@ -609,7 +609,7 @@ int ncplane_resize_internal(ncplane* n, int keepy, int keepx, int keepleny,
if(n->x >= xlen){
n->x = xlen - 1;
}
cell* preserved = n->fb;
nccell* preserved = n->fb;
ncplane_notcurses(n)->stats.fbbytes -= sizeof(*preserved) * (rows * cols);
ncplane_notcurses(n)->stats.fbbytes += fbsize;
n->fb = fb;
@ -833,7 +833,7 @@ init_banner(const notcurses* nc){
" compiled with gcc-%s, %s-endian\n"
" terminfo from %s\n",
nc->stdplane->leny, nc->stdplane->lenx,
bprefix(nc->stats.fbbytes, 1, prefixbuf, 0), sizeof(cell),
bprefix(nc->stats.fbbytes, 1, prefixbuf, 0), sizeof(nccell),
nc->tcache.colors, nc->tcache.RGBflag ? "+RGB" : "",
__VERSION__,
#ifdef __BYTE_ORDER__
@ -1353,7 +1353,7 @@ int ncplane_set_bg_palindex(ncplane* n, int idx){
return 0;
}
int ncplane_set_base_cell(ncplane* ncp, const cell* c){
int ncplane_set_base_cell(ncplane* ncp, const nccell* c){
return cell_duplicate(ncp, &ncp->basecell, c);
}
@ -1361,11 +1361,11 @@ int ncplane_set_base(ncplane* ncp, const char* egc, uint32_t stylemask, uint64_t
return cell_prime(ncp, &ncp->basecell, egc, stylemask, channels);
}
int ncplane_base(ncplane* ncp, cell* c){
int ncplane_base(ncplane* ncp, nccell* c){
return cell_duplicate(ncp, c, &ncp->basecell);
}
const char* cell_extended_gcluster(const ncplane* n, const cell* c){
const char* cell_extended_gcluster(const ncplane* n, const nccell* c){
if(cell_simple_p(c)){
return (const char*)&c->gcluster;
}
@ -1473,7 +1473,7 @@ void ncplane_cursor_yx(const ncplane* n, int* y, int* x){
}
static inline void
cell_obliterate(ncplane* n, cell* c){
cell_obliterate(ncplane* n, nccell* c){
cell_release(n, c);
cell_init(c);
}
@ -1483,7 +1483,7 @@ void scroll_down(ncplane* n){
n->x = 0;
if(n->y == n->leny - 1){
n->logrow = (n->logrow + 1) % n->leny;
cell* row = n->fb + nfbcellidx(n, n->y, 0);
nccell* row = n->fb + nfbcellidx(n, n->y, 0);
for(int clearx = 0 ; clearx < n->lenx ; ++clearx){
cell_release(n, &row[clearx]);
}
@ -1493,7 +1493,7 @@ void scroll_down(ncplane* n){
}
}
int cell_load(ncplane* n, cell* c, const char* gcluster){
int cell_load(ncplane* n, nccell* c, const char* gcluster){
return pool_load(&n->pool, c, gcluster);
}
@ -1537,10 +1537,10 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
// that cell as wide). Any character placed atop one half of a wide character
// obliterates the other half. Note that a wide char can thus obliterate two
// wide chars, totalling four columns.
cell* targ = ncplane_cell_ref_yx(n, n->y, n->x);
nccell* targ = ncplane_cell_ref_yx(n, n->y, n->x);
if(n->x > 0){
if(cell_double_wide_p(targ)){ // replaced cell is half of a wide char
cell* sacrifice = targ->gcluster == 0 ?
nccell* sacrifice = targ->gcluster == 0 ?
// right half will never be on the first column of a row
&n->fb[nfbcellidx(n, n->y, n->x - 1)] :
// left half will never be on the last column of a row
@ -1555,7 +1555,7 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
}
//fprintf(stderr, "%08x %016lx %c %d %d\n", targ->gcluster, targ->channels, cell_double_wide_p(targ) ? 'D' : 'd', bytes, cols);
if(cols > 1){ // must set our right wide, and check for further damage
cell* candidate = &n->fb[nfbcellidx(n, n->y, n->x + 1)];
nccell* candidate = &n->fb[nfbcellidx(n, n->y, n->x + 1)];
if(cell_wide_left_p(candidate)){
cell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + 2)]);
}
@ -1567,7 +1567,7 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
return cols;
}
int ncplane_putc_yx(ncplane* n, int y, int x, const cell* c){
int ncplane_putc_yx(ncplane* n, int y, int x, const nccell* c){
const int cols = cell_double_wide_p(c) ? 2 : 1;
const char* egc = cell_extended_gcluster(n, c);
return ncplane_put(n, y, x, egc, cols, c->stylemask, c->channels, strlen(egc));
@ -1589,7 +1589,7 @@ int ncplane_putegc_yx(ncplane* n, int y, int x, const char* gclust, int* sbytes)
int ncplane_putchar_stained(ncplane* n, char c){
uint64_t channels = n->channels;
uint32_t stylemask = n->stylemask;
const cell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
const nccell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
n->channels = targ->channels;
n->stylemask = targ->stylemask;
int ret = ncplane_putchar(n, c);
@ -1601,7 +1601,7 @@ int ncplane_putchar_stained(ncplane* n, char c){
int ncplane_putwegc_stained(ncplane* n, const wchar_t* gclust, int* sbytes){
uint64_t channels = n->channels;
uint32_t stylemask = n->stylemask;
const cell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
const nccell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
n->channels = targ->channels;
n->stylemask = targ->stylemask;
int ret = ncplane_putwegc(n, gclust, sbytes);
@ -1613,7 +1613,7 @@ int ncplane_putwegc_stained(ncplane* n, const wchar_t* gclust, int* sbytes){
int ncplane_putegc_stained(ncplane* n, const char* gclust, int* sbytes){
uint64_t channels = n->channels;
uint32_t stylemask = n->stylemask;
const cell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
const nccell* targ = &n->fb[nfbcellidx(n, n->y, n->x)];
n->channels = targ->channels;
n->stylemask = targ->stylemask;
int ret = ncplane_putegc(n, gclust, sbytes);
@ -1622,11 +1622,11 @@ int ncplane_putegc_stained(ncplane* n, const char* gclust, int* sbytes){
return ret;
}
int ncplane_cursor_at(const ncplane* n, cell* c, char** gclust){
int ncplane_cursor_at(const ncplane* n, nccell* c, char** gclust){
if(n->y == n->leny && n->x == n->lenx){
return -1;
}
const cell* src = &n->fb[nfbcellidx(n, n->y, n->x)];
const nccell* src = &n->fb[nfbcellidx(n, n->y, n->x)];
memcpy(c, src, sizeof(*src));
if(cell_simple_p(c)){
*gclust = NULL;
@ -1745,7 +1745,7 @@ int ncplane_vprintf_stained(struct ncplane* n, const char* format, va_list ap){
return ret;
}
int ncplane_hline_interp(ncplane* n, const cell* c, int len,
int ncplane_hline_interp(ncplane* n, const nccell* c, int len,
uint64_t c1, uint64_t c2){
unsigned ur, ug, ub;
int r1, g1, b1, r2, g2, b2;
@ -1765,7 +1765,7 @@ int ncplane_hline_interp(ncplane* n, const cell* c, int len,
int deltbg = bg2 - bg1;
int deltbb = bb2 - bb1;
int ret;
cell dupc = CELL_TRIVIAL_INITIALIZER;
nccell dupc = CELL_TRIVIAL_INITIALIZER;
if(cell_duplicate(n, &dupc, c) < 0){
return -1;
}
@ -1797,7 +1797,7 @@ int ncplane_hline_interp(ncplane* n, const cell* c, int len,
return ret;
}
int ncplane_vline_interp(ncplane* n, const cell* c, int len,
int ncplane_vline_interp(ncplane* n, const nccell* c, int len,
uint64_t c1, uint64_t c2){
unsigned ur, ug, ub;
int r1, g1, b1, r2, g2, b2;
@ -1818,7 +1818,7 @@ int ncplane_vline_interp(ncplane* n, const cell* c, int len,
int deltbb = (bb2 - bb1) / (len + 1);
int ret, ypos, xpos;
ncplane_cursor_yx(n, &ypos, &xpos);
cell dupc = CELL_TRIVIAL_INITIALIZER;
nccell dupc = CELL_TRIVIAL_INITIALIZER;
if(cell_duplicate(n, &dupc, c) < 0){
return -1;
}
@ -1853,9 +1853,9 @@ int ncplane_vline_interp(ncplane* n, const cell* c, int len,
return ret;
}
int ncplane_box(ncplane* n, const cell* ul, const cell* ur,
const cell* ll, const cell* lr, const cell* hl,
const cell* vl, int ystop, int xstop,
int ncplane_box(ncplane* n, const nccell* ul, const nccell* ur,
const nccell* ll, const nccell* lr, const nccell* hl,
const nccell* vl, int ystop, int xstop,
unsigned ctlword){
int yoff, xoff, ymax, xmax;
ncplane_cursor_yx(n, &yoff, &xoff);
@ -2558,12 +2558,12 @@ char* ncplane_contents(const ncplane* nc, int begy, int begx, int leny, int lenx
}
int cells_ascii_box(struct ncplane* n, uint32_t attr, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl){
nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){
return cells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, "/\\\\/-|");
}
int cells_double_box(struct ncplane* n, uint32_t attr, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl){
nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){
if(notcurses_canutf8(ncplane_notcurses(n))){
return cells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, "╔╗╚╝═║");
}
@ -2571,7 +2571,7 @@ int cells_double_box(struct ncplane* n, uint32_t attr, uint64_t channels,
}
int cells_rounded_box(struct ncplane* n, uint32_t attr, uint64_t channels,
cell* ul, cell* ur, cell* ll, cell* lr, cell* hl, cell* vl){
nccell* ul, nccell* ur, nccell* ll, nccell* lr, nccell* hl, nccell* vl){
if(notcurses_canutf8(ncplane_notcurses(n))){
return cells_load_box(n, attr, channels, ul, ur, ll, lr, hl, vl, "╭╮╰╯─│");
}

@ -252,7 +252,7 @@ class ncppplot {
return -1;
}
utf8[bytes] = '\0';
cell* c = ncplane_cell_ref_yx(ncp, dimy - y - 1, x);
nccell* c = ncplane_cell_ref_yx(ncp, dimy - y - 1, x);
cell_set_bchannel(c, channels_bchannel(channels));
cell_set_fchannel(c, channels_fchannel(channels));
cell_set_styles(c, NCSTYLE_NONE);

@ -65,8 +65,8 @@ ncreader_redraw(ncreader* n){
const int texty = y;
for(int x = 0 ; x < n->ncp->lenx ; ++x){
const int textx = x + n->xproject;
const cell* src = &n->textarea->fb[nfbcellidx(n->textarea, texty, textx)];
cell* dst = &n->ncp->fb[nfbcellidx(n->ncp, y, x)];
const nccell* src = &n->textarea->fb[nfbcellidx(n->textarea, texty, textx)];
nccell* dst = &n->ncp->fb[nfbcellidx(n->ncp, y, x)];
//fprintf(stderr, "projecting %d/%d [%s] to %d/%d [%s]\n", texty, textx, cell_extended_gcluster(n->textarea, src), y, x, cell_extended_gcluster(n->ncp, dst));
if(cellcmp_and_dupfar(&n->ncp->pool, dst, n->textarea, src) < 0){
ret = -1;

@ -119,7 +119,7 @@ draw_borders(ncplane* n, unsigned mask, uint64_t channel, direction_e direction)
ncplane_dim_yx(n, &leny, &lenx);
int maxx = lenx - 1;
int maxy = leny - 1;
cell ul, ur, ll, lr, hl, vl;
nccell ul, ur, ll, lr, hl, vl;
cell_init(&ul); cell_init(&ur); cell_init(&hl);
cell_init(&ll); cell_init(&lr); cell_init(&vl);
if(cells_rounded_box(n, 0, channel, &ul, &ur, &ll, &lr, &hl, &vl)){

@ -38,7 +38,7 @@ notcurses_resize_internal(ncplane* pp, int* restrict rows, int* restrict cols){
n->lfdimy = *rows;
n->lfdimx = *cols;
const size_t size = sizeof(*n->lastframe) * (n->lfdimy * n->lfdimx);
cell* fb = realloc(n->lastframe, size);
nccell* fb = realloc(n->lastframe, size);
if(fb == NULL){
return -1;
}
@ -155,12 +155,12 @@ update_render_stats(const struct timespec* time1, const struct timespec* time0,
}
}
void cell_release(ncplane* n, cell* c){
void cell_release(ncplane* n, nccell* c){
pool_release(&n->pool, c);
}
// Duplicate one cell onto another when they share a plane. Convenience wrapper.
int cell_duplicate(ncplane* n, cell* targ, const cell* c){
int cell_duplicate(ncplane* n, nccell* targ, const nccell* c){
if(cell_duplicate_far(&n->pool, targ, n, c) < 0){
logerror(ncplane_notcurses(n), "Failed duplicating cell");
return -1;
@ -172,7 +172,7 @@ int cell_duplicate(ncplane* n, cell* targ, const cell* c){
// crender per rendered cell, and they are initialized to all zeroes.
struct crender {
const ncplane *p; // source of glyph for this cell
cell c;
nccell c;
unsigned fgblends;
unsigned bgblends;
// we'll need recalculate the foreground relative to the solved background,
@ -262,11 +262,11 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
break;
}
struct crender* crender = &rvec[fbcellidx(absy, dstlenx, absx)];
cell* targc = &crender->c;
nccell* targc = &crender->c;
if(cell_wide_right_p(targc)){
continue;
}
const cell* vis = &p->fb[nfbcellidx(p, y, x)];
const nccell* vis = &p->fb[nfbcellidx(p, y, x)];
// if we never loaded any content into the cell (or obliterated it by
// writing in a zero), use the plane's base cell.
if(vis->gcluster == 0 && !cell_double_wide_p(vis)){
@ -369,7 +369,7 @@ init_rvec(struct crender* rvec, int totalcells){
// should be done at the end of rendering the cell, so that contrast is solved
// against the real background.
static inline void
lock_in_highcontrast(cell* targc, struct crender* crender){
lock_in_highcontrast(nccell* targc, struct crender* crender){
if(cell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_fg_default(targc);
}
@ -397,13 +397,13 @@ lock_in_highcontrast(cell* targc, struct crender* crender){
// wide glyph to its left. FIXME why can't we do this as we go along? FIXME can
// we not do the blend a single time here, if we track sums in paint()?
static void
postpaint(cell* lastframe, int dimy, int dimx, struct crender* rvec, egcpool* pool){
postpaint(nccell* lastframe, int dimy, int dimx, struct crender* rvec, egcpool* pool){
for(int y = 0 ; y < dimy ; ++y){
for(int x = 0 ; x < dimx ; ++x){
struct crender* crender = &rvec[fbcellidx(y, dimx, x)];
cell* targc = &crender->c;
nccell* targc = &crender->c;
lock_in_highcontrast(targc, crender);
cell* prevcell = &lastframe[fbcellidx(y, dimx, x)];
nccell* prevcell = &lastframe[fbcellidx(y, dimx, x)];
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc) > 0){
crender->damaged = true;
if(cell_wide_left_p(targc)){
@ -452,7 +452,7 @@ int ncplane_mergedown(const ncplane* restrict src, ncplane* restrict dst,
return -1;
}
const int totalcells = dst->leny * dst->lenx;
cell* rendfb = calloc(sizeof(*rendfb), totalcells);
nccell* rendfb = calloc(sizeof(*rendfb), totalcells);
const size_t crenderlen = sizeof(struct crender) * totalcells;
struct crender* rvec = malloc(crenderlen);
if(!rendfb || !rvec){
@ -503,9 +503,9 @@ ncfputc(char c, FILE* out){
#endif
}
// write the cell's UTF-8 extended grapheme cluster to the provided FILE*.
// write the nccell's UTF-8 extended grapheme cluster to the provided FILE*.
static int
term_putc(FILE* out, const egcpool* e, const cell* c){
term_putc(FILE* out, const egcpool* e, const nccell* c){
if(cell_simple_p(c)){
//fprintf(stderr, "[%.4s] %08x\n", (const char*)&c->gcluster, c->gcluster); }
uint32_t firstbyte = htole(c->gcluster) & 0xff;
@ -551,7 +551,7 @@ int term_setstyle(FILE* out, unsigned cur, unsigned targ, unsigned stylebit,
// write any escape sequences necessary to set the desired style
static inline int
term_setstyles(FILE* out, uint32_t* curattr, const cell* c, bool* normalized,
term_setstyles(FILE* out, uint32_t* curattr, const nccell* c, bool* normalized,
const char* sgr0, const char* sgr, const char* italics,
const char* italoff, const char* struck, const char* struckoff){
*normalized = false;
@ -791,7 +791,7 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){
const int innerx = x - nc->stdplane->absx;
const size_t damageidx = innery * nc->lfdimx + innerx;
unsigned r, g, b, br, bg, bb, palfg, palbg;
const cell* srccell = &nc->lastframe[damageidx];
const nccell* srccell = &nc->lastframe[damageidx];
if(!rvec[damageidx].damaged){
// no need to emit a cell; what we rendered appears to already be
// here. no updates are performed to elision state nor lastframe.
@ -1168,7 +1168,7 @@ int notcurses_render_to_buffer(notcurses* nc, char** buf, size_t* buflen){
// copy the UTF8-encoded EGC out of the cell, whether simple or complex. the
// result is not tied to the ncplane, and persists across erases / destruction.
static inline char*
pool_egc_copy(const egcpool* e, const cell* c){
pool_egc_copy(const egcpool* e, const nccell* c){
if(cell_simple_p(c)){
return strdup((const char*)&c->gcluster);
}
@ -1180,7 +1180,7 @@ char* notcurses_at_yx(notcurses* nc, int yoff, int xoff, uint16_t* stylemask, ui
if(nc->lastframe){
if(yoff >= 0 && yoff < nc->lfdimy){
if(xoff >= 0 || xoff < nc->lfdimx){
const cell* srccell = &nc->lastframe[yoff * nc->lfdimx + xoff];
const nccell* srccell = &nc->lastframe[yoff * nc->lfdimx + xoff];
if(stylemask){
*stylemask = srccell->stylemask;
}

@ -69,7 +69,7 @@ ncselector_body_width(const ncselector* n){
static int
ncselector_draw(ncselector* n){
ncplane_erase(n->ncp);
cell transchar = CELL_TRIVIAL_INITIALIZER;
nccell transchar = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_alpha(&transchar, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(&transchar, CELL_ALPHA_TRANSPARENT);
// if we have a title, we'll draw a riser. the riser is two rows tall, and
@ -145,7 +145,7 @@ ncselector_draw(ncselector* n){
++yoff;
ncplane_cursor_move_yx(n->ncp, yoff, xoff + 1);
for(int i = xoff + 1 ; i < dimx - 1 ; ++i){
cell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
nccell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
ncplane_putc(n->ncp, &transc);
}
const int bodyoffset = dimx - bodywidth + 2;
@ -169,7 +169,7 @@ ncselector_draw(ncselector* n){
}
ncplane_cursor_move_yx(n->ncp, yoff, xoff + 1);
for(int i = xoff + 1 ; i < dimx - 1 ; ++i){
cell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
nccell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
ncplane_putc(n->ncp, &transc);
}
n->ncp->channels = n->opchannels;
@ -190,7 +190,7 @@ ncselector_draw(ncselector* n){
// Bottom line of body (background and possibly down arrow)
ncplane_cursor_move_yx(n->ncp, yoff, xoff + 1);
for(int i = xoff + 1 ; i < dimx - 1 ; ++i){
cell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
nccell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
ncplane_putc(n->ncp, &transc);
}
if(n->maxdisplay && n->maxdisplay < n->itemcount){
@ -562,7 +562,7 @@ ncmultiselector_body_width(const ncmultiselector* n){
static int
ncmultiselector_draw(ncmultiselector* n){
ncplane_erase(n->ncp);
cell transchar = CELL_TRIVIAL_INITIALIZER;
nccell transchar = CELL_TRIVIAL_INITIALIZER;
cell_set_fg_alpha(&transchar, CELL_ALPHA_TRANSPARENT);
cell_set_bg_alpha(&transchar, CELL_ALPHA_TRANSPARENT);
// if we have a title, we'll draw a riser. the riser is two rows tall, and
@ -625,7 +625,7 @@ ncmultiselector_draw(ncmultiselector* n){
++yoff;
ncplane_cursor_move_yx(n->ncp, yoff, xoff + 1);
for(int i = xoff + 1 ; i < dimx - 1 ; ++i){
cell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
nccell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
ncplane_putc(n->ncp, &transc);
}
const int bodyoffset = dimx - bodywidth + 2;
@ -646,7 +646,7 @@ ncmultiselector_draw(ncmultiselector* n){
}
ncplane_cursor_move_yx(n->ncp, yoff, xoff + 1);
for(int i = xoff + 1 ; i < dimx - 1 ; ++i){
cell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
nccell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
ncplane_putc(n->ncp, &transc);
}
n->ncp->channels = n->descchannels;
@ -676,7 +676,7 @@ ncmultiselector_draw(ncmultiselector* n){
// Bottom line of body (background and possibly down arrow)
ncplane_cursor_move_yx(n->ncp, yoff, xoff + 1);
for(int i = xoff + 1 ; i < dimx - 1 ; ++i){
cell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
nccell transc = CELL_TRIVIAL_INITIALIZER; // fall back to base cell
ncplane_putc(n->ncp, &transc);
}
if(n->maxdisplay && n->maxdisplay < n->itemcount){

@ -36,7 +36,7 @@ TEST_CASE("Cell") {
}
SUBCASE("Loadchar") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == cell_load(n_, &c, " "));
CHECK(cell_simple_p(&c));
cell_release(n_, &c);
@ -68,7 +68,7 @@ TEST_CASE("Cell") {
}
SUBCASE("SetItalic") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
int dimy, dimx;
notcurses_term_dim_yx(nc_, &dimy, &dimx);
cell_set_styles(&c, NCSTYLE_ITALIC);
@ -81,7 +81,7 @@ TEST_CASE("Cell") {
}
SUBCASE("SetBold") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
int dimy, dimx;
notcurses_term_dim_yx(nc_, &dimy, &dimx);
cell_set_styles(&c, NCSTYLE_BOLD);
@ -94,7 +94,7 @@ TEST_CASE("Cell") {
}
SUBCASE("SetUnderline") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
int dimy, dimx;
notcurses_term_dim_yx(nc_, &dimy, &dimx);
cell_set_styles(&c, NCSTYLE_UNDERLINE);
@ -108,7 +108,7 @@ TEST_CASE("Cell") {
/*SUBCASE("CellLoadTamil") {
const char zerodeg[] = "\u0bb8\u0bc0\u0bb0\u0bc7\u0bb3\u0b95\u0bbf\u0b95\u0bbf\u0bb0\u0bbf";
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
size_t ulen = cell_load(n_, &c, zerodeg);
// First have U+0BB8 TAMIL LETTER SA U+0BC0 TAMIL VOWEL SIGN II
// // e0 ae b8 e0 af 80
@ -121,7 +121,7 @@ TEST_CASE("Cell") {
}*/
SUBCASE("CellSetFGAlpha"){
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 > cell_set_fg_alpha(&c, -1));
CHECK(0 > cell_set_fg_alpha(&c, 4));
CHECK(0 == cell_set_fg_alpha(&c, CELL_ALPHA_OPAQUE));
@ -135,7 +135,7 @@ TEST_CASE("Cell") {
}
SUBCASE("CellSetBGAlpha"){
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 > cell_set_bg_alpha(&c, -1));
CHECK(0 > cell_set_bg_alpha(&c, 4));
CHECK(0 == cell_set_bg_alpha(&c, CELL_ALPHA_OPAQUE));
@ -149,7 +149,7 @@ TEST_CASE("Cell") {
// white on a black background ought be unmolested for highcontrast
SUBCASE("HighContrastWhiteOnBlackBackground"){
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
CHECK(0 == cell_set_fg_rgb8(&c, 0xff, 0xff, 0xff));
CHECK(0 == cell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST));
CHECK(0 == cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT));
@ -188,7 +188,7 @@ TEST_CASE("Cell") {
// white on a white background ought be changed for highcontrast
SUBCASE("HighContrastWhiteOnWhiteBackground"){
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
CHECK(0 == cell_set_fg_rgb8(&c, 0xff, 0xff, 0xff));
CHECK(0 == cell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST));
CHECK(0 == cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT));
@ -227,7 +227,7 @@ TEST_CASE("Cell") {
// black on a black background must be changed for highcontrast
SUBCASE("HighContrastBlackOnBlackBackground"){
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
CHECK(0 == cell_set_fg_rgb8(&c, 0x0, 0x0, 0x0));
CHECK(0 == cell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST));
CHECK(0 == cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT));
@ -266,7 +266,7 @@ TEST_CASE("Cell") {
// black on a white background ought be unmolested for highcontrast
SUBCASE("HighContrastBlackOnWhiteBackground"){
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
CHECK(0 == cell_set_fg_rgb8(&c, 0x0, 0x0, 0x0));
CHECK(0 == cell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST));
CHECK(0 == cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT));
@ -306,7 +306,7 @@ TEST_CASE("Cell") {
// high contrast ought only be activated relevant to the background equal to
// or below them, not above.
SUBCASE("HighContrastBelowOnly"){
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
// top has a background of white
CHECK(0 == cell_set_bg_rgb8(&c, 0xff, 0xff, 0xff));
CHECK(0 == cell_set_fg_alpha(&c, CELL_ALPHA_TRANSPARENT));
@ -345,13 +345,13 @@ TEST_CASE("Cell") {
}
SUBCASE("CellLoadCharPrinting") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == cell_load_char(n_, &c, '*'));
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), "*"));
}
SUBCASE("CellLoadCharWhitespace") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == cell_load_char(n_, &c, '\f'));
CHECK(1 == cell_load_char(n_, &c, '\n'));
CHECK(1 == cell_load_char(n_, &c, '\t'));
@ -359,14 +359,14 @@ TEST_CASE("Cell") {
}
SUBCASE("CellLoadCharControl") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == cell_load_char(n_, &c, '\0'));
CHECK(-1 == cell_load_char(n_, &c, 1));
CHECK(-1 == cell_load_char(n_, &c, '\b'));
}
SUBCASE("CellLoadEGC32") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == cell_load_egc32(n_, &c, 0));
CHECK(1 == cell_load_egc32(n_, &c, 0x65)); // U+0061 LATIN SMALL LETTER A
CHECK(2 == cell_load_egc32(n_, &c, 0xb5c2)); // U+00B5 MICRO SIGN

@ -41,7 +41,7 @@ TEST_CASE("Fade") {
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
int dimy, dimx;
ncplane_dim_yx(n_, &dimy, &dimx);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
c.gcluster = '*';
cell_set_fg_rgb8(&c, 0xff, 0xff, 0xff);
unsigned rgb = 0xffffffu;

@ -18,7 +18,7 @@ TEST_CASE("Fills") {
SUBCASE("PolyfillNullGlyph") {
int dimx, dimy;
ncplane_dim_yx(n_, &dimy, &dimx);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 > ncplane_polyfill_yx(n_, dimy, dimx, &c));
}
@ -26,7 +26,7 @@ TEST_CASE("Fills") {
SUBCASE("PolyfillOffplane") {
int dimx, dimy;
ncplane_dim_yx(n_, &dimy, &dimx);
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
CHECK(0 > ncplane_polyfill_yx(n_, dimy, 0, &c));
CHECK(0 > ncplane_polyfill_yx(n_, 0, dimx, &c));
CHECK(0 > ncplane_polyfill_yx(n_, 0, -1, &c));
@ -34,7 +34,7 @@ TEST_CASE("Fills") {
}
SUBCASE("PolyfillOnGlyph") {
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
struct ncplane_options nopts = {
.y = 0,
.x = 0,
@ -60,13 +60,13 @@ TEST_CASE("Fills") {
}
SUBCASE("PolyfillStandardPlane") {
cell c = CELL_CHAR_INITIALIZER('-');
nccell c = CELL_CHAR_INITIALIZER('-');
CHECK(0 < ncplane_polyfill_yx(n_, 0, 0, &c));
CHECK(0 == notcurses_render(nc_));
}
SUBCASE("PolyfillEmptyPlane") {
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
struct ncplane_options nopts = {
.y = 0,
.x = 0,
@ -85,7 +85,7 @@ TEST_CASE("Fills") {
}
SUBCASE("PolyfillWalledPlane") {
cell c = CELL_CHAR_INITIALIZER('+');
nccell c = CELL_CHAR_INITIALIZER('+');
struct ncplane_options nopts = {
.y = 0,
.x = 0,
@ -116,7 +116,7 @@ TEST_CASE("Fills") {
int dimy, dimx;
ncplane_dim_yx(n_, &dimy, &dimx);
REQUIRE(0 < ncplane_gradient_sized(n_, "M", 0, c, c, c, c, dimy, dimx));
cell cl = CELL_TRIVIAL_INITIALIZER;
nccell cl = CELL_TRIVIAL_INITIALIZER;
uint64_t channels = 0;
channels_set_fg_rgb(&channels, 0x40f040);
channels_set_bg_rgb(&channels, 0x40f040);
@ -146,7 +146,7 @@ TEST_CASE("Fills") {
int dimy, dimx;
ncplane_dim_yx(n_, &dimy, &dimx);
REQUIRE(0 < ncplane_gradient_sized(n_, "V", 0, ul, ur, ll, lr, dimy, dimx));
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
uint64_t channels = 0;
channels_set_fg_rgb(&channels, 0x40f040);
channels_set_bg_rgb(&channels, 0x40f040);
@ -246,10 +246,10 @@ TEST_CASE("Fills") {
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;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_on_styles(&c, NCSTYLE_BOLD);
CHECK(0 < ncplane_format(n_, 0, 0, c.stylemask));
cell d = CELL_TRIVIAL_INITIALIZER;
nccell d = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == ncplane_at_yx_cell(n_, 0, 0, &d));
CHECK(d.stylemask == c.stylemask);
CHECK(0x444444 == cell_fg_rgb(&d));
@ -271,7 +271,7 @@ TEST_CASE("Fills") {
channels_set_bg_rgb(&channels, 0);
REQUIRE(0 < ncplane_stain(n_, 7, 7, channels, channels, channels, channels));
CHECK(0 == notcurses_render(nc_));
cell d = CELL_TRIVIAL_INITIALIZER;
nccell d = CELL_TRIVIAL_INITIALIZER;
for(int y = 0 ; y < 8 ; ++y){
for(int x = 0 ; x < 8 ; ++x){
CHECK(1 == ncplane_at_yx_cell(n_, y, x, &d));
@ -294,7 +294,7 @@ TEST_CASE("Fills") {
channels_set_bg_rgb(&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;
nccell d = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == ncplane_at_yx_cell(n_, 0, 0, &d));
CHECK(channels == d.channels);
REQUIRE(cell_simple_p(&d));
@ -315,7 +315,7 @@ TEST_CASE("Fills") {
channels_set_bg_rgb(&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;
nccell d = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == ncplane_at_yx_cell(n_, 0, 0, &d));
CHECK(chan1 == d.channels);
REQUIRE(cell_simple_p(&d));
@ -372,8 +372,8 @@ TEST_CASE("Fills") {
// make sure glyphs replace nulls
CHECK(0 < ncplane_putstr(p1, "0123456789"));
CHECK(0 == ncplane_mergedown_simple(p1, n_));
cell cbase = CELL_TRIVIAL_INITIALIZER;
cell cp = CELL_TRIVIAL_INITIALIZER;
nccell cbase = CELL_TRIVIAL_INITIALIZER;
nccell cp = CELL_TRIVIAL_INITIALIZER;
for(int i = 0 ; i < 10 ; ++i){
CHECK(0 < ncplane_at_yx_cell(n_, 0, i, &cbase));
CHECK(0 < ncplane_at_yx_cell(p1, 0, i, &cp));
@ -416,8 +416,8 @@ TEST_CASE("Fills") {
// make sure glyphs replace nulls
CHECK(0 < ncplane_putstr(p1, "█▀▄▌▐🞵🞶🞷🞸🞹"));
CHECK(0 == ncplane_mergedown_simple(p1, n_));
cell cbase = CELL_TRIVIAL_INITIALIZER;
cell cp = CELL_TRIVIAL_INITIALIZER;
nccell cbase = CELL_TRIVIAL_INITIALIZER;
nccell cp = CELL_TRIVIAL_INITIALIZER;
for(int i = 0 ; i < 10 ; ++i){
CHECK(0 < ncplane_at_yx_cell(n_, 0, i, &cbase));
CHECK(0 < ncplane_at_yx_cell(p1, 0, i, &cp));
@ -430,7 +430,7 @@ TEST_CASE("Fills") {
// make sure glyphs replace glyps
CHECK(0 < ncplane_putstr(p3, "🞵🞶🞷🞸🞹█▀▄▌▐"));
CHECK(0 == ncplane_mergedown_simple(p3, nullptr));
cell c3 = CELL_TRIVIAL_INITIALIZER;
nccell c3 = CELL_TRIVIAL_INITIALIZER;
for(int i = 0 ; i < 10 ; ++i){
CHECK(0 < ncplane_at_yx_cell(n_, 0, i, &cbase));
CHECK(0 < ncplane_at_yx_cell(p3, 0, i, &c3));
@ -467,7 +467,7 @@ TEST_CASE("Fills") {
};
struct ncplane* p1 = ncplane_create(n_, &nopts);
REQUIRE(p1);
cell c1 = CELL_TRIVIAL_INITIALIZER;
nccell c1 = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < cell_load(p1, &c1, ""));
CHECK(0 == cell_set_bg_rgb(&c1, 0x00ff00));
CHECK(0 == cell_set_fg_rgb(&c1, 0x0000ff));
@ -485,7 +485,7 @@ TEST_CASE("Fills") {
};
auto p2 = ncplane_create(n_, &n2opts);
REQUIRE(p2);
cell c2 = CELL_TRIVIAL_INITIALIZER;
nccell c2 = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < cell_load(p2, &c2, "🞶"));
CHECK(0 == cell_set_bg_rgb(&c2, 0x00ffff));
CHECK(0 == cell_set_fg_rgb(&c2, 0xff00ff));
@ -549,14 +549,14 @@ TEST_CASE("Fills") {
CHECK(0 == notcurses_render(nc_));
for(int y = 0 ; y < DIMY ; ++y){
for(int x = 0 ; x < DIMX ; ++x){
cell c1 = CELL_TRIVIAL_INITIALIZER;
nccell c1 = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < ncplane_at_yx_cell(p1, y, x, &c1));
if(y < 1 || y > 5 || x < 1 || x > 5){
auto cstr = cell_strdup(p1, &c1);
CHECK(0 == strcmp(cstr, ""));
free(cstr);
}else{
cell c2 = CELL_TRIVIAL_INITIALIZER;
nccell c2 = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < ncplane_at_yx_cell(p2, y - 1, x - 1, &c2));
CHECK(0 == cellcmp(p1, &c1, p2, &c2));
cell_release(p2, &c2);

@ -36,9 +36,9 @@ TEST_CASE("Geometry") {
};
auto n = ncplane_create(n_, &nopts);
REQUIRE(n);
cell tl = CELL_TRIVIAL_INITIALIZER; cell tr = CELL_TRIVIAL_INITIALIZER;
cell bl = CELL_TRIVIAL_INITIALIZER; cell br = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER; cell vl = CELL_TRIVIAL_INITIALIZER;
nccell tl = CELL_TRIVIAL_INITIALIZER, tr = CELL_TRIVIAL_INITIALIZER;
nccell bl = CELL_TRIVIAL_INITIALIZER, br = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == cells_double_box(n, 0, 0, &tl, &tr, &bl, &br, &hl, &vl));
CHECK(0 <= ncplane_perimeter(n, &tl, &tr, &bl, &br, &hl, &vl, 0));
CHECK(0 == notcurses_render(nc_));
@ -82,9 +82,9 @@ TEST_CASE("Geometry") {
};
auto n = ncplane_create(n_, &nopts);
REQUIRE(n);
cell tl = CELL_TRIVIAL_INITIALIZER; cell tr = CELL_TRIVIAL_INITIALIZER;
cell bl = CELL_TRIVIAL_INITIALIZER; cell br = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER; cell vl = CELL_TRIVIAL_INITIALIZER;
nccell tl = CELL_TRIVIAL_INITIALIZER, tr = CELL_TRIVIAL_INITIALIZER;
nccell bl = CELL_TRIVIAL_INITIALIZER, br = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == cells_double_box(n, 0, 0, &tl, &tr, &bl, &br, &hl, &vl));
CHECK(0 <= ncplane_perimeter(n, &tl, &tr, &bl, &br, &hl, &vl, 0));
CHECK(0 == notcurses_render(nc_));

@ -106,7 +106,7 @@ TEST_CASE("NCPlane") {
// Verify we can emit a multibyte character, and it advances the cursor
SUBCASE("EmitCell") {
const char cchar[] = "";
cell c{};
nccell c{};
CHECK(strlen(cchar) == cell_load(n_, &c, cchar));
CHECK(0 < ncplane_putc(n_, &c));
int x, y;
@ -173,7 +173,7 @@ TEST_CASE("NCPlane") {
ncplane_dim_yx(n_, &y, &x);
REQUIRE(0 < y);
REQUIRE(0 < x);
cell c{};
nccell c{};
cell_load(n_, &c, "-");
for(int yidx = 0 ; yidx < y ; ++yidx){
CHECK(0 == ncplane_cursor_move_yx(n_, yidx, 1));
@ -192,7 +192,7 @@ TEST_CASE("NCPlane") {
ncplane_dim_yx(n_, &y, &x);
REQUIRE(0 < y);
REQUIRE(0 < x);
cell c{};
nccell c{};
cell_load(n_, &c, "|");
for(int xidx = 1 ; xidx < x - 1 ; ++xidx){
CHECK(0 == ncplane_cursor_move_yx(n_, 1, xidx));
@ -212,7 +212,7 @@ TEST_CASE("NCPlane") {
ncplane_dim_yx(n_, &y, &x);
REQUIRE(2 < y);
REQUIRE(2 < x);
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
nccell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
REQUIRE(0 == cells_rounded_box(n_, 0, 0, &ul, &ur, &ll, &lr, &hl, &vl));
CHECK_GT(0, ncplane_box(n_, &ul, &ur, &ll, &lr, &hl, &vl, y + 1, x + 1, 0));
CHECK(0 == ncplane_cursor_move_yx(n_, 1, 0));
@ -310,9 +310,9 @@ TEST_CASE("NCPlane") {
const char* w1 = "à"; // U+00E0, U+0000 (c3 a0)
const char* w2 = ""; // U+0061, U+0300, U+0000 (61 cc 80)
const char* w3 = "a"; // U+0061, U+0000 (61)
cell cell1 = CELL_TRIVIAL_INITIALIZER;
cell cell2 = CELL_TRIVIAL_INITIALIZER;
cell cell3 = CELL_TRIVIAL_INITIALIZER;
nccell cell1 = CELL_TRIVIAL_INITIALIZER;
nccell cell2 = CELL_TRIVIAL_INITIALIZER;
nccell cell3 = CELL_TRIVIAL_INITIALIZER;
auto u1 = cell_load(n_, &cell1, w1);
auto u2 = cell_load(n_, &cell2, w2);
auto u3 = cell_load(n_, &cell3, w3);
@ -328,18 +328,18 @@ TEST_CASE("NCPlane") {
const char* w1 = "à"; // U+00E0, U+0000 (c3 a0)
const char* w2 = ""; // U+0061, U+0300, U+0000 (61 cc 80)
const char* w3 = "a"; // U+0061, U+0000 (61)
cell cell1 = CELL_TRIVIAL_INITIALIZER;
cell cell2 = CELL_TRIVIAL_INITIALIZER;
cell cell3 = CELL_TRIVIAL_INITIALIZER;
nccell cell1 = CELL_TRIVIAL_INITIALIZER;
nccell cell2 = CELL_TRIVIAL_INITIALIZER;
nccell cell3 = CELL_TRIVIAL_INITIALIZER;
auto u1 = cell_load(n_, &cell1, w1);
auto u2 = cell_load(n_, &cell2, w2);
auto u3 = cell_load(n_, &cell3, w3);
REQUIRE(2 == u1);
REQUIRE(3 == u2);
REQUIRE(1 == u3);
cell cell4 = CELL_TRIVIAL_INITIALIZER;
cell cell5 = CELL_TRIVIAL_INITIALIZER;
cell cell6 = CELL_TRIVIAL_INITIALIZER;
nccell cell4 = CELL_TRIVIAL_INITIALIZER;
nccell cell5 = CELL_TRIVIAL_INITIALIZER;
nccell cell6 = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == cell_duplicate(n_, &cell4, &cell1));
CHECK(0 == cell_duplicate(n_, &cell5, &cell2));
CHECK(0 == cell_duplicate(n_, &cell6, &cell3));
@ -354,8 +354,8 @@ TEST_CASE("NCPlane") {
SUBCASE("CellMultiColumn") {
const char* w1 = "\xf0\x9f\x91\xa9"; // U+1F469 WOMAN
const char* w2 = "N";
cell c1 = CELL_TRIVIAL_INITIALIZER;
cell c2 = CELL_TRIVIAL_INITIALIZER;
nccell c1 = CELL_TRIVIAL_INITIALIZER;
nccell c2 = CELL_TRIVIAL_INITIALIZER;
auto u1 = cell_load(n_, &c1, w1);
auto u2 = cell_load(n_, &c2, w2);
REQUIRE(0 < u1);
@ -548,7 +548,7 @@ TEST_CASE("NCPlane") {
ncplane_set_styles(n_, NCSCALE_NONE);
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
REQUIRE(0 < ncplane_putstr(n_, STR1));
cell testcell = CELL_TRIVIAL_INITIALIZER;
nccell testcell = CELL_TRIVIAL_INITIALIZER;
REQUIRE(0 == ncplane_at_cursor_cell(n_, &testcell)); // want nothing at the cursor
CHECK(0 == testcell.gcluster);
CHECK(0 == testcell.stylemask);
@ -586,7 +586,7 @@ TEST_CASE("NCPlane") {
ncplane_set_styles(n_, NCSTYLE_NONE);
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
REQUIRE(0 < ncplane_putstr(n_, STR1));
cell testcell = CELL_TRIVIAL_INITIALIZER;
nccell testcell = CELL_TRIVIAL_INITIALIZER;
ncplane_at_cursor_cell(n_, &testcell); // should be nothing at the cursor
CHECK(0 == testcell.gcluster);
CHECK(0 == testcell.stylemask);
@ -636,7 +636,7 @@ TEST_CASE("NCPlane") {
int newx;
ncplane_cursor_yx(n_, &y, &newx);
CHECK(newx == x);
cell testcell = CELL_TRIVIAL_INITIALIZER;
nccell testcell = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == ncplane_cursor_move_yx(n_, y - 2, x - 1));
REQUIRE(1 == ncplane_at_cursor_cell(n_, &testcell));
CHECK(testcell.gcluster == htole(STR1[strlen(STR1) - 1]));
@ -654,7 +654,7 @@ TEST_CASE("NCPlane") {
ncplane_dim_yx(n_, &dimy, &dimx);
REQUIRE(20 < dimy);
REQUIRE(40 < dimx);
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
nccell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
REQUIRE(0 == cells_double_box(n_, 0, 0, &ul, &ur, &ll, &lr, &hl, &vl));
CHECK(0 == channels_set_fg_rgb8(&ul.channels, 255, 0, 0));
CHECK(0 == channels_set_fg_rgb8(&ur.channels, 0, 255, 0));
@ -692,7 +692,7 @@ TEST_CASE("NCPlane") {
ncplane_dim_yx(n_, &dimy, &dimx);
REQUIRE(20 < dimy);
REQUIRE(40 < dimx);
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
nccell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
REQUIRE(0 == cells_rounded_box(n_, 0, 0, &ul, &ur, &ll, &lr, &hl, &vl));
// we'll try all 16 boxmasks in sideszXsidesz configurations in a 4x4 map
CHECK(0 == channels_set_fg_rgb8(&ul.channels, 255, 0, 0));
@ -742,7 +742,7 @@ TEST_CASE("NCPlane") {
SUBCASE("NewPlaneOnRight") {
int ncols, nrows;
ncplane_dim_yx(n_, &nrows, &ncols);
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
nccell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
int y, x;
ncplane_yx(n_, &y, &x);
struct ncplane_options nopts = {
@ -764,7 +764,7 @@ TEST_CASE("NCPlane") {
SUBCASE("MoveToLowerRight") {
int ncols, nrows;
ncplane_dim_yx(n_, &nrows, &ncols);
cell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
nccell ul{}, ll{}, lr{}, ur{}, hl{}, vl{};
int y, x;
ncplane_yx(n_, &y, &x);
struct ncplane_options nopts = {
@ -786,13 +786,13 @@ TEST_CASE("NCPlane") {
}
SUBCASE("Perimeter") {
cell c = CELL_CHAR_INITIALIZER('X');
nccell c = CELL_CHAR_INITIALIZER('X');
CHECK(0 == ncplane_perimeter(n_, &c, &c, &c, &c, &c, &c, 0));
CHECK(0 == notcurses_render(nc_));
}
SUBCASE("EGCStained") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
int sbytes;
CHECK(0 == ncplane_set_fg_rgb(n_, 0x444444));
CHECK(1 == ncplane_putegc(n_, "A", &sbytes));

@ -40,7 +40,7 @@ TEST_CASE("Palette256") {
// when we set a palette index, it ought change us from using default
SUBCASE("FAttributes") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(cell_fg_default_p(&c));
cell_set_fg_alpha(&c, CELL_ALPHA_TRANSPARENT);
CHECK(0 == cell_set_fg_palindex(&c, 0x20));
@ -51,7 +51,7 @@ TEST_CASE("Palette256") {
}
SUBCASE("BAttributes") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(cell_bg_default_p(&c));
cell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT);
CHECK(0 == cell_set_bg_palindex(&c, 0x20));
@ -63,13 +63,13 @@ TEST_CASE("Palette256") {
// write it to an ncplane, and verify attributes via reflection
SUBCASE("PutCAttrs") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == cell_load_char(n_, &c, 'X'));
CHECK(0 == cell_set_fg_palindex(&c, 0x20));
CHECK(0 == cell_set_bg_palindex(&c, 0x40));
CHECK(1 == ncplane_putc_yx(n_, 0, 0, &c));
cell_release(n_, &c);
cell r = CELL_TRIVIAL_INITIALIZER;
nccell r = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < ncplane_at_yx_cell(n_, 0, 0, &r));
CHECK(cell_fg_palindex_p(&r));
CHECK(cell_bg_palindex_p(&r));
@ -81,7 +81,7 @@ TEST_CASE("Palette256") {
}
SUBCASE("RenderCAttrs") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_load_char(n_, &c, 'X');
CHECK(0 == cell_set_fg_palindex(&c, 0x20));
CHECK(0 == cell_set_bg_palindex(&c, 0x40));
@ -90,7 +90,7 @@ TEST_CASE("Palette256") {
CHECK(0 < ncplane_putc_yx(n_, 0, 0, &c));
cell_release(n_, &c);
CHECK(0 == notcurses_render(nc_));
cell r = CELL_TRIVIAL_INITIALIZER;
nccell r = CELL_TRIVIAL_INITIALIZER;
CHECK(nullptr != notcurses_at_yx(nc_, 0, 0, &r.stylemask, &r.channels));
CHECK(cell_fg_palindex_p(&r));
CHECK(cell_bg_palindex_p(&r));

@ -19,9 +19,9 @@ TEST_CASE("Piles") {
CHECK(np == ncplane_parent_const(np));
CHECK(1 == ncplane_y(np));
CHECK(1 == ncplane_x(np));
cell c = CELL_CHAR_INITIALIZER('X');
nccell c = CELL_CHAR_INITIALIZER('X');
CHECK(0 < ncplane_polyfill_yx(np, 0, 0, &c));
cell o = CELL_CHAR_INITIALIZER('O');
nccell o = CELL_CHAR_INITIALIZER('O');
CHECK(0 < ncplane_polyfill_yx(n_, 0, 0, &o));
CHECK(0 == ncpile_render(np));
CHECK(0 == ncpile_render(n_));
@ -56,9 +56,9 @@ TEST_CASE("Piles") {
CHECK(np == ncplane_parent_const(np));
CHECK(-1 == ncplane_y(np));
CHECK(-1 == ncplane_x(np));
cell c = CELL_CHAR_INITIALIZER('X');
nccell c = CELL_CHAR_INITIALIZER('X');
CHECK(0 < ncplane_polyfill_yx(np, 0, 0, &c));
cell o = CELL_CHAR_INITIALIZER('O');
nccell o = CELL_CHAR_INITIALIZER('O');
CHECK(0 < ncplane_polyfill_yx(n_, 0, 0, &o));
CHECK(0 == ncpile_render(np));
CHECK(0 == ncpile_render(n_));

@ -66,9 +66,9 @@ TEST_CASE("Rotate") {
CHECK(0 == channels_set_fg_alpha(&channels, CELL_ALPHA_TRANSPARENT));
CHECK(0 == channels_set_bg_alpha(&channels, CELL_ALPHA_TRANSPARENT));
REQUIRE(0 >= ncplane_set_base(testn, "", 0, channels));
cell tl = CELL_TRIVIAL_INITIALIZER; cell tr = CELL_TRIVIAL_INITIALIZER;
cell bl = CELL_TRIVIAL_INITIALIZER; cell br = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER; cell vl = CELL_TRIVIAL_INITIALIZER;
nccell tl = CELL_TRIVIAL_INITIALIZER, tr = CELL_TRIVIAL_INITIALIZER;
nccell bl = CELL_TRIVIAL_INITIALIZER, br = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
CHECK(-1 < cell_prime(testn, &tl, "", 0, ul));
CHECK(-1 < cell_prime(testn, &tr, "", 0, ur));
CHECK(-1 < cell_prime(testn, &bl, "", 0, ll));

@ -146,9 +146,9 @@ TEST_CASE("Scrolling") {
REQUIRE(n);
// verify that the new plane was started without scrolling
CHECK(!ncplane_set_scrolling(n, true));
cell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
cell dl = CELL_TRIVIAL_INITIALIZER, dr = CELL_TRIVIAL_INITIALIZER;
cell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
nccell ul = CELL_TRIVIAL_INITIALIZER, ur = CELL_TRIVIAL_INITIALIZER;
nccell dl = CELL_TRIVIAL_INITIALIZER, dr = CELL_TRIVIAL_INITIALIZER;
nccell hl = CELL_TRIVIAL_INITIALIZER, vl = CELL_TRIVIAL_INITIALIZER;
CHECK(0 == cells_double_box(n, 0, 0, &ul, &ur, &dl, &dr, &hl, &vl));
CHECK(0 > ncplane_box_sized(n, &ul, &ur, &dl, &dr, &hl, &vl, 2, 25, 0));
CHECK(0 > ncplane_box_sized(n, &ul, &ur, &dl, &dr, &hl, &vl, 2, 21, 0));

@ -72,7 +72,7 @@ TEST_CASE("Wide") {
const char EGC2[] = "\u20a9"; // half-width won ₩
const char EGC3[] = "\u212b"; // ambiguous angstrom Å
const char EGC4[] = "\ufdfd"; // neutral yet huge bismillah ﷽
std::array<cell, 5> tcells;
std::array<nccell, 5> tcells;
for(auto & tcell : tcells){
cell_init(&tcell);
}
@ -88,7 +88,7 @@ TEST_CASE("Wide") {
int x = 0;
for(auto & tcell : tcells){
CHECK(0 == ncplane_cursor_move_yx(n_, 0, x));
cell testcell = CELL_TRIVIAL_INITIALIZER;
nccell testcell = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < ncplane_at_cursor_cell(n_, &testcell));
CHECK(!strcmp(cell_extended_gcluster(n_, &tcell), cell_extended_gcluster(n_, &testcell)));
CHECK(0 == testcell.stylemask);
@ -118,7 +118,7 @@ TEST_CASE("Wide") {
CHECK(1 == y);
CHECK(2 == x);
CHECK(0 < ncplane_putegc_yx(n_, 0, 0, w, &sbytes));
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < cell_load(n_, &c, w));
CHECK(0 < ncplane_putc_yx(n_, 1, 0, &c));
cell_release(n_, &c);
@ -149,7 +149,7 @@ TEST_CASE("Wide") {
ncplane_cursor_yx(n_, &y, &x);
CHECK(0 == y);
CHECK(1 + cols2 == x);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_at_yx_cell(n_, 0, 0, &c);
if(cols1 > 1){
CHECK(0 == c.gcluster); // should be nothing
@ -176,7 +176,7 @@ TEST_CASE("Wide") {
ncplane_cursor_yx(n_, &y, &x);
CHECK(0 == y);
CHECK(3 == x);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_at_yx_cell(n_, 0, 0, &c);
if(ncstrwidth(wbashedl) > 1){
CHECK(0 == c.gcluster); // should be nothing
@ -206,7 +206,7 @@ TEST_CASE("Wide") {
ncplane_cursor_yx(n_, &y, &x);
CHECK(0 == y);
CHECK(3 == x);
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_at_yx_cell(n_, 0, 0, &c);
CHECK(0 == strcmp(cell_extended_gcluster(n_, &c), SNAKE));
ncplane_at_yx_cell(n_, 0, 1, &c);
@ -238,7 +238,7 @@ TEST_CASE("Wide") {
CHECK(0 == ncplane_rounded_box_sized(ncp, 0, 0, 3, 4, 0));
CHECK(ncstrwidth(SCORPION) == ncplane_putegc_yx(ncp, 1, 1, SCORPION, nullptr));
CHECK(0 == notcurses_render(nc_));
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < ncplane_at_yx_cell(ncp, 1, 0, &c));
CHECK(!strcmp(cell_extended_gcluster(ncp, &c), ""));
cell_release(ncp, &c);
@ -258,7 +258,7 @@ TEST_CASE("Wide") {
SUBCASE("RenderWides") {
CHECK(0 <= ncplane_putstr(n_, "\xe5\xbd\xa2\xe5\x85\xa8"));
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_at_yx_cell(n_, 0, 0, &c);
CHECK(cell_double_wide_p(&c));
ncplane_at_yx_cell(n_, 0, 1, &c);
@ -285,7 +285,7 @@ TEST_CASE("Wide") {
// If an ncplane is moved atop the right half of a wide glyph, the entire
// glyph should be oblitrated.
SUBCASE("PlaneStompsWideGlyph"){
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
char* egc;
// print two wide glyphs on the standard plane
@ -404,7 +404,7 @@ TEST_CASE("Wide") {
};
struct ncplane* p = ncplane_create(n_, &nopts);
REQUIRE(nullptr != p);
cell c = CELL_CHAR_INITIALIZER('X');
nccell c = CELL_CHAR_INITIALIZER('X');
CHECK(0 == ncplane_perimeter(p, &c, &c, &c, &c, &c, &c, 0));
ncplane_set_bg_rgb8(n_, 0x20, 0x20, 0x20);
int sbytes;
@ -424,7 +424,7 @@ TEST_CASE("Wide") {
REQUIRE(nullptr != egc);
CHECK(0 == strcmp(" ", egc));
free(egc);
cell cl = CELL_TRIVIAL_INITIALIZER, cr = CELL_TRIVIAL_INITIALIZER;
nccell cl = CELL_TRIVIAL_INITIALIZER, cr = CELL_TRIVIAL_INITIALIZER;
CHECK(3 == ncplane_at_yx_cell(n_, 1, 1, &cl));
CHECK(0 == strcmp("", cell_extended_gcluster(n_, &cl)));
CHECK(0 == ncplane_at_yx_cell(n_, 1, 2, &cr));
@ -935,7 +935,7 @@ TEST_CASE("Wide") {
// the NUL backstop for long inlined UTF8).
// U+1F427 PINCHED FINGERS → UTF8(f0 9f a4 8c)
SUBCASE("ItalicEmoji") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_load(n_, &c, "\U0001F427");
CHECK(0xa7909ff0 == htole(c.gcluster));
cell_on_styles(&c, NCSTYLE_ITALIC);
@ -954,7 +954,7 @@ TEST_CASE("Wide") {
}
SUBCASE("StyleMaxEmoji") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
cell_load(n_, &c, "\U0001F427");
CHECK(0xa7909ff0 == htole(c.gcluster));
cell_on_styles(&c, NCSTYLE_MASK);
@ -1010,7 +1010,7 @@ TEST_CASE("Wide") {
// fill the screen with un-inlineable EGCs
SUBCASE("OfflineEGCs") {
cell c = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_TRIVIAL_INITIALIZER;
const char egc[] = "\U0001F471\u200D\u2640"; // all one EGC
CHECK(0 < cell_load(n_, &c, egc));
ncplane_set_scrolling(n_, true);

@ -106,8 +106,8 @@ TEST_CASE("ZAxis") {
// verify that moving one above another, with no other changes, is reflected at
// render time (requires explicit damage maintenance from move functionality).
SUBCASE("ZAxisDamage") {
cell cat = CELL_TRIVIAL_INITIALIZER;
cell c = CELL_CHAR_INITIALIZER('x');
nccell cat = CELL_TRIVIAL_INITIALIZER;
nccell c = CELL_CHAR_INITIALIZER('x');
REQUIRE(!cell_set_fg_rgb8(&c, 0xff, 0, 0));
REQUIRE(1 == ncplane_putc(n_, &c));
CHECK(!notcurses_render(nc_));

Loading…
Cancel
Save