mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
[core] introduce ncvisual_geom(), replacing ncvisual_blitter_geom() #1684
This commit is contained in:
parent
c906d2cf8a
commit
a0b34f7062
6
NEWS.md
6
NEWS.md
@ -12,6 +12,12 @@ rearrangements of Notcurses.
|
||||
deprecated functionality, ABI3 ought require small changes, if any.
|
||||
|
||||
* 2.4.9 (not yet released)
|
||||
* `ncvisual_geom()` has been introduced, using the `ncvgeom` struct
|
||||
introduced for direct mode. This allows complete statement of geometry
|
||||
for an `ncvisual`. It replaces `ncvisual_blitter_geom()`, which has been
|
||||
deprecated, and will be removed in ABI3. It furthermore exposes some of
|
||||
the information previously available only from `ncplane_pixelgeom()`,
|
||||
though that function continues to be supported.
|
||||
* On transition between `ncplane`s (on terminals implementing complex wide
|
||||
glyphs), Notcurses now always issues an `hpa` sequence to force horizontal
|
||||
positioning. This fixes a number of longstanding bugs in e.g. the
|
||||
|
43
USAGE.md
43
USAGE.md
@ -3299,17 +3299,38 @@ 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
|
||||
// and x axes. The input size (in pixels) will be written to 'y' and 'x'.
|
||||
// The scaling will be written to 'scaley' and 'scalex'. With these:
|
||||
// rows = (y / scaley) + !!(y % scaley) or (y + scaley - 1) / scaley
|
||||
// cols = (x / scalex) + !!(x % scalex) or (x + scalex - 1) / scalex
|
||||
// Returns non-zero for an invalid 'vopts'. The blitter that will be used
|
||||
// is returned in '*blitter'.
|
||||
// These results are invalidated upon a terminal resize.
|
||||
int ncvisual_blitter_geom(const struct notcurses* nc, const struct ncvisual* n,
|
||||
const struct ncvisual_options* vopts, int* y, int* x,
|
||||
int* scaley, int* scalex, ncblitter_e* blitter);
|
||||
// describes all geometries of an ncvisual: those which are inherent, and those
|
||||
// dependent upon a given rendering regime. pixy and pixx are the true internal
|
||||
// pixel geometry, taken directly from the load (and updated by
|
||||
// ncvisual_resize()). cdimy/cdimx are the cell-pixel geometry *at the time
|
||||
// of this call* (it can change with a font change, in which case all values
|
||||
// other than pixy/pixx are invalidated). rpixy/rpixx are the pixel geometry as
|
||||
// handed to the blitter, following any scaling. scaley/scalex are the number
|
||||
// of input pixels drawn to a single cell; when using NCBLIT_PIXEL, they are
|
||||
// equivalent to cdimy/cdimx. rcelly/rcellx are the cell geometry as written by
|
||||
// the blitter, following any padding (there is padding whenever rpix{y, x} is
|
||||
// not evenly divided by scale{y, x}, and also sometimes for Sixel).
|
||||
// maxpixely/maxpixelx are defined only when NCBLIT_PIXEL is used, and specify
|
||||
// the largest bitmap that the terminal is willing to accept. blitter is the
|
||||
// blitter which will be used, a function of the requested blitter and the
|
||||
// blitters actually supported by this environment. if no ncvisual was
|
||||
// supplied, only cdimy/cdimx are filled in.
|
||||
typedef struct ncvgeom {
|
||||
int pixy, pixx; // true pixel geometry of ncvisual data
|
||||
int cdimy, cdimx; // terminal cell geometry when this was calculated
|
||||
int rpixy, rpixx; // rendered pixel geometry (per visual_options)
|
||||
int rcelly, rcellx; // rendered cell geometry (per visual_options)
|
||||
int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
|
||||
int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
|
||||
ncblitter_e blitter;// blitter that will be used
|
||||
} ncvgeom;
|
||||
|
||||
// all-purpose ncvisual geometry solver. one or both of 'nc' and 'n' must be
|
||||
// non-NULL. if 'nc' is NULL, only pixy/pixx will be filled in, with the true
|
||||
// pixel geometry of 'n'. if 'n' is NULL, only cdimy/cdimx, blitter, and (if
|
||||
// applicable) maxpixely/maxpixelx are filled in.
|
||||
int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
|
||||
const struct ncvisual_options* vopts, ncvgeom* geom);
|
||||
|
||||
// Scale the visual to 'rows' X 'columns' pixels, using the best scheme
|
||||
// available. This is a lossy transformation, unless the size is unchanged.
|
||||
|
@ -51,6 +51,16 @@ struct ncvisual_options {
|
||||
};
|
||||
|
||||
typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
|
||||
|
||||
typedef struct ncvgeom {
|
||||
int pixy, pixx; // true pixel geometry of ncvisual data
|
||||
int cdimy, cdimx; // terminal cell geometry when this was calculated
|
||||
int rpixy, rpixx; // rendered pixel geometry (per visual_options)
|
||||
int rcelly, rcellx; // rendered cell geometry (per visual_options)
|
||||
int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
|
||||
int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
|
||||
ncblitter_e blitter;// blitter that will be used
|
||||
} ncvgeom;
|
||||
```
|
||||
|
||||
**struct ncvisual* ncvisual_from_file(const char* ***file***);**
|
||||
@ -67,7 +77,7 @@ 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_blitter_geom(const struct notcurses* ***nc***, const struct ncvisual* ***n***, const struct ncvisual_options* ***vopts***, int* ***y***, int* ***x***, int* ***scaley***, int* ***scalex***, ncblitter_e* ***blitter***);**
|
||||
**int ncvisual_geom(const struct notcurses* ***nc***, const struct ncvisual* ***n***, const struct ncvisual_options* ***vopts***, ncvgeom* ***geom***);**
|
||||
|
||||
**void ncvisual_destroy(struct ncvisual* ***ncv***);**
|
||||
|
||||
@ -177,9 +187,14 @@ geometry of same. ***flags*** is a bitfield over:
|
||||
as a transparent color.
|
||||
* **NCVISUAL_OPTION_CHILDPLANE**: Make a new plane, as a child of ***n***.
|
||||
|
||||
**ncvisual_blitter_geom** allows the caller to determine any or all of the
|
||||
visual's pixel geometry, the blitter to be used, and that blitter's scaling
|
||||
in both dimensions. Any but the first argument may be **NULL**.
|
||||
**ncvisual_geom** allows the caller to determine any or all of the visual's
|
||||
pixel geometry, the blitter to be used, and that blitter's scaling in both
|
||||
dimensions. Any but the final argument may be **NULL**, though at least one
|
||||
of ***nc*** and ***n*** must be non-**NULL**. If ***nc*** is **NULL**,
|
||||
only properties intrinsic to the visual are returned (i.e. its original
|
||||
pixel geometry). If ***n*** is **NULL**, only properties independent of the
|
||||
visual are returned (i.e. cell-pixel geometry and maximum bitmap geometry).
|
||||
If both are supplied, all fields of the **ncvgeom** structure are filled in.
|
||||
|
||||
**ncplane_qrcode** draws an ISO/IEC 18004:2015 QR Code for the **len** bytes of
|
||||
**data** using **NCBLIT_2x1** (this is the only blitter that will work with QR
|
||||
@ -317,7 +332,8 @@ which the visual was rendered. If **opts->n** is provided, this will be
|
||||
**opts->n**. Otherwise, a plane will be created, perfectly sized for the
|
||||
visual and the specified blitter.
|
||||
|
||||
**ncvisual_blitter_geom** returns non-zero if the specified blitter is invalid.
|
||||
**ncvisual_geom** returns non-zero if the specified configuration is invalid,
|
||||
or if both ***nc*** and ***n*** are **NULL**.
|
||||
|
||||
**ncvisual_media_defblitter** returns the blitter selected by **NCBLIT_DEFAULT**
|
||||
in the specified configuration. If UTF8 is not enabled, this will always be
|
||||
@ -358,7 +374,7 @@ When using non-interpolative blitting together with scaling, unless your goal
|
||||
includes minimizing the total area required, lower-resolution blitters will
|
||||
generally look just as good as higher resolution blitters, and be faster.
|
||||
|
||||
The results of **ncvisual_blitter_geom** are invalidated by a terminal resize.
|
||||
The results of **ncvisual_geom** are invalidated by a terminal resize.
|
||||
|
||||
# BUGS
|
||||
|
||||
|
@ -96,9 +96,9 @@ namespace ncpp
|
||||
return error_guard<int> (ncvisual_polyfill_yx (visual, y, x, rgba), -1);
|
||||
}
|
||||
|
||||
bool geom (const struct ncvisual_options *vopts, int *y, int *x, int *toy, int *tox, ncblitter_e* blitter) const NOEXCEPT_MAYBE
|
||||
bool geom (const struct ncvisual_options *vopts, ncvgeom* geom) const NOEXCEPT_MAYBE
|
||||
{
|
||||
return error_guard (ncvisual_blitter_geom (get_notcurses (), visual, vopts, y, x, toy, tox, blitter), -1);
|
||||
return error_guard (ncvisual_geom (get_notcurses (), visual, vopts, geom), -1);
|
||||
}
|
||||
|
||||
bool at (int y, int x, uint32_t* pixel) const
|
||||
|
@ -2895,13 +2895,14 @@ struct ncvisual_options {
|
||||
// maxpixely/maxpixelx are defined only when NCBLIT_PIXEL is used, and specify
|
||||
// the largest bitmap that the terminal is willing to accept. blitter is the
|
||||
// blitter which will be used, a function of the requested blitter and the
|
||||
// blitters actually supported by this environment.
|
||||
// blitters actually supported by this environment. if no ncvisual was
|
||||
// supplied, only cdimy/cdimx are filled in.
|
||||
typedef struct ncvgeom {
|
||||
int pixy, pixx; // true pixel geometry of ncvisual data
|
||||
int cdimy, cdimx; // terminal cell geometry when this was calculated
|
||||
int rpixy, rpixx; // rendered pixel geometry
|
||||
int rcelly, rcellx; // rendered cell geometry
|
||||
int scaley, scalex; // pixels per filled cell
|
||||
int rpixy, rpixx; // rendered pixel geometry (per visual_options)
|
||||
int rcelly, rcellx; // rendered cell geometry (per visual_options)
|
||||
int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
|
||||
int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
|
||||
ncblitter_e blitter;// blitter that will be used
|
||||
} ncvgeom;
|
||||
@ -2916,7 +2917,15 @@ typedef struct ncvgeom {
|
||||
API int ncvisual_blitter_geom(const struct notcurses* nc, const struct ncvisual* n,
|
||||
const struct ncvisual_options* vopts, int* y, int* x,
|
||||
int* scaley, int* scalex, ncblitter_e* blitter)
|
||||
__attribute__ ((nonnull (1)));
|
||||
__attribute__ ((nonnull (1))) __attribute__ ((deprecated));
|
||||
|
||||
// all-purpose ncvisual geometry solver. one or both of 'nc' and 'n' must be
|
||||
// non-NULL. if 'nc' is NULL, only pixy/pixx will be filled in, with the true
|
||||
// pixel geometry of 'n'. if 'n' is NULL, only cdimy/cdimx, blitter, and (if
|
||||
// applicable) maxpixely/maxpixelx are filled in.
|
||||
API int ncvisual_geom(const struct notcurses* nc, const struct ncvisual* n,
|
||||
const struct ncvisual_options* vopts, ncvgeom* geom)
|
||||
__attribute__ ((nonnull (4)));
|
||||
|
||||
// Destroy an ncvisual. Rendered elements will not be disrupted, but the visual
|
||||
// can be neither decoded nor rendered any further.
|
||||
|
@ -36,8 +36,6 @@ zoom_map(struct notcurses* nc, const char* map, int* ret){
|
||||
if(ncv == NULL){
|
||||
return NULL;
|
||||
}
|
||||
// true height and width of visual, and blitter scaling parameters
|
||||
int vheight, yscale, vwidth, xscale;
|
||||
// first we want to get the true size, so don't supply NCSSCALE_STRETCH yet,
|
||||
// but *do* explicitly supply NCBLIT_2x2 since we're not scaling.
|
||||
struct ncvisual_options vopts = {
|
||||
@ -45,11 +43,16 @@ zoom_map(struct notcurses* nc, const char* map, int* ret){
|
||||
.blitter = NCBLIT_2x2,
|
||||
.flags = NCVISUAL_OPTION_NOINTERPOLATE,
|
||||
};
|
||||
if(ncvisual_blitter_geom(nc, ncv, &vopts, &vheight, &vwidth,
|
||||
&yscale, &xscale, NULL)){
|
||||
ncvgeom geom;
|
||||
if(ncvisual_geom(nc, ncv, &vopts, &geom)){
|
||||
ncvisual_destroy(ncv);
|
||||
return NULL;
|
||||
}
|
||||
// true height and width of visual, and blitter scaling parameters
|
||||
int vheight = geom.pixy;
|
||||
int vwidth = geom.pixx;
|
||||
int yscale = geom.scaley;
|
||||
int xscale = geom.scalex;
|
||||
//fprintf(stderr, "VHEIGHT: %d VWIDTH: %d scale: %d/%d\n", vheight, vwidth, yscale, xscale);
|
||||
// we start at the lower left corner of the outzoomed map
|
||||
int placey, placex; // dimensions of true display
|
||||
|
@ -78,20 +78,11 @@ orcashow(struct notcurses* nc, int dimy, int dimx){
|
||||
.blitter = NCBLIT_PIXEL,
|
||||
.scaling = NCSCALE_STRETCH,
|
||||
};
|
||||
int cellpxy, cellpxx;
|
||||
ncplane_pixelgeom(notcurses_stdplane_const(nc), NULL, NULL,
|
||||
&cellpxy, &cellpxx, NULL, NULL);
|
||||
int odimy, odimx, scaley, scalex;
|
||||
ncvisual_blitter_geom(nc, ncv, &vopts, &odimy, &odimx, &scaley, &scalex, NULL);
|
||||
// even if we can't do pixel output, we want her the same size as if weu
|
||||
// *could* do pixel output. if we have no idea as to the geom, use scale.
|
||||
if(cellpxy == 0){
|
||||
cellpxy = scaley;
|
||||
cellpxx = scalex;
|
||||
}
|
||||
ncvgeom geom;
|
||||
ncvisual_geom(nc, ncv, &vopts, &geom);
|
||||
struct ncplane_options nopts = {
|
||||
.rows = (odimy / cellpxy) + !!(odimy % cellpxy),
|
||||
.cols = (odimx / cellpxx) + !!(odimx % cellpxx),
|
||||
.rows = geom.rcelly,
|
||||
.cols = geom.rcellx,
|
||||
.name = "orca",
|
||||
};
|
||||
if(nopts.cols > dimx - 1){
|
||||
|
@ -36,18 +36,18 @@ visualize(struct notcurses* nc, struct ncvisual* ncv){
|
||||
| NCVISUAL_OPTION_VERALIGNED
|
||||
| NCVISUAL_OPTION_CHILDPLANE,
|
||||
};
|
||||
int scalex, scaley, truey, truex;
|
||||
vopts.x = NCALIGN_CENTER;
|
||||
vopts.y = NCALIGN_CENTER;
|
||||
ncplane_erase(stdn); // to clear out old text
|
||||
struct ncplane* n = NULL;
|
||||
if(ncvisual_blitter_geom(nc, ncv, &vopts, &truey, &truex, &scaley, &scalex, NULL) == 0){
|
||||
ncvgeom geom;
|
||||
if(ncvisual_geom(nc, ncv, &vopts, &geom) == 0){
|
||||
if( (n = ncvisual_blit(nc, ncv, &vopts)) ){
|
||||
ncplane_move_below(n, stdn);
|
||||
ncplane_printf_aligned(stdn, ncplane_dim_y(stdn) / 2 - 1, NCALIGN_CENTER,
|
||||
"%03dx%03d", truex, truey);
|
||||
"%03dx%03d", geom.pixx, geom.pixy);
|
||||
ncplane_printf_aligned(stdn, ncplane_dim_y(stdn) / 2 + 1, NCALIGN_CENTER,
|
||||
"%d:%d pixels -> cell", scalex, scaley);
|
||||
"%d:%d pixels -> cell", geom.scalex, geom.scaley);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr, "X: %d truex: %d scalex: %d\n", vopts.x, truex, scalex);
|
||||
|
@ -219,10 +219,10 @@ int luigi_demo(struct notcurses* nc){
|
||||
ncplane_move_top(lastseen);
|
||||
}
|
||||
ncplane_move_yx(lastseen, yoff, i);
|
||||
int dimy, scaley;
|
||||
ncvisual_blitter_geom(nc, wmncv, NULL, &dimy, NULL, &scaley, NULL, NULL);
|
||||
dimy /= scaley;
|
||||
ncplane_move_yx(wmplane, rows * 4 / 5 - dimy + 1 + (i % 2), i - 60);
|
||||
ncvgeom geom;
|
||||
ncvisual_geom(nc, wmncv, NULL, &geom);
|
||||
geom.pixy /= geom.scaley;
|
||||
ncplane_move_yx(wmplane, rows * 4 / 5 - geom.pixy + 1 + (i % 2), i - 60);
|
||||
DEMO_RENDER(nc);
|
||||
demo_nanosleep(nc, &stepdelay);
|
||||
}
|
||||
|
@ -167,10 +167,10 @@ int normal_demo(struct notcurses* nc){
|
||||
struct ncvisual_options vopts = {
|
||||
.n = nstd,
|
||||
};
|
||||
int yscale, xscale;
|
||||
ncvisual_blitter_geom(nc, NULL, &vopts, NULL, NULL, &yscale, &xscale, NULL);
|
||||
dy *= yscale;
|
||||
dx *= xscale;
|
||||
ncvgeom geom;
|
||||
ncvisual_geom(nc, NULL, &vopts, &geom);
|
||||
dy *= geom.scaley;
|
||||
dx *= geom.scalex;
|
||||
uint32_t* rgba = malloc(sizeof(*rgba) * dy * dx);
|
||||
if(!rgba){
|
||||
goto err;
|
||||
@ -179,10 +179,10 @@ int normal_demo(struct notcurses* nc){
|
||||
rgba[off] = 0xff000000;
|
||||
}
|
||||
int y;
|
||||
if(dy / yscale % 2){
|
||||
y = dy / yscale + 1;
|
||||
if(dy / geom.scaley % 2){
|
||||
y = dy / geom.scaley + 1;
|
||||
for(int x = 0 ; x < dx ; ++x){
|
||||
if(mcell(offset(rgba, y, x, dx), y, x, dy / yscale, dx)){
|
||||
if(mcell(offset(rgba, y, x, dx), y, x, dy / geom.scaley, dx)){
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +237,8 @@ int yield_demo(struct notcurses* nc){
|
||||
ncplane_set_fg_rgb8(label, 0xff, 0xff, 0xff);
|
||||
ncplane_set_styles(label, NCSTYLE_BOLD);
|
||||
ncplane_printf_aligned(label, 0, NCALIGN_CENTER, "Yield: %03.1f%%", 0.0);
|
||||
if(ncvisual_blitter_geom(nc, v1, &m1.vopts, &maxy, &maxx, NULL, NULL, NULL)){
|
||||
ncvgeom geom;
|
||||
if(ncvisual_geom(nc, v1, &m1.vopts, &geom)){
|
||||
ncplane_destroy(label);
|
||||
ncvisual_destroy(v1);
|
||||
ncvisual_destroy(v2);
|
||||
@ -253,7 +254,7 @@ int yield_demo(struct notcurses* nc){
|
||||
ncplane_destroy(m1.vopts.n);
|
||||
return -1;
|
||||
}
|
||||
total = maxx * maxy;
|
||||
total = geom.pixy * geom.pixx;
|
||||
|
||||
DEMO_RENDER(nc);
|
||||
|
||||
|
@ -132,7 +132,6 @@ ncvisual_origin(const struct ncvisual_options* vopts, int* restrict begy, int* r
|
||||
// FIXME we ought also do the output calculations here (how many rows x cols,
|
||||
// given the input plane vopts->n and scaling vopts->scaling)--but do not
|
||||
// perform any actual scaling, nor create any planes!
|
||||
// takes tcache distinctly; nc is used only for logging, and can be NULL
|
||||
int ncvisual_blitset_geom(const notcurses* nc, const tinfo* tcache,
|
||||
const ncvisual* n, const struct ncvisual_options* vopts,
|
||||
int* y, int* x, int* scaley, int* scalex,
|
||||
@ -287,6 +286,16 @@ int ncvisual_blitter_geom(const notcurses* nc, const ncvisual* n,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ncvisual_geom(const notcurses* nc, const ncvisual* n,
|
||||
const struct ncvisual_options* vopts, ncvgeom* geom){
|
||||
if(nc == NULL && n == NULL){
|
||||
logerror("got NULL for both sources\n");
|
||||
return -1;
|
||||
}
|
||||
// FIXME
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* rgb_loose_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha){
|
||||
if(*rowstride % 4){ // must be a multiple of 4 bytes
|
||||
return NULL;
|
||||
|
@ -498,9 +498,11 @@ int ffmpeg_stream(notcurses* nc, ncvisual* ncv, float timescale,
|
||||
ncplane_erase(activevopts.n); // new frame could be partially transparent
|
||||
}
|
||||
// decay the blitter explicitly, so that the callback knows the blitter it
|
||||
// was actually rendered with
|
||||
ncvisual_blitter_geom(nc, ncv, &activevopts, NULL, NULL, NULL, NULL,
|
||||
&activevopts.blitter);
|
||||
// was actually rendered with. basically just need rgba_blitter(), but
|
||||
// that's not exported.
|
||||
ncvgeom geom;
|
||||
ncvisual_geom(nc, ncv, &activevopts, &geom);
|
||||
activevopts.blitter = geom.blitter;
|
||||
if((newn = ncvisual_blit(nc, ncv, &activevopts)) == NULL){
|
||||
if(activevopts.n != vopts->n){
|
||||
ncplane_destroy(activevopts.n);
|
||||
|
@ -41,7 +41,6 @@ int main(int argc, char** argv){
|
||||
if(!ncv){
|
||||
goto err;
|
||||
}
|
||||
int scaley, scalex;
|
||||
vopts.n = n;
|
||||
if((ncvisual_blit(nc, ncv, &vopts)) == NULL){
|
||||
goto err;
|
||||
@ -52,8 +51,9 @@ int main(int argc, char** argv){
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
|
||||
|
||||
ncplane_erase(n);
|
||||
ncvisual_blitter_geom(nc, ncv, &vopts, NULL, NULL, &scaley, &scalex, NULL);
|
||||
if(ncvisual_resize(ncv, dimy * scaley, dimx * scalex)){
|
||||
ncvgeom geom;
|
||||
ncvisual_geom(nc, ncv, &vopts, &geom);
|
||||
if(ncvisual_resize(ncv, dimy * geom.scaley, dimx * geom.scalex)){
|
||||
goto err;
|
||||
}
|
||||
if(ncvisual_blit(nc, ncv, &vopts) == NULL){
|
||||
|
@ -92,14 +92,18 @@ TEST_CASE("Media") {
|
||||
ncplane_dim_yx(ncp_, &dimy, &dimx);
|
||||
auto ncv = ncvisual_from_file(find_data("changes.jpg").get());
|
||||
REQUIRE(ncv);
|
||||
int odimy, odimx, ndimy, ndimx;
|
||||
struct ncvisual_options opts{};
|
||||
opts.n = ncp_;
|
||||
CHECK(0 == ncvisual_blitter_geom(nc_, ncv, &opts, &odimy, &odimx, nullptr, nullptr, nullptr));
|
||||
ncvgeom geom{};
|
||||
CHECK(0 == ncvisual_geom(nc_, ncv, &opts, &geom));
|
||||
int odimy = geom.pixy;
|
||||
int odimx = geom.pixx;
|
||||
CHECK(ncvisual_blit(nc_, ncv, &opts));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_resize_noninterpolative(ncv, ncv->pixy * 2, ncv->pixx * 2));
|
||||
CHECK(0 == ncvisual_blitter_geom(nc_, ncv, &opts, &ndimy, &ndimx, nullptr, nullptr, nullptr));
|
||||
CHECK(0 == ncvisual_geom(nc_, ncv, &opts, &geom));
|
||||
int ndimy = geom.pixy;
|
||||
int ndimx = geom.pixx;
|
||||
CHECK(ndimy == odimy * 2);
|
||||
CHECK(ndimx == odimx * 2);
|
||||
CHECK(ncvisual_blit(nc_, ncv, &opts));
|
||||
|
Loading…
x
Reference in New Issue
Block a user