From af07822d35039904a8e2ac86c0f5fd71a8c9f4c6 Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 2 Jan 2021 02:56:17 -0500 Subject: [PATCH] Document base cell better Improve the documentation for ncplane_set_base_cell() and ncplane_set_base(). Go by render.c's authority (all three channels are independently checked for transparency, and replaced with the base cell if so--egc, fg, and bg). Add a BASE CELL section to notcurses_plane.3. Check for, and reject, an nccell which is secondary among a multicolumn EGC. Closes #1238. --- USAGE.md | 20 ++++++++++---------- doc/man/man3/notcurses_plane.3.md | 15 +++++++++++++++ include/notcurses/notcurses.h | 14 +++++++------- src/lib/notcurses.c | 3 +++ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/USAGE.md b/USAGE.md index 31ff24022..32554c6e0 100644 --- a/USAGE.md +++ b/USAGE.md @@ -858,17 +858,17 @@ void ncplane_on_styles(struct ncplane* n, unsigned stylebits); // Remove the specified styles from the ncplane's existing spec. 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 nccell* c); +// Set the ncplane's base nccell to 'c'. The base cell is used for purposes of +// rendering anywhere that the ncplane's gcluster is 0. Note that the base cell +// is not affected by ncplane_erase(). 'c' must not be a secondary cell from a +// multicolumn EGC. +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 -// 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. -int ncplane_set_base(struct ncplane* ncp, const char* egc, - uint32_t styles, uint64_t channels); +// Set the ncplane's base nccell. It will be used for purposes of rendering +// anywhere that the ncplane's gcluster is 0. Note that the base cell is not +// affected by ncplane_erase(). 'egc' must be an extended grapheme cluster. +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 // 'ncp' is destroyed. diff --git a/doc/man/man3/notcurses_plane.3.md b/doc/man/man3/notcurses_plane.3.md index db3badfc0..dcf370792 100644 --- a/doc/man/man3/notcurses_plane.3.md +++ b/doc/man/man3/notcurses_plane.3.md @@ -253,6 +253,21 @@ invoked following resizing of its parent's plane. If it returns non-zero, the resizing cascade terminates, returning non-zero. Otherwise, resizing proceeds recursively. +## Base cells + +Each plane has a base cell, initialized to all zeroes. When rendering, the +cells of the plane are examined in turn. Each cell has three independent +rendering elements--its EGC, its foreground channel, and its background +channel. Any default channel is replaced with the corresponding channel from +that plane's base cell. **ncplane_erase** has no effect on the base cell. +Calling **ncplane_erase** on a plane whose base cell is a purple 'A' results +(for rendering purposes) in a plane made up entirely of purple 'A's. + +**ncplane_set_base_cell** uses the **nccell** ***c*** (which must be bound to +the **ncplane** ***ncp***, and must be the first **nccell** of a multicolumn +sequence) to set the base cell. **ncplane_set_base** does the same with +***egc***, ***stylemask***, and ***channels***. + ## Piles A single **notcurses** context is made up of one or more piles. A pile is a diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index e8974dad3..e8f78fade 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -1276,15 +1276,15 @@ 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 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'. +// Set the ncplane's base nccell to 'c'. The base cell is used for purposes of +// rendering anywhere that the ncplane's gcluster is 0. Note that the base cell +// is not affected by ncplane_erase(). 'c' must not be a secondary cell from a +// multicolumn EGC. API int ncplane_set_base_cell(struct ncplane* n, const nccell* c); -// 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. +// Set the ncplane's base nccell. It will be used for purposes of rendering +// anywhere that the ncplane's gcluster is 0. Note that the base cell is not +// affected by ncplane_erase(). 'egc' must be an extended grapheme cluster. API int ncplane_set_base(struct ncplane* n, const char* egc, uint32_t stylemask, uint64_t channels); diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 7bc8adf73..41d14eff4 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1390,6 +1390,9 @@ int ncplane_set_bg_palindex(ncplane* n, int idx){ } int ncplane_set_base_cell(ncplane* ncp, const nccell* c){ + if(cell_wide_right_p(c)){ + return -1; + } return cell_duplicate(ncp, &ncp->basecell, c); }