1% notcurses_plane(3) 2% nick black <nickblack@linux.com> 3% v3.0.1 4 5# NAME 6 7notcurses_plane - operations on ncplanes 8 9# SYNOPSIS 10 11**#include <notcurses/notcurses.h>** 12 13```c 14#define NCPLANE_OPTION_HORALIGNED 0x0001ull 15#define NCPLANE_OPTION_VERALIGNED 0x0002ull 16#define NCPLANE_OPTION_MARGINALIZED 0x0004ull 17#define NCPLANE_OPTION_FIXED 0x0008ull 18#define NCPLANE_OPTION_AUTOGROW 0x0010ull 19#define NCPLANE_OPTION_VSCROLL 0x0020ull 20 21typedef struct ncplane_options { 22 int y; // vertical placement relative to parent plane 23 int x; // horizontal placement relative to parent plane 24 int rows; // number of rows, must be positive 25 int cols; // number of columns, must be positive 26 void* userptr; // user curry, may be NULL 27 const char* name; // name (used only for debugging), may be NULL 28 int (*resizecb)(struct ncplane*); // called on parent resize 29 uint64_t flags; // closure over NCPLANE_OPTION_* 30 unsigned margin_b, margin_r; // bottom and right margins 31} ncplane_options; 32 33#define NCSTYLE_MASK 0xffffu 34#define NCSTYLE_ITALIC 0x0010u 35#define NCSTYLE_UNDERLINE 0x0008u 36#define NCSTYLE_UNDERCURL 0x0004u 37#define NCSTYLE_BOLD 0x0002u 38#define NCSTYLE_STRUCK 0x0001u 39#define NCSTYLE_NONE 0 40``` 41 42**struct ncplane* ncplane_create(struct ncplane* ***n***, const ncplane_options* ***nopts***);** 43 44**struct ncplane* ncpile_create(struct notcurses* ***n***, const ncplane_options* ***nopts***);** 45 46**struct ncplane* ncplane_reparent(struct ncplane* ***n***, struct ncplane* ***newparent***);** 47 48**struct ncplane* ncplane_reparent_family(struct ncplane* ***n***, struct ncplane* ***newparent***);** 49 50**int ncplane_descendant_p(const struct ncplane* ***n***, const struct ncplane* ***ancestor***);** 51 52**int ncplane_resize_realign(struct ncplane* ***n***);** 53 54**int ncplane_resize_maximize(struct ncplane* ***n***);** 55 56**int ncplane_resize_marginalized(struct ncplane* ***n***);** 57 58**int ncplane_resize_placewithin(struct ncplane* ***n***);** 59 60**void ncplane_set_resizecb(struct ncplane* ***n***, int(*resizecb)(struct ncplane*));** 61 62**int (*ncplane_resizecb(const struct ncplane* ***n***))(struct ncplane*);** 63 64**struct ncplane* ncplane_dup(struct ncplane* ***n***, void* ***opaque***);** 65 66**int ncplane_resize(struct ncplane* ***n***, int ***keepy***, int ***keepx***, int ***keepleny***, int ***keeplenx***, int ***yoff***, int ***xoff***, int ***ylen***, int ***xlen***);** 67 68**int ncplane_move_yx(struct ncplane* ***n***, int ***y***, int ***x***);** 69 70**int ncplane_move_rel(struct ncplane* ***n***, int ***y***, int ***x***);** 71 72**void ncplane_yx(const struct ncplane* ***n***, int* restrict ***y***, int* restrict ***x***);** 73 74**int ncplane_y(const struct ncplane* ***n***);** 75 76**int ncplane_x(const struct ncplane* ***n***);** 77 78**void ncplane_abs_yx(const struct ncplane* ***n***, int* ***y***, int* ***x***);** 79 80**int ncplane_abs_y(const struct ncplane* ***n***);** 81 82**int ncplane_abs_x(const struct ncplane* ***n***);** 83 84**struct ncplane* ncplane_parent(struct ncplane* ***n***);** 85 86**const struct ncplane* ncplane_parent_const(const struct ncplane* ***n***);** 87 88**int ncplane_set_base_cell(struct ncplane* ***ncp***, const nccell* ***c***);** 89 90**int ncplane_set_base(struct ncplane* ***ncp***, const char* ***egc***, uint16_t ***stylemask***, uint64_t ***channels***);** 91 92**int ncplane_base(struct ncplane* ***ncp***, nccell* ***c***);** 93 94**static inline void ncplane_move_top(struct ncplane* ***n***);** 95 96**static inline void ncplane_move_bottom(struct ncplane* ***n***);** 97 98**void ncplane_move_family_top(struct ncplane* ***n***);** 99 100**void ncplane_move_family_bottom(struct ncplane* ***n***);** 101 102**int ncplane_move_above(struct ncplane* restrict ***n***, struct ncplane* restrict ***targ***);** 103 104**int ncplane_move_below(struct ncplane* restrict ***n***, struct ncplane* restrict ***targ***);** 105 106**int ncplane_move_family_above(struct ncplane* restrict ***n***, struct ncplane* restrict ***targ***);** 107 108**int ncplane_move_family_below(struct ncplane* restrict ***n***, struct ncplane* restrict ***targ***);** 109 110**struct ncplane* ncplane_below(struct ncplane* ***n***);** 111 112**struct ncplane* ncplane_above(struct ncplane* ***n***);** 113 114**char* ncplane_at_cursor(struct ncplane* ***n***, uint16_t* ***stylemask***, uint64_t* ***channels***);** 115 116**int ncplane_at_cursor_cell(struct ncplane* ***n***, nccell* ***c***);** 117 118**char* ncplane_at_yx(const struct ncplane* ***n***, int ***y***, int ***x***, uint16_t* ***stylemask***, uint64_t* ***channels***);** 119 120**int ncplane_at_yx_cell(struct ncplane* ***n***, int ***y***, int ***x***, nccell* ***c***);** 121 122**uint32_t* ncplane_as_rgba(const struct ncplane* ***nc***, ncblitter_e ***blit***, unsigned ***begy***, unsigned ***begx***, unsigned ***leny***, unsigned ***lenx***, unsigned* ***pxdimy***, unsigned* ***pxdimx***);** 123 124**char* ncplane_contents(const struct ncplane* ***nc***, int ***begy***, int ***begx***, unsigned ***leny***, unsigned ***lenx***);** 125 126**void* ncplane_set_userptr(struct ncplane* ***n***, void* ***opaque***);** 127 128**void* ncplane_userptr(struct ncplane* ***n***);** 129 130**void ncplane_dim_yx(const struct ncplane* ***n***, unsigned* restrict ***rows***, unsigned* restrict ***cols***);** 131 132**static inline unsigned ncplane_dim_y(const struct ncplane* ***n***);** 133 134**static inline unsigned ncplane_dim_x(const struct ncplane* ***n***);** 135 136**void ncplane_cursor_yx(const struct ncplane* ***n***, unsigned* restrict ***y***, unsigned* restrict ***x***);** 137 138**void ncplane_translate(const struct ncplane* ***src***, const struct ncplane* ***dst***, int* restrict ***y***, int* restrict ***x***);** 139 140**bool ncplane_translate_abs(const struct ncplane* ***n***, int* restrict ***y***, int* restrict ***x***);** 141 142**uint64_t ncplane_channels(const struct ncplane* ***n***);** 143 144**void ncplane_set_channels(struct ncplane* ***nc***, uint64_t ***channels***);** 145 146**static inline unsigned ncplane_bchannel(struct ncplane* ***nc***);** 147 148**static inline unsigned ncplane_fchannel(struct ncplane* ***nc***);** 149 150**static inline unsigned ncplane_fg_rgb8(struct ncplane* ***nc***);** 151 152**static inline unsigned ncplane_bg_rgb8(struct ncplane* ***nc***);** 153 154**static inline unsigned ncplane_fg_alpha(struct ncplane* ***nc***);** 155 156**static inline unsigned ncplane_bg_alpha(struct ncplane* ***nc***);** 157 158**static inline unsigned ncplane_fg_rgb8(struct ncplane* ***n***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);** 159 160**static inline unsigned ncplane_bg_rgb8(struct ncplane* ***n***, unsigned* ***r***, unsigned* ***g***, unsigned* ***b***);** 161 162**int ncplane_set_fg_rgb8(struct ncplane* ***n***, unsigned ***r***, unsigned ***g***, unsigned ***b***);** 163 164**int ncplane_set_bg_rgb8(struct ncplane* ***n***, unsigned ***r***, unsigned ***g***, unsigned ***b***);** 165 166**void ncplane_set_fg_rgb8_clipped(struct ncplane* ***n***, int ***r***, int ***g***, int ***b***);** 167 168**void ncplane_set_bg_rgb8_clipped(struct ncplane* ***n***, int ***r***, int ***g***, int ***b***);** 169 170**int ncplane_set_fg_rgb8(struct ncplane* ***n***, uint32_t ***channel***);** 171 172**int ncplane_set_bg_rgb8(struct ncplane* ***n***, uint32_t ***channel***);** 173 174**void ncplane_set_fg_default(struct ncplane* ***n***);** 175 176**void ncplane_set_bg_default(struct ncplane* ***n***);** 177 178**int ncplane_set_fg_alpha(struct ncplane* ***n***, unsigned ***alpha***);** 179 180**int ncplane_set_bg_alpha(struct ncplane* ***n***, unsigned ***alpha***);** 181 182**int ncplane_set_fg_palindex(struct ncplane* ***n***, int ***idx***);** 183 184**int ncplane_set_bg_palindex(struct ncplane* ***n***, int ***idx***);** 185 186**uint16_t ncplane_styles(const struct ncplane* ***n***);** 187 188**void ncplane_set_styles(struct ncplane* ***n***, unsigned ***stylebits***);** 189 190**void ncplane_on_styles(struct ncplane* ***n***, unsigned ***stylebits***);** 191 192**void ncplane_off_styles(struct ncplane* ***n***, unsigned ***stylebits***);** 193 194**void ncplane_greyscale(struct ncplane* ***n***);** 195 196**int ncplane_blit_bgrx(struct ncplane* ***nc***, int ***placey***, int ***placex***, int ***linesize***, ncblitter_e ***blitter***, const unsigned char* ***data***, int ***begy***, int ***begx***, int ***leny***, int ***lenx***);** 197 198**int ncplane_blit_rgba(struct ncplane* ***nc***, int ***placey***, int ***placex***, int ***linesize***, ncblitter_e ***blitter***, const unsigned char* ***data***, int ***begy***, int ***begx***, int ***leny***, int ***lenx***);** 199 200**int ncplane_destroy(struct ncplane* ***ncp***);** 201 202**void notcurses_drop_planes(struct notcurses* ***nc***);** 203 204**int ncplane_mergedown(struct ncplane* ***src***, struct ncplane* ***dst***, int ***begsrcy***, int ***begsrcx***, unsigned ***leny***, unsigned ***lenx***, int ***dsty***, int ***dstx***);** 205 206**int ncplane_mergedown_simple(struct ncplane* restrict ***src***, struct ncplane* restrict ***dst***);** 207 208**void ncplane_erase(struct ncplane* ***n***);** 209 210**int ncplane_erase_region(struct ncplane* ***n***, int ***ystart***, int ***xstart***, int ***ylen***, int ***xlen***);** 211 212**bool ncplane_set_scrolling(struct ncplane* ***n***, unsigned ***scrollp***);** 213 214**bool ncplane_scrolling_p(const struct ncplane* ***n***);** 215 216**bool ncplane_set_autogrow(struct ncplane* ***n***, unsigned ***growp***);** 217 218**bool ncplane_autogrow_p(const struct ncplane* ***n***);** 219 220**int ncplane_scrollup(struct ncplane* ***n***, int ***r***);** 221 222**int ncplane_scrollup_child(struct ncplane* ***n***, const struct ncplane* ***child***);** 223 224**int ncplane_rotate_cw(struct ncplane* ***n***);** 225 226**int ncplane_rotate_ccw(struct ncplane* ***n***);** 227 228**void ncplane_pixel_geom(const struct notcurses* ***n***, unsigned* restrict ***pxy***, unsigned* restrict ***pxx***, unsigned* restrict ***celldimy***, unsigned* restrict ***celldimx***, unsigned* restrict ***maxbmapy***, unsigned* restrict ***maxbmapx***);** 229 230**int ncplane_set_name(struct ncplane* ***n***, const char* ***name***);** 231 232**char* ncplane_name(const struct ncplane* ***n***);** 233 234# DESCRIPTION 235 236Ncplanes are the fundamental drawing object of notcurses. All output functions 237take a **struct ncplane** as an argument. They can be any size, and placed 238anywhere. In addition to its framebuffer--a rectilinear matrix of **nccell**s 239(see **notcurses_cell(3)**)--an ncplane is defined by: 240 241* a base **nccell**, used for any cell on the plane without a glyph, 242* the egcpool backing its **nccell**s, 243* a current cursor location, 244* a current style, foreground channel, and background channel, 245* its geometry, 246* a configured user pointer, 247* position relative to the standard plane, 248* the plane, if any, to which it is bound, 249* the next plane bound by the plane to which it is bound, 250* the head of the list of its bound planes, 251* its resize methodology, 252* whether a sprixel (see **notcurses_visual(3)**) is associated, 253* its z-index, and 254* a name (used only for debugging). 255 256New planes can be created with **ncplane_create**. If a plane is bound to 257another, x and y coordinates are relative to the plane to which it is bound, 258and if this latter plane moves, all its bound planes move along with it. When a 259plane is destroyed, all planes bound to it (directly or transitively) are 260destroyed. 261 262If the **NCPLANE_OPTION_HORALIGNED** flag is provided, ***x*** is interpreted 263as an **ncalign_e** rather than an absolute position. If the 264**NCPLANE_OPTION_VERALIGNED** flag is provided, ***y*** is interpreted as an 265**ncalign_e** rather than an absolute postiion. Either way, all positions 266are relative to the parent plane. **ncplane_resize_realign** should usually be 267used together with these flags, so that the plane is automatically realigned 268upon a resize of its parent. 269 270If the **NCPLANE_OPTION_MARGINALIZED** flag is provided, neither 271**NCPLANE_OPTION_HORALIGNED** nor **NCPLANE_OPTION_VERALIGNED** may be 272provided, and ***rows*** and ***cols*** must both be 0. ***y*** and ***x*** 273will be interpreted as top and left margins. ***margin_b*** and ***margin_r*** 274will be interpreted as bottom and right margins. The plane will take the maximum 275space possible subject to its parent planes and these margins. The plane cannot 276become smaller than 1x1 (the margins are best-effort). 277**ncplane_resize_marginalized** should usually be used together with this flag, 278so that the plane is automatically resized. 279 280**ncplane_reparent** detaches the plane ***n*** from any plane to which it is 281bound, and binds it to ***newparent***. Its children are reparented to its 282previous parent. The standard plane cannot be reparented. If ***newparent*** is 283**NULL**, the plane becomes the root plane of a new, unrendered stack. When 284**ncplane_reparent_family** is used, all planes bound to ***n*** move along with 285it during a reparenting operation. See [Piles][] below. 286 287**ncplane_destroy** destroys a particular ncplane, after which it must not be 288used again. **notcurses_drop_planes** destroys all ncplanes other than the 289stdplane. Any references to such planes are, of course, invalidated. It is 290undefined to destroy a plane concurrently with any other operation involving 291that plane, or any operation involving the z-axis. 292 293It is an error for two threads to concurrently mutate a single ncplane. So long 294as rendering is not taking place, however, multiple threads may safely output 295to multiple ncplanes. So long as all threads are readers, multiple threads may 296work with a single ncplane. A reading function is any which accepts a **const 297struct ncplane**. 298 299A plane can be moved relative to its parent plane's origin with 300**ncplane_move_yx**. If the plane has no parent, the move is relative to 301the rendering area. A plane can be moved off-screen entirely, in which case 302it will not be visible following rasterization; it can also be partially 303off-screen. 304 305A plane has a virtual cursor; Set its new position with **ncplane_cursor_move_yx**. 306Specifying -1 as one or both coordinates will hold that axis constant. You may 307move a cursor relatively to its current position with **ncplane_cursor_move_rel**. 308Unless coordinates are specified for a call, action takes place at the plane's 309virtual cursor, which automatically moves along with output. The current virtual 310cursor location can be acquired with **ncplane_cursor_yx**. 311 312**ncplane_yx** returns the coordinates of the specified plane's origin, relative 313to the plane to which it is bound. Either or both of ***y*** and ***x*** may 314be **NULL**. **ncplane_y** and **ncplane_x** allow a single component of this 315location to be retrieved. **ncplane_abs_yx** returns the coordinates of the 316specified plane's origin relative to its pile. 317 318**ncplane_translate** translates coordinates expressed relative to the plane 319***src***, and writes the coordinates of that cell relative to ***dst***. The cell 320need not intersect with ***dst***, though this will yield coordinates which are 321invalid for writing or reading on ***dst***. If ***dst*** is **NULL**, it is taken 322to refer to the standard plane. **ncplane_translate_abs** takes coordinates 323expressed relative to the standard plane, and returns coordinates relative to 324***dst***, returning **false** if the coordinates are invalid for ***dst***. 325 326**ncplane_mergedown** writes to ***dst*** the frame that would be rendered if only 327***src*** and ***dst*** existed on the z-axis, ad ***dst*** represented the entirety 328of the rendering region. Only those cells where ***src*** intersects with ***dst*** 329might see changes. It is an error to merge a plane onto itself. 330 331**ncplane_erase** zeroes out every cell of the plane, dumps the egcpool, and 332homes the cursor. The base cell is preserved, as are the active attributes. 333**ncplane_erase_region** does the same for a subregion of the plane. For the 334latter, supply 0 for ***ylen*** and/or ***xlen*** to erase through that 335dimension, starting at the specified point. Supply -1 for ***ystart*** and/or 336***xstart*** to use the cursor's current position along that axis for a starting 337point. Negative ***ylen*** and ***xlen*** move up and to the left from the starting 338coordinate; positive ***ylen*** and ***xlen*** move down and to the right from same. 339See [BUGS][] below. 340 341When a plane is resized (whether by **ncplane_resize**, **SIGWINCH**, or any 342other mechanism), a depth-first recursion is performed on its children. 343Each child plane having a non-**NULL** **resizecb** will see that callback 344invoked following resizing of its parent's plane. If it returns non-zero, the 345resizing cascade terminates, returning non-zero. Otherwise, resizing proceeds 346recursively. 347 348**ncplane_move_top** and **ncplane_move_bottom** extract their argument 349***n*** from the z-axis, and reinsert it at the top or bottom, respectively, 350of its pile. These functions are both O(1). **ncplane_move_family_top** and 351**ncplane_move_family_bottom** do the same, and move any bound descendants 352along with the plane. Ordering among the plane and its descendants will be 353maintained. For example, assume a pile with A at the top of its z-axis, 354followed by B, C, D, and E, where E is bound to C. Calling 355**ncplane_move_family_top** on C will result in the order CEABD. Calling 356**ncplane_move_family_bottom** on C will result in the order ABDCE. Calling 357**ncplane_move_family_top** or **ncplane_move_top** on E will result in EABCD. 358Calling **ncplane_move_family_bottom** on E is a no-op. These two functions 359are O(N) on the number of planes in the pile. 360 361**ncplane_move_above** and **ncplane_move_below** move the argument ***n*** 362above or below, respectively, the argument ***targ***. Both operate in O(1). 363 364**ncplane_at_yx** and **ncplane_at_yx_cell** retrieve the contents of the plane 365at the specified coordinate. The content is returned as it will be used during 366rendering, and thus integrates any base cell as appropriate. If called on the 367secondary columns of a wide glyph, **ncplane_at_yx** returns the EGC, and thus 368cannot be used to distinguish between primary and secondary columns. 369**ncplane_at_yx_cell**, however, preserves this information: retrieving a 370secondary column of a wide glyph with **ncplane_at_yx_cell** will fill in 371the **nccell** argument such that **nccell_extended_gcluster(3)** returns an 372empty string, and **nccell_wide_right_p(3)** returns **true**. 373 374**ncplane_set_name** sets the plane's name, freeing any old name. ***name*** 375may be **NULL**. **ncplane_set_name** duplicates the provided name internally. 376 377## Base cells 378 379Each plane has a base cell, initialized to all zeroes. When rendering, the 380cells of the plane are examined in turn. Each cell has three independent 381rendering elements--its EGC, its foreground channel, and its background 382channel. Any default channel is replaced with the corresponding channel from 383that plane's base cell. **ncplane_erase** has no effect on the base cell. 384Calling **ncplane_erase** on a plane whose base cell is a purple 'A' results 385(for rendering purposes) in a plane made up entirely of purple 'A's. 386 387**ncplane_set_base_cell** uses the **nccell** ***c*** (which must be bound to 388the **ncplane** ***ncp***, and must be the first **nccell** of a multicolumn 389sequence) to set the base cell. **ncplane_set_base** does the same with 390***egc***, ***stylemask***, and ***channels***. 391 392## Piles 393 394A single **notcurses** context is made up of one or more piles. A pile is a 395set of one or more **ncplane**s, including the partial orderings made up of 396their binding and z-axis pointers. A pile has a top and bottom **ncplane** 397(this might be a single plane), and one or more root planes (planes which are 398bound to themselves). Multiple threads can concurrently operate on distinct 399piles, even changing one while rendering another. 400 401Each plane is part of one and only one pile. By default, a plane is part of the 402same pile containing that plane to which it is bound. If **ncpile_create** is 403used in the place of **ncplane_create**, the returned plane becomes the root 404plane, top, and bottom of a new pile. As a root plane, it is bound to itself. A 405new pile can also be created by reparenting a plane to itself, though if the 406plane is already a root plane, this is a no-op. 407 408When a plane is moved to a different pile (whether new or preexisting), any 409planes which were bound to it are rebound to its previous parent. If the plane 410was a root plane of some pile, any bound planes become root planes. The new 411plane is placed immediately atop its new parent on its new pile's z-axis. 412When **ncplane_reparent_family** is used, all planes bound to the reparented 413plane are moved along with it. Their relative z-order is maintained. 414 415More information is available from **notcurses_pile(3)**. 416 417## Binding 418 419The planes of a pile make up a directed acyclic forest. Planes bound to 420themselves make up the root planes of the pile. Every plane is either a 421root plane, or bound to some other plane in its pile. A plane and its 422descendants make up a family. When a plane is moved using **ncplane_move_yx**, 423its family is moved along with it. 424 425## Scrolling 426 427All planes, including the standard plane, are created with scrolling disabled. 428Control scrolling on a per-plane basis with **ncplane_set_scrolling**. 429Attempting to print past the end of a line will stop at the plane boundary, and 430indicate an error. On a plane 10 columns wide and two rows high, printing 431"0123456789" at the origin should succeed, but printing "01234567890" will by 432default fail at the eleventh character. In either case, the cursor will be left 433at location 0x10; it must be moved before further printing can take place. If 434scrolling is enabled, the first row will be filled with 01234546789, the second 435row will have 0 written to its first column, and the cursor will end up at 1x1. 436Note that it is still an error to manually attempt to move the cursor 437off-plane, or to specify off-plane output. Box-drawing does not result in 438scrolling; attempting to draw a 2x11 box on our 2x10 plane will result in an 439error and no output. When scrolling is enabled, and output takes place while 440the cursor is past the end of the last row, the first row is discarded, all 441other rows are moved up, the last row is cleared, and output begins at the 442beginning of the last row. This does not take place until output is generated 443(i.e. it is possible to fill a plane when scrolling is enabled). 444 445Creating a plane with the **NCPLANE_OPTION_VSCROLL** flag is equivalent to 446immediately calling **ncplane_set_scrolling** on that plane with an argument 447of **true**. 448 449By default, planes bound to a scrolling plane will scroll along with it, if 450they intersect the plane. This can be disabled by creating them with the 451**NCPLANE_OPTION_FIXED** flag. 452 453## Autogrow 454 455Normally, once output reaches the right boundary of a plane, it is impossible 456to place more output unless the cursor is first moved. If scrolling is 457enabled, the cursor will automatically move down and to the left in this case, 458but upon reaching the bottom right corner of the plane, it is impossible to 459place more output without a scrolling event. If autogrow is in play, the plane 460will automatically be enlarged to accommodate output. If scrolling is disabled, 461growth takes place to the right; it otherwise takes place at the bottom. The 462plane only grows in one dimension. Autogrow cannot be enabled for the standard 463plane. 464 465Creating a plane with the **NCPLANE_OPTION_AUTOGROW** flag is equivalent to 466immediately calling **ncplane_set_autogrow** on that plane with an argument 467of **true**. 468 469## Bitmaps 470 471**ncplane_pixel_geom** retrieves pixel geometry details. **pxy** and **pxx** 472return the size of the plane in pixels. **celldimy** and **celldimx** return 473the size of a cell in pixels (these ought be the same across planes). 474**maxbmapy** and **maxbmapx** describe the largest bitmap which can be 475displayed in the plane. Any parameter (save **n**) may be **NULL**. 476 477When a plane is blitted to using **ncvisual_blit** and **NCBLIT_PIXEL** (see 478**notcurses_visual(3)**), it ceases to accept cell-based output. The sprixel 479will remain associated until a new sprixel is blitted to the plane, the plane 480is resized, the plane is erased, or the plane is destroyed. The base cell of a 481sprixelated plane has no effect; if the sprixel is not even multiples of the 482cell geometry, the "excess plane" is ignored during rendering. 483 484# RETURN VALUES 485 486**ncplane_create** and **ncplane_dup** return a new **struct ncplane** on 487success, or **NULL** on failure. 488 489**ncplane_userptr** returns the configured user pointer for the ncplane, and 490cannot fail. 491 492**ncplane_below** returns the plane below the specified ncplane. If the provided 493plane is the bottommost plane, NULL is returned. It cannot fail. 494 495**ncplane_set_scrolling** returns **true** if scrolling was previously enabled, 496and **false** otherwise. 497 498**ncplane_at_yx** and **ncplane_at_cursor** return a heap-allocated copy of the 499EGC at the relevant cell, or **NULL** if the cell is invalid. The caller should 500free this result. **ncplane_at_yx_cell** and **ncplane_at_cursor_cell** instead 501load these values into an **nccell**, which is invalidated if the associated 502plane is destroyed. The caller should release this **nccell** with 503**nccell_release**. 504 505**ncplane_as_rgba** returns a heap-allocated array of **uint32_t** values, 506each representing a single RGBA pixel, or **NULL** on failure. 507 508**ncplane_erase_region** returns -1 if **ystart** or **xstart** are less than -1, 509or outside the plane. 510 511**ncplane_cursor_move_yx** returns -1 if the coordinates are beyond the 512dimensions of the specified plane (except for the special value -1). 513 514**ncplane_cursor_move_rel** returns -1 if the coordinates are beyond the 515dimensions of the specified plane. 516 517**ncplane_name** returns a heap-allocated copy of the plane's name, or NULL if 518it has no name (or on error). 519 520Functions returning **int** return 0 on success, and non-zero on error. 521 522All other functions cannot fail (and return **void**). 523 524# NOTES 525 526# BUGS 527 528**ncplane_at_yx** doesn't yet account for bitmap-based graphics (see 529**notcurses_visual(3)**). Whatever glyph-based contents existed on the plane when 530the bitmap was blitted will continue to be returned. 531 532When the alternate screen is not used (see **notcurses_init(3)**), the contents 533of the terminal at startup remain present until obliterated on a cell-by-cell 534basis. **ncplane_erase** and **ncplane_erase_region** **cannot** be used to 535clear the terminal of startup content. If you want the screen cleared on 536startup, but do not want to use (or rely on) the alternate screen, use something 537like: 538 539```c 540ncplane_set_base(notcurses_stdplane(nc), " ", 0, 0); 541notcurses_render(nc); 542``` 543 544or simply: 545 546```c 547notcurses_refresh(nc); 548``` 549 550# SEE ALSO 551 552**notcurses(3)**, 553**notcurses_capabilities(3)**, 554**notcurses_cell(3)**, 555**notcurses_output(3)**, 556**notcurses_pile(3)**, 557**notcurses_stdplane(3)**, 558**notcurses_visual(3)** 559