diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 6ef487a05..223aea4ab 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -2392,6 +2392,7 @@ API ALLOC struct ncvisual* ncvisual_from_plane(const struct ncplane* n, #define NCVISUAL_OPTION_NODEGRADE 0x0001ull // fail rather than degrade #define NCVISUAL_OPTION_BLEND 0x0002ull // use CELL_ALPHA_BLEND with visual #define NCVISUAL_OPTION_HORALIGNED 0x0004ull // x is an alignment, not absolute +#define NCVISUAL_OPTION_VERALIGNED 0x0004ull // y is an alignment, not absolute struct ncvisual_options { // if no ncplane is provided, one will be created using the exact size @@ -2405,7 +2406,8 @@ struct ncvisual_options { // if an ncplane is provided, y and x specify where the visual will be // rendered on that plane. otherwise, they specify where the created ncplane // will be placed relative to the standard plane's origin. x is an ncalign_e - // value if NCVISUAL_OPTION_HORALIGNED is provided. + // value if NCVISUAL_OPTION_HORALIGNED is provided. y is an ncalign_e if + // NCVISUAL_OPTION_VERALIGNED is provided. int y, x; // the section of the visual that ought be rendered. for the entire visual, // pass an origin of 0, 0 and a size of 0, 0 (or the true height and width). diff --git a/src/demo/keller.c b/src/demo/keller.c index c6273c324..2ef2eabb5 100644 --- a/src/demo/keller.c +++ b/src/demo/keller.c @@ -24,8 +24,9 @@ visualize(struct notcurses* nc, struct ncvisual* ncv){ struct ncvisual_options vopts = { .scaling = NCSCALE_SCALE, .blitter = bs[i], - .y = 1, - .flags = NCVISUAL_OPTION_NODEGRADE | NCVISUAL_OPTION_HORALIGNED, + .y = NCALIGN_CENTER, + .flags = NCVISUAL_OPTION_NODEGRADE | NCVISUAL_OPTION_HORALIGNED + | NCVISUAL_OPTION_VERALIGNED, }; int scalex, scaley, truey, truex; ncvisual_geom(nc, ncv, &vopts, &truey, &truex, &scaley, &scalex); diff --git a/src/lib/visual.c b/src/lib/visual.c index 1e2b818a8..641f14b62 100644 --- a/src/lib/visual.c +++ b/src/lib/visual.c @@ -453,6 +453,9 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse if(flags & NCVISUAL_OPTION_HORALIGNED){ nopts.flags |= NCPLANE_OPTION_HORALIGNED; } + if(flags & NCVISUAL_OPTION_VERALIGNED){ + nopts.flags |= NCPLANE_OPTION_VERALIGNED; + } if((n = ncplane_create(notcurses_stdplane(nc), &nopts)) == NULL){ return NULL; } @@ -469,7 +472,9 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse if(!(flags & NCVISUAL_OPTION_HORALIGNED)){ dispcols -= placex; } - disprows -= placey; + if(!(flags & NCVISUAL_OPTION_VERALIGNED)){ + disprows -= placey; + } if(scaling == NCSCALE_SCALE || scaling == NCSCALE_SCALE_HIRES){ scale_visual(ncv, &disprows, &dispcols); } // else stretch @@ -477,6 +482,10 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse if(flags & NCVISUAL_OPTION_HORALIGNED){ placex = ncplane_align(n, placex, dispcols / encoding_x_scale(&nc->tcache, bset)); } +fprintf(stderr, "DISPROWS: %d PLACEY: %d\n", disprows, placey); + if(flags & NCVISUAL_OPTION_VERALIGNED){ + placey = ncplane_align(n, placey, disprows / encoding_y_scale(&nc->tcache, bset)); + } } leny = (leny / (double)ncv->rows) * ((double)disprows); lenx = (lenx / (double)ncv->cols) * ((double)dispcols); @@ -486,6 +495,7 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse bargs.begx = begx; bargs.placey = placey; bargs.placex = placex; +fprintf(stderr, "ARRRRRRP %d/ %d\n", placey, placex); bargs.u.cell.blendcolors = flags & NCVISUAL_OPTION_BLEND; if(ncvisual_blit(ncv, disprows, dispcols, n, bset, leny, lenx, &bargs)){ ncplane_destroy(n); @@ -528,6 +538,9 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits if(flags & NCVISUAL_OPTION_HORALIGNED){ nopts.flags |= NCPLANE_OPTION_HORALIGNED; } + if(flags & NCVISUAL_OPTION_VERALIGNED){ + nopts.flags |= NCPLANE_OPTION_VERALIGNED; + } if((n = ncplane_create(stdn, &nopts)) == NULL){ return NULL; } @@ -538,8 +551,10 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits ncplane_dim_yx(n, &disprows, &dispcols); dispcols *= nc->tcache.cellpixx; disprows *= nc->tcache.cellpixy; - dispcols -= (placex * nc->tcache.cellpixx + 1); if(!(flags & NCVISUAL_OPTION_HORALIGNED)){ + dispcols -= (placex * nc->tcache.cellpixx + 1); + } + if(!(flags & NCVISUAL_OPTION_VERALIGNED)){ disprows -= (placey * nc->tcache.cellpixy + 1); } } @@ -554,6 +569,13 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits placex = ncplane_dim_x(n) - dispcols / nc->tcache.cellpixx; } } + if(flags & NCVISUAL_OPTION_VERALIGNED){ + if(placey == NCALIGN_CENTER){ + placey = (ncplane_dim_y(n) - disprows / nc->tcache.cellpixy) / 2; + }else if(placex == NCALIGN_BOTTOM){ + placey = ncplane_dim_y(n) - disprows / nc->tcache.cellpixy; + } + } //fprintf(stderr, "pblit: %dx%d <- %dx%d of %d/%d stride %u @%dx%d %p %u\n", disprows, dispcols, begy, begx, ncv->rows, ncv->cols, ncv->rowstride, placey, placex, ncv->data, nc->tcache.cellpixx); blitterargs bargs; bargs.begy = begy; diff --git a/src/player/play.cpp b/src/player/play.cpp index f3fdf7206..c8778b85f 100644 --- a/src/player/play.cpp +++ b/src/player/play.cpp @@ -351,7 +351,8 @@ 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; + vopts.flags |= NCVISUAL_OPTION_HORALIGNED | NCVISUAL_OPTION_VERALIGNED; + vopts.y = NCALIGN_CENTER; vopts.x = NCALIGN_CENTER; vopts.n = n; vopts.scaling = scalemode;