ncvisual_geom: account for scaling #726

This commit is contained in:
nick black 2020-06-17 21:29:44 -04:00
parent 85cef91ad9
commit d084513172
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
4 changed files with 33 additions and 17 deletions

View File

@ -6,6 +6,7 @@ rearrangements of Notcurses.
* A `NULL` value can now be passed as `sbytes` to `ncplane_puttext()`.
* `ncdirect_render_image()` has been added, allowing images to be
rendered in direct mode.
* `ncvisual_geom()` now takes scaling into account.
* 1.5.1 (2020-07-15)
* The semantics of rendering have changed slightly. In 1.5.0 and prior

View File

@ -2552,7 +2552,7 @@ it was built up:
// Get the size and ratio of ncvisual pixels to output cells along the y
// ('toy') and x ('tox') axes. A ncvisual of '*y'X'*x' pixels will require
// ('*y' * '*toy')X('x' * 'tox') cells for full output. Returns non-zero
// for an invalid 'vopts->blitter'.
// for an invalid 'vopts->blitter'. Scaling is taken into account.
int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
const struct ncvisual_options* vopts,
int* y, int* x, int* toy, int* tox);

View File

@ -2343,7 +2343,7 @@ API uint32_t* ncplane_rgba(const struct ncplane* nc, ncblitter_e blit,
// Get the size and ratio of ncvisual pixels to output cells along the y
// ('toy') and x ('tox') axes. A ncvisual of '*y'X'*x' pixels will require
// ('*y' * '*toy')X('x' * 'tox') cells for full output. Returns non-zero
// for an invalid 'vopts->blitter'.
// for an invalid 'vopts->blitter'. Scaling is taken into consideration.
API int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
const struct ncvisual_options* vopts,
int* y, int* x, int* toy, int* tox);

View File

@ -36,6 +36,15 @@ ncvisual_default_blitter(const notcurses* nc) -> ncblitter_e {
return NCBLIT_1x1;
}
void scale_visual(const ncvisual* ncv, int* disprows, int* dispcols) {
float xratio = (float)(*dispcols) / ncv->cols;
if(xratio * ncv->rows > *disprows){
xratio = (float)(*disprows) / ncv->rows;
}
*disprows = xratio * (ncv->rows);
*dispcols = xratio * (ncv->cols);
}
auto ncvisual_geom(const notcurses* nc, const ncvisual* n,
const struct ncvisual_options* vopts,
int* y, int* x, int* toy, int* tox) -> int {
@ -50,11 +59,27 @@ auto ncvisual_geom(const notcurses* nc, const ncvisual* n,
if(!bset){
return -1;
}
if(y){
*y = n->rows;
int fauxy, fauxx;
if(!y){
y = &fauxy;
}
if(x){
if(!x){
x = &fauxx;
}
if(vopts->scaling == NCSCALE_NONE){
*y = n->rows;
}else{
int rows = vopts->n ? ncplane_dim_y(vopts->n) : ncplane_dim_y(nc->stdscr);
*y = rows * encoding_y_scale(bset);
}
if(vopts->scaling == NCSCALE_NONE){
*x = n->cols;
}else{
int cols = vopts->n ? ncplane_dim_x(vopts->n) : ncplane_dim_x(nc->stdscr);
*x = cols * encoding_x_scale(bset);
}
if(vopts->scaling == NCSCALE_SCALE){
scale_visual(n, y, x);
}
if(toy){
*toy = encoding_y_scale(bset);
@ -436,12 +461,7 @@ auto ncvisual_render(notcurses* nc, ncvisual* ncv,
dispcols *= encoding_x_scale(bset);
disprows *= encoding_y_scale(bset);
if(vopts->scaling == NCSCALE_SCALE){
double xratio = (double)(dispcols) / ncv->cols;
if(xratio * ncv->rows > disprows){
xratio = (double)(disprows) / ncv->rows;
}
disprows = xratio * (ncv->rows);
dispcols = xratio * (ncv->cols);
scale_visual(ncv, &disprows, &dispcols);
}
}
//fprintf(stderr, "PLACING NEW PLANE: %d/%d @ %d/%d\n", disprows, dispcols, placey, placex);
@ -463,12 +483,7 @@ auto ncvisual_render(notcurses* nc, ncvisual* ncv,
disprows -= placey;
dispcols -= placex;
if(vopts->scaling == NCSCALE_SCALE){
double xratio = (double)(dispcols) / ncv->cols;
if(xratio * ncv->rows > (double)(disprows)){
xratio = (double)(disprows) / ncv->rows;
}
disprows = xratio * (ncv->rows);
dispcols = xratio * (ncv->cols);
scale_visual(ncv, &disprows, &dispcols);
}
}
}