From 86de98c5d273c05f2a830ccf0485ca6daa14b920 Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 27 Mar 2021 01:38:48 -0400 Subject: [PATCH] Fix cell blit / plane vertical alignment Deprecate ncplane_align(), after rewriting it as a passthrough to new function ncplane_halign(). Add ncplane_valign(). Update all callers. Closes #1468. --- NEWS.md | 2 ++ USAGE.md | 33 +++++++++++++++-------- doc/man/index.html | 2 +- include/ncpp/Plane.hh | 12 ++++++++- include/notcurses/notcurses.h | 49 +++++++++++++++++++++-------------- src/demo/mojibake.c | 2 +- src/demo/zoo.c | 2 +- src/lib/notcurses.c | 8 +++--- src/lib/selector.c | 8 +++--- src/lib/visual.c | 10 +++++-- src/player/play.cpp | 2 +- 11 files changed, 85 insertions(+), 45 deletions(-) diff --git a/NEWS.md b/NEWS.md index 19377ea11..c6f040504 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,6 +7,8 @@ rearrangements of Notcurses. * Added `notcurses_debug_caps()` to dump terminal properties, both those reported and those inferred, to a `FILE*`. * Added `NCOPTION_NO_CLEAR_BITMAPS` option for `notcurses_init()`. + * Added `ncplane_valign()` and `ncplane_halign()`. `ncplane_align()` is now + an alias for `ncplane_halign()`, and deprecated. * Added `NCVISUAL_OPTION_HORALIGNED` and `NCVISUAL_OPTION_VERALIGNED` flags for `ncvisual_render()`. * Added `NCPLANE_OPTION_VERALIGNED` flag for `ncplane_create()`. diff --git a/USAGE.md b/USAGE.md index 484c2c90e..9541a6aa2 100644 --- a/USAGE.md +++ b/USAGE.md @@ -492,23 +492,34 @@ typedef enum { NCALIGN_RIGHT, } ncalign_e; -// Return the column at which 'c' cols ought start in order to be aligned -// according to 'align' within ncplane 'n'. Returns INT_MAX on invalid 'align'. -// Undefined behavior on negative 'c'. +#define NCALIGN_TOP NCALIGN_LEFT +#define NCALIGN_BOTTOM NCALIGN_RIGHT + +// Return the offset into 'availu' at which 'u' ought be output given the +// requirements of 'align'. Return -INT_MAX on invalid 'align'. Undefined +// behavior on negative 'availu' or 'u'. static inline int -ncplane_align(const struct ncplane* n, ncalign_e align, int c){ - if(align == NCALIGN_LEFT){ +notcurses_align(int availu, ncalign_e align, int u){ + if(align == NCALIGN_LEFT || align == NCALIGN_TOP){ return 0; } - int cols; - ncplane_dim_yx(n, NULL, &cols); if(align == NCALIGN_CENTER){ - return (cols - c) / 2; - }else if(align == NCALIGN_RIGHT){ - return cols - c; + return (availu - u) / 2; } - return INT_MAX; + if(align == NCALIGN_RIGHT || align == NCALIGN_BOTTOM){ + return availu - u; + } + return -INT_MAX; // invalid |align| } + +// Return the column at which 'c' cols ought start in order to be aligned +// according to 'align' within ncplane 'n'. Return -INT_MAX on invalid +// 'align'. Undefined behavior on negative 'c'. +static inline int +ncplane_align(const struct ncplane* n, ncalign_e align, int c){ + return notcurses_align(ncplane_dim_x(n), align, c); +} + ``` ## Input diff --git a/doc/man/index.html b/doc/man/index.html index 5d3da7e4e..8504115ee 100644 --- a/doc/man/index.html +++ b/doc/man/index.html @@ -33,7 +33,7 @@
-

notcurses man pages (v2.2.3)

+

notcurses manual pages (v2.2.3)

notcurses(3)—a blingful TUI library

