diff --git a/src/lib/input.c b/src/lib/input.c index 41872c52a..83936eba4 100644 --- a/src/lib/input.c +++ b/src/lib/input.c @@ -1051,7 +1051,7 @@ pump_control_read(init_state* inits, unsigned char c){ break; case STATE_SIXEL_HEIGHT: if(c == 'S'){ - inits->tcache->sixel_maxy = inits->numeric; + inits->tcache->sixel_maxy_pristine = inits->numeric; inits->state = STATE_NULL; }else if(ruts_numeric(&inits->numeric, c)){ return -1; diff --git a/src/lib/internal.h b/src/lib/internal.h index f0d84fc3d..3768d8491 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -944,6 +944,7 @@ clamp_to_sixelmax(const tinfo* t, int* y, int* x, int* outy, ncscale_e scaling){ *outy = *y; if(*outy % t->sprixel_scale_height){ *outy += t->sprixel_scale_height - (*outy % t->sprixel_scale_height); + // FIXME use closed form while(t->sixel_maxy && *outy > t->sixel_maxy){ *outy -= t->sprixel_scale_height; } diff --git a/src/lib/render.c b/src/lib/render.c index 8842fde36..7166a23cd 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -30,6 +30,16 @@ notcurses_resize_internal(ncplane* pp, int* restrict rows, int* restrict cols){ if(*rows <= 0){ *rows = 1; } + if(n->tcache.sixel_maxy_pristine){ + n->tcache.sixel_maxy = n->tcache.sixel_maxy_pristine; + int sixelrows = *rows - 1; + // if the bottom margin is at least one row, we can draw into the last + // row of our visible area. we must leave the true bottom row alone. + if(n->margin_b){ + ++sixelrows; + } + n->tcache.sixel_maxy = sixelrows * n->tcache.cellpixy; + } *cols -= n->margin_l + n->margin_r; if(*cols <= 0){ *cols = 1; diff --git a/src/lib/termdesc.c b/src/lib/termdesc.c index 89ac4bdcd..9b54376f5 100644 --- a/src/lib/termdesc.c +++ b/src/lib/termdesc.c @@ -28,7 +28,6 @@ setup_kitty_bitmaps(tinfo* ti, int fd){ ti->sprixel_scale_height = 1; ti->pixel_rebuild = kitty_rebuild; ti->pixel_clear_all = kitty_clear_all; - ti->bitmap_lowest_line = true; set_pixel_blitter(kitty_blit); sprite_init(ti, fd); } diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index 38a88cb70..8ea3005f0 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -117,7 +117,15 @@ typedef struct tinfo { // on TERM heuristics. otherwise, we attempt to detect sixel support, and // query the details of the implementation. int color_registers; // sixel color registers (post pixel_query_done) - int sixel_maxx, sixel_maxy; // sixel size maxima (post pixel_query_done) + int sixel_maxx; // maximum theoretical sixel width + // in sixel, we can't render to the bottom row, lest we force a one-line + // scroll. we thus clamp sixel_maxy_pristine to the minimum of + // sixel_maxy_pristine (the reported sixel_maxy), and the number of rows + // less one times the cell height. sixel_maxy is thus recomputed whenever + // we get a resize event. it is only defined if we have sixel_maxy_pristine, + // so kitty graphics (which don't force a scroll) never deal with this. + int sixel_maxy; // maximum working sixel height + int sixel_maxy_pristine; // maximum theoretical sixel height, as queried int (*pixel_destroy)(const struct notcurses* nc, const struct ncpile* p, FILE* out, struct sprixel* s); // wipe out a cell's worth of pixels from within a sprixel. for sixel, this // means leaving out the pixels (and likely resizes the string). for kitty, @@ -135,7 +143,6 @@ typedef struct tinfo { struct termios tpreserved; // terminal state upon entry ncinputlayer input; // input layer bool bitmap_supported; // do we support bitmaps (post pixel_query_done)? - bool bitmap_lowest_line; // can we render pixels to the bottom row? bool BCEflag; // "BCE" flag for erases with background color bool AMflag; // "AM" flag for automatic movement to next line diff --git a/src/lib/visual.c b/src/lib/visual.c index 7b6caf907..3c4e1c81d 100644 --- a/src/lib/visual.c +++ b/src/lib/visual.c @@ -770,11 +770,9 @@ make_sprixel_plane(notcurses* nc, ncplane* parent, ncvisual* ncv, uint64_t flags, int* outy, int* placey, int* placex){ if(scaling != NCSCALE_NONE && scaling != NCSCALE_NONE_HIRES){ ncplane_dim_yx(parent, disppixy, disppixx); + // FIXME why do we clamp only vertical, not horizontal, here? if(*placey + *disppixy >= ncplane_dim_y(notcurses_stdplane_const(nc))){ *disppixy = ncplane_dim_y(notcurses_stdplane_const(nc)) - *placey; - if(!nc->tcache.bitmap_lowest_line){ - --*disppixy; - } } if(!(flags & NCVISUAL_OPTION_VERALIGNED)){ *disppixy -= *placey; @@ -845,7 +843,6 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits } int disppixy = 0, disppixx = 0, outy = 0; ncplane* createdn = NULL; -//fprintf(stderr, "INPUT N: %p rows: %d cols: %d 0x%016lx\n", n ? n : NULL, disppixy, disppixx, flags); if(n == NULL || (flags & NCVISUAL_OPTION_CHILDPLANE)){ // create plane if(n == NULL){ n = notcurses_stdplane(nc);