Progress towards NCBLIT_3x2 by default

Add a new member 'sextants' to the terminfo cache (both
notcurses and ncvisual contain one of these, and both
initialize it the same way -- interrogate_terminfo()).
Add a new function, 'notcurses_media_defblitter()', and
deprecate 'ncvisual_default_blitter()' (the latter didn't
receive enough information to return NCBLIT_3x2). Update
all callers. Add new *internal* function rgba_default_blitter(),
so this logic can be freely changed in the future. If
sextants are available, and we're scaling, return NCBLIT_3x2.
Once we detect sextant availability, we'll have sexblitter
as a default -- stay tuned! #1114
This commit is contained in:
nick black 2020-12-25 17:01:26 -05:00
parent 36e81a573a
commit 4d8efcab82
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
11 changed files with 70 additions and 22 deletions

View File

@ -6,6 +6,12 @@ rearrangements of Notcurses.
* Divide `ncdirect_render_image()` into component `ncdirect_render_frame()`
and `ncdirect_raster_frame()` (the original remains), allowing multiple
threads to decode images concurrently.
* Sextants are now considered supported for certain values of `TERM`.
* `ncvisual_default_blitter()` has been deprecated in favor of the new
function `ncvisual_media_defblitter()`. This function's opaque logic
accepts a `struct notcurses *`, providing some future-proofing against
blitter changes. This function is necessary to get `NCBLIT_3x2` from
`NCBLIT_DEFAULT`.
* 2.1.1 (2020-12-16)
* Progress bars via `ncprogbar`, using the standard widget API.

View File

