diff --git a/src/lib/direct.c b/src/lib/direct.c index aec622a26..b27f575cc 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -515,7 +515,7 @@ ncdirect_dump_plane(ncdirect* n, const ncplane* np, int xoff){ if(ncdirect_flush(n)){ return -1; } - if(blocking_write(fileno(n->ttyfp), np->sprite->glyph, np->sprite->glyphlen) < 0){ + if(sprite_draw(&n->tcache, NULL, np->sprite, n->ttyfp, 0, xoff)){ return -1; } if(sprite_commit(&n->tcache, n->ttyfp, np->sprite, true)){ diff --git a/src/lib/internal.h b/src/lib/internal.h index e2b65ad4f..5cc141dfa 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -682,28 +682,28 @@ sprite_scrub(const notcurses* n, const ncpile* p, sprixel* s){ // precondition: s->invalidated is SPRIXEL_INVALIDATED or SPRIXEL_MOVED. // returns -1 on error, or the number of bytes written. static inline int -sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out, +sprite_draw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out, int y, int x){ //sprixel_debug(s, stderr); logdebug("Sprixel %u state %d\n", s->id, s->invalidated); - return n->tcache.pixel_draw(p, s, out, y, x); + return ti->pixel_draw(ti, p, s, out, y, x); } // precondition: s->invalidated is SPRIXEL_MOVED or SPRIXEL_INVALIDATED // returns -1 on error, or the number of bytes written. static inline int -sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out, +sprite_redraw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out, int y, int x){ //sprixel_debug(s, stderr); logdebug("Sprixel %u state %d\n", s->id, s->invalidated); - if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){ + if(s->invalidated == SPRIXEL_MOVED && ti->pixel_move){ // if we are kitty prior to 0.20.0, C=1 isn't available to us, and we must // not emit it. we use sixel_maxy_pristine as a side channel to encode // this version information. - bool noscroll = !n->tcache.sixel_maxy_pristine; - return n->tcache.pixel_move(s, out, noscroll); + bool noscroll = !ti->sixel_maxy_pristine; + return ti->pixel_move(s, out, noscroll); }else{ - return n->tcache.pixel_draw(p, s, out, y, x); + return ti->pixel_draw(ti, p, s, out, y, x); } } diff --git a/src/lib/iterm.c b/src/lib/iterm.c index e697ac22f..4fdab71e3 100644 --- a/src/lib/iterm.c +++ b/src/lib/iterm.c @@ -26,9 +26,12 @@ int iterm_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec){ } // spit out the control sequence and data. -int iterm_draw(const ncpile *p, sprixel* s, FILE* out, int y, int x){ - if(goto_location(p->nc, out, y, x)){ - return -1; +int iterm_draw(const tinfo* ti, const ncpile *p, sprixel* s, FILE* out, int y, int x){ + (void)ti; + if(p){ + if(goto_location(p->nc, out, y, x)){ + return -1; + } } if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){ return -1; diff --git a/src/lib/kitty.c b/src/lib/kitty.c index bbfed87e4..eb926dfe6 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -952,7 +952,9 @@ int kitty_scrub(const ncpile* p, sprixel* s){ } // returns the number of bytes written -int kitty_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){ +int kitty_draw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out, + int y, int x){ + (void)ti; (void)p; (void)y; (void)x; diff --git a/src/lib/linux.c b/src/lib/linux.c index 44c6b4233..69447054e 100644 --- a/src/lib/linux.c +++ b/src/lib/linux.c @@ -124,16 +124,16 @@ int fbcon_scrub(const struct ncpile* p, sprixel* s){ return 0; } -int fbcon_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x){ +int fbcon_draw(const tinfo* ti, const struct ncpile *p, sprixel* s, FILE* out, int y, int x){ + (void)p; (void)out; // we don't write to the stream - const tinfo* ti = &p->nc->tcache; int wrote = 0; - for(int l = 0 ; l < s->pixy ; ++l){ + for(unsigned l = 0 ; l < (unsigned)s->pixy && l < ti->pixy ; ++l){ // FIXME pixel size isn't necessarily 4B, line isn't necessarily psize*pixx size_t offset = ((l + y * ti->cellpixy) * ti->pixx + x * ti->cellpixx) * 4; uint8_t* tl = ti->linux_fbuffer + offset; const char* src = s->glyph + (l * s->pixx * 4); - for(int c = 0 ; c < s->pixx ; ++c){ + for(unsigned c = 0 ; c < (unsigned)s->pixx && c < ti->pixx ; ++c){ uint32_t pixel; memcpy(&pixel, src, 4); if(!rgba_trans_p(pixel, 0)){ diff --git a/src/lib/render.c b/src/lib/render.c index 16d39f6ad..af66b3034 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -862,7 +862,7 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){ if(goto_location(nc, out, y + nc->margin_t, x + nc->margin_l)){ return -1; } - int r = sprite_redraw(nc, p, s, out, y + nc->margin_t, x + nc->margin_l); + int r = sprite_redraw(&nc->tcache, p, s, out, y + nc->margin_t, x + nc->margin_l); if(r < 0){ return -1; } @@ -923,7 +923,7 @@ rasterize_sprixels(notcurses* nc, ncpile* p, FILE* out){ //fprintf(stderr, "3 DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->margin_t, x + nc->margin_l, s->n); int y,x; ncplane_yx(s->n, &y, &x); - int r = sprite_draw(nc, p, s, out, y + nc->margin_t, x + nc->margin_l); + int r = sprite_draw(&nc->tcache, p, s, out, y + nc->margin_t, x + nc->margin_l); if(r < 0){ return -1; } diff --git a/src/lib/sixel.c b/src/lib/sixel.c index c4da92c09..e04e5e884 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -828,7 +828,9 @@ int sixel_scrub(const ncpile* p, sprixel* s){ } // returns the number of bytes written -int sixel_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){ +int sixel_draw(const tinfo* ti, const ncpile* p, sprixel* s, FILE* out, + int y, int x){ + (void)ti; // if we've wiped or rebuilt any cells, effect those changes now, or else // we'll get flicker when we move to the new location. if(s->wipes_outstanding){ @@ -837,15 +839,17 @@ int sixel_draw(const ncpile* p, sprixel* s, FILE* out, int y, int x){ } s->wipes_outstanding = false; } - if(goto_location(p->nc, out, y, x)){ - return -1; - } - if(s->invalidated == SPRIXEL_MOVED){ - for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){ - for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){ - struct crender *r = &p->crender[yy * p->dimx + xx]; - if(!r->sprixel || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE_SIXEL){ - r->s.damaged = 1; + if(p){ + if(goto_location(p->nc, out, y, x)){ + return -1; + } + if(s->invalidated == SPRIXEL_MOVED){ + for(int yy = s->movedfromy ; yy < s->movedfromy + s->dimy && yy < p->dimy ; ++yy){ + for(int xx = s->movedfromx ; xx < s->movedfromx + s->dimx && xx < p->dimx ; ++xx){ + struct crender *r = &p->crender[yy * p->dimx + xx]; + if(!r->sprixel || sprixel_state(r->sprixel, yy, xx) != SPRIXCELL_OPAQUE_SIXEL){ + r->s.damaged = 1; + } } } } diff --git a/src/lib/sprite.h b/src/lib/sprite.h index d88207000..04050d95e 100644 --- a/src/lib/sprite.h +++ b/src/lib/sprite.h @@ -172,9 +172,12 @@ int kitty_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec); int iterm_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec); int fbcon_rebuild(sprixel* s, int ycell, int xcell, uint8_t* auxvec); int kitty_rebuild_animation(sprixel* s, int ycell, int xcell, uint8_t* auxvec); -int sixel_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x); -int kitty_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x); -int iterm_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x); +int sixel_draw(const tinfo* ti, const struct ncpile *p, sprixel* s, + FILE* out, int y, int x); +int kitty_draw(const tinfo* ti, const struct ncpile *p, sprixel* s, + FILE* out, int y, int x); +int iterm_draw(const tinfo* ti, const struct ncpile *p, sprixel* s, + FILE* out, int y, int x); int kitty_move(sprixel* s, FILE* out, unsigned noscroll); int sixel_scrub(const struct ncpile* p, sprixel* s); int kitty_scrub(const struct ncpile* p, sprixel* s); @@ -198,7 +201,8 @@ int kitty_blit_animated(struct ncplane* n, int linesize, const void* data, int leny, int lenx, const struct blitterargs* bargs); int fbcon_blit(struct ncplane* nc, int linesize, const void* data, int leny, int lenx, const struct blitterargs* bargs); -int fbcon_draw(const struct ncpile *p, sprixel* s, FILE* out, int y, int x); +int fbcon_draw(const tinfo* ti, const struct ncpile *p, sprixel* s, + FILE* out, int y, int x); #ifdef __cplusplus } diff --git a/src/lib/termdesc.h b/src/lib/termdesc.h index da4f729d4..213d92777 100644 --- a/src/lib/termdesc.h +++ b/src/lib/termdesc.h @@ -152,8 +152,8 @@ typedef struct tinfo { int (*pixel_rebuild)(struct sprixel* s, int y, int x, uint8_t* auxvec); int (*pixel_remove)(int id, FILE* out); // kitty only, issue actual delete command int (*pixel_init)(const struct tinfo*, int fd); // called when support is detected - int (*pixel_draw)(const struct ncpile* p, struct sprixel* s, FILE* out, - int y, int x); + int (*pixel_draw)(const struct tinfo*, const struct ncpile* p, + struct sprixel* s, FILE* out, int y, int x); // execute move (erase old graphic, place at new location) if non-NULL int (*pixel_move)(struct sprixel* s, FILE* out, unsigned noscroll); int (*pixel_scrub)(const struct ncpile* p, struct sprixel* s);