1 #ifndef __NCPP_PLANE_HH
2 #define __NCPP_PLANE_HH
3 
4 #include <exception>
5 #include <cstdarg>
6 #include <ctime>
7 #include <map>
8 #include <mutex>
9 #include <notcurses/notcurses.h>
10 
11 #include "Root.hh"
12 #include "Cell.hh"
13 #include "CellStyle.hh"
14 #include "NCAlign.hh"
15 #include "NCBox.hh"
16 
17 namespace ncpp
18 {
19 	class NcReel;
20 
21 	class NCPP_API_EXPORT Plane : public Root
22 	{
23 	public:
Plane(Plane && other)24 		Plane (Plane&& other)
25 			: Root (nullptr)
26 		{
27 			unmap_plane (&other);
28 
29 			plane = other.plane;
30 			is_stdplane = other.is_stdplane;
31 
32 			map_plane (plane, this);
33 
34 			other.plane = nullptr;
35 			other.is_stdplane = false;
36 		}
37 
Plane(Plane const & other)38 		Plane (Plane const& other)
39 			: Root (nullptr)
40 		{
41 			plane = duplicate_plane (other, nullptr);
42 		}
43 
Plane(Plane const & other,void * opaque)44 		explicit Plane (Plane const& other, void *opaque)
45 			: Root (nullptr)
46 		{
47 			plane = duplicate_plane (other, opaque);
48 		}
49 
Plane(Plane * n,int rows,int cols,int yoff,int xoff,void * opaque=nullptr)50 		explicit Plane (Plane *n, int rows, int cols, int yoff, int xoff, void *opaque = nullptr)
51 			: Plane (static_cast<const Plane*>(n), rows, cols, yoff, xoff, opaque)
52 		{}
53 
Plane(const Plane * n,int rows,int cols,int yoff,int xoff,void * opaque=nullptr)54 		explicit Plane (const Plane *n, int rows, int cols, int yoff, int xoff, void *opaque = nullptr)
55 			: Root (nullptr)
56 		{
57 			if (n == nullptr)
58 				throw invalid_argument ("'n' must be a valid pointer");
59 
60 			plane = create_plane (*n, rows, cols, yoff, xoff, opaque);
61 		}
62 
Plane(Plane * n,ncplane_options const & nopts,NotCurses * ncinst=nullptr)63 		explicit Plane (Plane *n, ncplane_options const& nopts, NotCurses *ncinst = nullptr)
64 			: Plane (static_cast<const Plane*>(n), nopts, ncinst)
65 		{}
66 
Plane(const Plane * n,ncplane_options const & nopts,NotCurses * ncinst=nullptr)67 		explicit Plane (const Plane *n, ncplane_options const& nopts, NotCurses *ncinst = nullptr)
68 			: Root (ncinst)
69 		{
70 			if (n == nullptr) {
71 				throw invalid_argument ("'n' must be a valid pointer");
72 			}
73 
74 			plane = create_plane (*n, nopts);
75 		}
76 
Plane(const Plane & n,int rows,int cols,int yoff,int xoff,void * opaque=nullptr)77 		explicit Plane (const Plane &n, int rows, int cols, int yoff, int xoff, void *opaque = nullptr)
78 			: Root (nullptr)
79 		{
80 			plane = create_plane (n, rows, cols, yoff, xoff, opaque);
81 		}
82 
Plane(unsigned rows,unsigned cols,int yoff,int xoff,void * opaque=nullptr,NotCurses * ncinst=nullptr)83 		explicit Plane (unsigned rows, unsigned cols, int yoff, int xoff, void *opaque = nullptr, NotCurses *ncinst = nullptr)
84 			: Root (ncinst)
85 		{
86 			ncplane_options nopts = {
87 				.y = yoff,
88 				.x = xoff,
89 				.rows = rows,
90 				.cols = cols,
91 				.userptr = opaque,
92 				.name = nullptr,
93 				.resizecb = nullptr,
94 				.flags = 0,
95 				.margin_b = 0,
96 				.margin_r = 0,
97 			};
98 			plane = ncplane_create (
99 				notcurses_stdplane(get_notcurses ()),
100 				&nopts
101 			);
102 
103 			if (plane == nullptr)
104 				throw init_error ("Notcurses failed to create a new plane");
105 
106 			map_plane (plane, this);
107 		}
108 
Plane(Plane & n,int rows,int cols,int yoff,NCAlign align,void * opaque=nullptr)109 		explicit Plane (Plane &n, int rows, int cols, int yoff, NCAlign align, void *opaque = nullptr)
110 			: Root (nullptr)
111 		{
112 			plane = create_plane (n, rows, cols, yoff, align, opaque);
113 		}
114 
Plane(Plane const & n,int rows,int cols,int yoff,NCAlign align,void * opaque=nullptr)115 		explicit Plane (Plane const& n, int rows, int cols, int yoff, NCAlign align, void *opaque = nullptr)
116 			: Root (nullptr)
117 		{
118 			plane = create_plane (const_cast<Plane&>(n), rows, cols, yoff, align, opaque);
119 		}
120 
Plane(Plane & n,ncplane_options const & nopts,NotCurses * ncinst=nullptr)121 		explicit Plane (Plane &n, ncplane_options const& nopts, NotCurses *ncinst = nullptr)
122 			: Plane (static_cast<Plane const&>(n), nopts, ncinst)
123 		{}
124 
Plane(Plane const & n,ncplane_options const & nopts,NotCurses * ncinst=nullptr)125 		explicit Plane (Plane const& n, ncplane_options const& nopts, NotCurses *ncinst = nullptr)
126 			: Root (ncinst)
127 		{
128 			plane = create_plane (n, nopts);
129 		}
130 
Plane(Plane * n,int rows,int cols,int yoff,NCAlign align,void * opaque=nullptr)131 		explicit Plane (Plane *n, int rows, int cols, int yoff, NCAlign align, void *opaque = nullptr)
132 			: Root (nullptr)
133 		{
134 			if (n == nullptr)
135 				throw invalid_argument ("'n' must be a valid pointer");
136 
137 			plane = create_plane (*n, rows, cols, yoff, align, opaque);
138 		}
139 
Plane(Plane const * n,int rows,int cols,int yoff,NCAlign align,void * opaque=nullptr)140 		explicit Plane (Plane const* n, int rows, int cols, int yoff, NCAlign align, void *opaque = nullptr)
141 			: Root (nullptr)
142 		{
143 			if (n == nullptr)
144 				throw invalid_argument ("'n' must be a valid pointer");
145 
146 			plane = create_plane (const_cast<Plane&>(*n), rows, cols, yoff, align, opaque);
147 		}
148 
Plane(ncplane * _plane)149 		explicit Plane (ncplane *_plane) noexcept
150 			: Root (nullptr),
151 			  plane (_plane)
152 		{}
153 
~Plane()154 		~Plane () noexcept
155 		{
156 			if (is_stdplane || plane == nullptr)
157 				return;
158 
159 			if (!is_notcurses_stopped ())
160 				ncplane_destroy (plane);
161 			unmap_plane (this);
162 		}
163 
operator ncplane*()164 		operator ncplane* () noexcept
165 		{
166 			return plane;
167 		}
168 
operator ncplane const*() const169 		operator ncplane const* () const noexcept
170 		{
171 			return plane;
172 		}
173 
center_abs(int * y,int * x) const174 		void center_abs (int *y, int *x) const noexcept
175 		{
176 			ncplane_center_abs (plane, y, x);
177 		}
178 
to_ncplane() const179 		ncplane* to_ncplane () const noexcept
180 		{
181 			return plane;
182 		}
183 
resize_maximize() const184 		bool resize_maximize () const NOEXCEPT_MAYBE
185 		{
186 			return error_guard (ncplane_resize_maximize (plane), -1);
187 		}
188 
resize_realign() const189 		bool resize_realign () const NOEXCEPT_MAYBE
190 		{
191 			return error_guard (ncplane_resize_realign (plane), -1);
192 		}
193 
resize(int keepy,int keepx,int keepleny,int keeplenx,int yoff,int xoff,int ylen,int xlen) const194 		bool resize (int keepy, int keepx, int keepleny, int keeplenx, int yoff, int xoff, int ylen, int xlen) const NOEXCEPT_MAYBE
195 		{
196 			int ret = ncplane_resize (
197 				plane,
198 				keepy,
199 				keepx,
200 				keepleny,
201 				keeplenx,
202 				yoff,
203 				xoff,
204 				ylen,
205 				xlen
206 			);
207 
208 			return error_guard (ret, -1);
209 		}
210 
pulse(const timespec * ts,fadecb fader,void * curry) const211 		bool pulse (const timespec* ts, fadecb fader, void* curry) const NOEXCEPT_MAYBE
212 		{
213 			return error_guard (ncplane_pulse (plane, ts, fader, curry), -1);
214 		}
215 
gradient(int y,int x,unsigned ylen,unsigned xlen,const char * egc,uint16_t stylemask,uint64_t ul,uint64_t ur,uint64_t ll,uint64_t lr) const216 		int gradient (int y, int x, unsigned ylen, unsigned xlen, const char* egc, uint16_t stylemask, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr) const NOEXCEPT_MAYBE
217 		{
218 			return error_guard<int> (ncplane_gradient (plane, y, x, ylen, xlen, egc, stylemask, ul, ur, ll, lr), -1);
219 		}
220 
gradient2x1(int y,int x,unsigned ylen,unsigned xlen,uint32_t ul,uint32_t ur,uint32_t ll,uint32_t lr) const221 		int gradient2x1 (int y, int x, unsigned ylen, unsigned xlen, uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr) const NOEXCEPT_MAYBE
222 		{
223 			return error_guard<int> (ncplane_gradient2x1 (plane, y, x, ylen, xlen, ul, ur, ll, lr), -1);
224 		}
225 
greyscale() const226 		void greyscale () const noexcept
227 		{
228 			ncplane_greyscale (plane);
229 		}
230 
resize(int ylen,int xlen) const231 		bool resize (int ylen, int xlen) const NOEXCEPT_MAYBE
232 		{
233 			return error_guard (ncplane_resize_simple (plane, ylen, xlen), -1);
234 		}
235 
fadeout(timespec * ts,fadecb fader=nullptr,void * curry=nullptr) const236 		bool fadeout (timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
237 		{
238 			return fadeout (static_cast<const timespec*>(ts), fader, curry);
239 		}
240 
fadeout(timespec & ts,fadecb fader=nullptr,void * curry=nullptr) const241 		bool fadeout (timespec &ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
242 		{
243 			return fadeout (&ts, fader, curry);
244 		}
245 
fadeout(timespec const & ts,fadecb fader=nullptr,void * curry=nullptr) const246 		bool fadeout (timespec const& ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
247 		{
248 			return fadeout (&ts, fader, curry);
249 		}
250 
fadeout(const timespec * ts,fadecb fader=nullptr,void * curry=nullptr) const251 		bool fadeout (const timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
252 		{
253 			return error_guard (ncplane_fadeout (plane, ts, fader, curry), -1);
254 		}
255 
fadein(timespec * ts,fadecb fader=nullptr) const256 		bool fadein (timespec *ts, fadecb fader = nullptr) const NOEXCEPT_MAYBE
257 		{
258 			return fadein (static_cast<const timespec*>(ts), fader);
259 		}
260 
fadein(timespec & ts,fadecb fader=nullptr) const261 		bool fadein (timespec &ts, fadecb fader = nullptr) const NOEXCEPT_MAYBE
262 		{
263 			return fadein (&ts, fader);
264 		}
265 
fadein(timespec const & ts,fadecb fader=nullptr) const266 		bool fadein (timespec const& ts, fadecb fader = nullptr) const NOEXCEPT_MAYBE
267 		{
268 			return fadein (&ts, fader);
269 		}
270 
fadein(const timespec * ts,fadecb fader=nullptr,void * curry=nullptr) const271 		bool fadein (const timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
272 		{
273 			return error_guard (ncplane_fadein (plane, ts, fader, curry), -1);
274 		}
275 
erase() const276 		void erase () const noexcept
277 		{
278 			ncplane_erase (plane);
279 		}
280 
get_abs_x() const281 		int get_abs_x () const noexcept
282 		{
283 			return ncplane_abs_x (plane);
284 		}
285 
get_abs_y() const286 		int get_abs_y () const noexcept
287 		{
288 			return ncplane_abs_y (plane);
289 		}
290 
get_x() const291 		int get_x () const noexcept
292 		{
293 			return ncplane_x (plane);
294 		}
295 
get_y() const296 		int get_y () const noexcept
297 		{
298 			return ncplane_y (plane);
299 		}
300 
get_align(NCAlign align,int c) const301 		int get_align (NCAlign align, int c) const NOEXCEPT_MAYBE
302 		{
303 			return error_guard<int> (ncplane_halign (plane, static_cast<ncalign_e>(align), c), INT_MAX);
304 		}
305 
get_halign(NCAlign align,int c) const306 		int get_halign (NCAlign align, int c) const NOEXCEPT_MAYBE
307 		{
308 			return error_guard<int> (ncplane_halign (plane, static_cast<ncalign_e>(align), c), INT_MAX);
309 		}
310 
get_valign(NCAlign align,int r) const311 		int get_valign (NCAlign align, int r) const NOEXCEPT_MAYBE
312 		{
313 			return error_guard<int> (ncplane_valign (plane, static_cast<ncalign_e>(align), r), INT_MAX);
314 		}
315 
get_dim(unsigned * rows,unsigned * cols) const316 		void get_dim (unsigned *rows, unsigned *cols) const noexcept
317 		{
318 			ncplane_dim_yx (plane, rows, cols);
319 		}
320 
get_dim(unsigned & rows,unsigned & cols) const321 		void get_dim (unsigned &rows, unsigned &cols) const noexcept
322 		{
323 			get_dim (&rows, &cols);
324 		}
325 
get_dim_x() const326 		unsigned get_dim_x () const noexcept
327 		{
328 			return ncplane_dim_x (plane);
329 		}
330 
get_dim_y() const331 		unsigned get_dim_y () const noexcept
332 		{
333 			return ncplane_dim_y (plane);
334 		}
335 
get_abs_yx(int * y,int * x) const336 		void get_abs_yx (int* y, int* x) const noexcept
337 		{
338 			ncplane_abs_yx (plane, y, x);
339 		}
340 
get_yx(int * y,int * x) const341 		void get_yx (int *y, int *x) const noexcept
342 		{
343 			ncplane_yx (plane, y, x);
344 		}
345 
get_yx(int & y,int & x) const346 		void get_yx (int &y, int &x) const noexcept
347 		{
348 			get_yx (&y, &x);
349 		}
350 
get_parent() const351 		Plane* get_parent () const noexcept
352 		{
353 			ncplane *ret = ncplane_parent (plane);
354 			if (ret == nullptr) {
355 				return nullptr;
356 			}
357 
358 			return map_plane (ret);
359 		}
360 
reparent(Plane * newparent=nullptr) const361 		Plane* reparent (Plane *newparent = nullptr) const noexcept
362 		{
363 			ncplane *ret = ncplane_reparent (plane, newparent == nullptr ? plane : newparent->plane);
364 			if (ret == nullptr)
365 				return nullptr;
366 
367 			return map_plane (ret);
368 		}
369 
reparent(const Plane * newparent) const370 		Plane* reparent (const Plane *newparent) const noexcept
371 		{
372 			return reparent (const_cast<Plane*>(newparent));
373 		}
374 
reparent(const Plane & newparent) const375 		Plane* reparent (const Plane &newparent) const noexcept
376 		{
377 			return reparent (const_cast<Plane*>(&newparent));
378 		}
379 
reparent_family(Plane * newparent=nullptr) const380 		Plane* reparent_family (Plane *newparent = nullptr) const noexcept
381 		{
382 			ncplane *ret = ncplane_reparent_family (plane, newparent == nullptr ? plane : newparent->plane);
383 			if (ret == nullptr)
384 				return nullptr;
385 
386 			return map_plane (ret);
387 		}
388 
reparent_family(const Plane * newparent) const389 		Plane* reparent_family (const Plane *newparent) const noexcept
390 		{
391 			return reparent_family (const_cast<Plane*>(newparent));
392 		}
393 
reparent_family(const Plane & newparent) const394 		Plane* reparent_family (const Plane &newparent) const noexcept
395 		{
396 			return reparent_family (const_cast<Plane*>(&newparent));
397 		}
398 
home() const399 		void home () const noexcept
400 		{
401 			ncplane_home (plane);
402 		}
403 
move(int y,int x) const404 		bool move (int y, int x) const NOEXCEPT_MAYBE
405 		{
406 			return error_guard (ncplane_move_yx (plane, y, x), -1);
407 		}
408 
move_top()409 		void move_top () noexcept
410 		{
411 			ncplane_move_top (plane);
412 		}
413 
move_bottom()414 		void move_bottom () noexcept
415 		{
416 			ncplane_move_bottom (plane);
417 		}
418 
move_below(Plane & below) const419 		bool move_below (Plane &below) const NOEXCEPT_MAYBE
420 		{
421 			return error_guard (ncplane_move_below (plane, below.plane), -1);
422 		}
423 
move_below(Plane * below) const424 		bool move_below (Plane *below) const
425 		{
426 			if (below == nullptr)
427 				throw invalid_argument ("'below' must be a valid pointer");
428 
429 			return move_below (*below);
430 		}
431 
move_above(Plane & above) const432 		bool move_above (Plane &above) const NOEXCEPT_MAYBE
433 		{
434 			return error_guard (ncplane_move_above (plane, above.plane), -1);
435 		}
436 
move_above(Plane * above) const437 		bool move_above (Plane *above) const
438 		{
439 			if (above == nullptr)
440 				throw invalid_argument ("'above' must be a valid pointer");
441 
442 			return move_above (*above);
443 		}
444 
mergedown(Plane & dst,unsigned begsrcy,unsigned begsrcx,unsigned leny,unsigned lenx,unsigned dsty,unsigned dstx) const445 		bool mergedown (Plane &dst, unsigned begsrcy, unsigned begsrcx, unsigned leny, unsigned lenx, unsigned dsty, unsigned dstx) const
446 		{
447 			return mergedown (&dst, begsrcy, begsrcx, leny, lenx, dsty, dstx);
448 		}
449 
mergedown(Plane * dst,int begsrcy,int begsrcx,unsigned leny,unsigned lenx,int dsty,int dstx) const450 		bool mergedown (Plane *dst, int begsrcy, int begsrcx, unsigned leny, unsigned lenx, int dsty, int dstx) const
451 		{
452 			if (plane == dst->plane)
453 				throw invalid_argument ("'dst' must refer to a different plane than the one this method is called on");
454 
455 			return error_guard (ncplane_mergedown (plane, dst->plane, begsrcy, begsrcx, leny, lenx, dsty, dstx), -1);
456 		}
457 
mergedown_simple(Plane & dst) const458 		bool mergedown_simple (Plane &dst) const
459 		{
460 			return mergedown_simple (&dst);
461 		}
462 
mergedown_simple(Plane * dst) const463 		bool mergedown_simple (Plane *dst) const
464 		{
465 			if (plane == dst->plane)
466 				throw invalid_argument ("'dst' must refer to a different plane than the one this method is called on");
467 
468 			return error_guard (ncplane_mergedown_simple (plane, dst->plane), -1);
469 		}
470 
cursor_move(int y,int x) const471 		bool cursor_move (int y, int x) const NOEXCEPT_MAYBE
472 		{
473 			return error_guard (ncplane_cursor_move_yx (plane, y, x), -1);
474 		}
475 
get_cursor_yx(unsigned * y,unsigned * x) const476 		void get_cursor_yx (unsigned *y, unsigned *x) const noexcept
477 		{
478 			ncplane_cursor_yx (plane, y, x);
479 		}
480 
get_cursor_yx(unsigned & y,unsigned & x) const481 		void get_cursor_yx (unsigned &y, unsigned &x) const noexcept
482 		{
483 			get_cursor_yx (&y, &x);
484 		}
485 
putc(const Cell & c) const486 		int putc (const Cell &c) const NOEXCEPT_MAYBE
487 		{
488 			return error_guard<int> (ncplane_putc (plane, c), -1);
489 		}
490 
putc(const Cell * c) const491 		int putc (const Cell *c) const
492 		{
493 			if (c == nullptr)
494 				throw invalid_argument ("'c' must be a valid pointer");
495 
496 			return putc (*c);
497 		}
498 
putc(int y,int x,Cell const & c) const499 		int putc (int y, int x, Cell const& c) const NOEXCEPT_MAYBE
500 		{
501 			return error_guard<int> (ncplane_putc_yx (plane, y, x, c), -1);
502 		}
503 
putc(int y,int x,Cell const * c) const504 		int putc (int y, int x, Cell const* c) const NOEXCEPT_MAYBE
505 		{
506 			if (c == nullptr)
507 				return -1;
508 
509 			return putc (y, x, *c);
510 		}
511 
putc(char c,bool retain_styling=false) const512 		int putc (char c, bool retain_styling = false) const NOEXCEPT_MAYBE
513 		{
514 			int ret;
515 			if (retain_styling) {
516 				ret = ncplane_putchar_stained (plane, c);
517 			} else {
518 				ret = ncplane_putchar (plane, c);
519 			}
520 
521 			return error_guard<int> (ret, -1);
522 		}
523 
putc(int y,int x,char c) const524 		int putc (int y, int x, char c) const NOEXCEPT_MAYBE
525 		{
526 			return error_guard<int> (ncplane_putchar_yx (plane, y, x, c), -1);
527 		}
528 
putc(const char * gclust,size_t * sbytes=nullptr,bool retain_styling=false) const529 		int putc (const char *gclust, size_t *sbytes = nullptr, bool retain_styling = false) const NOEXCEPT_MAYBE
530 		{
531 			int ret;
532 			if (retain_styling) {
533 				ret = ncplane_putegc_stained (plane, gclust, sbytes);
534 			} else {
535 				ret = ncplane_putegc (plane, gclust, sbytes);
536 			}
537 
538 			return error_guard<int> (ret, -1);
539 		}
540 
putc(int y,int x,const char * gclust,size_t * sbytes=nullptr) const541 		int putc (int y, int x, const char *gclust, size_t *sbytes = nullptr) const NOEXCEPT_MAYBE
542 		{
543 			return error_guard<int> (ncplane_putegc_yx (plane, y, x, gclust, sbytes), -1);
544 		}
545 
putc(const wchar_t * gclust,size_t * sbytes=nullptr,bool retain_styling=false) const546 		int putc (const wchar_t *gclust, size_t *sbytes = nullptr, bool retain_styling = false) const NOEXCEPT_MAYBE
547 		{
548 			int ret;
549 			if (retain_styling) {
550 				ret = ncplane_putwegc_stained (plane, gclust, sbytes);
551 			} else {
552 				ret = ncplane_putwegc (plane, gclust, sbytes);
553 			}
554 
555 			return error_guard<int> (ret, -1);
556 		}
557 
putc(int y,int x,const wchar_t * gclust,size_t * sbytes=nullptr) const558 		int putc (int y, int x, const wchar_t *gclust, size_t *sbytes = nullptr) const NOEXCEPT_MAYBE
559 		{
560 			return error_guard<int> (ncplane_putwegc_yx (plane, y, x, gclust, sbytes), -1);
561 		}
562 
563 		// OK, this is ugly, but we need to rename this overload or calls similar to n->putc (0, 0, '0') will be
564 		// considered ambiguous with the above `putc (int, int, char)` overload.
putwch(int y,int x,wchar_t w) const565 		int putwch (int y, int x, wchar_t w) const NOEXCEPT_MAYBE
566 		{
567 			return error_guard<int> (ncplane_putwc_yx (plane, y, x, w), -1);
568 		}
569 
570 		// Ditto
putwch(wchar_t w) const571 		int putwch (wchar_t w) const NOEXCEPT_MAYBE
572 		{
573 			return error_guard<int> (ncplane_putwc (plane, w), -1);
574 		}
575 
putwc_stained(wchar_t w) const576 		int putwc_stained (wchar_t w) const NOEXCEPT_MAYBE
577 		{
578 			return error_guard<int> (ncplane_putwc_stained (plane, w), -1);
579 		}
580 
putstr(const char * gclustarr) const581 		int putstr (const char *gclustarr) const NOEXCEPT_MAYBE
582 		{
583 			int ret = ncplane_putstr (plane, gclustarr);
584 			return error_guard_cond<int> (ret, ret < 0);
585 		}
586 
putstr(int y,int x,const char * gclustarr) const587 		int putstr (int y, int x, const char *gclustarr) const NOEXCEPT_MAYBE
588 		{
589 			int ret = ncplane_putstr_yx (plane, y, x, gclustarr);
590 			return error_guard_cond<int> (ret, ret < 0);
591 		}
592 
putstr(int y,NCAlign atype,const char * s) const593 		int putstr (int y, NCAlign atype, const char *s) const NOEXCEPT_MAYBE
594 		{
595 			return error_guard<int> (ncplane_putstr_aligned (plane, y, static_cast<ncalign_e>(atype), s), -1);
596 		}
597 
putstr(const wchar_t * gclustarr) const598 		int putstr (const wchar_t *gclustarr) const NOEXCEPT_MAYBE
599 		{
600 			return error_guard<int> (ncplane_putwstr (plane, gclustarr), -1);
601 		}
602 
putstr(int y,int x,const wchar_t * gclustarr) const603 		int putstr (int y, int x, const wchar_t *gclustarr) const NOEXCEPT_MAYBE
604 		{
605 			return error_guard<int> (ncplane_putwstr_yx (plane, y, x, gclustarr), -1);
606 		}
607 
putstr(int y,NCAlign atype,const wchar_t * gcluststyles) const608 		int putstr (int y, NCAlign atype, const wchar_t *gcluststyles) const NOEXCEPT_MAYBE
609 		{
610 			return error_guard<int> (ncplane_putwstr_aligned (plane, y, static_cast<ncalign_e>(atype), gcluststyles), -1);
611 		}
612 
putstr_stained(const wchar_t * gclustarr) const613 		int putstr_stained (const wchar_t* gclustarr) const NOEXCEPT_MAYBE
614 		{
615 			return error_guard<int> (ncplane_putwstr_stained (plane, gclustarr), -1);
616 		}
617 
putstr_stained(const char * s) const618 		int putstr_stained (const char* s) const NOEXCEPT_MAYBE
619 		{
620 			int ret = ncplane_putstr_stained (plane, s);
621 			return error_guard_cond<int> (ret, ret < 0);
622 		}
623 
printf_stained(const char * format,...) const624 		int printf_stained (const char* format, ...) const NOEXCEPT_MAYBE
625 			__attribute__ ((format (printf, 2, 3)))
626 		{
627 			va_list va;
628 
629 			va_start (va, format);
630 			int ret = ncplane_vprintf_stained (plane, format, va);
631 			va_end (va);
632 
633 			return error_guard<int> (ret, -1);
634 		}
635 
printf(const char * format,...) const636 		int printf (const char* format, ...) const NOEXCEPT_MAYBE
637 			__attribute__ ((format (printf, 2, 3)))
638 		{
639 			va_list va;
640 
641 			va_start (va, format);
642 			int ret = ncplane_vprintf (plane, format, va);
643 			va_end (va);
644 
645 			return error_guard<int> (ret, -1);
646 		}
647 
printf(int y,int x,const char * format,...) const648 		int printf (int y, int x, const char *format, ...) const NOEXCEPT_MAYBE
649 			__attribute__ ((format (printf, 4, 5)))
650 		{
651 			va_list va;
652 
653 			va_start (va, format);
654 			int ret = ncplane_vprintf_yx (plane, y, x, format, va);
655 			va_end (va);
656 
657 			return error_guard<int> (ret, -1);
658 		}
659 
printf(int y,NCAlign align,const char * format,...) const660 		int printf (int y, NCAlign align, const char *format, ...) const NOEXCEPT_MAYBE
661 			__attribute__ ((format (printf, 4, 5)))
662 		{
663 			va_list va;
664 
665 			va_start (va, format);
666 			int ret = vprintf (y, align, format, va);
667 			va_end (va);
668 
669 			return error_guard<int> (ret, -1);
670 		}
671 
vprintf_stained(const char * format,va_list ap) const672 		int vprintf_stained (const char* format, va_list ap) const NOEXCEPT_MAYBE
673 		{
674 			return error_guard<int> (ncplane_vprintf_stained (plane, format, ap), -1);
675 		}
676 
vprintf(const char * format,va_list ap) const677 		int vprintf (const char* format, va_list ap) const NOEXCEPT_MAYBE
678 		{
679 			return error_guard<int> (ncplane_vprintf (plane, format, ap), -1);
680 		}
681 
vprintf(int y,int x,const char * format,va_list ap) const682 		int vprintf (int y, int x, const char* format, va_list ap) const NOEXCEPT_MAYBE
683 		{
684 			return error_guard<int> (ncplane_vprintf_yx (plane, y, x, format, ap), -1);
685 		}
686 
vprintf(int y,NCAlign align,const char * format,va_list ap) const687 		int vprintf (int y, NCAlign align, const char *format, va_list ap) const NOEXCEPT_MAYBE
688 		{
689 			return error_guard<int> (ncplane_vprintf_aligned (plane, y, static_cast<ncalign_e>(align), format, ap), -1);
690 		}
691 
hline(const Cell & c,unsigned len) const692 		int hline (const Cell &c, unsigned len) const NOEXCEPT_MAYBE
693 		{
694 			return error_guard<int> (ncplane_hline (plane, c, len), -1);
695 		}
696 
hline(const Cell & c,unsigned len,uint64_t c1,uint64_t c2) const697 		int hline (const Cell &c, unsigned len, uint64_t c1, uint64_t c2) const NOEXCEPT_MAYBE
698 		{
699 			return error_guard<int> (ncplane_hline_interp (plane, c, len, c1, c2), -1);
700 		}
701 
vline(const Cell & c,unsigned len) const702 		int vline (const Cell &c, unsigned len) const NOEXCEPT_MAYBE
703 		{
704 			return error_guard<int> (ncplane_vline (plane, c, len), -1);
705 		}
706 
vline(const Cell & c,unsigned len,uint64_t c1,uint64_t c2) const707 		int vline (const Cell &c, unsigned len, uint64_t c1, uint64_t c2) const NOEXCEPT_MAYBE
708 		{
709 			return error_guard<int> (ncplane_vline_interp (plane, c, len, c1, c2), -1);
710 		}
711 
load_box(uint16_t styles,uint64_t channels,Cell & ul,Cell & ur,Cell & ll,Cell & lr,Cell & hl,Cell & vl,const char * gclusters) const712 		bool load_box (uint16_t styles, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl, const char *gclusters) const NOEXCEPT_MAYBE
713 		{
714 			return error_guard (nccells_load_box (plane, styles, channels, ul, ur, ll, lr, hl, vl, gclusters), -1);
715 		}
716 
load_box(CellStyle style,uint64_t channels,Cell & ul,Cell & ur,Cell & ll,Cell & lr,Cell & hl,Cell & vl,const char * gclusters) const717 		bool load_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl, const char *gclusters) const NOEXCEPT_MAYBE
718 		{
719 			return load_box (static_cast<uint16_t>(style), channels, ul, ur, ll, lr, hl, vl, gclusters);
720 		}
721 
load_rounded_box(uint16_t styles,uint64_t channels,Cell & ul,Cell & ur,Cell & ll,Cell & lr,Cell & hl,Cell & vl) const722 		bool load_rounded_box (uint16_t styles, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
723 		{
724 			return error_guard (nccells_rounded_box (plane, styles, channels, ul, ur, ll, lr, hl, vl), -1);
725 		}
726 
load_rounded_box(CellStyle style,uint64_t channels,Cell & ul,Cell & ur,Cell & ll,Cell & lr,Cell & hl,Cell & vl) const727 		bool load_rounded_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
728 		{
729 			return load_rounded_box (static_cast<uint16_t>(style), channels, ul, ur, ll, lr, hl, vl);
730 		}
731 
load_double_box(uint16_t styles,uint64_t channels,Cell & ul,Cell & ur,Cell & ll,Cell & lr,Cell & hl,Cell & vl) const732 		bool load_double_box (uint16_t styles, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
733 		{
734 			return error_guard (nccells_double_box (plane, styles, channels, ul, ur, ll, lr, hl, vl), -1);
735 		}
736 
load_double_box(CellStyle style,uint64_t channels,Cell & ul,Cell & ur,Cell & ll,Cell & lr,Cell & hl,Cell & vl) const737 		bool load_double_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
738 		{
739 			return load_double_box (static_cast<uint16_t>(style), channels, ul, ur, ll, lr, hl, vl);
740 		}
741 
box(const Cell & ul,const Cell & ur,const Cell & ll,const Cell & lr,const Cell & hline,const Cell & vline,int ystop,int xstop,unsigned ctlword) const742 		bool box (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr,
743 							const Cell &hline, const Cell &vline, int ystop, int xstop,
744 							unsigned ctlword) const NOEXCEPT_MAYBE
745 		{
746 			return error_guard (ncplane_box (plane, ul, ur, ll, lr, hline, vline, ystop, xstop, ctlword), -1);
747 		}
748 
box_sized(const Cell & ul,const Cell & ur,const Cell & ll,const Cell & lr,const Cell & hline,const Cell & vline,int ylen,int xlen,unsigned ctlword) const749 		bool box_sized (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr,
750 						const Cell &hline, const Cell &vline, int ylen, int xlen,
751 						unsigned ctlword) const NOEXCEPT_MAYBE
752 		{
753 			return error_guard (ncplane_box_sized (plane, ul, ur, ll, lr, hline, vline, ylen, xlen, ctlword), -1);
754 		}
755 
rounded_box(uint16_t styles,uint64_t channels,int ystop,int xstop,unsigned ctlword) const756 		bool rounded_box (uint16_t styles, uint64_t channels, int ystop, int xstop, unsigned ctlword) const NOEXCEPT_MAYBE
757 		{
758 			return error_guard (ncplane_rounded_box (plane, styles, channels, ystop, xstop, ctlword), -1);
759 		}
760 
rounded_box_sized(uint16_t styles,uint64_t channels,int ylen,int xlen,unsigned ctlword) const761 		bool rounded_box_sized (uint16_t styles, uint64_t channels, int ylen, int xlen, unsigned ctlword) const NOEXCEPT_MAYBE
762 		{
763 			return error_guard (ncplane_rounded_box_sized (plane, styles, channels, ylen, xlen, ctlword), -1);
764 		}
765 
double_box(uint16_t styles,uint64_t channels,int ystop,int xstop,unsigned ctlword) const766 		bool double_box (uint16_t styles, uint64_t channels, int ystop, int xstop, unsigned ctlword) const NOEXCEPT_MAYBE
767 		{
768 			return error_guard (ncplane_double_box (plane, styles, channels, ystop, xstop, ctlword), -1);
769 		}
770 
double_box_sized(uint16_t styles,uint64_t channels,int ylen,int xlen,unsigned ctlword) const771 		bool double_box_sized (uint16_t styles, uint64_t channels, int ylen, int xlen, unsigned ctlword) const NOEXCEPT_MAYBE
772 		{
773 			return error_guard (ncplane_double_box_sized (plane, styles, channels, ylen, xlen, ctlword), -1);
774 		}
775 
perimeter(const Cell & ul,const Cell & ur,const Cell & ll,const Cell & lr,const Cell & hline,const Cell & vline,unsigned ctlword) const776 		bool perimeter (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr, const Cell &hline, const Cell &vline, unsigned ctlword) const NOEXCEPT_MAYBE
777 		{
778 			return error_guard (ncplane_perimeter (plane, ul, ur, ll, lr, hline, vline, ctlword), -1);
779 		}
780 
perimeter_rounded(uint16_t stylemask,uint64_t channels,unsigned ctlword) const781 		bool perimeter_rounded (uint16_t stylemask, uint64_t channels, unsigned ctlword) const NOEXCEPT_MAYBE
782 		{
783 			return error_guard (ncplane_perimeter_rounded (plane, stylemask, channels, ctlword), -1);
784 		}
785 
perimeter_double(uint16_t stylemask,uint64_t channels,unsigned ctlword) const786 		bool perimeter_double (uint16_t stylemask, uint64_t channels, unsigned ctlword) const NOEXCEPT_MAYBE
787 		{
788 			return error_guard (ncplane_perimeter_double (plane, stylemask, channels, ctlword), -1);
789 		}
790 
polyfill(int y,int x,const Cell & c) const791 		int polyfill (int y, int x, const Cell& c) const NOEXCEPT_MAYBE
792 		{
793 			return error_guard<int> (ncplane_polyfill_yx (plane, y, x, c), -1);
794 		}
795 
rgba(ncblitter_e blit,unsigned begy,unsigned begx,unsigned leny,unsigned lenx) const796 		uint32_t* rgba(ncblitter_e blit, unsigned begy, unsigned begx, unsigned leny, unsigned lenx) const noexcept
797 		{
798 			return ncplane_as_rgba (plane, blit, begy, begx, leny, lenx, nullptr, nullptr);
799 		}
800 
content(unsigned begy,unsigned begx,unsigned leny,unsigned lenx) const801 		char* content(unsigned begy, unsigned begx, unsigned leny, unsigned lenx) const noexcept
802 		{
803 			return ncplane_contents (plane, begy, begx, leny, lenx);
804 		}
805 
get_channels() const806 		uint64_t get_channels () const noexcept
807 		{
808 			return ncplane_channels (plane);
809 		}
810 
get_bchannel() const811 		unsigned get_bchannel () const noexcept
812 		{
813 			return ncplane_bchannel (plane);
814 		}
815 
get_fchannel() const816 		unsigned get_fchannel () const noexcept
817 		{
818 			return ncplane_fchannel (plane);
819 		}
820 
get_fg_rgb() const821 		unsigned get_fg_rgb () const noexcept
822 		{
823 			return ncplane_fg_rgb (plane);
824 		}
825 
get_bg_rgb() const826 		unsigned get_bg_rgb () const noexcept
827 		{
828 			return ncplane_bg_rgb (plane);
829 		}
830 
get_fg_alpha() const831 		unsigned get_fg_alpha () const noexcept
832 		{
833 			return ncplane_fg_alpha (plane);
834 		}
835 
set_fchannel(uint32_t channel) const836 		uint64_t set_fchannel (uint32_t channel) const noexcept
837 		{
838 			return ncplane_set_fchannel (plane, channel);
839 		}
840 
set_bchannel(uint32_t channel) const841 		uint64_t set_bchannel (uint32_t channel) const noexcept
842 		{
843 			return ncplane_set_bchannel (plane, channel);
844 		}
845 
set_channels(uint64_t channels) const846 		void set_channels (uint64_t channels) const noexcept
847 		{
848 			ncplane_set_channels (plane, channels);
849 		}
850 
set_fg_alpha(unsigned alpha) const851 		bool set_fg_alpha (unsigned alpha) const NOEXCEPT_MAYBE
852 		{
853 			return error_guard (ncplane_set_fg_alpha (plane, alpha), -1);
854 		}
855 
get_bg_alpha() const856 		unsigned get_bg_alpha () const noexcept
857 		{
858 			return ncplane_bg_alpha (plane);
859 		}
860 
set_bg_alpha(unsigned alpha) const861 		bool set_bg_alpha (unsigned alpha) const NOEXCEPT_MAYBE
862 		{
863 			return error_guard (ncplane_set_bg_alpha (plane, alpha), -1);
864 		}
865 
get_fg_rgb8(unsigned * r,unsigned * g,unsigned * b) const866 		unsigned get_fg_rgb8 (unsigned *r, unsigned *g, unsigned *b) const noexcept
867 		{
868 			return ncplane_fg_rgb8 (plane, r, g, b);
869 		}
870 
set_fg_rgb8(int r,int g,int b,bool clipped=false) const871 		bool set_fg_rgb8 (int r, int g, int b, bool clipped = false) const NOEXCEPT_MAYBE
872 		{
873 			if (clipped) {
874 				ncplane_set_fg_rgb8_clipped (plane, r, g, b);
875 				return true;
876 			}
877 
878 			return error_guard (ncplane_set_fg_rgb8 (plane, r, g, b), -1);
879 		}
880 
set_fg_palindex(int idx) const881 		bool set_fg_palindex (int idx) const NOEXCEPT_MAYBE
882 		{
883 			return error_guard (ncplane_set_fg_palindex (plane, idx), -1);
884 		}
885 
set_fg_rgb(uint32_t channel) const886 		bool set_fg_rgb (uint32_t channel) const NOEXCEPT_MAYBE
887 		{
888 			return error_guard (ncplane_set_fg_rgb (plane, channel), -1);
889 		}
890 
set_fg_default() const891 		void set_fg_default () const noexcept
892 		{
893 			ncplane_set_fg_default (plane);
894 		}
895 
get_bg_rgb8(unsigned * r,unsigned * g,unsigned * b) const896 		unsigned get_bg_rgb8 (unsigned *r, unsigned *g, unsigned *b) const noexcept
897 		{
898 			return ncplane_bg_rgb8 (plane, r, g, b);
899 		}
900 
set_bg_rgb8(int r,int g,int b,bool clipped=false) const901 		bool set_bg_rgb8 (int r, int g, int b, bool clipped = false) const NOEXCEPT_MAYBE
902 		{
903 			if (clipped) {
904 				ncplane_set_fg_rgb8_clipped (plane, r, g, b);
905 				return true;
906 			}
907 
908 			return error_guard (ncplane_set_bg_rgb8 (plane, r, g, b), -1);
909 		}
910 
set_bg_palindex(int idx) const911 		bool set_bg_palindex (int idx) const NOEXCEPT_MAYBE
912 		{
913 			return error_guard (ncplane_set_bg_alpha (plane, idx), -1);
914 		}
915 
set_bg_rgb(uint32_t channel) const916 		bool set_bg_rgb (uint32_t channel) const NOEXCEPT_MAYBE
917 		{
918 			return error_guard (ncplane_set_bg_rgb (plane, channel), -1);
919 		}
920 
set_bg_default() const921 		void set_bg_default () const noexcept
922 		{
923 			ncplane_set_bg_default (plane);
924 		}
925 
set_scrolling(bool scrollp) const926 		bool set_scrolling (bool scrollp) const noexcept
927 		{
928 			return ncplane_set_scrolling (plane, scrollp);
929 		}
930 
get_styles() const931 		unsigned get_styles () const noexcept
932 		{
933 			return ncplane_styles (plane);
934 		}
935 
styles_set(CellStyle styles) const936 		void styles_set (CellStyle styles) const noexcept
937 		{
938 			ncplane_set_styles (plane, static_cast<unsigned>(styles));
939 		}
940 
styles_on(CellStyle styles) const941 		void styles_on (CellStyle styles) const noexcept
942 		{
943 			ncplane_on_styles (plane, static_cast<unsigned>(styles));
944 		}
945 
styles_off(CellStyle styles) const946 		void styles_off (CellStyle styles) const noexcept
947 		{
948 			ncplane_off_styles (plane, static_cast<unsigned>(styles));
949 		}
950 
format(int y,int x,unsigned ylen,unsigned xlen,uint16_t stylemask) const951 		int format (int y, int x, unsigned ylen, unsigned xlen, uint16_t stylemask) const NOEXCEPT_MAYBE
952 		{
953 			return error_guard<int> (ncplane_format (plane, y, x, ylen, xlen, stylemask), -1);
954 		}
955 
stain(int y,int x,unsigned ylen,unsigned xlen,uint64_t ul,uint64_t ur,uint64_t ll,uint64_t lr) const956 		int stain (int y, int x, unsigned ylen, unsigned xlen, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr) const NOEXCEPT_MAYBE
957 		{
958 			return error_guard<int> (ncplane_stain (plane, y, x, ylen, xlen, ul, ur, ll, lr), -1);
959 		}
960 
get_below() const961 		Plane* get_below () const noexcept
962 		{
963 			return map_plane (ncplane_below (plane));
964 		}
965 
get_above() const966 		Plane* get_above () const noexcept
967 		{
968 			return map_plane (ncplane_above (plane));
969 		}
970 
set_base_cell(Cell & c) const971 		bool set_base_cell (Cell &c) const NOEXCEPT_MAYBE
972 		{
973 			bool ret = ncplane_set_base_cell (plane, c) < 0;
974 			return error_guard_cond<bool, bool> (ret, ret);
975 		}
976 
set_base(const char * egc,uint16_t stylemask,uint64_t channels) const977 		bool set_base (const char* egc, uint16_t stylemask, uint64_t channels) const NOEXCEPT_MAYBE
978 		{
979 			bool ret = ncplane_set_base (plane, egc, stylemask, channels) < 0;
980 			return error_guard_cond<bool, bool> (ret, ret);
981 		}
982 
get_base(Cell & c) const983 		bool get_base (Cell &c) const NOEXCEPT_MAYBE
984 		{
985 			bool ret = ncplane_base (plane, c) < 0;
986 			return error_guard_cond<bool, bool> (ret, ret);
987 		}
988 
at_cursor(Cell & c) const989 		int at_cursor (Cell &c) const NOEXCEPT_MAYBE
990 		{
991 			return error_guard<int>(ncplane_at_cursor_cell (plane, c), -1);
992 		}
993 
at_cursor(Cell * c) const994 		int at_cursor (Cell *c) const noexcept
995 		{
996 			if (c == nullptr)
997 				return false;
998 
999 			return at_cursor (*c);
1000 		}
1001 
at_cursor(uint16_t * stylemask,uint64_t * channels) const1002 		char* at_cursor (uint16_t* stylemask, uint64_t* channels) const
1003 		{
1004 			if (stylemask == nullptr || channels == nullptr)
1005 				return nullptr;
1006 
1007 			return ncplane_at_cursor (plane, stylemask, channels);
1008 		}
1009 
get_at(int y,int x,Cell & c) const1010 		int get_at (int y, int x, Cell &c) const NOEXCEPT_MAYBE
1011 		{
1012 			return error_guard<int> (ncplane_at_yx_cell (plane, y, x, c), -1);
1013 		}
1014 
get_at(int y,int x,Cell * c) const1015 		int get_at (int y, int x, Cell *c) const
1016 		{
1017 			if (c == nullptr)
1018 				return -1;
1019 
1020 			return get_at (y, x, *c);
1021 		}
1022 
get_at(int y,int x,uint16_t * stylemask,uint64_t * channels) const1023 		char* get_at (int y, int x, uint16_t* stylemask, uint64_t* channels) const
1024 		{
1025 			if (stylemask == nullptr || channels == nullptr)
1026 				return nullptr;
1027 
1028 			return ncplane_at_yx (plane, y, x, stylemask, channels);
1029 		}
1030 
set_userptr(void * opaque) const1031 		void* set_userptr (void *opaque) const noexcept
1032 		{
1033 			return ncplane_set_userptr (plane, opaque);
1034 		}
1035 
1036 		template<typename T>
set_userptr(T * opaque) const1037 		T* set_userptr (T *opaque) const noexcept
1038 		{
1039 			return static_cast<T*>(set_userptr (static_cast<void*>(opaque)));
1040 		}
1041 
get_userptr() const1042 		void* get_userptr () const noexcept
1043 		{
1044 			return ncplane_userptr (plane);
1045 		}
1046 
1047 		template<typename T>
get_userptr() const1048 		T* get_userptr () const noexcept
1049 		{
1050 			return static_cast<T*>(get_userptr ());
1051 		}
1052 
1053 		NcReel* ncreel_create (const ncreel_options *popts = nullptr);
1054 
1055 		// Some Cell APIs go here since they act on individual panels even though it may seem weird at points (e.g.
1056 		// release)
1057 
load_egc32(Cell & cell,uint32_t egc) const1058 		int load_egc32 (Cell &cell, uint32_t egc) const NOEXCEPT_MAYBE
1059 		{
1060 			int ret = nccell_load_egc32 (plane, cell, egc);
1061 			return error_guard_cond<int> (ret, ret != 1);
1062 		}
1063 
load(Cell & cell,const char * gcluster) const1064 		int load (Cell &cell, const char *gcluster) const NOEXCEPT_MAYBE
1065 		{
1066 			return error_guard<int> (nccell_load (plane, cell, gcluster), -1);
1067 		}
1068 
load(Cell & cell,char ch) const1069 		bool load (Cell &cell, char ch) const NOEXCEPT_MAYBE
1070 		{
1071 			return error_guard (nccell_load_char (plane, cell, ch), -1);
1072 		}
1073 
prime(Cell & cell,const char * gcluster,uint16_t styles,uint64_t channels) const1074 		int prime (Cell &cell, const char *gcluster, uint16_t styles, uint64_t channels) const NOEXCEPT_MAYBE
1075 		{
1076 			return error_guard<int> (nccell_prime (plane, cell, gcluster, styles, channels), -1);
1077 		}
1078 
release(Cell & cell) const1079 		void release (Cell &cell) const noexcept
1080 		{
1081 			nccell_release (plane, cell);
1082 		}
1083 
duplicate(Cell & target,Cell & source) const1084 		int duplicate (Cell &target, Cell &source) const NOEXCEPT_MAYBE
1085 		{
1086 			return error_guard<int> (nccell_duplicate (plane, target, source), -1);
1087 		}
1088 
duplicate(Cell & target,Cell const & source) const1089 		int duplicate (Cell &target, Cell const& source) const NOEXCEPT_MAYBE
1090 		{
1091 			return error_guard<int> (nccell_duplicate (plane, target, source), -1);
1092 		}
1093 
duplicate(Cell & target,Cell * source) const1094 		int duplicate (Cell &target, Cell *source) const
1095 		{
1096 			if (source == nullptr)
1097 				throw invalid_argument ("'source' must be a valid pointer");
1098 
1099 			return duplicate (target, *source);
1100 		}
1101 
duplicate(Cell & target,Cell const * source) const1102 		int duplicate (Cell &target, Cell const* source) const
1103 		{
1104 			if (source == nullptr)
1105 				throw invalid_argument ("'source' must be a valid pointer");
1106 
1107 			return duplicate (target, *source);
1108 		}
1109 
duplicate(Cell * target,Cell * source) const1110 		int duplicate (Cell *target, Cell *source) const
1111 		{
1112 			if (target == nullptr)
1113 				throw invalid_argument ("'target' must be a valid pointer");
1114 			if (source == nullptr)
1115 				throw invalid_argument ("'source' must be a valid pointer");
1116 
1117 			return duplicate (*target, *source);
1118 		}
1119 
duplicate(Cell * target,Cell const * source) const1120 		int duplicate (Cell *target, Cell const* source) const
1121 		{
1122 			if (target == nullptr)
1123 				throw invalid_argument ("'target' must be a valid pointer");
1124 			if (source == nullptr)
1125 				throw invalid_argument ("'source' must be a valid pointer");
1126 
1127 			return duplicate (*target, *source);
1128 		}
1129 
duplicate(Cell * target,Cell & source) const1130 		int duplicate (Cell *target, Cell &source) const
1131 		{
1132 			if (target == nullptr)
1133 				throw invalid_argument ("'target' must be a valid pointer");
1134 
1135 			return duplicate (*target, source);
1136 		}
1137 
duplicate(Cell * target,Cell const & source) const1138 		int duplicate (Cell *target, Cell const& source) const
1139 		{
1140 			if (target == nullptr)
1141 				throw invalid_argument ("'target' must be a valid pointer");
1142 
1143 			return duplicate (*target, source);
1144 		}
1145 
translate(const Plane * dst,int * y=nullptr,int * x=nullptr) const1146 		void translate (const Plane *dst, int *y = nullptr, int *x = nullptr) const noexcept
1147 		{
1148 			ncplane_translate (*this, dst ? dst->plane: nullptr, y, x);
1149 		}
1150 
translate(const Plane & dst,int * y=nullptr,int * x=nullptr) const1151 		void translate (const Plane &dst, int *y = nullptr, int *x = nullptr) const noexcept
1152 		{
1153 			translate (*this, dst, y, x);
1154 		}
1155 
translate(const Plane * src,const Plane * dst,int * y=nullptr,int * x=nullptr)1156 		static void translate (const Plane *src, const Plane *dst, int *y = nullptr, int *x = nullptr)
1157 		{
1158 			if (src == nullptr)
1159 				throw invalid_argument ("'src' must be a valid pointer");
1160 
1161 			ncplane_translate (*src, dst ? dst->plane : nullptr, y, x);
1162 		}
1163 
translate(const Plane & src,const Plane & dst,int * y=nullptr,int * x=nullptr)1164 		static void translate (const Plane &src, const Plane &dst, int *y = nullptr, int *x = nullptr) noexcept
1165 		{
1166 			ncplane_translate (src.plane, dst.plane, y, x);
1167 		}
1168 
translate_abs(int * y=nullptr,int * x=nullptr) const1169 		bool translate_abs (int *y = nullptr, int *x = nullptr) const NOEXCEPT_MAYBE
1170 		{
1171 			return error_guard<bool, bool> (ncplane_translate_abs (plane, y, x), false);
1172 		}
1173 
rotate_cw() const1174 		bool rotate_cw () const NOEXCEPT_MAYBE
1175 		{
1176 			return error_guard (ncplane_rotate_cw (plane), -1);
1177 		}
1178 
rotate_ccw() const1179 		bool rotate_ccw () const noexcept
1180 		{
1181 			return error_guard (ncplane_rotate_ccw (plane), -1);
1182 		}
1183 
strdup(Cell const & cell) const1184 		char* strdup (Cell const& cell) const noexcept
1185 		{
1186 			return nccell_strdup (plane, cell);
1187 		}
1188 
extract(Cell const & cell,uint16_t * stylemask=nullptr,uint64_t * channels=nullptr)1189 		char* extract (Cell const& cell, uint16_t *stylemask = nullptr, uint64_t *channels = nullptr)
1190 		{
1191 			return nccell_extract (plane, cell, stylemask, channels);
1192 		}
1193 
get_extended_gcluster(Cell & cell) const1194 		const char* get_extended_gcluster (Cell &cell) const noexcept
1195 		{
1196 			return nccell_extended_gcluster (plane, cell);
1197 		}
1198 
get_extended_gcluster(Cell const & cell) const1199 		const char* get_extended_gcluster (Cell const& cell) const noexcept
1200 		{
1201 			return nccell_extended_gcluster (plane, cell);
1202 		}
1203 
1204 		static Plane* map_plane (ncplane *ncp, Plane *associated_plane = nullptr) noexcept;
1205 
blit_bgrx(const void * data,int linesize,const struct ncvisual_options * vopts) const1206 		bool blit_bgrx (const void* data, int linesize, const struct ncvisual_options *vopts) const NOEXCEPT_MAYBE
1207 		{
1208 			bool ret = ncblit_bgrx (data, linesize, vopts) < 0;
1209 			return error_guard_cond<bool, bool> (ret, ret);
1210 		}
1211 
blit_rgba(const void * data,int linesize,const struct ncvisual_options * vopts) const1212 		bool blit_rgba (const void* data, int linesize, const struct ncvisual_options *vopts) const NOEXCEPT_MAYBE
1213 		{
1214 			bool ret = ncblit_rgba (data, linesize, vopts) < 0;
1215 			return error_guard_cond<bool, bool> (ret, ret);
1216 		}
1217 
qrcode(unsigned * ymax,unsigned * xmax,const void * data,size_t len) const1218 		int qrcode (unsigned* ymax, unsigned* xmax, const void *data, size_t len) const NOEXCEPT_MAYBE
1219 		{
1220 			int ret = ncplane_qrcode (plane, ymax, xmax, data, len);
1221 			return error_guard_cond<int> (ret, ret < 0);
1222 		}
1223 
is_descendant_of(const Plane & ancestor) const1224 		bool is_descendant_of (const Plane& ancestor) const noexcept
1225 		{
1226 			return ncplane_descendant_p (plane, ancestor) != 0;
1227 		}
1228 
is_fg_default() const1229 		bool is_fg_default () const noexcept
1230 		{
1231 			return ncplane_fg_default_p (plane);
1232 		}
1233 
is_bg_default() const1234 		bool is_bg_default () const noexcept
1235 		{
1236 			return ncplane_bg_default_p (plane);
1237 		}
1238 
is_valid() const1239 		bool is_valid () const noexcept
1240 		{
1241 			return plane != nullptr;
1242 		}
1243 
set_resizecb(int (* resizecb)(struct ncplane *)) const1244 		void set_resizecb (int(*resizecb)(struct ncplane*)) const noexcept
1245 		{
1246 			ncplane_set_resizecb (plane, resizecb);
1247 		}
1248 
1249 	protected:
Plane(ncplane * _plane,bool _is_stdplane)1250 		explicit Plane (ncplane *_plane, bool _is_stdplane)
1251 			: Root (nullptr),
1252 			  plane (_plane),
1253 			  is_stdplane (_is_stdplane)
1254 		{
1255 			if (_plane == nullptr)
1256 				throw invalid_argument ("_plane must be a valid pointer");
1257 		}
1258 
1259 		// This is used by child classes which cannot provide a valid ncplane* in their constructor when initializing
1260 		// the parent class (e.g. Pile)
Plane(NotCurses * ncinst=nullptr)1261 		Plane (NotCurses *ncinst = nullptr)
1262 			: Root (ncinst),
1263 			  plane (nullptr)
1264 		{}
1265 
1266 		// Can be used only once and only if plane == nullptr. Meant to be used by child classes which cannot provide a
1267 		// valid ncplane* in their constructor when initializing the parent class (e.g. Pile)
set_plane(ncplane * _plane)1268 		void set_plane (ncplane *_plane)
1269 		{
1270 			if (_plane == nullptr) {
1271 				throw invalid_argument ("_plane must be a valid pointer");
1272 			}
1273 
1274 			if (plane != nullptr) {
1275 				throw invalid_state_error ("Plane::set_plane can be called only once");
1276 			}
1277 
1278 			plane = _plane;
1279 			map_plane (plane, this);
1280 		}
1281 
release_native_plane()1282 		void release_native_plane () noexcept
1283 		{
1284 			if (plane == nullptr)
1285 				return;
1286 
1287 			unmap_plane (this);
1288 			plane = nullptr;
1289 		}
1290 
1291 		static void unmap_plane (Plane *p) noexcept;
1292 
1293 	private:
create_plane(const Plane & n,unsigned rows,unsigned cols,int yoff,int xoff,void * opaque)1294 		ncplane* create_plane (const Plane &n, unsigned rows, unsigned cols, int yoff, int xoff, void *opaque)
1295 		{
1296 			ncplane_options nopts = {
1297 				.y = yoff,
1298 				.x = xoff,
1299 				.rows = rows,
1300 				.cols = cols,
1301 				.userptr = opaque,
1302 				.name = nullptr,
1303 				.resizecb = nullptr,
1304 				.flags = 0,
1305 				.margin_b = 0,
1306 				.margin_r = 0,
1307 			};
1308 			return create_plane (n, nopts);
1309 		}
1310 
create_plane(Plane & n,unsigned rows,unsigned cols,int yoff,NCAlign align,void * opaque)1311 		ncplane* create_plane (Plane &n, unsigned rows, unsigned cols, int yoff, NCAlign align, void *opaque)
1312 		{
1313 			ncplane_options nopts = {
1314 				yoff,
1315 				static_cast<ncalign_e>(align),
1316 				rows,
1317 				cols,
1318 				opaque,
1319 				nullptr,
1320 				nullptr,
1321 				0,
1322 				0,
1323 				0,
1324 			};
1325 			return create_plane (n, nopts);
1326 		}
1327 
create_plane(const Plane & n,ncplane_options const & nopts)1328 		ncplane* create_plane (const Plane &n, ncplane_options const& nopts)
1329 		{
1330 			ncplane *ret = ncplane_create (
1331 				n.plane,
1332 				&nopts
1333 			);
1334 
1335 			if (ret == nullptr) {
1336 				throw init_error ("Notcurses failed to create an aligned plane");
1337 			}
1338 
1339 			map_plane (plane, this);
1340 			return ret;
1341 		}
1342 
duplicate_plane(const Plane & other,void * opaque)1343 		ncplane* duplicate_plane (const Plane &other, void *opaque)
1344 		{
1345 			ncplane *ret = ncplane_dup (other.plane, opaque);
1346 			if (ret == nullptr)
1347 				throw init_error ("Notcurses failed to duplicate plane");
1348 
1349 			return ret;
1350 		}
1351 
1352 	private:
1353 		ncplane *plane = nullptr;
1354 		bool is_stdplane = false;
1355 		static std::map<ncplane*,Plane*> *plane_map;
1356 		static std::mutex plane_map_mutex;
1357 
1358 		friend class NotCurses;
1359 		friend class NcReel;
1360 		friend class Tablet;
1361 		friend class Widget;
1362 		template<typename TPlot, typename TCoord> friend class PlotBase;
1363 	};
1364 }
1365 #endif
1366