convert another crop of cell_ to nccell_ #1532

This commit is contained in:
nick black 2021-04-15 01:31:12 -04:00
parent 452b7cd535
commit 7ad5219fa2
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
15 changed files with 252 additions and 187 deletions

View File

@ -1657,8 +1657,8 @@ Unlike the `notcurses` or `ncplane` objects, the definition of `nccell` is
available to the user. It is somewhat ironic, then, that the user typically available to the user. It is somewhat ironic, then, that the user typically
needn't (and shouldn't) use `nccell`s directly. Use an `nccell` when the EGC 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 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 `nccell_load()` (which tokenizes and verifies EGCs) can be saved. It can also
useful to use an `ncell` when the same styling is used in a discontinuous be useful to use an `nccell` when the same styling is used in a discontinuous
manner. manner.
```c ```c
@ -1813,10 +1813,10 @@ An `nccell` has three fundamental elements:
* The Curses-style attributes of the text. * The Curses-style attributes of the text.
* The 52 bits of foreground and background RGBA (2x8/8/8/2), plus a few flags. * The 52 bits of foreground and background RGBA (2x8/8/8/2), plus a few flags.
The EGC should be loaded using `cell_load()`. Either a single NUL-terminated The EGC should be loaded using `nccell_load()`. Either a single NUL-terminated
EGC can be provided, or a string composed of multiple EGCs. In the latter case, 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 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 is provided by the `ncplane` passed to `nccell_load()`; if this `ncplane` is
destroyed (or even erased), the `nccell` cannot safely be used. If you're done destroyed (or even erased), the `nccell` cannot safely be used. If you're done
using the `nccell` before being done with the `ncplane`, call `nccell_release()` using the `nccell` before being done with the `ncplane`, call `nccell_release()`
to free up the EGC resources. to free up the EGC resources.
@ -1825,15 +1825,15 @@ to free up the EGC resources.
// Breaks the UTF-8 string in 'gcluster' down, setting up the nccell 'c'. // 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 // 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. // styling of the cell is left untouched, but any resources are released.
int cell_load(struct ncplane* n, nccell* c, const char* gcluster); int nccell_load(struct ncplane* n, nccell* c, const char* gcluster);
// cell_load(), plus blast the styling with 'attr' and 'channels'. // nccell_load(), plus blast the styling with 'attr' and 'channels'.
static inline int static inline int
nccell_prime(struct ncplane* n, nccell* c, const char* gcluster, nccell_prime(struct ncplane* n, nccell* c, const char* gcluster,
uint32_t stylemask, uint64_t channels){ uint32_t stylemask, uint64_t channels){
c->stylemask = stylemask; c->stylemask = stylemask;
c->channels = channels; c->channels = channels;
int ret = cell_load(n, c, gcluster); int ret = nccell_load(n, c, gcluster);
return ret; return ret;
} }
@ -1879,19 +1879,19 @@ nccell_styles(const nccell* c){
// Add the specified styles (in the LSBs) to the cell's existing spec, whether // Add the specified styles (in the LSBs) to the cell's existing spec, whether
// they're actively supported or not. // they're actively supported or not.
static inline void static inline void
cell_on_styles(nccell* c, unsigned stylebits){ nccell_on_styles(nccell* c, unsigned stylebits){
c->stylemask |= (stylebits & NCSTYLE_MASK); 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 cell's existing spec.
static inline void static inline void
cell_off_styles(nccell* c, unsigned stylebits){ nccell_off_styles(nccell* c, unsigned stylebits){
c->stylemask &= ~(stylebits & NCSTYLE_MASK); c->stylemask &= ~(stylebits & NCSTYLE_MASK);
} }
// Is the cell part of a multicolumn element? // Is the cell part of a multicolumn element?
static inline bool static inline bool
cell_double_wide_p(const nccell* c){ nccell_double_wide_p(const nccell* c){
return (c->width >= 2); return (c->width >= 2);
} }
@ -1902,7 +1902,7 @@ nccell_load_char(struct ncplane* n, nccell* c, char ch){
char gcluster[2]; char gcluster[2];
gcluster[0] = ch; gcluster[0] = ch;
gcluster[1] = '\0'; gcluster[1] = '\0';
return cell_load(n, c, gcluster); return nccell_load(n, c, gcluster);
} }
// Load a UTF-8 encoded EGC of up to 4 bytes into the nccell 'c'. Returns the // Load a UTF-8 encoded EGC of up to 4 bytes into the nccell 'c'. Returns the
@ -1913,7 +1913,7 @@ nccell_load_egc32(struct ncplane* n, nccell* c, uint32_t egc){
egc = htole(egc); egc = htole(egc);
memcpy(gcluster, &egc, sizeof(egc)); memcpy(gcluster, &egc, sizeof(egc));
gcluster[4] = '\0'; gcluster[4] = '\0';
return cell_load(n, c, gcluster); return nccell_load(n, c, gcluster);
} }
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer // return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
@ -1989,103 +1989,103 @@ all implemented in terms of the lower-level [Channels API](#channels).
```c ```c
// Extract the 32-bit background channel from a cell. // Extract the 32-bit background channel from a cell.
static inline uint32_t static inline uint32_t
cell_bchannel(const nccell* cl){ nccell_bchannel(const nccell* cl){
return channels_bchannel(cl->channels); return channels_bchannel(cl->channels);
} }
// Extract the 32-bit foreground channel from a cell. // Extract the 32-bit foreground channel from a cell.
static inline uint32_t static inline uint32_t
cell_fchannel(const nccell* cl){ nccell_fchannel(const nccell* cl){
return channels_fchannel(cl->channels); return channels_fchannel(cl->channels);
} }
// Extract 24 bits of foreground RGB from 'cl', shifted to LSBs. // Extract 24 bits of foreground RGB from 'cl', shifted to LSBs.
static inline uint32_t static inline uint32_t
cell_fg_rgb(const nccell* cl){ nccell_fg_rgb(const nccell* cl){
return channels_fg_rgb(cl->channels); return channels_fg_rgb(cl->channels);
} }
// Extract 24 bits of background RGB from 'cl', shifted to LSBs. // Extract 24 bits of background RGB from 'cl', shifted to LSBs.
static inline uint32_t static inline uint32_t
cell_bg_rgb(const nccell* cl){ nccell_bg_rgb(const nccell* cl){
return channels_bg_rgb(cl->channels); return channels_bg_rgb(cl->channels);
} }
// Extract 2 bits of foreground alpha from 'cl', shifted to LSBs. // Extract 2 bits of foreground alpha from 'cl', shifted to LSBs.
static inline unsigned static inline unsigned
cell_fg_alpha(const nccell* cl){ nccell_fg_alpha(const nccell* cl){
return channels_fg_alpha(cl->channels); return channels_fg_alpha(cl->channels);
} }
// Extract 2 bits of background alpha from 'cl', shifted to LSBs. // Extract 2 bits of background alpha from 'cl', shifted to LSBs.
static inline unsigned static inline unsigned
cell_bg_alpha(const nccell* cl){ nccell_bg_alpha(const nccell* cl){
return channels_bg_alpha(cl->channels); return channels_bg_alpha(cl->channels);
} }
// Extract 24 bits of foreground RGB from 'cl', split into subcell. // Extract 24 bits of foreground RGB from 'cl', split into subcell.
static inline uint32_t static inline uint32_t
cell_fg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){ nccell_fg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
return channels_fg_rgb8(cl->channels, r, g, b); return channels_fg_rgb8(cl->channels, r, g, b);
} }
// Extract 24 bits of background RGB from 'cl', split into subcell. // Extract 24 bits of background RGB from 'cl', split into subcell.
static inline uint32_t static inline uint32_t
cell_bg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){ nccell_bg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
return channels_bg_rgb8(cl->channels, r, g, 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 // 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. // 'cell' variable, and mark it as not using the default color.
static inline int static inline int
cell_set_fg_rgb8(nccell* cl, int r, int g, int b){ nccell_set_fg_rgb8(nccell* cl, int r, int g, int b){
return channels_set_fg_rgb8(&cl->channels, r, g, b); return channels_set_fg_rgb8(&cl->channels, r, g, b);
} }
// Same, but clipped to [0..255]. // Same, but clipped to [0..255].
static inline void static inline void
cell_set_fg_rgb8_clipped(nccell* cl, int r, int g, int b){ nccell_set_fg_rgb8_clipped(nccell* cl, int r, int g, int b){
channels_set_fg_rgb8_clipped(&cl->channels, r, g, b); channels_set_fg_rgb8_clipped(&cl->channels, r, g, b);
} }
// Same, but with an assembled 24-bit RGB value. // Same, but with an assembled 24-bit RGB value.
static inline int static inline int
cell_set_fg_rgb(nccell* c, uint32_t channel){ nccell_set_fg_rgb(nccell* c, uint32_t channel){
return channels_set_fg_rgb(&c->channels, channel); return channels_set_fg_rgb(&c->channels, channel);
} }
// Set the r, g, and b cell for the background component of this 64-bit // 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. // 'cell' variable, and mark it as not using the default color.
static inline int static inline int
cell_set_bg_rgb8(nccell* cl, int r, int g, int b){ nccell_set_bg_rgb8(nccell* cl, int r, int g, int b){
return channels_set_bg_rgb8(&cl->channels, r, g, b); return channels_set_bg_rgb8(&cl->channels, r, g, b);
} }
// Same, but clipped to [0..255]. // Same, but clipped to [0..255].
static inline void static inline void
cell_set_bg_rgb8_clipped(nccell* cl, int r, int g, int b){ nccell_set_bg_rgb8_clipped(nccell* cl, int r, int g, int b){
channels_set_bg_rgb8_clipped(&cl->channels, r, g, b); channels_set_bg_rgb8_clipped(&cl->channels, r, g, b);
} }
// Same, but with an assembled 24-bit RGB value. // Same, but with an assembled 24-bit RGB value.
static inline int static inline int
cell_set_bg_rgb(nccell* c, uint32_t channel){ nccell_set_bg_rgb(nccell* c, uint32_t channel){
return channels_set_bg_rgb(&c->channels, channel); return channels_set_bg_rgb(&c->channels, channel);
} }
static inline int static inline int
cell_set_fg_alpha(nccell* c, unsigned alpha){ nccell_set_fg_alpha(nccell* c, unsigned alpha){
return channels_set_fg_alpha(&c->channels, alpha); return channels_set_fg_alpha(&c->channels, alpha);
} }
static inline int static inline int
cell_set_bg_alpha(nccell* c, unsigned alpha){ nccell_set_bg_alpha(nccell* c, unsigned alpha){
return channels_set_bg_alpha(&c->channels, alpha); return channels_set_bg_alpha(&c->channels, alpha);
} }
// Is the foreground using the "default foreground color"? // Is the foreground using the "default foreground color"?
static inline bool static inline bool
cell_fg_default_p(const nccell* cl){ nccell_fg_default_p(const nccell* cl){
return channels_fg_default_p(cl->channels); return channels_fg_default_p(cl->channels);
} }
@ -2093,19 +2093,19 @@ cell_fg_default_p(const nccell* cl){
// background color" must generally be used to take advantage of // background color" must generally be used to take advantage of
// terminal-effected transparency. // terminal-effected transparency.
static inline bool static inline bool
cell_bg_default_p(const nccell* cl){ nccell_bg_default_p(const nccell* cl){
return channels_bg_default_p(cl->channels); return channels_bg_default_p(cl->channels);
} }
// Use the default color for the foreground. // Use the default color for the foreground.
static inline void static inline void
cell_set_fg_default(nccell* c){ nccell_set_fg_default(nccell* c){
channels_set_fg_default(&c->channels); channels_set_fg_default(&c->channels);
} }
// Use the default color for the background. // Use the default color for the background.
static inline void static inline void
cell_set_bg_default(nccell* c){ nccell_set_bg_default(nccell* c){
channels_set_bg_default(&c->channels); channels_set_bg_default(&c->channels);
} }

View File

@ -57,19 +57,19 @@ typedef struct nccell {
**bool nccellcmp(const struct ncplane* ***n1***, const nccell* ***c1***, const struct ncplane* ***n2***, const nccell* ***c2***);** **bool nccellcmp(const struct ncplane* ***n1***, const nccell* ***c1***, const struct ncplane* ***n2***, const nccell* ***c2***);**
**void cell_on_styles(nccell* ***c***, unsigned ***stylebits***);** **void nccell_on_styles(nccell* ***c***, unsigned ***stylebits***);**
**void cell_off_styles(nccell* ***c***, unsigned ***stylebits***);** **void nccell_off_styles(nccell* ***c***, unsigned ***stylebits***);**
**void cell_set_fg_default(nccell* ***c***);** **void nccell_set_fg_default(nccell* ***c***);**
**void cell_set_bg_default(nccell* ***c***);** **void nccell_set_bg_default(nccell* ***c***);**
**int cell_set_fg_alpha(nccell* ***c***, unsigned ***alpha***);** **int nccell_set_fg_alpha(nccell* ***c***, unsigned ***alpha***);**
**int cell_set_bg_alpha(nccell* ***c***, unsigned ***alpha***);** **int nccell_set_bg_alpha(nccell* ***c***, unsigned ***alpha***);**
**bool cell_double_wide_p(const nccell* ***c***);** **bool nccell_double_wide_p(const nccell* ***c***);**
**const char* nccell_extended_gcluster(const struct ncplane* ***n***, const nccell* ***c***);** **const char* nccell_extended_gcluster(const struct ncplane* ***n***, const nccell* ***c***);**
@ -79,43 +79,43 @@ typedef struct nccell {
**int nccell_load_egc32(struct ncplane* ***n***, nccell* ***c***, uint32_t ***egc***);** **int nccell_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***);** **char* nccell_extract(const struct ncplane* ***n***, const nccell* ***c***, uint16_t* ***stylemask***, uint64_t* ***channels***);**
**uint32_t cell_bchannel(const nccell* ***c***);** **uint32_t nccell_bchannel(const nccell* ***c***);**
**uint32_t cell_fchannel(const nccell* ***c***);** **uint32_t nccell_fchannel(const nccell* ***c***);**
**uint64_t cell_set_bchannel(nccell* ***c***, uint32_t ***channel***);** **uint64_t nccell_set_bchannel(nccell* ***c***, uint32_t ***channel***);**
**uint64_t cell_set_fchannel(nccell* ***c***, uint32_t ***channel***);** **uint64_t nccell_set_fchannel(nccell* ***c***, uint32_t ***channel***);**
**uint32_t cell_fg_rgb(const nccell* ***c***);** **uint32_t nccell_fg_rgb(const nccell* ***c***);**
**uint32_t cell_bg_rgb(const nccell* ***c***);** **uint32_t nccell_bg_rgb(const nccell* ***c***);**
**unsigned cell_fg_alpha(const nccell* ***c***);** **unsigned nccell_fg_alpha(const nccell* ***c***);**
**unsigned cell_bg_alpha(const nccell* ***c***);** **unsigned nccell_bg_alpha(const nccell* ***c***);**
**unsigned cell_fg_rgb8(const nccell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);** **unsigned nccell_fg_rgb8(const nccell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);**
**unsigned cell_bg_rgb8(const ncell* ***c***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);** **unsigned nccell_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 nccell_set_fg_rgb8(nccell* ***c***, int ***r***, int ***g***, int ***b***);**
**int cell_set_bg_rgb8(nccell* ***c***, int ***r***, int ***g***, int ***b***);** **int nccell_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 nccell_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***);** **void nccell_set_bg_rgb8_clipped(nccell* ***c***, int ***r***, int ***g***, int ***b***);**
**int cell_set_fg_rgb(nccell* ***c***, uint32_t ***channel***);** **int nccell_set_fg_rgb(nccell* ***c***, uint32_t ***channel***);**
**int cell_set_bg_rgb(nccell* ***c***, uint32_t ***channel***);** **int nccell_set_bg_rgb(nccell* ***c***, uint32_t ***channel***);**
**bool cell_fg_default_p(const nccell* ***c***);** **bool nccell_fg_default_p(const nccell* ***c***);**
**bool cell_bg_default_p(const nccell* ***c***);** **bool nccell_bg_default_p(const nccell* ***c***);**
**int ncstrwidth(const char* ***text***)**; **int ncstrwidth(const char* ***text***)**;
@ -151,7 +151,7 @@ A heap-allocated copy can be acquired with **nccell_strdup**.
EGC, or -1 on failure. They can fail due to either an invalid UTF-8 input, or 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. backing egcpool reaching its maximum size.
**cell_set_fg_rgb8** and similar functions will return -1 if provided invalid **nccell_set_fg_rgb8** and similar functions will return -1 if provided invalid
inputs, and 0 otherwise. inputs, and 0 otherwise.
**nccellcmp** returns a negative integer, 0, or a positive integer if ***c1*** is **nccellcmp** returns a negative integer, 0, or a positive integer if ***c1*** is

View File

@ -97,7 +97,7 @@ namespace ncpp
bool is_double_wide () const noexcept bool is_double_wide () const noexcept
{ {
return cell_double_wide_p (&_cell); return nccell_double_wide_p (&_cell);
} }
unsigned get_fg_rgb () const noexcept unsigned get_fg_rgb () const noexcept
@ -112,12 +112,12 @@ namespace ncpp
unsigned get_fg_alpha () const noexcept unsigned get_fg_alpha () const noexcept
{ {
return cell_fg_alpha (&_cell); return nccell_fg_alpha (&_cell);
} }
bool is_fg_default () const noexcept bool is_fg_default () const noexcept
{ {
return cell_fg_default_p (&_cell); return nccell_fg_default_p (&_cell);
} }
bool set_fg_alpha (unsigned alpha) noexcept bool set_fg_alpha (unsigned alpha) noexcept
@ -127,7 +127,7 @@ namespace ncpp
unsigned get_bg_alpha () const noexcept unsigned get_bg_alpha () const noexcept
{ {
return cell_bg_alpha (&_cell); return nccell_bg_alpha (&_cell);
} }
bool set_bg_alpha (unsigned alpha) noexcept bool set_bg_alpha (unsigned alpha) noexcept
@ -187,17 +187,17 @@ namespace ncpp
bool is_bg_default () const noexcept bool is_bg_default () const noexcept
{ {
return cell_bg_default_p (&_cell); return nccell_bg_default_p (&_cell);
} }
bool is_wide_right () const noexcept bool is_wide_right () const noexcept
{ {
return cell_wide_right_p (&_cell); return nccell_wide_right_p (&_cell);
} }
bool is_wide_left () const noexcept bool is_wide_left () const noexcept
{ {
return cell_wide_left_p (&_cell); return nccell_wide_left_p (&_cell);
} }
private: private:

View File

@ -788,20 +788,35 @@ cell_set_bg_alpha(nccell* c, int alpha){
// Is the cell part of a multicolumn element? // Is the cell part of a multicolumn element?
static inline bool static inline bool
cell_double_wide_p(const nccell* c){ nccell_double_wide_p(const nccell* c){
return (c->width >= 2); return (c->width >= 2);
} }
__attribute__ ((deprecated)) static inline bool
cell_double_wide_p(const nccell* c){
return nccell_double_wide_p(c);
}
// Is this the right half of a wide character? // Is this the right half of a wide character?
static inline bool static inline bool
nccell_wide_right_p(const nccell* c){
return nccell_double_wide_p(c) && c->gcluster == 0;
}
__attribute__ ((deprecated)) static inline bool
cell_wide_right_p(const nccell* c){ cell_wide_right_p(const nccell* c){
return cell_double_wide_p(c) && c->gcluster == 0; return nccell_wide_right_p(c);
} }
// Is this the left half of a wide character? // Is this the left half of a wide character?
static inline bool static inline bool
nccell_wide_left_p(const nccell* c){
return nccell_double_wide_p(c) && c->gcluster;
}
__attribute__ ((deprecated)) static inline bool
cell_wide_left_p(const nccell* c){ cell_wide_left_p(const nccell* c){
return cell_double_wide_p(c) && c->gcluster; return nccell_wide_left_p(c);
} }
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer // return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
@ -2083,16 +2098,26 @@ cell_bg_rgb(const nccell* cl){
// Extract 2 bits of foreground alpha from 'cl', shifted to LSBs. // Extract 2 bits of foreground alpha from 'cl', shifted to LSBs.
static inline uint32_t static inline uint32_t
cell_fg_alpha(const nccell* cl){ nccell_fg_alpha(const nccell* cl){
return channels_fg_alpha(cl->channels); return channels_fg_alpha(cl->channels);
} }
__attribute__ ((deprecated)) static inline uint32_t
cell_fg_alpha(const nccell* cl){
return nccell_fg_alpha(cl);
}
// Extract 2 bits of background alpha from 'cl', shifted to LSBs. // Extract 2 bits of background alpha from 'cl', shifted to LSBs.
static inline uint32_t static inline uint32_t
cell_bg_alpha(const nccell* cl){ nccell_bg_alpha(const nccell* cl){
return channels_bg_alpha(cl->channels); return channels_bg_alpha(cl->channels);
} }
__attribute__ ((deprecated)) static inline uint32_t
cell_bg_alpha(const nccell* cl){
return nccell_bg_alpha(cl);
}
// Extract 24 bits of foreground RGB from 'cl', split into components. // Extract 24 bits of foreground RGB from 'cl', split into components.
static inline uint32_t static inline uint32_t
nccell_fg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){ nccell_fg_rgb8(const nccell* cl, unsigned* r, unsigned* g, unsigned* b){
@ -2153,15 +2178,25 @@ cell_set_fg_rgb(nccell* c, uint32_t channel){
// Set the cell's foreground palette index, set the foreground palette index // Set the cell's foreground palette index, set the foreground palette index
// bit, set it foreground-opaque, and clear the foreground default color bit. // bit, set it foreground-opaque, and clear the foreground default color bit.
static inline int static inline int
cell_set_fg_palindex(nccell* cl, int idx){ nccell_set_fg_palindex(nccell* cl, int idx){
return channels_set_fg_palindex(&cl->channels, idx); return channels_set_fg_palindex(&cl->channels, idx);
} }
__attribute__ ((deprecated)) static inline int
cell_set_fg_palindex(nccell* cl, int idx){
return nccell_set_fg_palindex(cl, idx);
}
static inline uint32_t static inline uint32_t
cell_fg_palindex(const nccell* cl){ nccell_fg_palindex(const nccell* cl){
return channels_fg_palindex(cl->channels); return channels_fg_palindex(cl->channels);
} }
__attribute__ ((deprecated)) static inline uint32_t
cell_fg_palindex(const nccell* cl){
return nccell_fg_palindex(cl);
}
// Set the r, g, and b cell for the background component of this 64-bit // Set the r, g, and b cell for the background component of this 64-bit
// 'cl' variable, and mark it as not using the default color. // 'cl' variable, and mark it as not using the default color.
static inline int static inline int
@ -2195,39 +2230,69 @@ cell_set_bg_rgb(nccell* c, uint32_t channel){
// Set the cell's background palette index, set the background palette index // Set the cell's background palette index, set the background palette index
// bit, set it background-opaque, and clear the background default color bit. // bit, set it background-opaque, and clear the background default color bit.
static inline int static inline int
cell_set_bg_palindex(nccell* cl, int idx){ nccell_set_bg_palindex(nccell* cl, int idx){
return channels_set_bg_palindex(&cl->channels, idx); return channels_set_bg_palindex(&cl->channels, idx);
} }
__attribute__ ((deprecated)) static inline int
cell_set_bg_palindex(nccell* cl, int idx){
return nccell_set_bg_palindex(cl, idx);
}
static inline uint32_t static inline uint32_t
cell_bg_palindex(const nccell* cl){ nccell_bg_palindex(const nccell* cl){
return channels_bg_palindex(cl->channels); return channels_bg_palindex(cl->channels);
} }
__attribute__ ((deprecated)) static inline uint32_t
cell_bg_palindex(const nccell* cl){
return nccell_bg_palindex(cl);
}
// Is the foreground using the "default foreground color"? // Is the foreground using the "default foreground color"?
static inline bool static inline bool
cell_fg_default_p(const nccell* cl){ nccell_fg_default_p(const nccell* cl){
return channels_fg_default_p(cl->channels); return channels_fg_default_p(cl->channels);
} }
__attribute__ ((deprecated)) static inline bool
cell_fg_default_p(const nccell* cl){
return nccell_fg_default_p(cl);
}
static inline bool static inline bool
cell_fg_palindex_p(const nccell* cl){ nccell_fg_palindex_p(const nccell* cl){
return channels_fg_palindex_p(cl->channels); return channels_fg_palindex_p(cl->channels);
} }
__attribute__ ((deprecated)) static inline bool
cell_fg_palindex_p(const nccell* cl){
return nccell_fg_palindex_p(cl);
}
// Is the background using the "default background color"? The "default // Is the background using the "default background color"? The "default
// background color" must generally be used to take advantage of // background color" must generally be used to take advantage of
// terminal-effected transparency. // terminal-effected transparency.
static inline bool static inline bool
cell_bg_default_p(const nccell* cl){ nccell_bg_default_p(const nccell* cl){
return channels_bg_default_p(cl->channels); return channels_bg_default_p(cl->channels);
} }
__attribute__ ((deprecated)) static inline bool
cell_bg_default_p(const nccell* cl){
return nccell_bg_default_p(cl);
}
static inline bool static inline bool
cell_bg_palindex_p(const nccell* cl){ nccell_bg_palindex_p(const nccell* cl){
return channels_bg_palindex_p(cl->channels); return channels_bg_palindex_p(cl->channels);
} }
__attribute__ ((deprecated)) static inline bool
cell_bg_palindex_p(const nccell* cl){
return nccell_bg_palindex_p(cl);
}
// Extract the 32-bit working background channel from an ncplane. // Extract the 32-bit working background channel from an ncplane.
static inline uint32_t static inline uint32_t
ncplane_bchannel(const struct ncplane* n){ ncplane_bchannel(const struct ncplane* n){

View File

@ -162,7 +162,7 @@ int fallin_demo(struct notcurses* nc){
if(ncplane_putc_yx(n, usey - y, usex - x, &c) < 0){ if(ncplane_putc_yx(n, usey - y, usex - x, &c) < 0){
// allow a fail if we were printing a wide char to the // allow a fail if we were printing a wide char to the
// last column of our plane // last column of our plane
if(!cell_double_wide_p(&c) || usex + 1 < x + newx){ if(!nccell_double_wide_p(&c) || usex + 1 < x + newx){
nccell_release(n, &c); nccell_release(n, &c);
goto err; goto err;
} }

View File

@ -26622,15 +26622,15 @@ int jungle_demo(struct notcurses* nc){
for(size_t x = 1 ; x < ORIGWIDTH ; x += xiter){ for(size_t x = 1 ; x < ORIGWIDTH ; x += xiter){
int idx = y * ORIGWIDTH + x; int idx = y * ORIGWIDTH + x;
int idx2 = (y + yiter) * ORIGWIDTH + x; int idx2 = (y + yiter) * ORIGWIDTH + x;
if(cell_set_fg_palindex(&c, buf[idx])){ if(nccell_set_fg_palindex(&c, buf[idx])){
return -1; return -1;
} }
if(y + yiter < ORIGHEIGHT){ if(y + yiter < ORIGHEIGHT){
if(cell_set_bg_palindex(&c, buf[idx2])){ if(nccell_set_bg_palindex(&c, buf[idx2])){
return -1; return -1;
} }
}else{ }else{
if(cell_set_bg_palindex(&c, 0)){ if(nccell_set_bg_palindex(&c, 0)){
return -1; return -1;
} }
} }

View File

@ -49,7 +49,7 @@ mathplane(struct notcurses* nc){
// the closer the coordinate is (lower distance), the more we lighten the cell // the closer the coordinate is (lower distance), the more we lighten the cell
static inline int static inline int
lighten(struct ncplane* n, nccell* 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 if(nccell_wide_right_p(c)){ // not really a character
return 0; return 0;
} }
unsigned r, g, b; unsigned r, g, b;

View File

@ -120,13 +120,13 @@ int ncplane_fadein_iteration(ncplane* n, ncfadectx* nctx, int iter,
unsigned br, bg, bb; unsigned br, bg, bb;
channels_bg_rgb8(nctx->channels[nctx->cols * y + x], &br, &bg, &bb); channels_bg_rgb8(nctx->channels[nctx->cols * y + x], &br, &bg, &bb);
nccell* c = &n->fb[dimx * y + x]; nccell* c = &n->fb[dimx * y + x];
if(!cell_fg_default_p(c)){ if(!nccell_fg_default_p(c)){
r = r * iter / nctx->maxsteps; r = r * iter / nctx->maxsteps;
g = g * iter / nctx->maxsteps; g = g * iter / nctx->maxsteps;
b = b * iter / nctx->maxsteps; b = b * iter / nctx->maxsteps;
nccell_set_fg_rgb8(c, r, g, b); nccell_set_fg_rgb8(c, r, g, b);
} }
if(!cell_bg_default_p(c)){ if(!nccell_bg_default_p(c)){
br = br * iter / nctx->maxsteps; br = br * iter / nctx->maxsteps;
bg = bg * iter / nctx->maxsteps; bg = bg * iter / nctx->maxsteps;
bb = bb * iter / nctx->maxsteps; bb = bb * iter / nctx->maxsteps;
@ -183,14 +183,14 @@ int ncplane_fadeout_iteration(ncplane* n, ncfadectx* nctx, int iter,
for(y = 0 ; y < nctx->rows && y < dimy ; ++y){ for(y = 0 ; y < nctx->rows && y < dimy ; ++y){
for(x = 0 ; x < nctx->cols && x < dimx; ++x){ for(x = 0 ; x < nctx->cols && x < dimx; ++x){
nccell* c = &n->fb[dimx * y + x]; nccell* c = &n->fb[dimx * y + x];
if(!cell_fg_default_p(c)){ if(!nccell_fg_default_p(c)){
channels_fg_rgb8(nctx->channels[nctx->cols * y + x], &r, &g, &b); channels_fg_rgb8(nctx->channels[nctx->cols * y + x], &r, &g, &b);
r = r * (nctx->maxsteps - iter) / nctx->maxsteps; r = r * (nctx->maxsteps - iter) / nctx->maxsteps;
g = g * (nctx->maxsteps - iter) / nctx->maxsteps; g = g * (nctx->maxsteps - iter) / nctx->maxsteps;
b = b * (nctx->maxsteps - iter) / nctx->maxsteps; b = b * (nctx->maxsteps - iter) / nctx->maxsteps;
nccell_set_fg_rgb8(c, r, g, b); nccell_set_fg_rgb8(c, r, g, b);
} }
if(!cell_bg_default_p(c)){ if(!nccell_bg_default_p(c)){
channels_bg_rgb8(nctx->channels[nctx->cols * y + x], &br, &bg, &bb); channels_bg_rgb8(nctx->channels[nctx->cols * y + x], &br, &bg, &bb);
br = br * (nctx->maxsteps - iter) / nctx->maxsteps; br = br * (nctx->maxsteps - iter) / nctx->maxsteps;
bg = bg * (nctx->maxsteps - iter) / nctx->maxsteps; bg = bg * (nctx->maxsteps - iter) / nctx->maxsteps;
@ -200,14 +200,14 @@ int ncplane_fadeout_iteration(ncplane* n, ncfadectx* nctx, int iter,
} }
} }
nccell* c = &n->basecell; nccell* c = &n->basecell;
if(!cell_fg_default_p(c)){ if(!nccell_fg_default_p(c)){
channels_fg_rgb8(nctx->channels[nctx->cols * y], &r, &g, &b); channels_fg_rgb8(nctx->channels[nctx->cols * y], &r, &g, &b);
r = r * (nctx->maxsteps - iter) / nctx->maxsteps; r = r * (nctx->maxsteps - iter) / nctx->maxsteps;
g = g * (nctx->maxsteps - iter) / nctx->maxsteps; g = g * (nctx->maxsteps - iter) / nctx->maxsteps;
b = b * (nctx->maxsteps - iter) / nctx->maxsteps; b = b * (nctx->maxsteps - iter) / nctx->maxsteps;
nccell_set_fg_rgb8(&n->basecell, r, g, b); nccell_set_fg_rgb8(&n->basecell, r, g, b);
} }
if(!cell_bg_default_p(c)){ if(!nccell_bg_default_p(c)){
channels_bg_rgb8(nctx->channels[nctx->cols * y], &br, &bg, &bb); channels_bg_rgb8(nctx->channels[nctx->cols * y], &br, &bg, &bb);
br = br * (nctx->maxsteps - iter) / nctx->maxsteps; br = br * (nctx->maxsteps - iter) / nctx->maxsteps;
bg = bg * (nctx->maxsteps - iter) / nctx->maxsteps; bg = bg * (nctx->maxsteps - iter) / nctx->maxsteps;

View File

@ -1280,7 +1280,7 @@ int ncplane_set_bg_palindex(ncplane* n, int idx){
} }
int ncplane_set_base_cell(ncplane* ncp, const nccell* c){ int ncplane_set_base_cell(ncplane* ncp, const nccell* c){
if(cell_wide_right_p(c)){ if(nccell_wide_right_p(c)){
return -1; return -1;
} }
return nccell_duplicate(ncp, &ncp->basecell, c); return nccell_duplicate(ncp, &ncp->basecell, c);
@ -1475,7 +1475,7 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
// wide chars, totalling four columns. // wide chars, totalling four columns.
nccell* 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(n->x > 0){
if(cell_double_wide_p(targ)){ // replaced cell is half of a wide char if(nccell_double_wide_p(targ)){ // replaced cell is half of a wide char
nccell* sacrifice = targ->gcluster == 0 ? nccell* sacrifice = targ->gcluster == 0 ?
// right half will never be on the first column of a row // right half will never be on the first column of a row
&n->fb[nfbcellidx(n, n->y, n->x - 1)] : &n->fb[nfbcellidx(n, n->y, n->x - 1)] :
@ -1489,12 +1489,12 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
if(cell_load_direct(n, targ, egc, bytes, cols) < 0){ if(cell_load_direct(n, targ, egc, bytes, cols) < 0){
return -1; return -1;
} }
//fprintf(stderr, "%08x %016lx %c %d %d\n", targ->gcluster, targ->channels, cell_double_wide_p(targ) ? 'D' : 'd', bytes, cols); //fprintf(stderr, "%08x %016lx %c %d %d\n", targ->gcluster, targ->channels, nccell_double_wide_p(targ) ? 'D' : 'd', bytes, cols);
// must set our right hand sides wide, and check for further damage // must set our right hand sides wide, and check for further damage
++n->x; ++n->x;
for(int i = 1 ; i < cols ; ++i){ for(int i = 1 ; i < cols ; ++i){
nccell* candidate = &n->fb[nfbcellidx(n, n->y, n->x)]; nccell* candidate = &n->fb[nfbcellidx(n, n->y, n->x)];
if(cell_wide_left_p(candidate)){ if(nccell_wide_left_p(candidate)){
nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + 1)]); nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + 1)]);
} }
nccell_release(n, candidate); nccell_release(n, candidate);
@ -1507,7 +1507,7 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
} }
int ncplane_putc_yx(ncplane* n, int y, int x, const nccell* 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 int cols = nccell_double_wide_p(c) ? 2 : 1;
const char* egc = nccell_extended_gcluster(n, c); const char* egc = nccell_extended_gcluster(n, c);
return ncplane_put(n, y, x, egc, cols, c->stylemask, c->channels, strlen(egc)); return ncplane_put(n, y, x, egc, cols, c->stylemask, c->channels, strlen(egc));
} }

View File

@ -205,7 +205,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
struct crender* crender = &rvec[fbcellidx(absy, dstlenx, absx)]; struct crender* crender = &rvec[fbcellidx(absy, dstlenx, absx)];
//fprintf(stderr, "p: %p damaged: %u %d/%d\n", p, crender->s.damaged, y, x); //fprintf(stderr, "p: %p damaged: %u %d/%d\n", p, crender->s.damaged, y, x);
nccell* targc = &crender->c; nccell* targc = &crender->c;
if(cell_wide_right_p(targc)){ if(nccell_wide_right_p(targc)){
continue; continue;
} }
const nccell* vis = &p->fb[nfbcellidx(p, y, x)]; const nccell* vis = &p->fb[nfbcellidx(p, y, x)];
@ -218,17 +218,17 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
continue; continue;
} }
if(cell_fg_alpha(targc) > CELL_ALPHA_OPAQUE){ if(nccell_fg_alpha(targc) > CELL_ALPHA_OPAQUE){
vis = &p->fb[nfbcellidx(p, y, x)]; vis = &p->fb[nfbcellidx(p, y, x)];
if(cell_fg_default_p(vis)){ if(nccell_fg_default_p(vis)){
vis = &p->basecell; vis = &p->basecell;
} }
if(cell_fg_palindex_p(vis)){ if(nccell_fg_palindex_p(vis)){
if(cell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){ if(nccell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_fg_palindex(targc, cell_fg_palindex(vis)); nccell_set_fg_palindex(targc, nccell_fg_palindex(vis));
} }
}else{ }else{
if(cell_fg_alpha(vis) == CELL_ALPHA_HIGHCONTRAST){ if(nccell_fg_alpha(vis) == CELL_ALPHA_HIGHCONTRAST){
crender->s.highcontrast = true; crender->s.highcontrast = true;
crender->s.hcfgblends = crender->s.fgblends; crender->s.hcfgblends = crender->s.fgblends;
crender->hcfg = cell_fchannel(targc); crender->hcfg = cell_fchannel(targc);
@ -250,19 +250,19 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
// If it's transparent, it has no effect. Otherwise, update the // If it's transparent, it has no effect. Otherwise, update the
// background channel and balpha. // background channel and balpha.
// Evaluate the background first, in case we have HIGHCONTRAST fg text. // Evaluate the background first, in case we have HIGHCONTRAST fg text.
if(cell_bg_alpha(targc) > CELL_ALPHA_OPAQUE){ if(nccell_bg_alpha(targc) > CELL_ALPHA_OPAQUE){
vis = &p->fb[nfbcellidx(p, y, x)]; vis = &p->fb[nfbcellidx(p, y, x)];
// to be on the blitter stacking path, we need // to be on the blitter stacking path, we need
// 1) crender->s.blittedquads to be non-zero (we're below semigraphics) // 1) crender->s.blittedquads to be non-zero (we're below semigraphics)
// 2) cell_blittedquadrants(vis) to be non-zero (we're semigraphics) // 2) cell_blittedquadrants(vis) to be non-zero (we're semigraphics)
// 3) somewhere crender is 0, blittedquads is 1 (we're visible) // 3) somewhere crender is 0, blittedquads is 1 (we're visible)
if(!crender->s.blittedquads || !((~crender->s.blittedquads) & cell_blittedquadrants(vis))){ if(!crender->s.blittedquads || !((~crender->s.blittedquads) & cell_blittedquadrants(vis))){
if(cell_bg_default_p(vis)){ if(nccell_bg_default_p(vis)){
vis = &p->basecell; vis = &p->basecell;
} }
if(cell_bg_palindex_p(vis)){ if(nccell_bg_palindex_p(vis)){
if(cell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){ if(nccell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_bg_palindex(targc, cell_bg_palindex(vis)); nccell_set_bg_palindex(targc, nccell_bg_palindex(vis));
} }
}else{ }else{
unsigned bgblends = crender->s.bgblends; unsigned bgblends = crender->s.bgblends;
@ -270,12 +270,12 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
crender->s.bgblends = bgblends; crender->s.bgblends = bgblends;
} }
}else{ // use the local foreground; we're stacking blittings }else{ // use the local foreground; we're stacking blittings
if(cell_fg_default_p(vis)){ if(nccell_fg_default_p(vis)){
vis = &p->basecell; vis = &p->basecell;
} }
if(cell_fg_palindex_p(vis)){ if(nccell_fg_palindex_p(vis)){
if(cell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){ if(nccell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
cell_set_bg_palindex(targc, cell_fg_palindex(vis)); nccell_set_bg_palindex(targc, nccell_fg_palindex(vis));
} }
}else{ }else{
unsigned bgblends = crender->s.bgblends; unsigned bgblends = crender->s.bgblends;
@ -295,7 +295,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
// from cells underneath us. // from cells underneath us.
if(!crender->p){ if(!crender->p){
vis = &p->fb[nfbcellidx(p, y, x)]; vis = &p->fb[nfbcellidx(p, y, x)];
if(vis->gcluster == 0 && !cell_double_wide_p(vis)){ if(vis->gcluster == 0 && !nccell_double_wide_p(vis)){
vis = &p->basecell; vis = &p->basecell;
} }
// if the following is true, we're a real glyph, and not the right-hand // if the following is true, we're a real glyph, and not the right-hand
@ -307,7 +307,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
crender->s.blittedquads = cell_blittedquadrants(vis); crender->s.blittedquads = cell_blittedquadrants(vis);
// we can't plop down a wide glyph if the next cell is beyond the // we can't plop down a wide glyph if the next cell is beyond the
// screen, nor if we're bisected by a higher plane. // screen, nor if we're bisected by a higher plane.
if(cell_double_wide_p(vis)){ if(nccell_double_wide_p(vis)){
// are we on the last column of the real screen? if so, 0x20 us // are we on the last column of the real screen? if so, 0x20 us
if(absx >= dstlenx - 1){ if(absx >= dstlenx - 1){
targc->gcluster = htole(' '); targc->gcluster = htole(' ');
@ -326,7 +326,7 @@ paint(const ncplane* p, struct crender* rvec, int dstleny, int dstlenx,
targc->width = vis->width; targc->width = vis->width;
} }
crender->p = p; crender->p = p;
}else if(cell_wide_right_p(vis)){ }else if(nccell_wide_right_p(vis)){
crender->p = p; crender->p = p;
targc->width = 0; targc->width = 0;
} }
@ -352,15 +352,15 @@ init_rvec(struct crender* rvec, int totalcells){
// against the real background. // against the real background.
static inline void static inline void
lock_in_highcontrast(nccell* targc, struct crender* crender){ lock_in_highcontrast(nccell* targc, struct crender* crender){
if(cell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){ if(nccell_fg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
nccell_set_fg_default(targc); nccell_set_fg_default(targc);
} }
if(cell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){ if(nccell_bg_alpha(targc) == CELL_ALPHA_TRANSPARENT){
nccell_set_bg_default(targc); nccell_set_bg_default(targc);
} }
if(crender->s.highcontrast){ if(crender->s.highcontrast){
// highcontrast weighs the original at 1/4 and the contrast at 3/4 // highcontrast weighs the original at 1/4 and the contrast at 3/4
if(!cell_fg_default_p(targc)){ if(!nccell_fg_default_p(targc)){
unsigned fgblends = 3; unsigned fgblends = 3;
uint32_t fchan = cell_fchannel(targc); uint32_t fchan = cell_fchannel(targc);
uint32_t bchan = cell_bchannel(targc); uint32_t bchan = cell_bchannel(targc);
@ -387,7 +387,7 @@ postpaint_cell(nccell* lastframe, int dimx, struct crender* crender,
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc) > 0){ if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc) > 0){
//fprintf(stderr, "damaging due to cmp\n"); //fprintf(stderr, "damaging due to cmp\n");
crender->s.damaged = 1; crender->s.damaged = 1;
assert(!cell_wide_right_p(targc)); assert(!nccell_wide_right_p(targc));
const int width = targc->width; const int width = targc->width;
for(int i = 1 ; i < width ; ++i){ for(int i = 1 ; i < width ; ++i){
const ncplane* tmpp = crender->p; const ncplane* tmpp = crender->p;
@ -808,7 +808,7 @@ raster_defaults(notcurses* nc, bool fgdef, bool bgdef, FILE* out){
// these are unlikely, so we leave it uninlined // these are unlikely, so we leave it uninlined
static int static int
emit_fg_palindex(notcurses* nc, FILE* out, const nccell* srccell){ emit_fg_palindex(notcurses* nc, FILE* out, const nccell* srccell){
unsigned palfg = cell_fg_palindex(srccell); unsigned palfg = nccell_fg_palindex(srccell);
// we overload lastr for the palette index; both are 8 bits // we overload lastr for the palette index; both are 8 bits
if(nc->rstate.fgpalelidable && nc->rstate.lastr == palfg){ if(nc->rstate.fgpalelidable && nc->rstate.lastr == palfg){
++nc->stats.fgelisions; ++nc->stats.fgelisions;
@ -827,7 +827,7 @@ emit_fg_palindex(notcurses* nc, FILE* out, const nccell* srccell){
static int static int
emit_bg_palindex(notcurses* nc, FILE* out, const nccell* srccell){ emit_bg_palindex(notcurses* nc, FILE* out, const nccell* srccell){
unsigned palbg = cell_bg_palindex(srccell); unsigned palbg = nccell_bg_palindex(srccell);
if(nc->rstate.bgpalelidable && nc->rstate.lastbr == palbg){ if(nc->rstate.bgpalelidable && nc->rstate.lastbr == palbg){
++nc->stats.bgelisions; ++nc->stats.bgelisions;
}else{ }else{
@ -930,7 +930,7 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
// no need to emit a cell; what we rendered appears to already be // no need to emit a cell; what we rendered appears to already be
// here. no updates are performed to elision state nor lastframe. // here. no updates are performed to elision state nor lastframe.
++nc->stats.cellelisions; ++nc->stats.cellelisions;
if(cell_wide_left_p(srccell)){ if(nccell_wide_left_p(srccell)){
++x; ++x;
} }
}else if(phase != 0 || !rvec[damageidx].s.p_beats_sprixel){ }else if(phase != 0 || !rvec[damageidx].s.p_beats_sprixel){
@ -952,9 +952,9 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
// * we are a no-foreground glyph, and the previous was default background, or // * we are a no-foreground glyph, and the previous was default background, or
// * we are a no-background glyph, and the previous was default foreground // * we are a no-background glyph, and the previous was default foreground
bool nobackground = cell_nobackground_p(srccell); bool nobackground = cell_nobackground_p(srccell);
if((cell_fg_default_p(srccell)) || (!nobackground && cell_bg_default_p(srccell))){ if((nccell_fg_default_p(srccell)) || (!nobackground && nccell_bg_default_p(srccell))){
if(raster_defaults(nc, cell_fg_default_p(srccell), if(raster_defaults(nc, nccell_fg_default_p(srccell),
!nobackground && cell_bg_default_p(srccell), out)){ !nobackground && nccell_bg_default_p(srccell), out)){
return -1; return -1;
} }
} }
@ -962,11 +962,11 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
// non-default foreground set iff either: // non-default foreground set iff either:
// * the previous was non-default, and matches what we have now, or // * the previous was non-default, and matches what we have now, or
// * we are a no-foreground glyph (iswspace() is true) // * we are a no-foreground glyph (iswspace() is true)
if(cell_fg_palindex_p(srccell)){ // palette-indexed foreground if(nccell_fg_palindex_p(srccell)){ // palette-indexed foreground
if(emit_fg_palindex(nc, out, srccell)){ if(emit_fg_palindex(nc, out, srccell)){
return -1; return -1;
} }
}else if(!cell_fg_default_p(srccell)){ // rgb foreground }else if(!nccell_fg_default_p(srccell)){ // rgb foreground
nccell_fg_rgb8(srccell, &r, &g, &b); nccell_fg_rgb8(srccell, &r, &g, &b);
if(nc->rstate.fgelidable && nc->rstate.lastr == r && nc->rstate.lastg == g && nc->rstate.lastb == b){ if(nc->rstate.fgelidable && nc->rstate.lastr == r && nc->rstate.lastg == g && nc->rstate.lastb == b){
++nc->stats.fgelisions; ++nc->stats.fgelisions;
@ -987,11 +987,11 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){
// * the previous was non-default, and matches what we have now, or // * the previous was non-default, and matches what we have now, or
if(nobackground){ if(nobackground){
++nc->stats.bgelisions; ++nc->stats.bgelisions;
}else if(cell_bg_palindex_p(srccell)){ // palette-indexed background }else if(nccell_bg_palindex_p(srccell)){ // palette-indexed background
if(emit_bg_palindex(nc, out, srccell)){ if(emit_bg_palindex(nc, out, srccell)){
return -1; return -1;
} }
}else if(!cell_bg_default_p(srccell)){ // rgb background }else if(!nccell_bg_default_p(srccell)){ // rgb background
nccell_bg_rgb8(srccell, &br, &bg, &bb); nccell_bg_rgb8(srccell, &br, &bg, &bb);
if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){ if(nc->rstate.bgelidable && nc->rstate.lastbr == br && nc->rstate.lastbg == bg && nc->rstate.lastbb == bb){
++nc->stats.bgelisions; ++nc->stats.bgelisions;

View File

@ -353,7 +353,7 @@ query_sixel(tinfo* ti, int fd){
// perhaps the most lackadaisical response is that of st, which returns a // perhaps the most lackadaisical response is that of st, which returns a
// bare ESC[?6c (note no semicolon). this is equivalent to alacritty's // bare ESC[?6c (note no semicolon). this is equivalent to alacritty's
// return, both suggesting a VT102. alacritty's miraculous technicolor VT102 // return, both suggesting a VT102. alacritty's miraculous technicolor VT102
// can display sixel, but real VT102s can even reply to XTSMGRAPHICS, so we // can display sixel, but real VT102s don't even reply to XTSMGRAPHICS, so we
// detect VT102 + TERM including alacritty, and special-case that. // detect VT102 + TERM including alacritty, and special-case that.
// FIXME need unit tests on this // FIXME need unit tests on this
enum { enum {

View File

@ -125,13 +125,13 @@ TEST_CASE("Cell") {
CHECK(0 > nccell_set_fg_alpha(&c, -1)); CHECK(0 > nccell_set_fg_alpha(&c, -1));
CHECK(0 > nccell_set_fg_alpha(&c, 4)); CHECK(0 > nccell_set_fg_alpha(&c, 4));
CHECK(0 == nccell_set_fg_alpha(&c, CELL_ALPHA_OPAQUE)); CHECK(0 == nccell_set_fg_alpha(&c, CELL_ALPHA_OPAQUE));
CHECK(cell_fg_default_p(&c)); CHECK(nccell_fg_default_p(&c));
CHECK(cell_bg_default_p(&c)); CHECK(nccell_bg_default_p(&c));
CHECK(CELL_ALPHA_OPAQUE == cell_fg_alpha(&c)); CHECK(CELL_ALPHA_OPAQUE == nccell_fg_alpha(&c));
CHECK(0 == nccell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST)); CHECK(0 == nccell_set_fg_alpha(&c, CELL_ALPHA_HIGHCONTRAST));
CHECK(CELL_ALPHA_HIGHCONTRAST == cell_fg_alpha(&c)); CHECK(CELL_ALPHA_HIGHCONTRAST == nccell_fg_alpha(&c));
CHECK(!cell_fg_default_p(&c)); CHECK(!nccell_fg_default_p(&c));
CHECK(cell_bg_default_p(&c)); CHECK(nccell_bg_default_p(&c));
} }
SUBCASE("CellSetBGAlpha"){ SUBCASE("CellSetBGAlpha"){
@ -139,12 +139,12 @@ TEST_CASE("Cell") {
CHECK(0 > nccell_set_bg_alpha(&c, -1)); CHECK(0 > nccell_set_bg_alpha(&c, -1));
CHECK(0 > nccell_set_bg_alpha(&c, 4)); CHECK(0 > nccell_set_bg_alpha(&c, 4));
CHECK(0 == nccell_set_bg_alpha(&c, CELL_ALPHA_OPAQUE)); CHECK(0 == nccell_set_bg_alpha(&c, CELL_ALPHA_OPAQUE));
CHECK(CELL_ALPHA_OPAQUE == cell_bg_alpha(&c)); CHECK(CELL_ALPHA_OPAQUE == nccell_bg_alpha(&c));
CHECK(0 != nccell_set_bg_alpha(&c, CELL_ALPHA_HIGHCONTRAST)); CHECK(0 != nccell_set_bg_alpha(&c, CELL_ALPHA_HIGHCONTRAST));
CHECK(0 == nccell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT)); CHECK(0 == nccell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT));
CHECK(CELL_ALPHA_TRANSPARENT == cell_bg_alpha(&c)); CHECK(CELL_ALPHA_TRANSPARENT == nccell_bg_alpha(&c));
CHECK(cell_fg_default_p(&c)); CHECK(nccell_fg_default_p(&c));
CHECK(!cell_bg_default_p(&c)); CHECK(!nccell_bg_default_p(&c));
} }
// white on a black background ought be unmolested for highcontrast // white on a black background ought be unmolested for highcontrast

View File

@ -41,50 +41,50 @@ TEST_CASE("Palette256") {
// when we set a palette index, it ought change us from using default // when we set a palette index, it ought change us from using default
SUBCASE("FAttributes") { SUBCASE("FAttributes") {
nccell c = CELL_TRIVIAL_INITIALIZER; nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(cell_fg_default_p(&c)); CHECK(nccell_fg_default_p(&c));
nccell_set_fg_alpha(&c, CELL_ALPHA_TRANSPARENT); nccell_set_fg_alpha(&c, CELL_ALPHA_TRANSPARENT);
CHECK(0 == cell_set_fg_palindex(&c, 0x20)); CHECK(0 == nccell_set_fg_palindex(&c, 0x20));
CHECK(!cell_fg_default_p(&c)); CHECK(!nccell_fg_default_p(&c));
CHECK(cell_fg_palindex_p(&c)); CHECK(nccell_fg_palindex_p(&c));
CHECK(CELL_ALPHA_OPAQUE == cell_fg_alpha(&c)); CHECK(CELL_ALPHA_OPAQUE == nccell_fg_alpha(&c));
CHECK(0x20 == cell_fg_palindex(&c)); CHECK(0x20 == nccell_fg_palindex(&c));
} }
SUBCASE("BAttributes") { SUBCASE("BAttributes") {
nccell c = CELL_TRIVIAL_INITIALIZER; nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(cell_bg_default_p(&c)); CHECK(nccell_bg_default_p(&c));
nccell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT); nccell_set_bg_alpha(&c, CELL_ALPHA_TRANSPARENT);
CHECK(0 == cell_set_bg_palindex(&c, 0x20)); CHECK(0 == nccell_set_bg_palindex(&c, 0x20));
CHECK(!cell_bg_default_p(&c)); CHECK(!nccell_bg_default_p(&c));
CHECK(cell_bg_palindex_p(&c)); CHECK(nccell_bg_palindex_p(&c));
CHECK(CELL_ALPHA_OPAQUE == cell_bg_alpha(&c)); CHECK(CELL_ALPHA_OPAQUE == nccell_bg_alpha(&c));
CHECK(0x20 == cell_bg_palindex(&c)); CHECK(0x20 == nccell_bg_palindex(&c));
} }
// write it to an ncplane, and verify attributes via reflection // write it to an ncplane, and verify attributes via reflection
SUBCASE("PutCAttrs") { SUBCASE("PutCAttrs") {
nccell c = CELL_TRIVIAL_INITIALIZER; nccell c = CELL_TRIVIAL_INITIALIZER;
CHECK(1 == nccell_load_char(n_, &c, 'X')); CHECK(1 == nccell_load_char(n_, &c, 'X'));
CHECK(0 == cell_set_fg_palindex(&c, 0x20)); CHECK(0 == nccell_set_fg_palindex(&c, 0x20));
CHECK(0 == cell_set_bg_palindex(&c, 0x40)); CHECK(0 == nccell_set_bg_palindex(&c, 0x40));
CHECK(1 == ncplane_putc_yx(n_, 0, 0, &c)); CHECK(1 == ncplane_putc_yx(n_, 0, 0, &c));
nccell_release(n_, &c); nccell_release(n_, &c);
nccell r = CELL_TRIVIAL_INITIALIZER; nccell r = CELL_TRIVIAL_INITIALIZER;
CHECK(0 < ncplane_at_yx_cell(n_, 0, 0, &r)); CHECK(0 < ncplane_at_yx_cell(n_, 0, 0, &r));
CHECK(cell_fg_palindex_p(&r)); CHECK(nccell_fg_palindex_p(&r));
CHECK(cell_bg_palindex_p(&r)); CHECK(nccell_bg_palindex_p(&r));
CHECK(CELL_ALPHA_OPAQUE == cell_fg_alpha(&r)); CHECK(CELL_ALPHA_OPAQUE == nccell_fg_alpha(&r));
CHECK(CELL_ALPHA_OPAQUE == cell_bg_alpha(&r)); CHECK(CELL_ALPHA_OPAQUE == nccell_bg_alpha(&r));
CHECK(0x20 == cell_fg_palindex(&r)); CHECK(0x20 == nccell_fg_palindex(&r));
CHECK(0x40 == cell_bg_palindex(&r)); CHECK(0x40 == nccell_bg_palindex(&r));
nccell_release(n_, &r); nccell_release(n_, &r);
} }
SUBCASE("RenderCAttrs") { SUBCASE("RenderCAttrs") {
nccell c = CELL_TRIVIAL_INITIALIZER; nccell c = CELL_TRIVIAL_INITIALIZER;
nccell_load_char(n_, &c, 'X'); nccell_load_char(n_, &c, 'X');
CHECK(0 == cell_set_fg_palindex(&c, 0x20)); CHECK(0 == nccell_set_fg_palindex(&c, 0x20));
CHECK(0 == cell_set_bg_palindex(&c, 0x40)); CHECK(0 == nccell_set_bg_palindex(&c, 0x40));
CHECK(0 == ncplane_set_fg_palindex(n_, 0x20)); CHECK(0 == ncplane_set_fg_palindex(n_, 0x20));
CHECK(0 == ncplane_set_bg_palindex(n_, 0x40)); CHECK(0 == ncplane_set_bg_palindex(n_, 0x40));
CHECK(0 < ncplane_putc_yx(n_, 0, 0, &c)); CHECK(0 < ncplane_putc_yx(n_, 0, 0, &c));
@ -92,12 +92,12 @@ TEST_CASE("Palette256") {
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
nccell r = CELL_TRIVIAL_INITIALIZER; nccell r = CELL_TRIVIAL_INITIALIZER;
CHECK(nullptr != notcurses_at_yx(nc_, 0, 0, &r.stylemask, &r.channels)); CHECK(nullptr != notcurses_at_yx(nc_, 0, 0, &r.stylemask, &r.channels));
CHECK(cell_fg_palindex_p(&r)); CHECK(nccell_fg_palindex_p(&r));
CHECK(cell_bg_palindex_p(&r)); CHECK(nccell_bg_palindex_p(&r));
CHECK(CELL_ALPHA_OPAQUE == cell_fg_alpha(&r)); CHECK(CELL_ALPHA_OPAQUE == nccell_fg_alpha(&r));
CHECK(CELL_ALPHA_OPAQUE == cell_bg_alpha(&r)); CHECK(CELL_ALPHA_OPAQUE == nccell_bg_alpha(&r));
CHECK(0x20 == cell_fg_palindex(&r)); CHECK(0x20 == nccell_fg_palindex(&r));
CHECK(0x40 == cell_bg_palindex(&r)); CHECK(0x40 == nccell_bg_palindex(&r));
nccell_release(n_, &r); nccell_release(n_, &r);
} }

View File

@ -362,8 +362,8 @@ TEST_CASE("Plane") {
REQUIRE(0 < u2); REQUIRE(0 < u2);
REQUIRE(strlen(w1) == u1); REQUIRE(strlen(w1) == u1);
REQUIRE(strlen(w2) == u2); REQUIRE(strlen(w2) == u2);
CHECK(ncstrwidth(w1) == 1 + cell_double_wide_p(&c1)); CHECK(ncstrwidth(w1) == 1 + nccell_double_wide_p(&c1));
CHECK_FALSE(cell_double_wide_p(&c2)); CHECK_FALSE(nccell_double_wide_p(&c2));
nccell_release(n_, &c1); nccell_release(n_, &c1);
nccell_release(n_, &c2); nccell_release(n_, &c2);
} }

View File

@ -125,13 +125,13 @@ TEST_CASE("Wide") {
ncplane_at_yx_cell(n_, 0, 0, &c); ncplane_at_yx_cell(n_, 0, 0, &c);
CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), FROG)); CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), FROG));
ncplane_at_yx_cell(n_, 0, 1, &c); ncplane_at_yx_cell(n_, 0, 1, &c);
CHECK(ncstrwidth(FROG) == 1 + cell_double_wide_p(&c)); // should be wide CHECK(ncstrwidth(FROG) == 1 + nccell_double_wide_p(&c)); // should be wide
ncplane_at_yx_cell(n_, 0, 2, &c); ncplane_at_yx_cell(n_, 0, 2, &c);
CHECK(0 == strlen(nccell_extended_gcluster(n_, &c))); // should be nothing CHECK(0 == strlen(nccell_extended_gcluster(n_, &c))); // should be nothing
ncplane_at_yx_cell(n_, 1, 0, &c); ncplane_at_yx_cell(n_, 1, 0, &c);
CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), FROG)); CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), FROG));
ncplane_at_yx_cell(n_, 1, 1, &c); ncplane_at_yx_cell(n_, 1, 1, &c);
CHECK(ncstrwidth(FROG) == 1 + cell_double_wide_p(&c)); //should be wide CHECK(ncstrwidth(FROG) == 1 + nccell_double_wide_p(&c)); //should be wide
CHECK(0 == notcurses_render(nc_)); // should be nothing CHECK(0 == notcurses_render(nc_)); // should be nothing
} }
@ -157,7 +157,7 @@ TEST_CASE("Wide") {
ncplane_at_yx_cell(n_, 0, 1, &c); ncplane_at_yx_cell(n_, 0, 1, &c);
CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), SNAKE)); CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), SNAKE));
ncplane_at_yx_cell(n_, 0, 2, &c); ncplane_at_yx_cell(n_, 0, 2, &c);
CHECK(ncstrwidth(SNAKE) == 1 + cell_double_wide_p(&c)); // should be wide CHECK(ncstrwidth(SNAKE) == 1 + nccell_double_wide_p(&c)); // should be wide
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
} }
@ -210,13 +210,13 @@ TEST_CASE("Wide") {
ncplane_at_yx_cell(n_, 0, 0, &c); ncplane_at_yx_cell(n_, 0, 0, &c);
CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), SNAKE)); CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), SNAKE));
ncplane_at_yx_cell(n_, 0, 1, &c); ncplane_at_yx_cell(n_, 0, 1, &c);
CHECK(ncstrwidth(SNAKE) == 1 + cell_double_wide_p(&c)); CHECK(ncstrwidth(SNAKE) == 1 + nccell_double_wide_p(&c));
ncplane_at_yx_cell(n_, 0, 2, &c); ncplane_at_yx_cell(n_, 0, 2, &c);
CHECK(0 == strcmp(cc, nccell_extended_gcluster(n_, &c))); // should be 'X' CHECK(0 == strcmp(cc, nccell_extended_gcluster(n_, &c))); // should be 'X'
ncplane_at_yx_cell(n_, 0, 3, &c); ncplane_at_yx_cell(n_, 0, 3, &c);
CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), SCORPION)); CHECK(0 == strcmp(nccell_extended_gcluster(n_, &c), SCORPION));
ncplane_at_yx_cell(n_, 0, 4, &c); ncplane_at_yx_cell(n_, 0, 4, &c);
CHECK(ncstrwidth(SCORPION) == 1 + cell_double_wide_p(&c)); CHECK(ncstrwidth(SCORPION) == 1 + nccell_double_wide_p(&c));
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
} }
@ -261,15 +261,15 @@ TEST_CASE("Wide") {
CHECK(0 <= ncplane_putstr(n_, "\u5f62\u5168")); CHECK(0 <= ncplane_putstr(n_, "\u5f62\u5168"));
nccell c = CELL_TRIVIAL_INITIALIZER; nccell c = CELL_TRIVIAL_INITIALIZER;
ncplane_at_yx_cell(n_, 0, 0, &c); ncplane_at_yx_cell(n_, 0, 0, &c);
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
ncplane_at_yx_cell(n_, 0, 1, &c); ncplane_at_yx_cell(n_, 0, 1, &c);
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
ncplane_at_yx_cell(n_, 0, 2, &c); ncplane_at_yx_cell(n_, 0, 2, &c);
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
ncplane_at_yx_cell(n_, 0, 3, &c); ncplane_at_yx_cell(n_, 0, 3, &c);
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
ncplane_at_yx_cell(n_, 0, 4, &c); ncplane_at_yx_cell(n_, 0, 4, &c);
CHECK(!cell_double_wide_p(&c)); CHECK(!nccell_double_wide_p(&c));
CHECK(0 == notcurses_render(nc_)); CHECK(0 == notcurses_render(nc_));
auto egc = notcurses_at_yx(nc_, 0, 0, &c.stylemask, &c.channels); auto egc = notcurses_at_yx(nc_, 0, 0, &c.stylemask, &c.channels);
REQUIRE(nullptr != egc); REQUIRE(nullptr != egc);
@ -310,42 +310,42 @@ TEST_CASE("Wide") {
// should be wide char 1 // should be wide char 1
CHECK(3 == ncplane_at_yx_cell(n_, 0, 0, &c)); CHECK(3 == ncplane_at_yx_cell(n_, 0, 0, &c));
CHECK(!strcmp("\xe5\x85\xa8", nccell_extended_gcluster(n_, &c))); CHECK(!strcmp("\xe5\x85\xa8", nccell_extended_gcluster(n_, &c)));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
egc = notcurses_at_yx(nc_, 0, 0, &c.stylemask, &c.channels); egc = notcurses_at_yx(nc_, 0, 0, &c.stylemask, &c.channels);
REQUIRE(egc); REQUIRE(egc);
CHECK(!strcmp("\xe5\x85\xa8", egc)); CHECK(!strcmp("\xe5\x85\xa8", egc));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
free(egc); free(egc);
nccell_init(&c); nccell_init(&c);
// should be wide char 1 right side // should be wide char 1 right side
REQUIRE(0 == ncplane_at_yx_cell(n_, 0, 1, &c)); REQUIRE(0 == ncplane_at_yx_cell(n_, 0, 1, &c));
CHECK(!strcmp("", nccell_extended_gcluster(n_, &c))); CHECK(!strcmp("", nccell_extended_gcluster(n_, &c)));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
egc = notcurses_at_yx(nc_, 0, 1, &c.stylemask, &c.channels); egc = notcurses_at_yx(nc_, 0, 1, &c.stylemask, &c.channels);
REQUIRE(egc); REQUIRE(egc);
CHECK(!strcmp("", egc)); CHECK(!strcmp("", egc));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
free(egc); free(egc);
nccell_init(&c); nccell_init(&c);
// should be wide char 2 // should be wide char 2
REQUIRE(3 == ncplane_at_yx_cell(n_, 0, 2, &c)); REQUIRE(3 == ncplane_at_yx_cell(n_, 0, 2, &c));
CHECK(!strcmp("\xe5\xbd\xa2", nccell_extended_gcluster(n_, &c))); CHECK(!strcmp("\xe5\xbd\xa2", nccell_extended_gcluster(n_, &c)));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
egc = notcurses_at_yx(nc_, 0, 2, &c.stylemask, &c.channels); egc = notcurses_at_yx(nc_, 0, 2, &c.stylemask, &c.channels);
REQUIRE(egc); REQUIRE(egc);
CHECK(!strcmp("\xe5\xbd\xa2", egc)); CHECK(!strcmp("\xe5\xbd\xa2", egc));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
free(egc); free(egc);
nccell_init(&c); nccell_init(&c);
// should be wide char 2 right side // should be wide char 2 right side
CHECK(0 == ncplane_at_yx_cell(n_, 0, 3, &c)); CHECK(0 == ncplane_at_yx_cell(n_, 0, 3, &c));
CHECK(!strcmp("", nccell_extended_gcluster(n_, &c))); CHECK(!strcmp("", nccell_extended_gcluster(n_, &c)));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
egc = notcurses_at_yx(nc_, 0, 3, &c.stylemask, &c.channels); egc = notcurses_at_yx(nc_, 0, 3, &c.stylemask, &c.channels);
REQUIRE(egc); REQUIRE(egc);
CHECK(!strcmp("", egc)); CHECK(!strcmp("", egc));
CHECK(cell_double_wide_p(&c)); CHECK(nccell_double_wide_p(&c));
free(egc); free(egc);
nccell_init(&c); nccell_init(&c);