Executables (section 1)

ncls—list files, displaying multimedia along with them
diff --git a/include/ncpp/Plane.hh b/include/ncpp/Plane.hh index a16e1b814..a8afc34bd 100644 --- a/include/ncpp/Plane.hh +++ b/include/ncpp/Plane.hh @@ -308,7 +308,17 @@ namespace ncpp int get_align (NCAlign align, int c) const NOEXCEPT_MAYBE { - return error_guard (ncplane_align (plane, static_cast(align), c), INT_MAX); + return error_guard (ncplane_halign (plane, static_cast(align), c), INT_MAX); + } + + int get_halign (NCAlign align, int c) const NOEXCEPT_MAYBE + { + return error_guard (ncplane_halign (plane, static_cast(align), c), INT_MAX); + } + + int get_valign (NCAlign align, int r) const NOEXCEPT_MAYBE + { + return error_guard (ncplane_valign (plane, static_cast(align), r), INT_MAX); } void get_dim (int *rows, int *cols) const noexcept diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 223aea4ab..28d1aca90 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -1454,35 +1454,46 @@ API void* ncplane_userptr(struct ncplane* n); API void ncplane_center_abs(const struct ncplane* n, int* RESTRICT y, int* RESTRICT x); -// Return the offset into 'availcols' at which 'cols' ought be output given the -// requirements of 'align'. Return -INT_MAX if unaligned or in case of invalid -// 'align'. Undefined behavior on negative 'cols'. +// Return the offset into 'availu' at which 'u' ought be output given the +// requirements of 'align'. Return -INT_MAX on invalid 'align'. Undefined +// behavior on negative 'availu' or 'u'. static inline int -notcurses_align(int availcols, ncalign_e align, int cols){ - if(cols < 0){ - return -INT_MAX; - } - if(align == NCALIGN_LEFT){ - return 0; - } - if(cols > availcols){ +notcurses_align(int availu, ncalign_e align, int u){ + if(align == NCALIGN_LEFT || align == NCALIGN_TOP){ return 0; } if(align == NCALIGN_CENTER){ - return (availcols - cols) / 2; + return (availu - u) / 2; } - if(align == NCALIGN_RIGHT){ - return availcols - cols; + if(align == NCALIGN_RIGHT || align == NCALIGN_BOTTOM){ + return availu - u; } - return -INT_MAX; + return -INT_MAX; // invalid |align| } // Return the column at which 'c' cols ought start in order to be aligned -// according to 'align' within ncplane 'n'. Return -INT_MAX if unaligned -// or in case of invalid 'align'. Undefined behavior on negative 'c'. +// according to 'align' within ncplane 'n'. Return -INT_MAX on invalid +// 'align'. Undefined behavior on negative 'c'. +static inline int +ncplane_halign(const struct ncplane* n, ncalign_e align, int c){ + return notcurses_align(ncplane_dim_x(n), align, c); +} + +static inline int +ncplane_align(const struct ncplane* n, ncalign_e align, int c) +__attribute__ ((deprecated)); + static inline int ncplane_align(const struct ncplane* n, ncalign_e align, int c){ - return notcurses_align(ncplane_dim_x(n), align, c); + return ncplane_halign(n, align, c); +} + +// Return the row at which 'r' rows ought start in order to be aligned +// according to 'align' within ncplane 'n'. Return -INT_MAX on invalid +// 'align'. Undefined behavior on negative 'r'. +static inline int +ncplane_valign(const struct ncplane* n, ncalign_e align, int r){ + return notcurses_align(ncplane_dim_y(n), align, r); } // Move the cursor to the specified position (the cursor needn't be visible). @@ -1646,7 +1657,7 @@ static inline int ncplane_putwstr_aligned(struct ncplane* n, int y, ncalign_e align, const wchar_t* gclustarr){ int width = wcswidth(gclustarr, INT_MAX); - int xpos = ncplane_align(n, align, width); + int xpos = ncplane_halign(n, align, width); if(xpos < 0){ return -1; } diff --git a/src/demo/mojibake.c b/src/demo/mojibake.c index ca3be8a14..3d50daf68 100644 --- a/src/demo/mojibake.c +++ b/src/demo/mojibake.c @@ -3417,7 +3417,7 @@ mojiplane(struct ncplane* title, int y, int rows, const char* summary){ ncplane_destroy(n); return NULL; } - const int x = ncplane_align(n, NCALIGN_RIGHT, strlen(summary) + 2); + const int x = ncplane_halign(n, NCALIGN_RIGHT, strlen(summary) + 2); if(ncplane_putstr_yx(n, rows - 1, x, summary) < 0){ ncplane_destroy(n); return NULL; diff --git a/src/demo/zoo.c b/src/demo/zoo.c index 6c6cfbb41..cdad93715 100644 --- a/src/demo/zoo.c +++ b/src/demo/zoo.c @@ -376,7 +376,7 @@ reader_demo(struct notcurses* nc){ struct ncplane* std = notcurses_stddim_yx(nc, &dimy, &dimx); const int READER_COLS = 64; const int READER_ROWS = 8; - const int x = ncplane_align(std, NCALIGN_CENTER, READER_COLS); + const int x = ncplane_halign(std, NCALIGN_CENTER, READER_COLS); struct ncselector* selector = NULL; struct ncmultiselector* mselector = NULL; struct ncplane_options nopts = { diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index de346f988..e3f2dda42 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -334,14 +334,14 @@ ncplane* ncplane_new_internal(notcurses* nc, ncplane* n, p->boundto = p; }else{ // bound to preexisting pile if(nopts->flags & NCPLANE_OPTION_HORALIGNED){ - p->absx = ncplane_align(n, nopts->x, nopts->cols); + p->absx = ncplane_halign(n, nopts->x, nopts->cols); p->halign = nopts->x; }else{ p->absx = nopts->x; } p->absx += n->absx; if(nopts->flags & NCPLANE_OPTION_VERALIGNED){ - p->absy = ncplane_align(n, nopts->y, nopts->rows); + p->absy = ncplane_halign(n, nopts->y, nopts->rows); p->valign = nopts->y; }else{ p->absy = nopts->y; @@ -2176,11 +2176,11 @@ int ncplane_resize_realign(ncplane* n){ } int xpos = ncplane_x(n); if(n->halign != NCALIGN_UNALIGNED){ - xpos = ncplane_align(parent, n->halign, ncplane_dim_x(n)); + xpos = ncplane_halign(parent, n->halign, ncplane_dim_x(n)); } int ypos = ncplane_y(n); if(n->valign != NCALIGN_UNALIGNED){ - ypos = ncplane_align(parent, n->valign, ncplane_dim_y(n)); + ypos = ncplane_valign(parent, n->valign, ncplane_dim_y(n)); } return ncplane_move_yx(n, ypos, xpos); } diff --git a/src/lib/selector.c b/src/lib/selector.c index c47009c32..4ecb8423f 100644 --- a/src/lib/selector.c +++ b/src/lib/selector.c @@ -78,7 +78,7 @@ ncselector_draw(ncselector* n){ int yoff = 0; if(n->title){ size_t riserwidth = n->titlecols + 4; - int offx = ncplane_align(n->ncp, NCALIGN_RIGHT, riserwidth); + int offx = ncplane_halign(n->ncp, NCALIGN_RIGHT, riserwidth); ncplane_cursor_move_yx(n->ncp, 0, 0); ncplane_hline(n->ncp, &transchar, offx); ncplane_cursor_move_yx(n->ncp, 0, offx); @@ -92,7 +92,7 @@ ncselector_draw(ncselector* n){ int bodywidth = ncselector_body_width(n); int dimy, dimx; ncplane_dim_yx(n->ncp, &dimy, &dimx); - int xoff = ncplane_align(n->ncp, NCALIGN_RIGHT, bodywidth); + int xoff = ncplane_halign(n->ncp, NCALIGN_RIGHT, bodywidth); if(xoff){ for(int y = yoff + 1 ; y < dimy ; ++y){ ncplane_cursor_move_yx(n->ncp, y, 0); @@ -572,7 +572,7 @@ ncmultiselector_draw(ncmultiselector* n){ int yoff = 0; if(n->title){ size_t riserwidth = n->titlecols + 4; - int offx = ncplane_align(n->ncp, NCALIGN_RIGHT, riserwidth); + int offx = ncplane_halign(n->ncp, NCALIGN_RIGHT, riserwidth); ncplane_cursor_move_yx(n->ncp, 0, 0); ncplane_hline(n->ncp, &transchar, offx); ncplane_rounded_box_sized(n->ncp, 0, n->boxchannels, 3, riserwidth, 0); @@ -585,7 +585,7 @@ ncmultiselector_draw(ncmultiselector* n){ int bodywidth = ncmultiselector_body_width(n); int dimy, dimx; ncplane_dim_yx(n->ncp, &dimy, &dimx); - int xoff = ncplane_align(n->ncp, NCALIGN_RIGHT, bodywidth); + int xoff = ncplane_halign(n->ncp, NCALIGN_RIGHT, bodywidth); if(xoff){ for(int y = yoff + 1 ; y < dimy ; ++y){ ncplane_cursor_move_yx(n->ncp, y, 0); diff --git a/src/lib/visual.c b/src/lib/visual.c index dc6bf8bdc..e4d80a749 100644 --- a/src/lib/visual.c +++ b/src/lib/visual.c @@ -421,6 +421,12 @@ ncvisual* ncvisual_from_bgra(const void* bgra, int rows, int rowstride, int cols return ncv; } +// by the end, disprows/dispcols refer to the number of source rows/cols (in +// pixels), which will be mapped to a region of cells scaled by the encodings). +// the blit will begin at placey/placex (in terms of cells). begy/begx define +// the origin of the source region to draw (in pixels). leny/lenx defined the +// geometry of the source region to draw, again in pixels. ncv->rows and +// ncv->cols define the source geometry in pixels. ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitset* bset, int placey, int placex, int begy, int begx, int leny, int lenx, ncplane* n, ncscale_e scaling, @@ -480,10 +486,10 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse } // else stretch } if(flags & NCVISUAL_OPTION_HORALIGNED){ - placex = ncplane_align(n, placex, dispcols / encoding_x_scale(&nc->tcache, bset)); + placex = ncplane_halign(n, placex, dispcols / encoding_x_scale(&nc->tcache, bset)); } if(flags & NCVISUAL_OPTION_VERALIGNED){ - placey = ncplane_align(n, placey, disprows / encoding_y_scale(&nc->tcache, bset)); + placey = ncplane_valign(n, placey, disprows / encoding_y_scale(&nc->tcache, bset)); } } leny = (leny / (double)ncv->rows) * ((double)disprows); diff --git a/src/player/play.cpp b/src/player/play.cpp index fae09dce3..c8778b85f 100644 --- a/src/player/play.cpp +++ b/src/player/play.cpp @@ -351,7 +351,7 @@ int rendered_mode_player_inner(NotCurses& nc, int argc, char** argv, ncv = std::make_unique(argv[i]); struct ncvisual_options vopts{}; int r; - vopts.flags |= NCVISUAL_OPTION_HORALIGNED/* | NCVISUAL_OPTION_VERALIGNED*/; + vopts.flags |= NCVISUAL_OPTION_HORALIGNED | NCVISUAL_OPTION_VERALIGNED; vopts.y = NCALIGN_CENTER; vopts.x = NCALIGN_CENTER; vopts.n = n;