notcurses_cell - operations on nccell objects
Contents
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 nccells.
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
ncplanes, so nccells must be considered associated with ncplanes. Indeed, ncplane_erase destroys the
backing storage for all a plane's cells, invalidating them. This association is formed at the time of
nccell_load, nccell_prime, or nccell_duplicate. All of these functions first call nccell_release, as do
nccell_load_egc32, nccell_load_char, and nccell_load_ucs32. When done using a nccell entirely, call nc‐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 nccells can eventually block new output. Writing over an
ncplane's cells releases them automatically.
nccell_extended_gcluster provides a nul-terminated handle to the EGC. This ought be considered invali‐
dated 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 nccell_strdup.
ncstrwidth_valid returns the number of columns occupied by a valid UTF-8 string, or -1 if an error is en‐
countered. In either case, the number of valid bytes and columns, respectively, consumed before error
into validbytes and validwidth (assuming them to not be NULL).
nccell_fg_palindex extracts the palette index from a cell's foreground channel. The channel must be
palette-indexed, or the return value is meaningless. Verify palette indexing with nccell_fg_palindex_p.
A cell's foreground channel can be set to palette-indexed mode (and have the index set) with nc‐cell_set_fg_palindex. The index must be less than NCPALETTESIZE. Replace fg with bg to operate on the
background channel.
Name
notcurses_cell - operations on nccell objects
Notes
cell was renamed to nccell in Notcurses 2.2.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. Likewise, many functions
prefixed with cell have been renamed to start with nccell.
Return Values
nccell_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.
nccell_set_fg_rgb8 and similar functions will return -1 if provided invalid inputs, and 0 otherwise.
nccellcmp returns a negative integer, 0, or a positive integer if c1 is less than, equal to, or more than
c2, respectively.
nccell_extended_gcluster returns NULL if called on a sprixel (see notcurses_visual(3).
nccell_cols returns the number of columns occupied by c, according to wcwidth(3)*. ncstrwidth is an
equivalent for strings. ncstrwidth_valid returns the same value as ncstrwidth.
See Also
notcurses(3), notcurses_channels(3), notcurses_plane(3), notcurses_output(3), notcurses_visual(3), wcwidth(3), utf8(7)
Synopsis
#include<notcurses/notcurses.h>
// 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 width; // 1B → 6B (8 bits of column width)
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 NCALPHA_HIGHCONTRAST 0x30000000ull
#define NCALPHA_TRANSPARENT 0x20000000ull
#define NCALPHA_BLEND 0x10000000ull
#define NCALPHA_OPAQUE 0x00000000ull
voidnccell_init(nccell*c);intnccell_load(structncplane*n,nccell*c,constchar*gcluster);intnccell_prime(structncplane*n,nccell*c,constchar*gcluster,uint32_tstylemask,uint64_tchan‐nels);intnccell_duplicate(structncplane*n,nccell*targ,constnccell*c);voidnccell_release(structncplane*n,nccell*c);intnccell_cols(constnccell*c);voidnccell_styles_set(nccell*c,unsignedstylebits);unsignednccell_styles(constnccell*c);boolnccellcmp(conststructncplane*n1,constnccell*c1,conststructncplane*n2,constnccell*c2);voidnccell_on_styles(nccell*c,unsignedstylebits);voidnccell_off_styles(nccell*c,unsignedstylebits);voidnccell_set_fg_default(nccell*c);voidnccell_set_bg_default(nccell*c);intnccell_set_fg_alpha(nccell*c,unsignedalpha);intnccell_set_bg_alpha(nccell*c,unsignedalpha);boolnccell_double_wide_p(constnccell*c);constchar*nccell_extended_gcluster(conststructncplane*n,constnccell*c);char*nccell_strdup(conststructncplane*n,constnccell*c);intnccell_load_char(structncplane*n,nccell*c,charch);intnccell_load_egc32(structncplane*n,nccell*c,uint32_tegc);intnccell_load_ucs32(structncplane*n,nccell*c,uint32_tu);char*nccell_extract(conststructncplane*n,constnccell*c,uint16_t*stylemask,uint64_t*channels);uint64_tnccell_channels(constnccell*c);uint32_tnccell_bchannel(constnccell*c);uint32_tnccell_fchannel(constnccell*c);uint64_tnccell_set_channels(nccell*c,uint64_tchannels);uint64_tnccell_set_bchannel(nccell*c,uint32_tchannel);uint64_tnccell_set_fchannel(nccell*c,uint32_tchannel);uint32_tnccell_fg_rgb(constnccell*c);uint32_tnccell_bg_rgb(constnccell*c);unsignednccell_fg_alpha(constnccell*c);unsignednccell_bg_alpha(constnccell*c);unsignednccell_fg_rgb8(constnccell*c,unsigned*r,unsigned*g,unsigned*b);unsignednccell_bg_rgb8(constncell*c,unsigned*r,unsigned*g,unsigned*b);intnccell_set_fg_rgb8(nccell*c,unsignedr,unsignedg,unsignedb);intnccell_set_bg_rgb8(nccell*c,unsignedr,unsignedg,unsignedb);voidnccell_set_fg_rgb8_clipped(nccell*c,intr,intg,intb);voidnccell_set_bg_rgb8_clipped(nccell*c,intr,intg,intb);intnccell_set_fg_rgb(nccell*c,uint32_tchannel);intnccell_set_bg_rgb(nccell*c,uint32_tchannel);boolnccell_fg_default_p(constnccell*c);boolnccell_bg_default_p(constnccell*c);intnccell_set_fg_palindex(nccell*cl,unsignedidx);intnccell_set_bg_palindex(nccell*cl,unsignedidx);uint32_tnccell_fg_palindex(constnccell*cl);uint32_tnccell_bg_palindex(constnccell*cl);boolnccell_fg_palindex_p(constnccell*cl);boolnccell_bg_palindex_p(constnccell*cl);intncstrwidth(constchar*text);
intncstrwidth_valid(constchar*text,int*validbytes,int*validwidth);
