mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
ncvisual_rotate() for arbitrary radians (#600)
* normal/visual: need dup stdplane for rotate * add ncplane_center(), unit tests * ncplane_center_abs(): add, unit tests * ncvisual_bounding_box() for #599 * ncvisual_rotate(): works via bounding box #599 * normal demo: comment out broken section * rotate: resize underlying plane as needed #599 * ncvisual_rotate: support negative rads #599
This commit is contained in:
parent
420ef740b1
commit
f602c440a6
@ -35,12 +35,17 @@ offset(uint32_t* rgba, int y, int x, int dx){
|
||||
// make a pixel array out from the center, blitting it as we go
|
||||
int normal_demo(struct notcurses* nc){
|
||||
int dy, dx;
|
||||
struct ncplane* n = notcurses_stddim_yx(nc, &dy, &dx);
|
||||
// we can't resize (and thus can't rotate) the standard plane, so dup it
|
||||
struct ncplane* n = ncplane_dup(notcurses_stddim_yx(nc, &dy, &dx), NULL);
|
||||
if(n == NULL){
|
||||
return -1;
|
||||
}
|
||||
ncplane_erase(n);
|
||||
struct ncvisual* ncv = NULL;
|
||||
dy *= VSCALE; // double-block trick means both 2x resolution and even linecount yay
|
||||
uint32_t* rgba = malloc(sizeof(*rgba) * dy * dx);
|
||||
if(!rgba){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
memset(rgba, 0, sizeof(*rgba) * dy * dx);
|
||||
int y;
|
||||
@ -48,38 +53,47 @@ int normal_demo(struct notcurses* nc){
|
||||
y = dy / VSCALE + 1;
|
||||
for(int x = 0 ; x < dx ; ++x){
|
||||
if(mcell(offset(rgba, y, x, dx), y, x, dy / VSCALE, dx)){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(y = 0 ; y < dy / 2 ; ++y){
|
||||
for(int x = 0 ; x < dx ; ++x){
|
||||
if(mcell(offset(rgba, dy / 2 - y, x, dx), dy / 2 - y, x, dy, dx)){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
if(mcell(offset(rgba, dy / 2 + y - 1, x, dx), dy / 2 + y - 1, x, dy, dx)){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if(ncblit_rgba(n, 0, 0, dx * sizeof(*rgba), rgba, 0, 0, dy, dx) < 0){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
DEMO_RENDER(nc);
|
||||
}
|
||||
free(rgba);
|
||||
struct ncvisual* ncv = ncvisual_from_plane(n, 0, 0, -1, -1);
|
||||
rgba = NULL;
|
||||
// FIXME ncvisual_from_plane is failing
|
||||
/*ncv = ncvisual_from_plane(n, 0, 0, -1, -1);
|
||||
if(!ncv){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
for(int i = 1 ; i < 100 ; ++i){
|
||||
if(ncvisual_rotate(ncv, M_PI / 2)){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
if(ncvisual_render(ncv, 0, 0, -1, -1) <= 0){
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
DEMO_RENDER(nc);
|
||||
}
|
||||
}*/
|
||||
ncvisual_destroy(ncv);
|
||||
ncplane_destroy(n);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free(rgba);
|
||||
ncvisual_destroy(ncv);
|
||||
ncplane_destroy(n);
|
||||
return -1;
|
||||
}
|
||||
|
@ -643,10 +643,43 @@ ncplane* rotate_plane(const ncplane* n);
|
||||
|
||||
void* bgra_to_rgba(const void* data, int rows, int rowstride, int cols);
|
||||
|
||||
static inline void
|
||||
center_box(int* RESTRICT y, int* RESTRICT x){
|
||||
if(y){
|
||||
*y = (*y - 1) / 2;
|
||||
}
|
||||
if(x){
|
||||
*x = (*x - 1) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// find the "center" cell of a plane. in the case of even rows/columns, we
|
||||
// place the center on the top/left. in such a case there will be one more
|
||||
// cell to the bottom/right of the center.
|
||||
void ncplane_center(const ncplane* n, int* y, int* x);
|
||||
static inline void
|
||||
ncplane_center(const ncplane* n, int* RESTRICT y, int* RESTRICT x){
|
||||
*y = n->leny;
|
||||
*x = n->lenx;
|
||||
center_box(y, x);
|
||||
}
|
||||
|
||||
// find the center coordinate of a plane, preferring the top/left in the
|
||||
// case of an even number of rows/columns (in such a case, there will be one
|
||||
// more cell to the bottom/right of the center than the top/left). the
|
||||
// center is then modified relative to the plane's origin.
|
||||
static inline void
|
||||
ncplane_center_abs(const ncplane* n, int* RESTRICT y, int* RESTRICT x){
|
||||
ncplane_center(n, y, x);
|
||||
if(y){
|
||||
*y += n->absy;
|
||||
}
|
||||
if(x){
|
||||
*x += n->absx;
|
||||
}
|
||||
}
|
||||
|
||||
int ncvisual_bounding_box(const struct ncvisual* ncv, int* leny, int* lenx,
|
||||
int* offy, int* offx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ int ncplane_resize_internal(ncplane* n, int keepy, int keepx, int keepleny,
|
||||
int ncplane_resize(ncplane* n, int keepy, int keepx, int keepleny,
|
||||
int keeplenx, int yoff, int xoff, int ylen, int xlen){
|
||||
if(n == n->nc->stdscr){
|
||||
//fprintf(stderr, "Can't resize standard plane\n");
|
||||
fprintf(stderr, "Can't resize standard plane\n");
|
||||
return -1;
|
||||
}
|
||||
return ncplane_resize_internal(n, keepy, keepx, keepleny, keeplenx,
|
||||
|
@ -349,8 +349,6 @@ paint(ncplane* p, cell* lastframe, struct crender* rvec,
|
||||
fprintf(stderr, "WROTE %u [%c] to %d/%d (%d/%d)\n", targc->gcluster, prevcell->gcluster, y, x, absy, absx);
|
||||
}else{
|
||||
fprintf(stderr, "WROTE %u [%s] to %d/%d (%d/%d)\n", targc->gcluster, extended_gcluster(crender->p, targc), y, x, absy, absx);
|
||||
}
|
||||
fprintf(stderr, "POOL: %p NC: %p SRC: %p\n", pool->pool, nc, crender->p);
|
||||
}*/
|
||||
if(cellcmp_and_dupfar(pool, prevcell, crender->p, targc)){
|
||||
crender->damaged = true;
|
||||
|
@ -113,8 +113,7 @@ auto ncvisual_from_plane(const ncplane* n, int begy, int begx, int leny, int len
|
||||
}
|
||||
int dimy, dimx;
|
||||
ncplane_dim_yx(n, &dimy, &dimx);
|
||||
// FIXME needs to make use of begy, begx, leny, lenx!
|
||||
auto* ncv = ncvisual_from_rgba(n->nc, rgba, n->leny, n->lenx * 4, n->lenx);
|
||||
auto* ncv = ncvisual_from_rgba(n->nc, rgba, leny, lenx * 4, lenx);
|
||||
if(ncv == nullptr){
|
||||
free(rgba);
|
||||
return nullptr;
|
||||
@ -156,78 +155,169 @@ auto ncvisual_setplane(ncvisual* ncv, ncplane* n) -> int {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if we're rotating around our center, we can't require any radius greater
|
||||
// than our longer length. rotation can thus be held entirely within a square
|
||||
// plane having length of our longest length. after one rotation, this decays
|
||||
// to the same square throughout any rotations.
|
||||
static auto
|
||||
rotate_new_geom(ncvisual* ncv, double rads, double *stheta, double *ctheta) -> int {
|
||||
*stheta = sin(rads);
|
||||
*ctheta = cos(rads);
|
||||
const int scaledy = ncv->ncp->leny * encoding_vert_scale(ncv);
|
||||
const int diam = scaledy < ncv->ncp->lenx ? ncv->ncp->lenx : scaledy;
|
||||
//fprintf(stderr, "rotating %d -> %d / %d\n", ncv->ncp->leny, scaledy, ncv->ncp->lenx);
|
||||
if(ncv->ncp->lenx != scaledy){
|
||||
if(ncplane_resize_simple(ncv->ncp, diam / encoding_vert_scale(ncv), diam) < 0){
|
||||
return -1;
|
||||
// Inspects the visual to find the minimum rectangle that can contain all
|
||||
// "real" pixels, where "real" pixels are, by convention, all zeroes.
|
||||
// Placing this box at offyXoffx relative to the visual will encompass all
|
||||
// pixels. Returns the area of the box (0 if there are no pixels).
|
||||
auto ncvisual_bounding_box(const ncvisual* ncv, int* leny, int* lenx,
|
||||
int* offy, int* offx) -> int {
|
||||
int trow, lcol, rcol;
|
||||
// first, find the topmost row with a real pixel. if there is no such row,
|
||||
// there are no such pixels. if we find one, we needn't look in this region
|
||||
// for other extrema, so long as we keep the leftmost and rightmost through
|
||||
// this row (from the top). said leftmost and rightmost will be the leftmost
|
||||
// and rightmost pixel of whichever row has the topmost valid pixel. unlike
|
||||
// the topmost, they'll need be further verified.
|
||||
for(trow = 0 ; trow < ncv->dstheight ; ++trow){
|
||||
int x;
|
||||
for(x = 0 ; x < ncv->dstwidth ; ++x){
|
||||
uint32_t rgba = ncv->data[trow * ncv->rowstride / 4 + x];
|
||||
if(rgba){
|
||||
lcol = x; // leftmost pixel of topmost row
|
||||
// now find rightmost pixel of topmost row
|
||||
int xr;
|
||||
for(xr = ncv->dstwidth - 1 ; xr > x ; --xr){
|
||||
rgba = ncv->data[trow * ncv->rowstride / 4 + xr];
|
||||
if(rgba){ // rightmost pixel of topmost row
|
||||
break;
|
||||
}
|
||||
}
|
||||
rcol = xr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(x < ncv->dstwidth){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return diam;
|
||||
if(trow == ncv->dstheight){ // no real pixels
|
||||
*leny = 0;
|
||||
*lenx = 0;
|
||||
*offy = 0;
|
||||
*offx = 0;
|
||||
}else{
|
||||
assert(lcol >= 0);
|
||||
assert(rcol < ncv->dstwidth);
|
||||
// we now know topmost row, and left/rightmost through said row. now we must
|
||||
// find the bottommost row, checking left/rightmost throughout.
|
||||
int brow;
|
||||
for(brow = ncv->dstheight - 1 ; brow > trow ; --brow){
|
||||
int x;
|
||||
for(x = 0 ; x < ncv->dstwidth ; ++x){
|
||||
uint32_t rgba = ncv->data[brow * ncv->rowstride / 4 + x];
|
||||
if(rgba){
|
||||
if(x < lcol){
|
||||
lcol = x;
|
||||
}
|
||||
int xr;
|
||||
for(xr = ncv->dstwidth - 1 ; xr > x && xr > rcol ; --xr){
|
||||
rgba = ncv->data[brow * ncv->rowstride / 4 + xr];
|
||||
if(rgba){ // rightmost pixel of topmost row
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(xr > rcol){
|
||||
rcol = xr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(x < ncv->dstwidth){
|
||||
break;
|
||||
}
|
||||
}
|
||||
// we now know topmost and bottommost row, and left/rightmost within those
|
||||
// two sections. now check the rest for left and rightmost.
|
||||
for(int y = trow + 1 ; y < brow ; ++y){
|
||||
for(int x = 0 ; x < lcol ; ++x){
|
||||
uint32_t rgba = ncv->data[y * ncv->rowstride / 4 + x];
|
||||
if(rgba){
|
||||
lcol = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(int x = ncv->dstwidth ; x > rcol ; --x){
|
||||
uint32_t rgba = ncv->data[y * ncv->rowstride / 4 + x];
|
||||
if(rgba){
|
||||
rcol = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*offy = trow;
|
||||
*leny = brow - trow + 1;
|
||||
*offx = lcol;
|
||||
*lenx = rcol - lcol + 1;
|
||||
}
|
||||
return *leny * *lenx;
|
||||
}
|
||||
|
||||
// find the "center" cell of a visual. in the case of even rows/columns, we
|
||||
// place the center on the top/left. in such a case there will be one more
|
||||
// cell to the bottom/right of the center.
|
||||
static inline void
|
||||
ncvisual_center(const ncvisual* n, int* RESTRICT y, int* RESTRICT x){
|
||||
*y = n->dstheight;
|
||||
*x = n->dstwidth;
|
||||
center_box(y, x);
|
||||
}
|
||||
|
||||
auto ncvisual_rotate(ncvisual* ncv, double rads) -> int {
|
||||
rads = -rads; // we're a left-handed Cartesian
|
||||
if(ncv->data == nullptr){
|
||||
return -1;
|
||||
}
|
||||
double stheta, ctheta; // sine, cosine
|
||||
auto diam = rotate_new_geom(ncv, rads, &stheta, &ctheta);
|
||||
if(diam <= 0){
|
||||
return -1;
|
||||
stheta = sin(rads);
|
||||
ctheta = cos(rads);
|
||||
int centy, centx;
|
||||
ncvisual_center(ncv, ¢y, ¢x); // pixel center (center of 'data')
|
||||
// bounding box for real data within the ncvisual. we must only resize to
|
||||
// accommodate real data, lest we grow without band as we rotate.
|
||||
// see https://github.com/dankamongmen/notcurses/issues/599.
|
||||
int bby, bbx, bboffy, bboffx, bbarea;
|
||||
if((bbarea = ncvisual_bounding_box(ncv, &bby, &bbx, &bboffy, &bboffx)) == 0){
|
||||
return 0;
|
||||
}
|
||||
ncplane* n = ncvisual_plane(ncv);
|
||||
ncplane* newp = rotate_plane(n); // FIXME how to resize properly?
|
||||
if(newp == nullptr){
|
||||
return -1;
|
||||
}
|
||||
// pixel diameter
|
||||
int pdiam = ncv->dstheight > ncv->dstwidth ? ncv->dstheight : ncv->dstwidth;
|
||||
int bbcentx = bbx, bbcenty = bby;
|
||||
center_box(&bbcenty, &bbcentx);
|
||||
//fprintf(stderr, "stride: %d height: %d width: %d\n", ncv->rowstride, ncv->dstheight, ncv->dstwidth);
|
||||
assert(ncv->rowstride / 4 >= ncv->dstwidth);
|
||||
auto data = static_cast<uint32_t*>(malloc(pdiam * pdiam * 4));
|
||||
auto data = static_cast<uint32_t*>(malloc(bbarea * 4));
|
||||
if(data == nullptr){
|
||||
ncplane_destroy(newp);
|
||||
return -1;
|
||||
}
|
||||
// targy <- x, targx <- ncv->dstheight - y - 1
|
||||
int centx = ncv->dstwidth / 2; // pixel center
|
||||
int centy = ncv->dstheight / 2;
|
||||
//fprintf(stderr, "DIAM: %d CENTER: %d/%d LEN: %d/%d\n", diam, centy, centx, ncv->ncp->leny, ncv->ncp->lenx);
|
||||
if(ncplane_resize_simple(ncv->ncp, bby / encoding_vert_scale(ncv), bbx) < 0){
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
memset(data, 0, bbarea * 4);
|
||||
//fprintf(stderr, "prad: %d DIAM: %d CENTER: %d/%d LEN: %d/%d\n", prad, diam, centy, centx, ncv->ncp->leny, ncv->ncp->lenx);
|
||||
for(int y = 0 ; y < ncv->dstheight ; ++y){
|
||||
for(int x = 0 ; x < ncv->dstwidth ; ++x){
|
||||
const int convy = y - centy; // converted coordinates
|
||||
const int convx = x - centx;
|
||||
const int convy = y - centy; // converted coordinates
|
||||
const int targx = convx * ctheta - convy * stheta;
|
||||
const int targy = convx * stheta + convy * ctheta;
|
||||
const int targx = convx * ctheta + convy * stheta;
|
||||
const int deconvy = targy + pdiam / 2;
|
||||
const int deconvx = targx + pdiam / 2;
|
||||
//fprintf(stderr, "%d/%d -> %d/%d -> %d/%d -> %d/%d\n", y, x, convy, convx, targy, targx, deconvy, deconvx);
|
||||
assert(deconvy >= 0);
|
||||
assert(deconvx >= 0);
|
||||
assert(deconvy < pdiam);
|
||||
assert(deconvx < pdiam);
|
||||
data[deconvy * pdiam + deconvx] = ncv->data[y * (ncv->rowstride / 4) + x];
|
||||
const int deconvx = targx + bbcentx;
|
||||
const int deconvy = targy + bbcenty;
|
||||
if(deconvy < 0 || deconvx < 0 || deconvy >= bby || deconvx >= bbx){
|
||||
//fprintf(stderr, "NOCOPY %d/%d -> %d/%d -> %d/%d -> %d/%d (%dx%d + %dx%d)\n", y, x, convy, convx, targy, targx, deconvy, deconvx, bboffy, bboffx, bby, bbx);
|
||||
}else{
|
||||
//fprintf(stderr, "YESCOPY %d/%d (%d) <- (%d) %08x\n", deconvy, deconvx, deconvy * ncv->dstwidth + deconvx, y * (ncv->rowstride / 4) + x, ncv->data[y * (ncv->rowstride / 4) + x]);
|
||||
data[deconvy * bbx + deconvx] = ncv->data[y * (ncv->rowstride / 4) + x];
|
||||
}
|
||||
// data[deconvy * (ncv->dstwidth) + deconvx] = ncv->data[y * (ncv->rowstride / 4) + x];
|
||||
//fprintf(stderr, "CW: %d/%d (%08x) -> %d/%d (stride: %d)\n", y, x, ncv->data[y * (ncv->rowstride / 4) + x], targy, targx, ncv->rowstride);
|
||||
// data[targy * ncv->dstheight + targx] = ncv->data[y * (ncv->rowstride / 4) + x];
|
||||
//fprintf(stderr, "wrote %08x to %d (%d)\n", data[targy * ncv->dstheight + targx], targy * ncv->dstheight + targx, (targy * ncv->dstheight + targx) * 4);
|
||||
}
|
||||
}
|
||||
int ret = ncplane_destroy(n);
|
||||
ncvisual_set_data(ncv, data, true);
|
||||
ncv->dstwidth = pdiam;
|
||||
ncv->dstheight = pdiam;
|
||||
ncv->rowstride = ncv->dstwidth * 4;
|
||||
ncv->ncp = newp;
|
||||
return ret;
|
||||
ncv->dstwidth = bbx;
|
||||
ncv->dstheight = bby;
|
||||
ncv->rowstride = bbx * 4;
|
||||
ncplane_erase(ncv->ncp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto ncvisual_from_rgba(notcurses* nc, const void* rgba, int rows,
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <clocale>
|
||||
@ -20,10 +21,14 @@ int main(int argc, char** argv){
|
||||
if((nc = notcurses_init(&opts, stdout)) == nullptr){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct ncplane* n = notcurses_stdplane(nc);
|
||||
struct ncplane* n = ncplane_dup(notcurses_stdplane(nc), nullptr);
|
||||
if(!n){
|
||||
notcurses_stop(nc);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
int dimx, dimy;
|
||||
ncplane_dim_yx(n, &dimy, &dimx);
|
||||
|
||||
bool failed = false;
|
||||
nc_err_e ncerr;
|
||||
auto ncv = ncplane_visual_open(n, file, &ncerr);
|
||||
if(!ncv){
|
||||
@ -38,7 +43,22 @@ int main(int argc, char** argv){
|
||||
if(notcurses_render(nc)){
|
||||
goto err;
|
||||
}
|
||||
return notcurses_stop(nc) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
for(double i = 0 ; i < 256 ; ++i){
|
||||
if(ncvisual_rotate(ncv, M_PI / 8)){
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
if(ncvisual_render(ncv, 0, 0, -1, -1) < 0){
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
if(notcurses_render(nc)){
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
return notcurses_stop(nc) || failed ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
|
||||
err:
|
||||
notcurses_stop(nc);
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "main.h"
|
||||
#include "internal.h"
|
||||
|
||||
TEST_CASE("Geometry") {
|
||||
|
||||
if(getenv("TERM") == nullptr){
|
||||
return;
|
||||
}
|
||||
|
||||
notcurses_options nopts{};
|
||||
nopts.inhibit_alternate_screen = true;
|
||||
nopts.suppress_banner = true;
|
||||
@ -38,6 +40,49 @@ TEST_CASE("Geometry") {
|
||||
CHECK(0 == cells_double_box(n, 0, 0, &tl, &tr, &bl, &br, &hl, &vl));
|
||||
CHECK(0 <= ncplane_perimeter(n, &tl, &tr, &bl, &br, &hl, &vl, 0));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
int y, x;
|
||||
ncplane_center(n, &y, &x);
|
||||
CHECK(y == t->centy);
|
||||
CHECK(x == t->centx);
|
||||
CHECK(0 == ncplane_destroy(n));
|
||||
}
|
||||
}
|
||||
|
||||
SUBCASE("CenterAbs") {
|
||||
const struct test {
|
||||
int leny, lenx; // geometries
|
||||
int absy, absx; // location of the origin
|
||||
int centy, centx; // pre-calculated centers
|
||||
} tests[] = {
|
||||
{ 1, 1, 10, 20, 0, 0, },
|
||||
{ 1, 2, 10, 20, 0, 0, },
|
||||
{ 3, 1, 10, 20, 1, 0, }, { 1, 3, 10, 20, 0, 1, }, { 2, 3, 10, 20, 0, 1, },
|
||||
{ 3, 2, 10, 20, 1, 0, }, { 3, 3, 10, 20, 1, 1, },
|
||||
{ 4, 1, 10, 20, 1, 0, }, { 1, 4, 10, 20, 0, 1, }, { 2, 4, 10, 20, 0, 1, },
|
||||
{ 4, 2, 10, 20, 0, 1, }, { 3, 4, 10, 20, 1, 1, },
|
||||
{ 4, 3, 10, 20, 1, 1, }, { 4, 4, 10, 20, 1, 1, }, { 4, 4, 10, 20, 1, 1, },
|
||||
{ 5, 1, 10, 20, 2, 0, }, { 1, 5, 10, 20, 0, 2, }, { 2, 5, 10, 20, 0, 2, },
|
||||
{ 5, 2, 10, 20, 2, 1, }, { 3, 5, 10, 20, 1, 2, },
|
||||
{ 5, 3, 10, 20, 2, 1, }, { 4, 5, 10, 20, 1, 2, }, { 5, 4, 10, 20, 2, 1, },
|
||||
{ 5, 5, 10, 20, 2, 2, },
|
||||
{ 0, 0, 10, 20, 0, 0, }
|
||||
}, *t;
|
||||
for(t = tests ; !t->leny ; ++t){
|
||||
auto n = ncplane_new(nc_, t->leny, t->lenx, t->absy, t->absx, nullptr);
|
||||
REQUIRE(n);
|
||||
cell tl = CELL_TRIVIAL_INITIALIZER; cell tr = CELL_TRIVIAL_INITIALIZER;
|
||||
cell bl = CELL_TRIVIAL_INITIALIZER; cell br = CELL_TRIVIAL_INITIALIZER;
|
||||
cell hl = CELL_TRIVIAL_INITIALIZER; cell vl = CELL_TRIVIAL_INITIALIZER;
|
||||
CHECK(0 == cells_double_box(n, 0, 0, &tl, &tr, &bl, &br, &hl, &vl));
|
||||
CHECK(0 <= ncplane_perimeter(n, &tl, &tr, &bl, &br, &hl, &vl, 0));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
int y, x;
|
||||
ncplane_center_abs(n, &y, &x);
|
||||
CHECK(y == t->centy + t->absy);
|
||||
CHECK(x == t->centx + t->absx);
|
||||
ncplane_center(n, &y, &x);
|
||||
CHECK(y == t->centy);
|
||||
CHECK(x == t->centx);
|
||||
CHECK(0 == ncplane_destroy(n));
|
||||
}
|
||||
}
|
||||
|
@ -136,16 +136,16 @@ TEST_CASE("Rotate") {
|
||||
CHECK(0xffccbb == (channels_bg(channels) & CELL_BG_MASK));
|
||||
free(c);
|
||||
}
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
ncvisual_destroy(ncv);
|
||||
@ -177,16 +177,16 @@ TEST_CASE("Rotate") {
|
||||
CHECK(0xffccbb == (channels_bg(channels) & CELL_BG_MASK));
|
||||
free(c);
|
||||
}
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI/2));
|
||||
CHECK(0 == ncvisual_rotate(ncv, -M_PI / 2));
|
||||
CHECK(0 <= ncvisual_render(ncv, 0, 0, -1, -1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
ncvisual_destroy(ncv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user