From 268a72022573aae4762f06ee5185e77ef3b1afd2 Mon Sep 17 00:00:00 2001 From: nick black Date: Thu, 11 Mar 2021 20:46:54 -0500 Subject: [PATCH] Keep hardcursurpos bool across rasterizations Move hardcursorpos into the renderstate carried across rasterizations. This eliminates undesirable vertical movement following pixel image emission #1400. --- USAGE.md | 4 ++-- include/notcurses/notcurses.h | 2 +- src/lib/internal.h | 3 +++ src/lib/render.c | 14 +++++++------- src/poc/pixel.c | 3 ++- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/USAGE.md b/USAGE.md index 731b48d4e..5450b61b8 100644 --- a/USAGE.md +++ b/USAGE.md @@ -19,7 +19,7 @@ A full API reference [is available](https://nick-black.com/notcurses/) in the form of manual pages; these ought have been installed along with Notcurses. This document is a secondary reference, and should not be considered authoritative. For a more unified commentary, consider the [paperback](https://www.amazon.com/dp/B086PNVNC9) -(also available as a [free PDF](https://nick-black.com/dankwiki/index.php?title=Hacking_The_Planet!_with_Notcurses). +(also available as a [free PDF](https://nick-black.com/dankwiki/index.php?title=Hacking_The_Planet!_with_Notcurses)). A program wishing to use Notcurses will need to link it, ideally using the output of `pkg-config --libs notcurses`. It is advised to compile with the @@ -2854,7 +2854,7 @@ typedef enum { NCBLIT_1x1, // space, compatible with ASCII NCBLIT_2x1, // halves + 1x1 (space) ▄▀ NCBLIT_2x2, // quadrants + 2x1 ▗▐ ▖▀▟▌▙ - NCBLIT_3x2, // sextants (*NOT* 2x2) 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻 + NCBLIT_3x2, // sextants (*NOT* 2x2) 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞 NCBLIT_4x1, // four vertical levels █▆▄▂ NCBLIT_BRAILLE, // 4 rows, 2 cols (braille) ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿ NCBLIT_8x1, // eight vertical levels █▇▆▅▄▃▂▁ diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 0e108fe6d..2d23cdb11 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -63,7 +63,7 @@ typedef enum { NCBLIT_1x1, // space, compatible with ASCII NCBLIT_2x1, // halves + 1x1 (space) ▄▀ NCBLIT_2x2, // quadrants + 2x1 ▗▐ ▖▀▟▌▙ - NCBLIT_3x2, // sextants (*NOT* 2x2) 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻 + NCBLIT_3x2, // sextants (*NOT* 2x2) 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞 NCBLIT_4x1, // four vertical levels █▆▄▂ NCBLIT_BRAILLE, // 4 rows, 2 cols (braille) ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿ NCBLIT_8x1, // eight vertical levels █▇▆▅▄▃▂▁ diff --git a/src/lib/internal.h b/src/lib/internal.h index 8ab95341c..7665569a4 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -128,6 +128,9 @@ typedef struct rasterstate { bool bgpalelidable; bool fgdefelidable; bool bgdefelidable; + + // need we do a hard cursor update (i.e. did we just emit a pixel graphic)? + bool hardcursorpos; } rasterstate; // Tablets are the toplevel entitites within an ncreel. Each corresponds to diff --git a/src/lib/render.c b/src/lib/render.c index a96ce0c8c..efc41d289 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -826,14 +826,15 @@ update_palette(notcurses* nc, FILE* out){ // our understanding of our horizontal location is faulty. // FIXME fall back to synthesized moves in the absence of capabilities (i.e. // textronix lacks cup; fake it with horiz+vert moves) -// if hardposupdate is non-zero, we always perform a cup +// if hardcursorpos is non-zero, we always perform a cup static inline int -goto_location(notcurses* nc, FILE* out, int y, int x, unsigned hardposupdate){ +goto_location(notcurses* nc, FILE* out, int y, int x, unsigned hardcursorpos){ +//fprintf(stderr, "going to %d/%d from %d/%d hard: %u\n", y, x, nc->rstate.y, nc->rstate.x, hardcursorpos); int ret = 0; // if we don't have hpa, force a cup even if we're only 1 char away. the only // terminal i know supporting cup sans hpa is vt100, and vt100 can suck it. // you can't use cuf for backwards moves anyway; again, vt100 can suck it. - if(nc->rstate.y == y && nc->tcache.hpa && !hardposupdate){ // only need move x + if(nc->rstate.y == y && nc->tcache.hpa && !hardcursorpos){ // only need move x if(nc->rstate.x == x){ // needn't move shit return 0; } @@ -916,7 +917,6 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){ // we explicitly move the cursor at the beginning of each output line, so no // need to home it expliticly. update_palette(nc, out); - bool hardposupdate = false; //fprintf(stderr, "pile %p ymax: %d xmax: %d\n", p, p->dimy + nc->stdplane->absy, p->dimx + nc->stdplane->absx); for(y = nc->stdplane->absy ; y < p->dimy + nc->stdplane->absy ; ++y){ const int innery = y - nc->stdplane->absy; @@ -934,10 +934,10 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){ } }else{ ++nc->stats.cellemissions; - if(goto_location(nc, out, y, x, hardposupdate)){ + if(goto_location(nc, out, y, x, nc->rstate.hardcursorpos)){ return -1; } - hardposupdate = false; + nc->rstate.hardcursorpos = false; if(!cell_pixels_p(srccell)){ // set the style. this can change the color back to the default; if it // does, we need update our elision possibilities. @@ -1028,7 +1028,7 @@ notcurses_rasterize_inner(notcurses* nc, const ncpile* p, FILE* out){ nc->rstate.bgpalelidable = false; } }else{ - hardposupdate = true; + nc->rstate.hardcursorpos = true; } //fprintf(stderr, "RAST %08x [%s] to %d/%d cols: %u %016lx\n", srccell->gcluster, pool_extended_gcluster(&nc->pool, srccell), y, x, srccell->width, srccell->channels); if(term_putc(out, &nc->pool, srccell)){ diff --git a/src/poc/pixel.c b/src/poc/pixel.c index 32ee03179..632d87326 100644 --- a/src/poc/pixel.c +++ b/src/poc/pixel.c @@ -12,7 +12,7 @@ handle(struct notcurses* nc, const char *fn){ struct ncplane* stdn = notcurses_stddim_yx(nc, &dimy, &dimx); uint64_t channels = CHANNELS_RGB_INITIALIZER(100, 140, 100, 140, 100, 140); ncplane_set_base(stdn, "a", 0, channels); - for(int x = 0 ; x < dimx ; ++x){ + for(int x = 0 ; x < dimx ; x += 5){ struct ncvisual_options vopts = { .x = x, .scaling = NCSCALE_NONE_HIRES, @@ -24,6 +24,7 @@ handle(struct notcurses* nc, const char *fn){ return -1; } notcurses_render(nc); + ncplane_destroy(nv); sleep(1); } ncvisual_destroy(ncv);