subtle ncplane bugfixes

ncplane_dup(): properly set target plane attributes/channels
ncplane_move_below_unsafe(): speedup, at most one traversal
ncplane_rgba(): accept null glyph
ncvisual_from_plane(): dup the plane, own it in ncvisual
normal: spin the visual
pull/600/head
nick black 4 years ago
parent 084bb721fa
commit 0f5333f103
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -3,6 +3,13 @@ rearrangements of Notcurses.
* 1.4.2 (not yet released)
* Added `notcurses_canutf8()`, to verify use of UTF-8 encoding.
* Fixed bug in `ncvisual_from_plane()` when invoked on the standard plane.
* `ncvisual_from_plane()` now accepts the same four geometric parameters
as other plane selectors. To reproduce the old behavior, for `ncv`, call
it as `ncvisual_from_plane(ncv, 0, 0, -1, -1)`.
* `ncvisual_from_plane()`, `ncplane_move_below_unsafe()`, `ncplane_dup()`,
and `ncplane_move_above_unsafe()` now accept `const` arguments where they
did not before.
* 1.4.1 (2020-05-11)
* No user-visible changes (fixed two unit tests).

@ -990,7 +990,7 @@ API struct ncplane* ncplane_reparent(struct ncplane* n, struct ncplane* newparen
// Duplicate an existing ncplane. The new plane will have the same geometry,
// will duplicate all content, and will start with the same rendering state.
// The new plane will be immediately above the old one on the z axis.
API struct ncplane* ncplane_dup(struct ncplane* n, void* opaque);
API struct ncplane* ncplane_dup(const struct ncplane* n, void* opaque);
// provided a coordinate relative to the origin of 'src', map it to the same
// absolute coordinate relative to thte origin of 'dst'. either or both of 'y'
@ -1126,7 +1126,7 @@ API int ncplane_move_bottom(struct ncplane* n);
// Splice ncplane 'n' out of the z-buffer, and reinsert it above 'above'.
API int ncplane_move_above_unsafe(struct ncplane* RESTRICT n,
struct ncplane* RESTRICT above);
const struct ncplane* RESTRICT above);
static inline int
ncplane_move_above(struct ncplane* n, struct ncplane* above){
@ -1138,7 +1138,7 @@ ncplane_move_above(struct ncplane* n, struct ncplane* above){
// Splice ncplane 'n' out of the z-buffer, and reinsert it below 'below'.
API int ncplane_move_below_unsafe(struct ncplane* RESTRICT n,
struct ncplane* RESTRICT below);
const struct ncplane* RESTRICT below);
static inline int
ncplane_move_below(struct ncplane* n, struct ncplane* below){
@ -2802,7 +2802,8 @@ API int ncplane_qrcode(struct ncplane* n, int maxversion, const void* data, size
// in a NULL being returned. This function exists so that planes can be
// subjected to ncvisual transformations. If possible, it's usually better
// to create the ncvisual from memory using ncvisual_from_rgba().
API struct ncvisual* ncvisual_from_plane(struct ncplane* n);
API struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
int begy, int begx, int leny, int lenx);
#define NCREADER_OPTION_HORSCROLL 0x0001
#define NCREADER_OPTION_VERSCROLL 0x0002

@ -36,6 +36,7 @@ offset(uint32_t* rgba, int y, int x, int dx){
int normal_demo(struct notcurses* nc){
int dy, dx;
struct ncplane* n = notcurses_stddim_yx(nc, &dy, &dx);
ncplane_erase(n);
dy *= VSCALE; // double-block trick means both 2x resolution and even linecount yay
uint32_t* rgba = malloc(sizeof(*rgba) * dy * dx);
if(!rgba){
@ -66,5 +67,20 @@ int normal_demo(struct notcurses* nc){
DEMO_RENDER(nc);
}
free(rgba);
struct ncvisual* ncv = ncvisual_from_plane(n, 0, 0, -1, -1);
if(!ncv){
return -1;
}
// FIXME use smaller rotations once supported
for(int i = 1 ; i < 4 ; ++i){
if(ncvisual_rotate(ncv, M_PI / 2)){
return -1;
}
if(ncvisual_render(ncv, 0, 0, -1, -1) <= 0){
return -1;
}
DEMO_RENDER(nc);
}
ncvisual_destroy(ncv);
return 0;
}

@ -367,7 +367,7 @@ inline int ncplane_cursor_move_yx(ncplane* n, int y, int x){
return 0;
}
ncplane* ncplane_dup(ncplane* n, void* opaque){
ncplane* ncplane_dup(const ncplane* n, void* opaque){
int dimy = n->leny;
int dimx = n->lenx;
int aty = n->absy;
@ -383,8 +383,8 @@ ncplane* ncplane_dup(ncplane* n, void* opaque){
return NULL;
}else{
ncplane_cursor_move_yx(newn, y, x);
n->attrword = attr;
n->channels = chan;
newn->attrword = attr;
newn->channels = chan;
ncplane_move_above_unsafe(newn, n);
memmove(newn->fb, n->fb, sizeof(*n->fb) * dimx * dimy);
}
@ -499,7 +499,7 @@ int ncplane_resize(ncplane* n, int keepy, int keepx, int keepleny,
// find the pointer on the z-index referencing the specified plane. writing to
// this pointer will remove the plane (and everything below it) from the stack.
static ncplane**
find_above_ncplane(ncplane* n){
find_above_ncplane(const ncplane* n){
notcurses* nc = n->nc;
ncplane** above = &nc->top;
while(*above){
@ -1189,7 +1189,7 @@ const char* cell_extended_gcluster(const ncplane* n, const cell* c){
}
// 'n' ends up above 'above'
int ncplane_move_above_unsafe(ncplane* restrict n, ncplane* restrict above){
int ncplane_move_above_unsafe(ncplane* restrict n, const ncplane* restrict above){
if(n->z == above){
return 0;
}
@ -1201,24 +1201,37 @@ int ncplane_move_above_unsafe(ncplane* restrict n, ncplane* restrict above){
if(aa == NULL){
return -1;
}
ncplane* deconst_above = *aa;
*an = n->z; // splice n out
n->z = above; // attach above below n
n->z = deconst_above; // attach above below n
*aa = n; // spline n in above
return 0;
}
// 'n' ends up below 'below'
int ncplane_move_below_unsafe(ncplane* restrict n, ncplane* restrict below){
int ncplane_move_below_unsafe(ncplane* restrict n, const ncplane* restrict below){
if(below->z == n){
return 0;
}
ncplane** an = find_above_ncplane(n);
ncplane* deconst_below = NULL;
ncplane** an = &n->nc->top;
// go down, looking for n and below. if we find below, mark it. if we
// find n, break from the loop.
while(*an){
if(*an == below){
deconst_below = *an;
}else if(*an == n){
*an = n->z; // splice n out
}
}
if(an == NULL){
return -1;
}
*an = n->z; // splice n out
n->z = below->z; // reattach subbelow list to n
below->z = n; // splice n in below
while(deconst_below != below){
deconst_below = deconst_below->z;
}
n->z = deconst_below->z; // reattach subbelow list to n
deconst_below->z = n; // splice n in below
return 0;
}
@ -2054,7 +2067,7 @@ uint32_t* ncplane_rgba(const ncplane* nc, int begy, int begx, int leny, int lenx
// FIXME how do we deal with transparency?
uint32_t frgba = (fr << 24u) + (fg << 16u) + (fb << 8u) + 0xff;
uint32_t brgba = (br << 24u) + (bg << 16u) + (bb << 8u) + 0xff;
if(strcmp(c, " ") == 0){
if((strcmp(c, " ") == 0) || (strcmp(c, "") == 0)){
*top = *bot = brgba;
}else if(strcmp(c, "") == 0){
*top = frgba;

@ -105,8 +105,9 @@ auto ncvisual_create(float timescale) -> ncvisual* {
return ret;
}
auto ncvisual_from_plane(ncplane* n) -> ncvisual* {
uint32_t* rgba = ncplane_rgba(n, 0, 0, -1, -1);
auto ncvisual_from_plane(const ncplane* n, int begy, int begx, int leny, int lenx)
-> ncvisual* {
uint32_t* rgba = ncplane_rgba(n, begx, begy, leny, lenx);
if(rgba == nullptr){
return nullptr;
}
@ -118,8 +119,8 @@ auto ncvisual_from_plane(ncplane* n) -> ncvisual* {
return nullptr;
}
ncplane_destroy(ncv->ncp);
ncv->ncp = n;
ncv->ncobj = nullptr;
ncv->ncp = ncplane_dup(n, nullptr);
ncv->ncobj = n->nc;
return ncv;
}

Loading…
Cancel
Save