mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
new unit test PixelCellWipePolychromatic
This commit is contained in:
parent
51409439f6
commit
3a3baae753
@ -931,10 +931,6 @@ int sprite_kitty_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel*
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sprite_sixel_cell_wipe(notcurses* nc, sprixel* s, int y, int x){
|
||||
return 0; // FIXME
|
||||
}
|
||||
|
||||
int sprite_sixel_annihilate(notcurses* nc, const ncpile* p, FILE* out, sprixel* s){
|
||||
(void)out;
|
||||
struct crender* rvec = p->crender;
|
||||
|
@ -1,5 +1,52 @@
|
||||
#include "internal.h"
|
||||
|
||||
// sixel is in a sense simpler to edit in-place than kitty, as it has neither
|
||||
// chunking nor base64 to worry about. in another sense, it's waaay suckier,
|
||||
// because you effectively have to lex through a byte at a time (since the
|
||||
// color bands have varying size). le sigh! we work geometrically here,
|
||||
// blasting through each band and scrubbing the necessary cells therein.
|
||||
// define a rectangle that will be scrubbed.
|
||||
int sprite_sixel_cell_wipe(notcurses* nc, sprixel* s, int ycell, int xcell){
|
||||
if(ycell >= s->dimy){
|
||||
return -1;
|
||||
}
|
||||
if(xcell >= s->dimx){
|
||||
return -1;
|
||||
}
|
||||
const int xpixels = nc->tcache.cellpixx;
|
||||
const int ypixels = nc->tcache.cellpixy;
|
||||
const int top = ypixels * ycell; // start scrubbing on this row
|
||||
int bottom = ypixels * (ycell + 1); // do *not* scrub this row
|
||||
const int left = xpixels * xcell; // start scrubbing on this column
|
||||
int right = xpixels * (xcell + 1); // do *not* scrub this column
|
||||
// if the cell is on the right or bottom borders, it might only be partially
|
||||
// filled by actual graphic data, and we need to cap our target area.
|
||||
if(right > s->pixx){
|
||||
right = s->pixx;
|
||||
}
|
||||
if(bottom > s->pixy){
|
||||
bottom = s->pixy;
|
||||
}
|
||||
fprintf(stderr, "TARGET AREA: [ %dx%d -> %dx%d ] of %dx%d\n", top, left, bottom - 1, right - 1, s->pixy, s->pixx);
|
||||
char* c = s->glyph;
|
||||
// lines of sixels are broken by a hyphen. if we were guaranteed to already
|
||||
// be in the meat of the sixel, it would be sufficient to count hyphens, but
|
||||
// we must distinguish the introductory material from the sixmap, alas
|
||||
// (after that, simply count hyphens). FIXME store loc in sprixel metadata?
|
||||
// it seems sufficient to look for the first #d not followed by a semicolon.
|
||||
// remember, these are sixels *we've* created internally, not random ones.
|
||||
do{
|
||||
while(*c != '#'){
|
||||
++c;
|
||||
}
|
||||
while(isdigit(*c)){
|
||||
++c;
|
||||
}
|
||||
}while(*c == ';');
|
||||
fprintf(stderr, "FOUND SIXMAP AT %zd\n", c - s->glyph);
|
||||
return 0; // FIXME
|
||||
}
|
||||
|
||||
#define RGBSIZE 3
|
||||
#define CENTSIZE (RGBSIZE + 1) // size of a color table entry
|
||||
|
||||
|
@ -269,27 +269,21 @@ int ffmpeg_resize(ncvisual* nc, int rows, int cols) {
|
||||
}
|
||||
|
||||
auto ffmpeg_details_init(void) -> ncvisual_details* {
|
||||
auto deets = static_cast<ncvisual_details*>(malloc(sizeof(ncvisual_details)));
|
||||
if(deets){
|
||||
memset(deets, 0, sizeof(*deets));
|
||||
deets->stream_index = -1;
|
||||
deets->sub_stream_index = -1;
|
||||
if((deets->frame = av_frame_alloc()) == nullptr){
|
||||
free(deets);
|
||||
return nullptr;
|
||||
}
|
||||
auto deets = new ncvisual_details{};
|
||||
deets->stream_index = -1;
|
||||
deets->sub_stream_index = -1;
|
||||
if((deets->frame = av_frame_alloc()) == nullptr){
|
||||
delete deets;
|
||||
return nullptr;
|
||||
}
|
||||
return deets;
|
||||
}
|
||||
|
||||
auto ffmpeg_create() -> ncvisual* {
|
||||
auto nc = static_cast<ncvisual*>(malloc(sizeof(ncvisual)));
|
||||
if(nc){
|
||||
memset(nc, 0, sizeof(*nc));
|
||||
if((nc->details = ffmpeg_details_init()) == nullptr){
|
||||
free(nc);
|
||||
return nullptr;
|
||||
}
|
||||
auto nc = new ncvisual{};
|
||||
if((nc->details = ffmpeg_details_init()) == nullptr){
|
||||
delete nc;
|
||||
return nullptr;
|
||||
}
|
||||
return nc;
|
||||
}
|
||||
@ -595,14 +589,14 @@ auto ffmpeg_details_destroy(ncvisual_details* deets) -> void {
|
||||
av_packet_free(&deets->packet);
|
||||
avformat_close_input(&deets->fmtctx);
|
||||
avsubtitle_free(&deets->subtitle);
|
||||
free(deets);
|
||||
delete deets;
|
||||
}
|
||||
|
||||
auto ffmpeg_destroy(ncvisual* ncv) -> void {
|
||||
if(ncv){
|
||||
ffmpeg_details_destroy(ncv->details);
|
||||
if(ncv->owndata){
|
||||
delete ncv->data;
|
||||
free(ncv->data);
|
||||
}
|
||||
delete ncv;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ auto oiio_destroy(ncvisual* ncv) -> void {
|
||||
if(ncv){
|
||||
oiio_details_destroy(ncv->details);
|
||||
if(ncv->owndata){
|
||||
delete ncv->data;
|
||||
free(ncv->data);
|
||||
}
|
||||
delete ncv;
|
||||
}
|
||||
|
@ -71,5 +71,41 @@ TEST_CASE("Pixel") {
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
}
|
||||
|
||||
SUBCASE("PixelCellWipePolychromatic") {
|
||||
// first, assemble a visual equivalent to 4 cells
|
||||
auto y = 2 * nc_->tcache.cellpixy;
|
||||
auto x = 2 * nc_->tcache.cellpixx;
|
||||
std::vector<uint32_t> v(x * y, 0xffffffff);
|
||||
for(auto& e : v){
|
||||
e -= random() % 0x1000000;
|
||||
}
|
||||
auto ncv = ncvisual_from_rgba(v.data(), y, sizeof(decltype(v)::value_type) * x, x);
|
||||
REQUIRE(nullptr != ncv);
|
||||
struct ncvisual_options vopts = {
|
||||
.n = nullptr,
|
||||
.scaling = NCSCALE_NONE,
|
||||
.y = 0, .x = 0,
|
||||
.begy = 0, .begx = 0,
|
||||
.leny = y, .lenx = x,
|
||||
.blitter = NCBLIT_PIXEL,
|
||||
.flags = NCVISUAL_OPTION_NODEGRADE,
|
||||
};
|
||||
auto n = ncvisual_render(nc_, ncv, &vopts);
|
||||
REQUIRE(nullptr != n);
|
||||
auto s = n->sprite;
|
||||
REQUIRE(nullptr != s);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == nc_->tcache.pixel_cell_wipe(nc_, s, 0, 0));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == nc_->tcache.pixel_cell_wipe(nc_, s, 1, 1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == nc_->tcache.pixel_cell_wipe(nc_, s, 1, 0));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == nc_->tcache.pixel_cell_wipe(nc_, s, 0, 1));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
ncplane_destroy(n);
|
||||
ncvisual_destroy(ncv);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
}
|
||||
CHECK(!notcurses_stop(nc_));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user