diff --git a/USAGE.md b/USAGE.md index c6b1b19c8..217b7ff0d 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1854,6 +1854,9 @@ int nccell_duplicate(struct ncplane* n, nccell* targ, const cell* c); // Release resources held by the cell 'c'. void nccell_release(struct ncplane* n, nccell* c); +// Get the number of columns occupied by 'c'. +int nccell_width(const struct ncplane* n, const nccell* c); + #define NCSTYLE_MASK 0x03fful #define NCSTYLE_STANDOUT 0x0080ul #define NCSTYLE_UNDERLINE 0x0040ul diff --git a/doc/man/man3/notcurses_cell.3.md b/doc/man/man3/notcurses_cell.3.md index dd442ce52..0fd35efd2 100644 --- a/doc/man/man3/notcurses_cell.3.md +++ b/doc/man/man3/notcurses_cell.3.md @@ -51,6 +51,8 @@ typedef struct nccell { **void nccell_release(struct ncplane* ***n***, nccell* ***c***);** +**int nccell_width(const struct ncplane* ***n***, const nccell* ***c***);** + **void nccell_styles_set(nccell* ***c***, unsigned ***stylebits***);** **unsigned nccell_styles(const nccell* ***c***);** @@ -160,6 +162,9 @@ less than, equal to, or more than ***c2***, respectively. **nccell_extended_gcluster** returns **NULL** if called on a sprixel (see **notcurses_visual(3)**. +**nccell_width** returns the number of columns occupied by ***c***, according +to **wcwidth(3)***. **ncstrwidth** is an equivalent for strings. + # NOTES **cell** was renamed to **nccell** in Notcurses 2.2.0, so as not to bleed such @@ -173,4 +178,5 @@ have been renamed to start with **nccell**. **notcurses_channels(3)**, **notcurses_plane(3)**, **notcurses_output(3)**, -**notcurses_visual(3)** +**notcurses_visual(3)**, +**wcwidth(3)** diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 65ae2960d..d74852022 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -749,6 +749,10 @@ nccell_wide_left_p(const nccell* c){ // returns NULL if called on a pixel graphic. API const char* nccell_extended_gcluster(const struct ncplane* n, const nccell* c); +// return the number of columns occupied by 'c'. returns -1 if passed a +// sprixcell. see ncstrwidth() for an equivalent for multiple EGCs. +API int nccell_width(const struct ncplane* n, const nccell* c); + // copy the UTF8-encoded EGC out of the nccell. the result is not tied to any // ncplane, and persists across erases / destruction. ALLOC static inline char* diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 55f64ef07..ef254930c 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1450,6 +1450,16 @@ void scroll_down(ncplane* n){ } } +int nccell_width(const ncplane* n, const nccell* c){ + const char* egc = nccell_extended_gcluster(n, c); + if(egc == NULL){ + return -1; + } + int cols; + utf8_egc_len(egc, &cols); + return cols; +} + int nccell_load(ncplane* n, nccell* c, const char* gcluster){ int cols; int bytes = utf8_egc_len(gcluster, &cols);