@ -293,6 +293,11 @@ namespace ncpp
return error_guard (notcurses_ucs32_to_utf8 (ucs32, ucs32count, resultbuf, buflen), -1);
}
ncblitter_e get_media_defblitter (ncscale_e scale) noexcept
{
return ncvisual_media_defblitter (nc, scale);
}
Plane* get_stdplane () noexcept
{
return new Plane (notcurses_stdplane (nc), true);

View File

@ -114,11 +114,6 @@ namespace ncpp
return error_guard (ncvisual_set_yx (visual, y, x, pixel), -1);
}
static ncblitter_e get_default_blitter (bool utf8, ncscale_e scale) noexcept
{
return ncvisual_default_blitter (utf8, scale);
}
private:
void common_init (ncplane *plane, const char *file)
{

View File

@ -3296,20 +3296,37 @@ struct blitset {
API extern const struct blitset notcurses_blitters[];
// replaced by ncvisual_media_defblitter(). this original version never returns
// NCBLIT_3x2.
static inline ncblitter_e
ncvisual_default_blitter(bool utf8, ncscale_e scale)
__attribute__ ((deprecated));
static inline ncblitter_e
ncvisual_default_blitter(bool utf8, ncscale_e scale){
if(utf8){
// NCBLIT_3x2 is better image quality, especially for large images, but
// it's not the general default because it doesn't preserve aspect ratio.
// NCSCALE_STRETCH throws away aspect ratio, and can safely use NCBLIT_3x2.
// NCBLIT_3x2/NCBLIT_2x2 are better image quality, especially for large
// images, but it's not the general default because it doesn't preserve
// aspect ratio (as does NCBLIT_2x1). NCSCALE_STRETCH throws away aspect
// ratio, and can safely use NCBLIT_3x2/2x2.
if(scale == NCSCALE_STRETCH){
return NCBLIT_2x2;
return NCBLIT_3x2;
}
return NCBLIT_2x1;
}
return NCBLIT_1x1;
}
// Get the default *media* (not plot) blitter for this environment when using
// the specified scaling method. Currently, this means:
// - if lacking UTF-8, NCBLIT_1x1
// - otherwise, if not NCSCALE_STRETCH, NCBLIT_2x1
// - otherwise, if sextants are not known to be good, NCBLIT_2x2
// - otherwise NCBLIT_3x2
// NCBLIT_2x2 and NCBLIT_3x2 both distort the original aspect ratio, thus
// NCBLIT_2x1 is used outside of NCSCALE_STRETCH.
API ncblitter_e ncvisual_media_defblitter(const struct notcurses* nc, ncscale_e scale);
#undef API
#ifdef __cplusplus

View File

@ -42,7 +42,7 @@ zoom_map(struct notcurses* nc, const char* map, int* ret){
// but *do* explicitly supply NCBLIT_2x2 since we're not scaling.
struct ncvisual_options vopts = {
.y = 1,
.blitter = NCBLIT_2x2,
.blitter = ncvisual_media_defblitter(nc, NCSCALE_NONE),
};
if(ncvisual_geom(nc, ncv, &vopts, &vheight, &vwidth, &yscale, &xscale)){
ncvisual_destroy(ncv);

View File

@ -863,8 +863,7 @@ int ncblit_rgba(const void* data, int linesize, const struct ncvisual_options* v
}
ncblitter_e blitter;
if(!vopts || vopts->blitter == NCBLIT_DEFAULT){
blitter = ncvisual_default_blitter(notcurses_canutf8(ncplane_notcurses(nc)),
NCSCALE_NONE);
blitter = ncvisual_media_defblitter(ncplane_notcurses(nc), NCSCALE_NONE);
}else{
blitter = vopts->blitter;
}
@ -885,3 +884,7 @@ int rgba_blit_dispatch(ncplane* nc, const struct blitset* bset, int placey,
return bset->blit(nc, placey, placex, linesize, data, begy, begx,
leny, lenx, blendcolors);
}
ncblitter_e ncvisual_media_defblitter(const notcurses* nc, ncscale_e scale){
return rgba_blitter_default(nc->utf8, scale, nc->tcache.sextants);
}

View File

@ -38,13 +38,29 @@ encoding_x_scale(const struct blitset* bset) {
return bset->width;
}
// Expand NCBLIT_DEFAULT for media blitting, based on environment.
static inline ncblitter_e
rgba_blitter_default(bool utf8, ncscale_e scale, bool sextants){
if(!utf8){
return NCBLIT_1x1;
}
if(scale != NCSCALE_STRETCH){
return NCBLIT_2x1;
}
if(!sextants){
return NCBLIT_2x2;
}
return NCBLIT_3x2;
}
static inline const struct blitset*
rgba_blitter_low(bool utf8, ncscale_e scale, bool maydegrade, ncblitter_e blitrec) {
rgba_blitter_low(bool utf8, bool sextants, ncscale_e scale, bool maydegrade,
ncblitter_e blitrec) {
const struct blitset* bset;
if(blitrec != NCBLIT_DEFAULT){
bset = lookup_blitset(utf8, blitrec, maydegrade);
}else{
bset = lookup_blitset(utf8, ncvisual_default_blitter(utf8, scale), maydegrade);
bset = lookup_blitset(utf8, rgba_blitter_default(utf8, scale, sextants), maydegrade);
}
if(bset && !bset->blit){ // FIXME remove this once all blitters are enabled
bset = NULL;
@ -58,8 +74,8 @@ static inline const struct blitset*
rgba_blitter(const struct notcurses* nc, const struct ncvisual_options* opts) {
const bool maydegrade = !(opts && (opts->flags & NCVISUAL_OPTION_NODEGRADE));
const ncscale_e scale = opts ? opts->scaling : NCSCALE_NONE;
return rgba_blitter_low(notcurses_canutf8(nc), scale, maydegrade,
opts ? opts->blitter : NCBLIT_DEFAULT);
return rgba_blitter_low(notcurses_canutf8(nc), notcurses_cansextant(nc),
scale, maydegrade, opts ? opts->blitter : NCBLIT_DEFAULT);
}
#endif

View File

@ -427,7 +427,7 @@ ncdirect_dump_plane(ncdirect* n, const ncplane* np, int xoff){
int ncdirect_raster_frame(ncdirect* n, ncdirectv* faken, ncalign_e align,
ncblitter_e blitter, ncscale_e scale){
auto bset = rgba_blitter_low(n->utf8, scale, true, blitter);
auto bset = rgba_blitter_low(n->utf8, n->tcache.sextants, scale, true, blitter);
if(!bset){
free_plane(faken);
return -1;
@ -457,7 +457,7 @@ ncdirectv* ncdirect_render_frame(ncdirect* n, const char* file,
return nullptr;
}
//fprintf(stderr, "render %d/%d to %d+%dx%d scaling: %d\n", ncv->rows, ncv->cols, leny, lenx, scale);
auto bset = rgba_blitter_low(n->utf8, scale, true, blitter);
auto bset = rgba_blitter_low(n->utf8, n->tcache.sextants, scale, true, blitter);
if(!bset){
ncvisual_destroy(ncv);
return nullptr;

View File

@ -95,8 +95,6 @@ typedef struct ncplane {
bool scrolling; // is scrolling enabled? always disabled by default
} ncplane;
#include "blitset.h"
// current presentation state of the terminal. it is carried across render
// instances. initialize everything to 0 on a terminal reset / startup.
typedef struct rasterstate {
@ -281,6 +279,7 @@ typedef struct tinfo {
// background_opaque is in use. detect this, and avoid the default if so.
// bg_collides_default is either 0x0000000 or 0x1RRGGBB.
uint32_t bg_collides_default;
bool sextants; // do we have Unicode 13 sextant support?
} tinfo;
typedef struct ncinputlayer {
@ -367,6 +366,13 @@ typedef struct notcurses {
bool libsixel; // do we have Sixel support?
} notcurses;
static inline bool
notcurses_cansextant(const notcurses* nc){
return nc->tcache.sextants;
}
#include "blitset.h"
void sigwinch_handler(int signo);
void init_lang(notcurses* nc); // nc may be NULL, only used for logging

View File

@ -15,7 +15,7 @@ auto ncvisual_geom(const notcurses* nc, const ncvisual* n,
const ncscale_e scale = vopts ? vopts->scaling : NCSCALE_NONE;
ncblitter_e blitter;
if(!vopts || vopts->blitter == NCBLIT_DEFAULT){
blitter = ncvisual_default_blitter(nc, scale);
blitter = ncvisual_media_defblitter(nc, scale);
}else{
blitter = vopts->blitter;
}

View File

@ -74,7 +74,7 @@ auto perframe(struct ncvisual* ncv, struct ncvisual_options* vopts,
intmax_t ns = timespec_to_ns(&now) - timespec_to_ns(start);
marsh->blitter = vopts->blitter;
if(marsh->blitter == NCBLIT_DEFAULT){
marsh->blitter = ncvisual_default_blitter(notcurses_canutf8(nc), vopts->scaling);
marsh->blitter = ncvisual_media_defblitter(nc, vopts->scaling);
}
if(!marsh->quiet){
stdn->printf(0, NCAlign::Left, "frame %06d\u2026 (%s)", marsh->framecount,