diff --git a/NEWS.md b/NEWS.md index 50a001b61..b7536605d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,9 @@ rearrangements of Notcurses. * `ncplane_rgba()` has been deprecated in favor of the new function `ncplane_as_rgba()`, which the former now wraps. It will be removed in ABI3. The new function can report the synthesized pixel geometry. + * `ncplane_pixelgeom()` has been added, allowing callers to determine the + size of the plane and cells in pixels, as well as the maximum bitmap + size that can be displayed. * 2.2.5 (2021-04-04) * Bugfix release, no user-visible changes. diff --git a/USAGE.md b/USAGE.md index 4d14e1738..be8156470 100644 --- a/USAGE.md +++ b/USAGE.md @@ -233,7 +233,6 @@ notcurses_stddim_yx_const(const struct notcurses* nc, int* restrict y, int* rest ncplane_dim_yx(s, y, x); // accepts NULL return s; } - ``` A reference to the standard plane *is* persistent across a screen resize, as are @@ -908,6 +907,16 @@ ncplane_dim_x(const struct ncplane* n){ return dimx; } +// Retrieve pixel geometry for the display region ('pxy', 'pxx'), each cell +// ('celldimy', 'celldimx'), and the maximum displayable bitmap ('maxbmapy', +// 'maxbmapx'). Note that this will call notcurses_check_pixel_support(), +// possibly leading to an interrogation of the terminal. If bitmaps are not +// supported, 'maxbmapy' and 'maxbmapx' will be 0. Any of the geometry +// arguments may be NULL. +void ncplane_pixelgeom(struct ncplane* n, int* restrict pxy, int* restrict pxx, + int* restrict celldimy, int* restrict celldimx, + int* restrict maxbmapy, int* restrict maxbmapx); + // provided a coordinate relative to the origin of 'src', map it to the same // absolute coordinate relative to the origin of 'dst'. either or both of 'y' // and 'x' may be NULL. if 'dst' is NULL, it is taken to be the standard plane. diff --git a/doc/man/man3/notcurses_plane.3.md b/doc/man/man3/notcurses_plane.3.md index 40575c3b8..abb669fa1 100644 --- a/doc/man/man3/notcurses_plane.3.md +++ b/doc/man/man3/notcurses_plane.3.md @@ -198,6 +198,8 @@ typedef struct ncplane_options { **int ncplane_rotate_ccw(struct ncplane* ***n***);** +**void ncplane_pixelgeom(struct notcurses* ***n***, int* restrict ***pxy***, int* restrict ***pxx***, int* restrict ***celldimy***, int* restrict ***celldimx***, int* restrict ***maxbmapy***, int* restrict ***maxbmapx***);** + ## DESCRIPTION Ncplanes are the fundamental drawing object of notcurses. All output functions @@ -349,6 +351,15 @@ last row is cleared, and output begins at the beginning of the last row. This does not take place until output is generated (i.e. it is possible to fill a plane when scrolling is enabled). +**ncplane_pixelgeom** retrieves pixel geometry details. **pxy** and **pxx** +return the size of the plane in pixels. **celldimy** and **celldimx** return +the size of a cell in pixels (these ought be the same across planes). +**maxbmapy** and **maxbmapx** describe the largest bitmap which can be +displayed in the plane. This function transitively calls +**notcurses_check_pixel_support**, possibly leading to terminal interrogation +(see **notcurses_capabilities(3)** for why this may be undesirable). Any +parameter (save **n**) may be **NULL**. + # RETURN VALUES **ncplane_create** and **ncplane_dup** return a new **struct ncplane** on @@ -393,6 +404,7 @@ It should not be used in new code. # SEE ALSO **notcurses(3)**, +**notcurses_capabilities(3)**, **notcurses_cell(3)**, **notcurses_output(3)**, **notcurses_stdplane(3)**, diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 4932b0ee5..7685d92c8 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -1114,6 +1114,17 @@ ncplane_dim_x(const struct ncplane* n){ return dimx; } +// Retrieve pixel geometry for the display region ('pxy', 'pxx'), each cell +// ('celldimy', 'celldimx'), and the maximum displayable bitmap ('maxbmapy', +// 'maxbmapx'). Note that this will call notcurses_check_pixel_support(), +// possibly leading to an interrogation of the terminal. If bitmaps are not +// supported, 'maxbmapy' and 'maxbmapx' will be 0. Any of the geometry +// arguments may be NULL. +API void ncplane_pixelgeom(struct ncplane* n, int* RESTRICT pxy, int* RESTRICT pxx, + int* RESTRICT celldimy, int* RESTRICT celldimx, + int* RESTRICT maxbmapy, int* RESTRICT maxbmapx) + __attribute__ ((nonnull (1))); + // Return our current idea of the terminal dimensions in rows and cols. static inline void notcurses_term_dim_yx(const struct notcurses* n, int* RESTRICT rows, int* RESTRICT cols){ @@ -1193,7 +1204,7 @@ API int (*ncplane_resizecb(const struct ncplane* n))(struct ncplane*); // The standard plane cannot be reparented. Any planes bound to 'n' are // reparented to the previous parent of 'n'. API struct ncplane* ncplane_reparent(struct ncplane* n, struct ncplane* newparent) - __attribute__ ((nonnull(1, 2))); + __attribute__ ((nonnull (1, 2))); // The same as ncplane_reparent(), except any planes bound to 'n' come along // with it to its new destination. Their z-order is maintained. If 'newparent' @@ -1307,16 +1318,16 @@ typedef struct ncstats { // Allocate an ncstats object. Use this rather than allocating your own, since // future versions of Notcurses might enlarge this structure. API ALLOC ncstats* notcurses_stats_alloc(const struct notcurses* nc) - __attribute__ ((nonnull(1))); + __attribute__ ((nonnull (1))); // Acquire an atomic snapshot of the Notcurses object's stats. API void notcurses_stats(struct notcurses* nc, ncstats* stats) - __attribute__ ((nonnull(1, 2))); + __attribute__ ((nonnull (1, 2))); // Reset all cumulative stats (immediate ones, such as fbbytes, are not reset), // first copying them into |*stats| (if |stats| is not NULL). API void notcurses_stats_reset(struct notcurses* nc, ncstats* stats) - __attribute__ ((nonnull(1))); + __attribute__ ((nonnull (1))); // Resize the specified ncplane. The four parameters 'keepy', 'keepx', // 'keepleny', and 'keeplenx' define a subset of the ncplane to keep, diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 86b21c3ab..b7e21368b 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -2718,3 +2718,42 @@ int ncstrwidth(const char* mbs){ }while(*mbs); return cols; } + +void ncplane_pixelgeom(ncplane* n, int* RESTRICT pxy, int* RESTRICT pxx, + int* RESTRICT celldimy, int* RESTRICT celldimx, + int* RESTRICT maxbmapy, int* RESTRICT maxbmapx){ + notcurses* nc = ncplane_notcurses(n); + if(celldimy){ + *celldimy = nc->tcache.cellpixy; + } + if(celldimx){ + *celldimx = nc->tcache.cellpixx; + } + if(pxy){ + *pxy = nc->tcache.cellpixy * ncplane_dim_y(n); + } + if(pxx){ + *pxx = nc->tcache.cellpixx * ncplane_dim_x(n); + } + if(notcurses_check_pixel_support(nc) > 0){ + if(maxbmapy){ + *maxbmapy = nc->tcache.cellpixy * ncplane_dim_y(n); + if(*maxbmapy > nc->tcache.sixel_maxy && nc->tcache.sixel_maxy){ + *maxbmapy = nc->tcache.sixel_maxy; + } + } + if(maxbmapx){ + *maxbmapx = nc->tcache.cellpixx * ncplane_dim_x(n); + if(*maxbmapx > nc->tcache.sixel_maxx && nc->tcache.sixel_maxx){ + *maxbmapx = nc->tcache.sixel_maxx; + } + } + }else{ + if(maxbmapy){ + *maxbmapy = 0; + } + if(maxbmapx){ + *maxbmapx = 0; + } + } +} diff --git a/src/lib/render.c b/src/lib/render.c index b0bdce42e..623981992 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -1328,11 +1328,15 @@ int ncpile_render(ncplane* n){ } int notcurses_render(notcurses* nc){ +//fprintf(stderr, "--------------- BEGIN RENDER\n"); +notcurses_debug(nc, stderr); ncplane* stdn = notcurses_stdplane(nc); if(ncpile_render(stdn)){ return -1; } - return(ncpile_rasterize(stdn)); + int i = ncpile_rasterize(stdn); +//fprintf(stderr, "----------------- END RENDER\n"); + return i; } // for now, we just run the top half of notcurses_render(), and copy out the