mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
ncvisual_geom: take degradation into account #697
In order to properly determine the scaling of an ncvisual to be rendered, ncvisual_geom() needs know the blitting method. For this reason, it took an ncblitter_e argument. It also, however, needs handle degradation, which means knowing whether NCVISUAL_OPTIONS_NODEGRADE is in use. It thus really wants the struct ncvisual_options. Pass and accept it. Closes #697, and fixes the "yield" demo in ASCII mode (#696).
This commit is contained in:
parent
827c2f2013
commit
af46077775
5
NEWS.md
5
NEWS.md
@ -1,6 +1,11 @@
|
||||
This document attempts to list user-visible changes and any major internal
|
||||
rearrangements of Notcurses.
|
||||
|
||||
* 1.5.1 (not yet released)
|
||||
* `ncvisual_geom()`'s `ncblitter_e` argument has been replaced with a
|
||||
`const struct ncvisual_options*`, so that `NCVISUAL_OPTIONS_NODEGRADE`
|
||||
can be taken into account (the latter contains a `blitter_e` field).
|
||||
|
||||
* 1.5.0 (2020-07-08)
|
||||
* The various `bool`s of `struct notcurses_options` have been folded into
|
||||
that `struct`'s `flags` field. Each `bool` has its own `NCOPTION_`.
|
||||
|
8
USAGE.md
8
USAGE.md
@ -2544,6 +2544,14 @@ Various transformations can be applied to an `ncvisual`, regardless of how
|
||||
it was built up:
|
||||
|
||||
```c
|
||||
// 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'.
|
||||
int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
|
||||
const struct ncvisual_options* vopts,
|
||||
int* y, int* x, int* toy, int* tox);
|
||||
|
||||
// Rotate the visual 'rads' radians. Only M_PI/2 and -M_PI/2 are
|
||||
// supported at the moment, but this will change FIXME.
|
||||
nc_err_e ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
|
@ -58,17 +58,17 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
|
||||
|
||||
**struct ncvisual* ncvisual_from_plane(struct ncplane* n, ncblitter_e blit, int begy, int begx, int leny, int lenx);**
|
||||
|
||||
**int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n, ncblitter_e blitter, int* y, int* x, int* toy, int* tox);**
|
||||
**int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n, const struct ncvisual_options* vopts, int* y, int* x, int* toy, int* tox);**
|
||||
|
||||
**void ncvisual_destroy(struct ncvisual* ncv);**
|
||||
|
||||
**nc_err_e ncvisual_decode(struct ncvisual* nc);**
|
||||
|
||||
**struct ncplane* ncvisual_render(struct notcurses* nc, struct ncvisual* ncv, const struct visual_options* vopts);**
|
||||
**struct ncplane* ncvisual_render(struct notcurses* nc, struct ncvisual* ncv, const struct ncvisual_options* vopts);**
|
||||
|
||||
**int ncvisual_simple_streamer(struct ncplane* n, struct ncvisual* ncv, const struct timespec* disptime, void* curry);**
|
||||
|
||||
**int ncvisual_stream(struct notcurses* nc, struct ncvisual* ncv, nc_err_e* err, float timescale, streamcb streamer, const struct visual_options* vopts, void* curry);**
|
||||
**int ncvisual_stream(struct notcurses* nc, struct ncvisual* ncv, nc_err_e* err, float timescale, streamcb streamer, const struct ncvisual_options* vopts, void* curry);**
|
||||
|
||||
**int ncvisual_rotate(struct ncvisual* n, double rads);**
|
||||
|
||||
|
@ -2229,46 +2229,6 @@ API struct ncvisual* ncvisual_from_plane(const struct ncplane* n,
|
||||
int begy, int begx,
|
||||
int leny, int lenx);
|
||||
|
||||
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
|
||||
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
|
||||
// 'lenx' can be specified as -1 to go through the boundary of the plane.
|
||||
// Only glyphs from the specified blitset may be present.
|
||||
API uint32_t* ncplane_rgba(const struct ncplane* nc, ncblitter_e blit,
|
||||
int begy, int begx, int leny, int lenx);
|
||||
|
||||
// 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 'blitter'.
|
||||
API int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
|
||||
ncblitter_e blitter, int* y, int* x, int* toy, int* tox);
|
||||
|
||||
// Destroy an ncvisual. Rendered elements will not be disrupted, but the visual
|
||||
// can be neither decoded nor rendered any further.
|
||||
API void ncvisual_destroy(struct ncvisual* ncv);
|
||||
|
||||
// extract the next frame from an ncvisual. returns NCERR_EOF on end of file,
|
||||
// and NCERR_SUCCESS on success, otherwise some other NCERR.
|
||||
API nc_err_e ncvisual_decode(struct ncvisual* nc);
|
||||
|
||||
// Rotate the visual 'rads' radians. Only M_PI/2 and -M_PI/2 are
|
||||
// supported at the moment, but this will change FIXME.
|
||||
API nc_err_e ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
|
||||
// Resize the visual so that it is 'rows' X 'columns'. This is a lossy
|
||||
// transformation, unless the size is unchanged.
|
||||
API nc_err_e ncvisual_resize(struct ncvisual* n, int rows, int cols);
|
||||
|
||||
// Polyfill at the specified location within the ncvisual 'n', using 'rgba'.
|
||||
API int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);
|
||||
|
||||
// Get the specified pixel from the specified ncvisual.
|
||||
API int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel);
|
||||
|
||||
// Set the specified pixel in the specified ncvisual.
|
||||
API int ncvisual_set_yx(const struct ncvisual* n, int y, int x, uint32_t pixel);
|
||||
|
||||
#define NCVISUAL_OPTION_NODEGRADE 0x0001 // fail rather than degrading
|
||||
#define NCVISUAL_OPTION_BLEND 0x0002 // use CELL_ALPHA_BLEND with visual
|
||||
|
||||
@ -2297,6 +2257,47 @@ struct ncvisual_options {
|
||||
uint64_t flags; // bitmask over NCVISUAL_OPTION_*
|
||||
};
|
||||
|
||||
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
|
||||
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||
// plane), continuing for 'leny'x'lenx' cells. Either or both of 'leny' and
|
||||
// 'lenx' can be specified as -1 to go through the boundary of the plane.
|
||||
// Only glyphs from the specified blitset may be present.
|
||||
API uint32_t* ncplane_rgba(const struct ncplane* nc, ncblitter_e blit,
|
||||
int begy, int begx, int leny, int lenx);
|
||||
|
||||
// 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'.
|
||||
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);
|
||||
|
||||
// Destroy an ncvisual. Rendered elements will not be disrupted, but the visual
|
||||
// can be neither decoded nor rendered any further.
|
||||
API void ncvisual_destroy(struct ncvisual* ncv);
|
||||
|
||||
// extract the next frame from an ncvisual. returns NCERR_EOF on end of file,
|
||||
// and NCERR_SUCCESS on success, otherwise some other NCERR.
|
||||
API nc_err_e ncvisual_decode(struct ncvisual* nc);
|
||||
|
||||
// Rotate the visual 'rads' radians. Only M_PI/2 and -M_PI/2 are
|
||||
// supported at the moment, but this will change FIXME.
|
||||
API nc_err_e ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
|
||||
// Resize the visual so that it is 'rows' X 'columns'. This is a lossy
|
||||
// transformation, unless the size is unchanged.
|
||||
API nc_err_e ncvisual_resize(struct ncvisual* n, int rows, int cols);
|
||||
|
||||
// Polyfill at the specified location within the ncvisual 'n', using 'rgba'.
|
||||
API int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);
|
||||
|
||||
// Get the specified pixel from the specified ncvisual.
|
||||
API int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel);
|
||||
|
||||
// Set the specified pixel in the specified ncvisual.
|
||||
API int ncvisual_set_yx(const struct ncvisual* n, int y, int x, uint32_t pixel);
|
||||
|
||||
// Render the decoded frame to the specified ncplane (if one is not provided,
|
||||
// one will be created, having the exact size necessary to display the visual.
|
||||
// In this case, 'style' must be NCSTYLE_NONE). A subregion of the visual can
|
||||
|
@ -38,7 +38,12 @@ zoom_map(struct notcurses* nc, const char* map, int* ret){
|
||||
}
|
||||
int vheight, yscale;
|
||||
int vwidth, xscale;
|
||||
if(ncvisual_geom(nc, ncv, NCBLIT_2x2, &vheight, &vwidth, &yscale, &xscale)){
|
||||
struct ncvisual_options vopts = {
|
||||
.y = 1,
|
||||
.scaling = NCSCALE_STRETCH,
|
||||
.blitter = NCBLIT_2x2,
|
||||
};
|
||||
if(ncvisual_geom(nc, ncv, &vopts, &vheight, &vwidth, &yscale, &xscale)){
|
||||
ncvisual_destroy(ncv);
|
||||
return NULL;
|
||||
}
|
||||
@ -64,12 +69,7 @@ zoom_map(struct notcurses* nc, const char* map, int* ret){
|
||||
}
|
||||
vheight /= yscale;
|
||||
vwidth /= xscale;
|
||||
struct ncvisual_options vopts = {
|
||||
.y = 1,
|
||||
.n = zncp,
|
||||
.scaling = NCSCALE_STRETCH,
|
||||
.blitter = NCBLIT_2x2,
|
||||
};
|
||||
vopts.n = zncp;
|
||||
if(ncvisual_render(nc, ncv, &vopts) == NULL || (*ret = demo_render(nc))){
|
||||
ncvisual_destroy(ncv);
|
||||
ncplane_destroy(zncp);
|
||||
|
@ -30,7 +30,7 @@ int yield_demo(struct notcurses* nc){
|
||||
ncplane_erase(std);
|
||||
|
||||
int vy, vx, vscaley, vscalex;
|
||||
ncvisual_geom(nc, wmv, vopts.blitter, &vy, &vx, &vscaley, &vscalex);
|
||||
ncvisual_geom(nc, wmv, &vopts, &vy, &vx, &vscaley, &vscalex);
|
||||
struct timespec scaled;
|
||||
const long total = vy * vx;
|
||||
const long threshold_painted = total * 4 / 5;
|
||||
|
@ -36,12 +36,17 @@ ncvisual_default_blitter(const notcurses* nc) -> ncblitter_e {
|
||||
return NCBLIT_1x1;
|
||||
}
|
||||
|
||||
auto ncvisual_geom(const notcurses* nc, const ncvisual* n, ncblitter_e blitter,
|
||||
auto ncvisual_geom(const notcurses* nc, const ncvisual* n,
|
||||
const struct ncvisual_options* vopts,
|
||||
int* y, int* x, int* toy, int* tox) -> int {
|
||||
if(blitter == NCBLIT_DEFAULT){
|
||||
ncblitter_e blitter;
|
||||
if(!vopts || vopts->blitter == NCBLIT_DEFAULT){
|
||||
blitter = ncvisual_default_blitter(nc);
|
||||
}else{
|
||||
blitter = vopts->blitter;
|
||||
}
|
||||
const struct blitset* bset = lookup_blitset(nc, blitter, false);
|
||||
const bool maydegrade = !(vopts && (vopts->flags & NCVISUAL_OPTION_NODEGRADE));
|
||||
const struct blitset* bset = lookup_blitset(nc, blitter, maydegrade);
|
||||
if(!bset){
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user