mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
Avoid drawing sixel to the bottom row
Sixels, unlike Kitties, can't be drawn to the bottom row, lest we scroll. We were properly guarding against creation of a sixel that touched the bottom row when creating the plane within ncvisual_blit(), but not when we were provided with a plane. This used to be fine because ncplayer cut the plane off less one row, but when we enabled the bottom row for Kitties, this ceased. We don't want to expose this wart to userspace, so instead clamp sixel_maxy based off the screen height when appropriate. Closes #1789. 1789?!?! Liberté, Egalité, Fraternité!
This commit is contained in:
parent
fc390da020
commit
50a304bada
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user