disable quadrants except where whitelisted #1517

Require a known-good TERM heuristic match to enable
quadrants (NCBLIT_2x2); they otherwise decay to halves
(NCBLIT_2x1). The only terminal that supports quadrants
but does not support sextants is the Linux console, where
we program quadrants directly into the font table,
like a beast. Closes #1517, and #1298 if we're lucky.
pull/1520/head
nick black 4 years ago
parent 62242f0e41
commit 80d93fdfb6
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -881,8 +881,8 @@ const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid, boo
return NULL;
}
}
// without pixel support, NCBLIT_PIXEL decays to NCBLIT_3x2
if(!tcache->sixel_supported && setid == NCBLIT_PIXEL){
// without bitmap support, NCBLIT_PIXEL decays to NCBLIT_3x2
if(!tcache->bitmap_supported && setid == NCBLIT_PIXEL){
if(may_degrade){
setid = NCBLIT_3x2;
}else{
@ -897,6 +897,14 @@ const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid, boo
return NULL;
}
}
// without quadrant support, NCBLIT_2x2 decays to NCBLIT_2x1
if(!tcache->quadrants && setid == NCBLIT_2x2){
if(may_degrade){
setid = NCBLIT_2x1;
}else{
return NULL;
}
}
// the only viable blitters in ASCII are NCBLIT_1x1 and NCBLIT_PIXEL
if(!tcache->utf8 && (setid != NCBLIT_1x1 && setid != NCBLIT_PIXEL)){
if(may_degrade){

@ -21,19 +21,23 @@ encoding_x_scale(const tinfo* tcache, const struct blitset* bset) {
return bset->width;
}
// Expand NCBLIT_DEFAULT for media blitting, based on environment.
// Expand NCBLIT_DEFAULT for media blitting, based on environment. We never
// use NCBLIT_PIXEL for NCBLIT_DEFAULT, though maybe this ought change.
static inline ncblitter_e
rgba_blitter_default(const tinfo* tcache, ncscale_e scale){
if(!tcache->utf8){
return NCBLIT_1x1;
return NCBLIT_1x1; // only one that works in ASCII
}
if(scale == NCSCALE_NONE || scale == NCSCALE_SCALE){
return NCBLIT_2x1;
}
if(!tcache->sextants){
if(tcache->sextants){
return NCBLIT_3x2;
}
if(tcache->quadrants){
return NCBLIT_2x2;
}
return NCBLIT_3x2;
return NCBLIT_2x1;
}
static inline ncblitter_e

@ -25,7 +25,7 @@ tinfo_debug_caps(const tinfo* ti, FILE* debugfp, int rows, int cols,
if(!ti->pixel_query_done){
fprintf(debugfp, "%sno bitmap graphics information yet\n", indent);
}else{
if(!ti->sixel_supported){
if(!ti->bitmap_supported){
fprintf(debugfp, "%sdidn't detect bitmap graphics support\n", indent);
}else if(ti->sixel_maxy || ti->color_registers){
fprintf(debugfp, "%smax sixel size: %dx%d colorregs: %u\n",
@ -34,8 +34,9 @@ tinfo_debug_caps(const tinfo* ti, FILE* debugfp, int rows, int cols,
fprintf(debugfp, "%sRGBA pixel graphics supported\n", indent);
}
}
fprintf(debugfp, "%sUTF8: %c sextants: %c braille: %c images: %c videos: %c\n",
indent, capbool(ti->utf8), capbool(ti->sextants), capbool(ti->braille),
fprintf(debugfp, "%sUTF8: %c quad: %c sex: %c braille: %c images: %c videos: %c\n",
indent, capbool(ti->utf8), capbool(ti->quadrants),
capbool(ti->sextants), capbool(ti->braille),
capbool(images), capbool(videos));
if(ti->bg_collides_default){
fprintf(debugfp, "%sbackground of 0x%06lx is considered transparent\n", indent, ti->bg_collides_default & 0xfffffful);

@ -1112,7 +1112,7 @@ int ncdirect_check_pixel_support(ncdirect* n){
if(query_term(&n->tcache, n->ctermfd)){
return -1;
}
if(n->tcache.sixel_supported){
if(n->tcache.bitmap_supported){
return 1;
}
return 0;

@ -359,7 +359,7 @@ typedef struct tinfo {
pthread_mutex_t pixel_query; // only query for pixel support once
int color_registers; // sixel color registers (post pixel_query_done)
int sixel_maxx, sixel_maxy; // sixel size maxima (post pixel_query_done)
bool sixel_supported; // do we support sixel (post pixel_query_done)?
bool bitmap_supported; // do we support bitmaps (post pixel_query_done)?
int sprixelnonce; // next sprixel id
int (*pixel_destroy)(const struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s);
// wipe out a cell's worth of pixels from within a sprixel. for sixel, this
@ -369,6 +369,7 @@ typedef struct tinfo {
int (*pixel_init)(int fd);
int (*pixel_draw)(const struct notcurses* n, const struct ncpile* p, sprixel* s, FILE* out);
bool pixel_query_done; // have we yet performed pixel query?
bool quadrants; // do we have (good, vetted) Unicode 1 quadrant support?
bool sextants; // do we have (good, vetted) Unicode 13 sextant support?
bool braille; // do we have Braille support? (linux console does not)
// alacritty went rather off the reservation for their sixel support. they

@ -908,7 +908,7 @@ int notcurses_check_pixel_support(notcurses* nc){
if(query_term(&nc->tcache, nc->ttyfd)){
return -1;
}
if(nc->tcache.sixel_supported){
if(nc->tcache.bitmap_supported){
return 1;
}
return 0;

@ -316,12 +316,12 @@ write_rle(int* printed, int color, FILE* fp, int seenrle, unsigned char crle){
// Emit the sprixel in its entirety, plus enable and disable pixel mode.
// Closes |fp| on all paths.
static int
write_sixel_data(FILE* fp, int lenx, const sixeltable* stab, int* parse_start){
write_sixel_data(FILE* fp, int leny, int lenx, const sixeltable* stab, int* parse_start){
*parse_start = fprintf(fp, "\ePq");
// Set Raster Attributes - pan/pad=1 (pixel aspect ratio), Ph=lenx, Pv=leny
// using Ph/Pv causes a background to be drawn using color register 0 for all
// unspecified pixels, which we do not want.
// fprintf(fp, "\"1;1;%d;%d", lenx, leny);
fprintf(fp, "\"1;2;%d;%d", lenx, leny);
for(int i = 0 ; i < stab->colors ; ++i){
const unsigned char* rgb = stab->table + i * CENTSIZE;
@ -396,7 +396,7 @@ sixel_blit_inner(int leny, int lenx, const sixeltable* stab, int rows, int cols,
}
int parse_start = 0;
// calls fclose() on success
if(write_sixel_data(fp, lenx, stab, &parse_start)){
if(write_sixel_data(fp, leny, lenx, stab, &parse_start)){
free(buf);
return -1;
}

@ -58,25 +58,32 @@ apply_term_heuristics(tinfo* ti, const char* termname){
// be RGB(0, 0, 0) (the default). we could also just set it, i guess.
ti->bg_collides_default = 0x1000000;
ti->sextants = true; // work since bugfix in 0.19.3
ti->quadrants = true;
ti->pixel_query_done = true;
ti->sixel_supported = true;
ti->bitmap_supported = true;
ti->pixel_cell_wipe = sprite_kitty_cell_wipe;
ti->pixel_destroy = sprite_kitty_annihilate;
ti->pixel_init = sprite_kitty_init;
ti->pixel_draw = kitty_draw;
set_pixel_blitter(kitty_blit);
/*}else if(strstr(termname, "alacritty")){
ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
}else if(strstr(termname, "alacritty")){
ti->alacritty_sixel_hack = true;
ti->quadrants = true;
// ti->sextants = true; // alacritty https://github.com/alacritty/alacritty/issues/4409 */
}else if(strstr(termname, "vte") || strstr(termname, "gnome") || strstr(termname, "xfce")){
ti->sextants = true; // VTE has long enjoyed good sextant support
ti->quadrants = true;
}else if(strncmp(termname, "foot", 4) == 0){
ti->sextants = true;
ti->quadrants = true;
}else if(strncmp(termname, "st", 2) == 0){
// st had neithersextants nor quadrants last i checked (0.8.4)
}else if(strcmp(termname, "linux") == 0){
ti->braille = false; // no braille, no sextants in linux console
// FIXME if the NCOPTION_NO_FONT_CHANGES, this isn't true
ti->quadrants = true; // we program quadrants on the console
}
// run a wcwidth() to guarantee libc Unicode 13 support
// run a wcwidth() to guarantee libc Unicode 13 support, independently of term
if(wcwidth(L'🬸') < 0){
ti->sextants = false;
}
@ -309,13 +316,14 @@ query_sixel_details(tinfo* ti, int fd){
// we found Sixel support -- set up the API
static void
setup_sixel(tinfo* ti){
ti->sixel_supported = true;
setup_sixel(tinfo* ti, int fd){
ti->bitmap_supported = true;
ti->color_registers = 256; // assumed default [shrug]
ti->pixel_init = sprite_sixel_init;
ti->pixel_draw = sixel_draw;
ti->sixel_maxx = ti->sixel_maxy = 0;
ti->pixel_destroy = sixel_delete;
query_sixel_details(ti, fd);
}
// query for Sixel support
@ -364,7 +372,7 @@ fprintf(stderr, "SIXEL QUERY!\n");
case WANT_VT102_C:
if(in == 'c'){
if(ti->alacritty_sixel_hack){
setup_sixel(ti);
setup_sixel(ti, fd);
}
state = DONE;
}else if(in == ';'){
@ -375,7 +383,7 @@ fprintf(stderr, "SIXEL QUERY!\n");
if(in == 'c'){
state = DONE;
}else if(in == '4'){
setup_sixel(ti);
setup_sixel(ti, fd);
state = DONE;
}
break;
@ -384,9 +392,6 @@ fprintf(stderr, "SIXEL QUERY!\n");
break;
}
}
if(ti->sixel_supported){
query_sixel_details(ti, fd);
}
return 0;
}
@ -415,7 +420,7 @@ int query_term(tinfo* ti, int fd){
}
ret = query_sixel(ti, fd);
ti->pixel_query_done = true;
if(ti->sixel_supported){
if(ti->bitmap_supported){
ti->pixel_init(fd);
}
if(flags & O_NONBLOCK){

@ -10,7 +10,7 @@ TEST_CASE("Pixel") {
REQUIRE(n_);
if(notcurses_check_pixel_support(nc_) <= 0){
CHECK(0 == nc_->tcache.sixel_supported);
CHECK(0 == nc_->tcache.bitmap_supported);
CHECK(!notcurses_stop(nc_));
return;
}
@ -18,7 +18,7 @@ TEST_CASE("Pixel") {
SUBCASE("SprixelTermValues") {
CHECK(0 < nc_->tcache.cellpixy);
CHECK(0 < nc_->tcache.cellpixx);
CHECK(nc_->tcache.sixel_supported);
CHECK(nc_->tcache.bitmap_supported);
}
#ifdef NOTCURSES_USE_MULTIMEDIA

Loading…
Cancel
Save