normalize geometry for ncvisual_from_plane, ncplane_contents, and ncplane_as_rgba() #1696

pull/2331/head
nick black 3 years ago committed by nick black
parent 3bdbf6e2e2
commit d80884ea48

@ -12,6 +12,11 @@ rearrangements of Notcurses.
deprecated functionality, ABI3 ought require small changes, if any.
* 2.4.9 (not yet released)
* The handling of geometry and distance has been normalized across all
functions. Lengths are now `unsigned` as opposed to `int`. Where -1 was
being used to indicate "everything", 0 is now required. This affects
`ncplane_as_rgba()`, `ncplane_contents()`, and `ncvisual_from_plane()`,
which all used -1.
* `ncvisual_geom()` has been introduced, using the `ncvgeom` struct
introduced for direct mode. This allows complete statement of geometry
for an `ncvisual`. It replaces `ncvisual_blitter_geom()`, which has been

@ -1214,16 +1214,19 @@ int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c);
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
// 'lenx' can be specified as -1 to go through the boundary of the plane.
// 'lenx' can be specified as 0 to go through the boundary of the plane.
// Only glyphs from the specified blitset may be present. If 'pxdimy' and/or
// 'pxdimx' are non-NULL, they will be filled in with the pixel geometry.
uint32_t* ncplane_as_rgba(const struct ncplane* n, ncblitter_e blit,
int begy, int begx, int leny, int lenx,
int* pxdimy, int* pxdimx);
unsigned begy, unsigned begx, unsigned leny,
unsigned lenx, unsigned* pxdimy, unsigned* pxdimx);
// return a nul-terminated, heap copy of the current (UTF-8) contents.
char* ncplane_contents(const struct ncplane* nc, int begy, int begx,
int leny, int lenx);
// Create a flat string from the EGCs of the selected region of the ncplane
// 'n'. Start at the plane's 'begy'x'begx' coordinate (which must lie on the
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
// 'lenx' can be specified as 0 to go through the boundary of the plane.
char* ncplane_contents(const struct ncplane* nc, unsigned begy, unsigned begx,
unsigned leny, unsigned lenx);
// Manipulate the opaque user pointer associated with this plane.
// ncplane_set_userptr() returns the previous userptr after replacing
@ -3291,8 +3294,11 @@ struct ncvisual* ncvisual_from_palidx(const void* data, int rows,
// glyph will result in a NULL being returned. This function exists so that
// planes can be subjected to ncvisual transformations. If possible, it's
// better to create the ncvisual from memory using ncvisual_from_rgba().
struct ncvisual* ncvisual_from_plane(const struct ncplane* n, ncblitter_e blit,
int begy, int begx, int leny, int lenx);
// Lengths of 0 are interpreted to mean "all available remaining area".
struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
ncblitter_e blit,
unsigned begy, unsigned begx,
unsigned leny, unsigned lenx);
```
Various transformations can be applied to an `ncvisual`, regardless of how

@ -123,9 +123,9 @@ typedef struct ncplane_options {
**int ncplane_at_yx_cell(struct ncplane* ***n***, int ***y***, int ***x***, nccell* ***c***);**
**uint32_t* ncplane_as_rgba(const struct ncplane* ***nc***, ncblitter_e ***blit***, int ***begy***, int ***begx***, int ***leny***, int ***lenx***, int* ***pxdimy***, int* ***pxdimx***);**
**uint32_t* ncplane_as_rgba(const struct ncplane* ***nc***, ncblitter_e ***blit***, unsigned ***begy***, unsigned ***begx***, unsigned ***leny***, unsigned ***lenx***, unsigned* ***pxdimy***, unsigned* ***pxdimx***);**
**char* ncplane_contents(const struct ncplane* ***nc***, int ***begy***, int ***begx***, int ***leny***, int ***lenx***);**
**char* ncplane_contents(const struct ncplane* ***nc***, unsigned ***begy***, unsigned ***begx***, unsigned ***leny***, unsigned ***lenx***);**
**void* ncplane_set_userptr(struct ncplane* ***n***, void* ***opaque***);**

@ -77,7 +77,7 @@ typedef struct ncvgeom {
**struct ncvisual* ncvisual_from_palidx(const void* ***data***, int ***rows***, int ***rowstride***, int ***cols***, int ***palsize***, int ***pstride***, const uint32_t* ***palette***);**
**struct ncvisual* ncvisual_from_plane(struct ncplane* ***n***, ncblitter_e ***blit***, int ***begy***, int ***begx***, int ***leny***, int ***lenx***);**
**struct ncvisual* ncvisual_from_plane(struct ncplane* ***n***, ncblitter_e ***blit***, unsigned ***begy***, unsigned ***begx***, unsigned ***leny***, unsigned ***lenx***);**
**int ncvisual_geom(const struct notcurses* ***nc***, const struct ncvisual* ***n***, const struct ncvisual_options* ***vopts***, ncvgeom* ***geom***);**

@ -32,7 +32,7 @@ namespace ncpp
throw init_error ("Notcurses failed to create a new visual");
}
explicit Visual (const Plane& p, ncblitter_e blit, int begy, int begx, int leny, int lenx)
explicit Visual (const Plane& p, ncblitter_e blit, unsigned begy, unsigned begx, unsigned leny, unsigned lenx)
: Root (NotCurses::get_instance ())
{
visual = ncvisual_from_plane (p, blit, begy, begx, leny, lenx);

@ -1763,9 +1763,9 @@ API int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c);
// Create a flat string from the EGCs of the selected region of the ncplane
// 'n'. Start at the plane's 'begy'x'begx' coordinate (which must lie on the
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
// 'lenx' can be specified as -1 to go through the boundary of the plane.
API char* ncplane_contents(struct ncplane* n, int begy, int begx,
int leny, int lenx);
// 'lenx' can be specified as 0 to go through the boundary of the plane.
API char* ncplane_contents(struct ncplane* n, unsigned begy, unsigned begx,
unsigned leny, unsigned lenx);
// Manipulate the opaque user pointer associated with this plane.
// ncplane_set_userptr() returns the previous userptr after replacing
@ -1783,12 +1783,13 @@ API void ncplane_center_abs(const struct ncplane* n, int* RESTRICT y,
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
// 'lenx' can be specified as -1 to go through the boundary of the plane.
// 'lenx' can be specified as 0 to go through the boundary of the plane.
// Only glyphs from the specified ncblitset may be present. If 'pxdimy' and/or
// 'pxdimx' are non-NULL, they will be filled in with the pixel geometry.
// 'pxdimx' are non-NULL, they will be filled in with the total pixel geometry.
API ALLOC uint32_t* ncplane_as_rgba(const struct ncplane* n, ncblitter_e blit,
int begy, int begx, int leny, int lenx,
int* pxdimy, int* pxdimx)
unsigned begy, unsigned begx,
unsigned leny, unsigned lenx,
unsigned* pxdimy, unsigned* pxdimx)
__attribute__ ((nonnull (1)));
// Return the offset into 'availu' at which 'u' ought be output given the
@ -2832,10 +2833,12 @@ API ALLOC struct ncvisual* ncvisual_from_palidx(const void* data, int rows,
// glyph will result in a NULL being returned. This function exists so that
// planes can be subjected to ncvisual transformations. If possible, it's
// better to create the ncvisual from memory using ncvisual_from_rgba().
// Lengths of 0 are interpreted to mean "all available remaining area".
API ALLOC struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
ncblitter_e blit,
int begy, int begx,
int leny, int lenx);
unsigned begy, unsigned begx,
unsigned leny, unsigned lenx)
__attribute__ ((nonnull (1)));
#define NCVISUAL_OPTION_NODEGRADE 0x0001ull // fail rather than degrade
#define NCVISUAL_OPTION_BLEND 0x0002ull // use NCALPHA_BLEND with visual

@ -2837,44 +2837,36 @@ is_bg_p(int idx, int py, int px, int width){
static inline uint32_t*
ncplane_as_rgba_internal(const ncplane* nc, ncblitter_e blit,
int begy, int begx, int leny, int lenx,
int* pxdimy, int* pxdimx){
unsigned begy, unsigned begx, unsigned leny,
unsigned lenx, unsigned* pxdimy, unsigned* pxdimx){
const notcurses* ncur = ncplane_notcurses_const(nc);
if(begy < 0 || begx < 0){
logerror("Nil offset (%d,%d)\n", begy, begx);
if(begx >= (unsigned)nc->lenx || begy >= (unsigned)nc->leny){
logerror("invalid origin (%u,%u)\n", begy, begx);
return NULL;
}
if(begx >= nc->lenx || begy >= nc->leny){
logerror("Invalid offset (%d,%d)\n", begy, begx);
return NULL;
}
if(lenx == -1){ // -1 means "to the end"; use all space available
if(lenx == 0){ // -1 means "to the end"; use all space available
lenx = nc->lenx - begx;
}
if(leny == -1){
if(leny == 0){
leny = nc->leny - begy;
}
if(lenx <= 0 || leny <= 0){ // no need to draw zero-size object, exit
logerror("Nil geometry (%dx%d)\n", leny, lenx);
return NULL;
}
//fprintf(stderr, "sum: %d/%d avail: %d/%d\n", begy + leny, begx + lenx, nc->leny, nc->lenx);
if(begx + lenx > nc->lenx || begy + leny > nc->leny){
logerror("Invalid specs %d + %d > %d or %d + %d > %d\n",
if(nc->lenx - begx < lenx || nc->leny - begy < leny){
logerror("invalid specs %u + %u > %d or %u + %u > %d\n",
begx, lenx, nc->lenx, begy, leny, nc->leny);
return NULL;
}
if(blit == NCBLIT_PIXEL){ // FIXME extend this to support sprixels
logerror("Pixel blitter %d not yet supported\n", blit);
logerror("pixel blitter %d not yet supported\n", blit);
return NULL;
}
if(blit == NCBLIT_DEFAULT){
logerror("Must specify exact blitter, not NCBLIT_DEFAULT\n");
logerror("must specify exact blitter, not NCBLIT_DEFAULT\n");
return NULL;
}
const struct blitset* bset = lookup_blitset(&ncur->tcache, blit, false);
if(bset == NULL){
logerror("Blitter %d invalid in current environment\n", blit);
logerror("blitter %d invalid in current environment\n", blit);
return NULL;
}
//fprintf(stderr, "ALLOCATING %u %d %d %p\n", 4u * lenx * leny * 2, leny, lenx, bset);
@ -2887,8 +2879,8 @@ ncplane_as_rgba_internal(const ncplane* nc, ncblitter_e blit,
uint32_t* ret = malloc(sizeof(*ret) * lenx * bset->width * leny * bset->height);
//fprintf(stderr, "GEOM: %d/%d %d/%d ret: %p\n", bset->height, bset->width, *pxdimy, *pxdimx, ret);
if(ret){
for(int y = begy, targy = 0 ; y < begy + leny ; ++y, targy += bset->height){
for(int x = begx, targx = 0 ; x < begx + lenx ; ++x, targx += bset->width){
for(unsigned y = begy, targy = 0 ; y < begy + leny ; ++y, targy += bset->height){
for(unsigned x = begx, targx = 0 ; x < begx + lenx ; ++x, targx += bset->width){
uint16_t stylemask;
uint64_t channels;
char* c = ncplane_at_yx(nc, y, x, &stylemask, &channels);
@ -2941,9 +2933,9 @@ ncplane_as_rgba_internal(const ncplane* nc, ncblitter_e blit,
}
uint32_t* ncplane_as_rgba(const ncplane* nc, ncblitter_e blit,
int begy, int begx, int leny, int lenx,
int* pxdimy, int* pxdimx){
int px, py;
unsigned begy, unsigned begx, unsigned leny,
unsigned lenx, unsigned* pxdimy, unsigned* pxdimx){
unsigned px, py;
if(!pxdimy){
pxdimy = &py;
}
@ -2954,36 +2946,28 @@ uint32_t* ncplane_as_rgba(const ncplane* nc, ncblitter_e blit,
}
// return a heap-allocated copy of the contents
char* ncplane_contents(ncplane* nc, int begy, int begx, int leny, int lenx){
if(begy < 0 || begx < 0){
logerror("Beginning coordinates (%d/%d) below 0\n", begy, begx);
return NULL;
}
if(begx >= nc->lenx || begy >= nc->leny){
logerror("Beginning coordinates (%d/%d) exceeded lengths (%d/%d)\n",
char* ncplane_contents(ncplane* nc, unsigned begy, unsigned begx, unsigned leny, unsigned lenx){
if(begx >= (unsigned)nc->lenx || begy >= (unsigned)nc->leny){
logerror("beginning coordinates (%u/%u) exceeded area (%d/%d)\n",
begy, begx, nc->leny, nc->lenx);
return NULL;
}
if(lenx == -1){ // -1 means "to the end"; use all space available
if(lenx == 0){ // 0 means "to the end"; use all space available
lenx = nc->lenx - begx;
}
if(leny == -1){
if(leny == 0){
leny = nc->leny - begy;
}
if(lenx < 0 || leny < 0){ // no need to draw zero-size object, exit
logerror("Lengths (%d/%d) below 0\n", leny, lenx);
return NULL;
}
if(begx + lenx > nc->lenx || begy + leny > nc->leny){
logerror("Ending coordinates (%d/%d) exceeded lengths (%d/%d)\n",
if(nc->lenx - begx < lenx || nc->leny - begy < leny){
logerror("ending coordinates (%u/%u) exceeded lengths (%d/%d)\n",
begy + leny, begx + lenx, nc->leny, nc->lenx);
return NULL;
}
size_t retlen = 1;
char* ret = malloc(retlen);
if(ret){
for(int y = begy, targy = 0 ; y < begy + leny ; ++y, targy += 2){
for(int x = begx, targx = 0 ; x < begx + lenx ; ++x, ++targx){
for(unsigned y = begy, targy = 0 ; y < begy + leny ; ++y, targy += 2){
for(unsigned x = begx, targx = 0 ; x < begx + lenx ; ++x, ++targx){
nccell ncl = CELL_TRIVIAL_INITIALIZER;
// we need ncplane_at_yx_cell() here instead of ncplane_at_yx(),
// because we should only have one copy of each wide EGC.

@ -381,7 +381,7 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){
}
char* ncreader_contents(const ncreader* n){
return ncplane_contents(n->ncp, 0, 0, -1, -1);
return ncplane_contents(n->ncp, 0, 0, 0, 0);
}
void ncreader_destroy(ncreader* n, char** contents){

@ -1190,9 +1190,10 @@ ncplane* ncvisual_render(notcurses* nc, ncvisual* ncv, const struct ncvisual_opt
return ncvisual_blit(nc, ncv, vopts);
}
ncvisual* ncvisual_from_plane(const ncplane* n, ncblitter_e blit, int begy, int begx,
int leny, int lenx){
int py, px;
ncvisual* ncvisual_from_plane(const ncplane* n, ncblitter_e blit,
unsigned begy, unsigned begx,
unsigned leny, unsigned lenx){
unsigned py, px;
uint32_t* rgba = ncplane_as_rgba(n, blit, begy, begx, leny, lenx, &py, &px);
//fprintf(stderr, "snarg: %d/%d @ %d/%d (%p)\n", leny, lenx, begy, begx, rgba);
if(rgba == NULL){

@ -94,7 +94,7 @@ TEST_CASE("Ncpp"
REQUIRE(n);
// FIXME load it into visual, erase plane, render visual, check for equivalence...
{
Visual v = Visual(*n, NCBLIT_1x1, 0, 0, -1, -1);
Visual v = Visual(*n, NCBLIT_1x1, 0, 0, 0, 0);
}
}
CHECK(nc.stop());

@ -166,8 +166,8 @@ TEST_CASE("Blit") {
CHECK(0 == notcurses_render(nc_));
CHECK(1 == ncplane_dim_y(p));
CHECK(2 == ncplane_dim_x(p));
int pxdimy, pxdimx;
auto edata = ncplane_as_rgba(p, vopts.blitter, 0, 0, -1, -1, &pxdimy, &pxdimx);
unsigned pxdimy, pxdimx;
auto edata = ncplane_as_rgba(p, vopts.blitter, 0, 0, 0, 0, &pxdimy, &pxdimx);
REQUIRE(nullptr != edata);
CHECK(0 == memcmp(data, edata, sizeof(data)));
free(edata);
@ -193,8 +193,8 @@ TEST_CASE("Blit") {
REQUIRE(nullptr != p);
CHECK(1 == ncplane_dim_y(p));
CHECK(4 == ncplane_dim_x(p));
int pxdimy, pxdimx;
auto edata = ncplane_as_rgba(p, vopts.blitter, 0, 0, -1, -1, &pxdimy, &pxdimx);
unsigned pxdimy, pxdimx;
auto edata = ncplane_as_rgba(p, vopts.blitter, 0, 0, 0, 0, &pxdimy, &pxdimx);
REQUIRE(nullptr != edata);
for(size_t i = 0 ; i < sizeof(data) / sizeof(*data) ; ++i){
CHECK(edata[i] == data[i]);
@ -238,8 +238,8 @@ TEST_CASE("Blit") {
REQUIRE(nullptr != p);
CHECK(1 == ncplane_dim_y(p));
CHECK(16 == ncplane_dim_x(p));
int pxdimy, pxdimx;
auto edata = ncplane_as_rgba(p, vopts.blitter, 0, 0, -1, -1, &pxdimy, &pxdimx);
unsigned pxdimy, pxdimx;
auto edata = ncplane_as_rgba(p, vopts.blitter, 0, 0, 0, 0, &pxdimy, &pxdimx);
REQUIRE(nullptr != edata);
for(size_t i = 0 ; i < sizeof(data) / sizeof(*data) ; ++i){
CHECK(edata[i] == data[i]);

@ -91,7 +91,9 @@ TEST_CASE("Palette256") {
nccell_release(n_, &c);
CHECK(0 == notcurses_render(nc_));
nccell r = CELL_TRIVIAL_INITIALIZER;
CHECK(nullptr != notcurses_at_yx(nc_, 0, 0, &r.stylemask, &r.channels));
auto egc = notcurses_at_yx(nc_, 0, 0, &r.stylemask, &r.channels);
CHECK(nullptr != egc);
free(egc);
CHECK(nccell_fg_palindex_p(&r));
CHECK(nccell_bg_palindex_p(&r));
CHECK(NCALPHA_OPAQUE == nccell_fg_alpha(&r));

@ -175,9 +175,9 @@ TEST_CASE("Rotate") {
opts.flags = NCVISUAL_OPTION_CHILDPLANE;
auto rendered = ncvisual_blit(nc_, ncv, &opts);
REQUIRE(rendered);
int pxdimy, pxdimx;
unsigned pxdimy, pxdimx;
uint32_t* rgbaret = ncplane_as_rgba(rendered, NCBLIT_2x1,
0, 0, -1, -1, &pxdimy, &pxdimx);
0, 0, 0, 0, &pxdimy, &pxdimx);
REQUIRE(rgbaret);
if(height % 2){
++height;
@ -237,9 +237,9 @@ TEST_CASE("Rotate") {
opts.flags = NCVISUAL_OPTION_CHILDPLANE;
auto rendered = ncvisual_blit(nc_, ncv, &opts);
REQUIRE(rendered);
int pxdimy, pxdimx;
unsigned pxdimy, pxdimx;
uint32_t* rgbaret = ncplane_as_rgba(rendered, NCBLIT_2x1,
0, 0, -1, -1, &pxdimy, &pxdimx);
0, 0, 0, 0, &pxdimy, &pxdimx);
REQUIRE(rgbaret);
if(height % 2){
++height;

@ -37,7 +37,8 @@ TEST_CASE("Selectors") {
SUBCASE("TitledSelector") {
struct ncselector_options opts{};
opts.title = strdup("hey hey whaddya say");
auto title = strdup("hey hey whaddya say");
opts.title = title;
struct ncplane_options nopts = {
.y = 0,
.x = 0,
@ -57,11 +58,13 @@ TEST_CASE("Selectors") {
CHECK(6 == dimy);
CHECK(strlen(opts.title) + 4 == dimx);
ncselector_destroy(ncs, nullptr);
free(title);
}
SUBCASE("SecondarySelector") {
struct ncselector_options opts{};
opts.secondary = strdup("this is not a title, but it's not *not* a title");
auto secondary = strdup("this is not a title, but it's not *not* a title");
opts.secondary = secondary;
struct ncplane_options nopts = {
.y = 0,
.x = 0,
@ -81,11 +84,13 @@ TEST_CASE("Selectors") {
CHECK(4 == dimy);
CHECK(strlen(opts.secondary) + 2 == dimx);
ncselector_destroy(ncs, nullptr);
free(secondary);
}
SUBCASE("FooterSelector") {
struct ncselector_options opts{};
opts.footer = strdup("i am a lone footer, little old footer");
auto foot = strdup("i am a lone footer, little old footer");
opts.footer = foot;
struct ncplane_options nopts = {
.y = 0,
.x = 0,
@ -105,6 +110,7 @@ TEST_CASE("Selectors") {
CHECK(4 == dimy);
CHECK(strlen(opts.footer) + 2 == dimx);
ncselector_destroy(ncs, nullptr);
free(foot);
}
SUBCASE("PopulatedSelector") {

@ -105,7 +105,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "my nuclear arms"));
free(line);
@ -132,7 +132,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "my grasping arms"));
free(line);
@ -159,7 +159,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "abcde")); // FIXME should have newlines
free(line);
@ -186,7 +186,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "abcdefgh"));
free(line);
@ -214,7 +214,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, boundstr));
free(line);
@ -243,7 +243,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "my thermonuclear arms"));
free(line);
@ -272,7 +272,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "1 我能吞下玻璃"));
free(line);
@ -299,7 +299,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, " my thermonuclear arms"));
free(line);
@ -326,7 +326,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "quarkgluonfart "));
free(line);
@ -353,7 +353,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "quark gluon fart "));
free(line);
@ -380,7 +380,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "quantum balls"));
free(line);
@ -407,7 +407,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "quantum balls scratchy no?! "));
free(line);
@ -434,7 +434,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "0123456789AB"));
free(line);
@ -462,7 +462,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "我能吞 下玻璃 "));
free(line);
@ -492,7 +492,7 @@ TEST_CASE("TextLayout") {
CHECK(0 > res);
CHECK(0 == notcurses_render(nc_));
CHECK(bytes < strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "quantum balls scratchy no?! "));
free(line);
@ -519,7 +519,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, boundstr, &bytes));
CHECK(0 == notcurses_render(nc_));
CHECK(bytes == strlen(boundstr));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "scratchy?! true! arrrrp"));
free(line);
@ -553,7 +553,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, text, &bytes));
CHECK(bytes == strlen(text));
CHECK(0 == notcurses_render(nc_));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ornare neque ac ipsum viverra, vestibulum hendrerit leo consequat. Integer velit, pharetra sed nisl quis, porttitor ornare purus. Cras ac sollicitudin dolor, eget elementum dolor. Quisque lobortis sagittis."));
free(line);
@ -589,7 +589,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, text, &bytes));
CHECK(bytes == strlen(text));
CHECK(0 == notcurses_render(nc_));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "to be selected from a list of n items. NCFdplane streams a file descriptor, while NCSubproc spawns a subprocess and streams its output. A variety of plots are supported, and menus can be placed along the top and/or bottom of any plane.Widgets can be controlled with the keyboard and/or mouse. They are implemented atop ncplanes, and these planes can be manipulated like all others."));
free(line);
@ -626,7 +626,7 @@ TEST_CASE("TextLayout") {
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_LEFT, text, &bytes));
CHECK(bytes == strlen(text));
CHECK(0 == notcurses_render(nc_));
char* line = ncplane_contents(sp, 0, 0, -1, -1);
char* line = ncplane_contents(sp, 0, 0, 0, 0);
REQUIRE(line);
CHECK(0 == strcmp(line, "Notcurses provides several widgets to quickly build vivid TUIs.This NCReader widget facilitates free-form text entry complete with readline-style bindings. NCSelector allows a single option to be selected from a list. NCMultiselector allows 0..n options to be selected from a list of n items. NCFdplane streams a file descriptor, while NCSubproc spawns a subprocess and streams its output. A variety of plots are supported, and menus can be placed along the top and/or bottom of any plane.Widgets can be controlled with the keyboard and/or mouse. They are implemented atop ncplanes, and these planes can be manipulated like all others."));
free(line);

Loading…
Cancel
Save