mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-18 03:25:55 +00:00
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
This commit is contained in:
parent
084bb721fa
commit
0f5333f103
7
NEWS.md
7
NEWS.md
@ -3,6 +3,13 @@ rearrangements of Notcurses.
|
|||||||
|
|
||||||
* 1.4.2 (not yet released)
|
* 1.4.2 (not yet released)
|
||||||
* Added `notcurses_canutf8()`, to verify use of UTF-8 encoding.
|
* 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)
|
* 1.4.1 (2020-05-11)
|
||||||
* No user-visible changes (fixed two unit tests).
|
* 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,
|
// Duplicate an existing ncplane. The new plane will have the same geometry,
|
||||||
// will duplicate all content, and will start with the same rendering state.
|
// 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.
|
// 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
|
// 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'
|
// 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'.
|
// Splice ncplane 'n' out of the z-buffer, and reinsert it above 'above'.
|
||||||
API int ncplane_move_above_unsafe(struct ncplane* RESTRICT n,
|
API int ncplane_move_above_unsafe(struct ncplane* RESTRICT n,
|
||||||
struct ncplane* RESTRICT above);
|
const struct ncplane* RESTRICT above);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ncplane_move_above(struct ncplane* n, struct ncplane* above){
|
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'.
|
// Splice ncplane 'n' out of the z-buffer, and reinsert it below 'below'.
|
||||||
API int ncplane_move_below_unsafe(struct ncplane* RESTRICT n,
|
API int ncplane_move_below_unsafe(struct ncplane* RESTRICT n,
|
||||||
struct ncplane* RESTRICT below);
|
const struct ncplane* RESTRICT below);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ncplane_move_below(struct ncplane* n, struct ncplane* below){
|
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
|
// in a NULL being returned. This function exists so that planes can be
|
||||||
// subjected to ncvisual transformations. If possible, it's usually better
|
// subjected to ncvisual transformations. If possible, it's usually better
|
||||||
// to create the ncvisual from memory using ncvisual_from_rgba().
|
// 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_HORSCROLL 0x0001
|
||||||
#define NCREADER_OPTION_VERSCROLL 0x0002
|
#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 normal_demo(struct notcurses* nc){
|
||||||
int dy, dx;
|
int dy, dx;
|
||||||
struct ncplane* n = notcurses_stddim_yx(nc, &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
|
dy *= VSCALE; // double-block trick means both 2x resolution and even linecount yay
|
||||||
uint32_t* rgba = malloc(sizeof(*rgba) * dy * dx);
|
uint32_t* rgba = malloc(sizeof(*rgba) * dy * dx);
|
||||||
if(!rgba){
|
if(!rgba){
|
||||||
@ -66,5 +67,20 @@ int normal_demo(struct notcurses* nc){
|
|||||||
DEMO_RENDER(nc);
|
DEMO_RENDER(nc);
|
||||||
}
|
}
|
||||||
free(rgba);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ inline int ncplane_cursor_move_yx(ncplane* n, int y, int x){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ncplane* ncplane_dup(ncplane* n, void* opaque){
|
ncplane* ncplane_dup(const ncplane* n, void* opaque){
|
||||||
int dimy = n->leny;
|
int dimy = n->leny;
|
||||||
int dimx = n->lenx;
|
int dimx = n->lenx;
|
||||||
int aty = n->absy;
|
int aty = n->absy;
|
||||||
@ -383,8 +383,8 @@ ncplane* ncplane_dup(ncplane* n, void* opaque){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}else{
|
}else{
|
||||||
ncplane_cursor_move_yx(newn, y, x);
|
ncplane_cursor_move_yx(newn, y, x);
|
||||||
n->attrword = attr;
|
newn->attrword = attr;
|
||||||
n->channels = chan;
|
newn->channels = chan;
|
||||||
ncplane_move_above_unsafe(newn, n);
|
ncplane_move_above_unsafe(newn, n);
|
||||||
memmove(newn->fb, n->fb, sizeof(*n->fb) * dimx * dimy);
|
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
|
// 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.
|
// this pointer will remove the plane (and everything below it) from the stack.
|
||||||
static ncplane**
|
static ncplane**
|
||||||
find_above_ncplane(ncplane* n){
|
find_above_ncplane(const ncplane* n){
|
||||||
notcurses* nc = n->nc;
|
notcurses* nc = n->nc;
|
||||||
ncplane** above = &nc->top;
|
ncplane** above = &nc->top;
|
||||||
while(*above){
|
while(*above){
|
||||||
@ -1189,7 +1189,7 @@ const char* cell_extended_gcluster(const ncplane* n, const cell* c){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 'n' ends up above 'above'
|
// '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){
|
if(n->z == above){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1201,24 +1201,37 @@ int ncplane_move_above_unsafe(ncplane* restrict n, ncplane* restrict above){
|
|||||||
if(aa == NULL){
|
if(aa == NULL){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
ncplane* deconst_above = *aa;
|
||||||
*an = n->z; // splice n out
|
*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
|
*aa = n; // spline n in above
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'n' ends up below 'below'
|
// '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){
|
if(below->z == n){
|
||||||
return 0;
|
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){
|
if(an == NULL){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*an = n->z; // splice n out
|
while(deconst_below != below){
|
||||||
n->z = below->z; // reattach subbelow list to n
|
deconst_below = deconst_below->z;
|
||||||
below->z = n; // splice n in below
|
}
|
||||||
|
n->z = deconst_below->z; // reattach subbelow list to n
|
||||||
|
deconst_below->z = n; // splice n in below
|
||||||
return 0;
|
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?
|
// FIXME how do we deal with transparency?
|
||||||
uint32_t frgba = (fr << 24u) + (fg << 16u) + (fb << 8u) + 0xff;
|
uint32_t frgba = (fr << 24u) + (fg << 16u) + (fb << 8u) + 0xff;
|
||||||
uint32_t brgba = (br << 24u) + (bg << 16u) + (bb << 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;
|
*top = *bot = brgba;
|
||||||
}else if(strcmp(c, "▄") == 0){
|
}else if(strcmp(c, "▄") == 0){
|
||||||
*top = frgba;
|
*top = frgba;
|
||||||
|
@ -105,8 +105,9 @@ auto ncvisual_create(float timescale) -> ncvisual* {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ncvisual_from_plane(ncplane* n) -> ncvisual* {
|
auto ncvisual_from_plane(const ncplane* n, int begy, int begx, int leny, int lenx)
|
||||||
uint32_t* rgba = ncplane_rgba(n, 0, 0, -1, -1);
|
-> ncvisual* {
|
||||||
|
uint32_t* rgba = ncplane_rgba(n, begx, begy, leny, lenx);
|
||||||
if(rgba == nullptr){
|
if(rgba == nullptr){
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -118,8 +119,8 @@ auto ncvisual_from_plane(ncplane* n) -> ncvisual* {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
ncplane_destroy(ncv->ncp);
|
ncplane_destroy(ncv->ncp);
|
||||||
ncv->ncp = n;
|
ncv->ncp = ncplane_dup(n, nullptr);
|
||||||
ncv->ncobj = nullptr;
|
ncv->ncobj = n->nc;
|
||||||
return ncv;
|
return ncv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user