diff --git a/src/lib/internal.h b/src/lib/internal.h index f352fd731..265223b0c 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -917,8 +917,6 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int y, int x); int sixel_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell); int sprite_destroy(const struct notcurses* nc, const struct ncpile* p, FILE* out, sprixel* s); void sprixel_free(sprixel* s); -void sprixel_invalidate(sprixel* s, int y, int x); -void sprixel_movefrom(sprixel* s, int y, int x); void sprixel_hide(sprixel* s); int sprite_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out); int kitty_draw(const notcurses* n, const ncpile *p, sprixel* s, FILE* out); @@ -937,6 +935,22 @@ int sprite_init(const notcurses* nc); int kitty_shutdown(int fd); int sixel_shutdown(int fd); sprixel* sprixel_by_id(const notcurses* nc, uint32_t id); +// these three all use absolute coordinates +void sprixel_invalidate(sprixel* s, int y, int x); +void sprixel_movefrom(sprixel* s, int y, int x); + +// is the sprixel backend kitty? +static inline bool sprixel_kitty_p(const tinfo* t){ + return t->pixel_shutdown == kitty_shutdown; +} + +// get the TAM entry for these (absolute) coordinates +static inline sprixcell_e sprixel_state(sprixel* s, int y, int x){ + int localy = y - s->n->absy; + int localx = x - s->n->absx; + return s->n->tacache[localy * s->dimx + localx]; +} + static inline void pool_release(egcpool* pool, nccell* c){ diff --git a/src/lib/render.c b/src/lib/render.c index f6582da49..01b011043 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -865,7 +865,7 @@ clean_sprixels(notcurses* nc, const ncpile* p, FILE* out){ ncplane_yx(s->n, &y, &x); y += s->y; x += s->x; -//fprintf(stderr, "DRAWING BITMAP %d AT %d/%d for %p\n", s->id, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n); +//fprintf(stderr, "DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n); if(goto_location(nc, out, y + nc->stdplane->absy, x + nc->stdplane->absx) == 0){ if(sprite_draw(nc, p, s, out)){ return -1; @@ -891,7 +891,7 @@ rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){ ncplane_yx(s->n, &y, &x); y += s->y; x += s->x; -//fprintf(stderr, "DRAWING BITMAP %d AT %d/%d for %p\n", s->id, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n); +//fprintf(stderr, "DRAWING BITMAP %d STATE %d AT %d/%d for %p\n", s->id, s->invalidated, y + nc->stdplane->absy, x + nc->stdplane->absx, s->n); if(goto_location(nc, out, y + nc->stdplane->absy, x + nc->stdplane->absx) == 0){ if(sprite_draw(nc, p, s, out)){ return -1; @@ -1009,7 +1009,15 @@ rasterize_core(notcurses* nc, const ncpile* p, FILE* out, unsigned phase){ nc->rstate.bgpalelidable = false; } //fprintf(stderr, "RAST %08x [%s] to %d/%d cols: %u %016lx\n", srccell->gcluster, pool_extended_gcluster(&nc->pool, srccell), y, x, srccell->width, srccell->channels); - if(rvec[damageidx].sprixel){ + // this is used to invalidate the sprixel in the first text round, + // which is only necessary for sixel, not kitty. + if(rvec[damageidx].sprixel + && sprixel_state(rvec[damageidx].sprixel, y, x) != SPRIXCELL_TRANSPARENT + && sprixel_state(rvec[damageidx].sprixel, y, x) != SPRIXCELL_ANNIHILATED + && !rvec[damageidx].s.p_beats_sprixel + && !sprixel_kitty_p(&nc->tcache)){ +//fprintf(stderr, "INVALIDATING at %d/%d (%u)\n", y, x, rvec[damageidx].s.p_beats_sprixel); + sprixel_invalidate(rvec[damageidx].sprixel, y, x); } if(term_putc(out, &nc->pool, srccell)){ diff --git a/src/lib/sprite.c b/src/lib/sprite.c index e929dbf69..4558cb55b 100644 --- a/src/lib/sprite.c +++ b/src/lib/sprite.c @@ -60,7 +60,7 @@ void sprixel_hide(sprixel* s){ } } -// y and x are absolute coordinates +// y and x are absolute coordinates. void sprixel_invalidate(sprixel* s, int y, int x){ //fprintf(stderr, "INVALIDATING AT %d/%d\n", y, x); if(s->invalidated != SPRIXEL_HIDE && s->n){ diff --git a/src/tests/pixel.cpp b/src/tests/bitmap.cpp similarity index 96% rename from src/tests/pixel.cpp rename to src/tests/bitmap.cpp index cce3ef076..05d1d8edb 100644 --- a/src/tests/pixel.cpp +++ b/src/tests/bitmap.cpp @@ -1,7 +1,7 @@ #include "main.h" #include -TEST_CASE("Pixel") { +TEST_CASE("Bitmaps") { auto nc_ = testing_notcurses(); REQUIRE(nullptr != nc_); ncplane* ncp_ = notcurses_stdplane(nc_); @@ -169,7 +169,7 @@ TEST_CASE("Pixel") { struct ncvisual_options vopts = { .n = nullptr, .scaling = NCSCALE_NONE, - .y = 0, .x = 0, + .y = 2, .x = 2, .begy = 0, .begx = 0, .leny = y, .lenx = x, .blitter = NCBLIT_PIXEL, @@ -193,6 +193,11 @@ TEST_CASE("Pixel") { CHECK((i % 2) == tam[(i / dimx) + (i % dimx)]); ncpixel_set_a(&v[py * x + px], 0); } + for(int yy = vopts.y ; yy < vopts.y + dimy ; ++yy){ + for(int xx = vopts.x ; xx < vopts.x + dimx ; ++xx){ + CHECK(((yy * dimx + xx) % 2) == sprixel_state(s, yy, xx)); + } + } ncplane_destroy(n); }