mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
reject sprixels larger than plane, add unit test #1572
This commit is contained in:
parent
cc73811dd4
commit
5a72383cb0
@ -352,6 +352,8 @@ last row is cleared, and output begins at the beginning of the last row. This
|
|||||||
does not take place until output is generated (i.e. it is possible to fill a
|
does not take place until output is generated (i.e. it is possible to fill a
|
||||||
plane when scrolling is enabled).
|
plane when scrolling is enabled).
|
||||||
|
|
||||||
|
## Bitmaps
|
||||||
|
|
||||||
**ncplane_pixelgeom** retrieves pixel geometry details. **pxy** and **pxx**
|
**ncplane_pixelgeom** retrieves pixel geometry details. **pxy** and **pxx**
|
||||||
return the size of the plane in pixels. **celldimy** and **celldimx** return
|
return the size of the plane in pixels. **celldimy** and **celldimx** return
|
||||||
the size of a cell in pixels (these ought be the same across planes).
|
the size of a cell in pixels (these ought be the same across planes).
|
||||||
@ -364,9 +366,9 @@ parameter (save **n**) may be **NULL**.
|
|||||||
When a plane is blitted to using **ncvisual_render** and **NCBLIT_PIXEL** (see
|
When a plane is blitted to using **ncvisual_render** and **NCBLIT_PIXEL** (see
|
||||||
**notcurses_visual(3)**), it ceases to accept cell-based output. The sprixel
|
**notcurses_visual(3)**), it ceases to accept cell-based output. The sprixel
|
||||||
will remain associated until a new sprixel is blitted to the plane, the plane
|
will remain associated until a new sprixel is blitted to the plane, the plane
|
||||||
is resized, or the plane is destroyed. The base cell of a sprixelated plane
|
is resized, the plane is erased, or the plane is destroyed. The base cell of a
|
||||||
has no effect; if the sprixel is not even multiples of the cell geometry, the
|
sprixelated plane has no effect; if the sprixel is not even multiples of the
|
||||||
"excess plane" is ignored during rendering.
|
cell geometry, the "excess plane" is ignored during rendering.
|
||||||
|
|
||||||
# RETURN VALUES
|
# RETURN VALUES
|
||||||
|
|
||||||
|
@ -583,10 +583,6 @@ int resize_callbacks_children(ncplane* n){
|
|||||||
// can be used on stdplane, unlike ncplane_resize() which prohibits it.
|
// can be used on stdplane, unlike ncplane_resize() which prohibits it.
|
||||||
int ncplane_resize_internal(ncplane* n, int keepy, int keepx, int keepleny,
|
int ncplane_resize_internal(ncplane* n, int keepy, int keepx, int keepleny,
|
||||||
int keeplenx, int yoff, int xoff, int ylen, int xlen){
|
int keeplenx, int yoff, int xoff, int ylen, int xlen){
|
||||||
if(n->sprite){
|
|
||||||
logerror(ncplane_notcurses_const(n), "Can't resize sprixelated (id %d) plane\n", n->sprite->id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(keepleny < 0 || keeplenx < 0){ // can't retain negative size
|
if(keepleny < 0 || keeplenx < 0){ // can't retain negative size
|
||||||
logerror(ncplane_notcurses_const(n), "Can't retain negative size %dx%d\n", keepleny, keeplenx);
|
logerror(ncplane_notcurses_const(n), "Can't retain negative size %dx%d\n", keepleny, keeplenx);
|
||||||
return -1;
|
return -1;
|
||||||
@ -626,6 +622,9 @@ int ncplane_resize_internal(ncplane* n, int keepy, int keepx, int keepleny,
|
|||||||
}
|
}
|
||||||
loginfo(ncplane_notcurses_const(n), "%dx%d @ %d/%d → %d/%d @ %d/%d (keeping %dx%d from %d/%d)\n", rows, cols, n->absy, n->absx, ylen, xlen, n->absy + keepy + yoff, n->absx + keepx + xoff, keepleny, keeplenx, keepy, keepx);
|
loginfo(ncplane_notcurses_const(n), "%dx%d @ %d/%d → %d/%d @ %d/%d (keeping %dx%d from %d/%d)\n", rows, cols, n->absy, n->absx, ylen, xlen, n->absy + keepy + yoff, n->absx + keepx + xoff, keepleny, keeplenx, keepy, keepx);
|
||||||
notcurses* nc = ncplane_notcurses(n);
|
notcurses* nc = ncplane_notcurses(n);
|
||||||
|
if(n->sprite){
|
||||||
|
sprixel_hide(n->sprite);
|
||||||
|
}
|
||||||
// we're good to resize. we'll need alloc up a new framebuffer, and copy in
|
// we're good to resize. we'll need alloc up a new framebuffer, and copy in
|
||||||
// those elements we're retaining, zeroing out the rest. alternatively, if
|
// those elements we're retaining, zeroing out the rest. alternatively, if
|
||||||
// we've shrunk, we will be filling the new structure.
|
// we've shrunk, we will be filling the new structure.
|
||||||
|
@ -158,6 +158,16 @@ ncvisual_blitset_geom(const notcurses* nc, const ncvisual* n,
|
|||||||
logerror(nc, "Non-origin x placement %d for sprixel\n", vopts->x);
|
logerror(nc, "Non-origin x placement %d for sprixel\n", vopts->x);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int rows = (*leny + nc->tcache.cellpixy - 1) / nc->tcache.cellpixy;
|
||||||
|
if(rows > ncplane_dim_y(vopts->n)){
|
||||||
|
logerror(nc, "Sprixel too tall %d for plane %d\n", *leny, ncplane_dim_y(vopts->n) * nc->tcache.cellpixy);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int cols = (*lenx + nc->tcache.cellpixx - 1) / nc->tcache.cellpixx;
|
||||||
|
if(cols > ncplane_dim_x(vopts->n)){
|
||||||
|
logerror(nc, "Sprixel too wide %d for plane %d\n", *lenx, ncplane_dim_x(vopts->n) * nc->tcache.cellpixx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(n){
|
if(n){
|
||||||
|
@ -38,7 +38,7 @@ TEST_CASE("Bitmaps") {
|
|||||||
.flags = NCVISUAL_OPTION_NODEGRADE,
|
.flags = NCVISUAL_OPTION_NODEGRADE,
|
||||||
.transcolor = 0,
|
.transcolor = 0,
|
||||||
};
|
};
|
||||||
CHECK(0 == ncvisual_resize(ncv, 6, 1)); // FIXME get down to 1, 1
|
CHECK(0 == ncvisual_resize(ncv, 6, 1)); // FIXME get down to 1, 1 (sixel needs handle)
|
||||||
auto n = ncvisual_render(nc_, ncv, &vopts);
|
auto n = ncvisual_render(nc_, ncv, &vopts);
|
||||||
REQUIRE(nullptr != n);
|
REQUIRE(nullptr != n);
|
||||||
auto s = n->sprite;
|
auto s = n->sprite;
|
||||||
@ -46,6 +46,38 @@ TEST_CASE("Bitmaps") {
|
|||||||
ncvisual_destroy(ncv);
|
ncvisual_destroy(ncv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a sprixel requires a plane large enough to hold it
|
||||||
|
SUBCASE("SprixelTooBig") {
|
||||||
|
auto y = nc_->tcache.cellpixy + 1;
|
||||||
|
auto x = nc_->tcache.cellpixx + 1;
|
||||||
|
std::vector<uint32_t> v(x * y, htole(0xe61c28ff));
|
||||||
|
auto ncv = ncvisual_from_rgba(v.data(), y, sizeof(decltype(v)::value_type) * x, x);
|
||||||
|
REQUIRE(nullptr != ncv);
|
||||||
|
struct ncplane_options nopts = {
|
||||||
|
.y = 0, .x = 0,
|
||||||
|
.rows = 1, .cols = 1,
|
||||||
|
.userptr = nullptr, .name = "small", .resizecb = nullptr,
|
||||||
|
.flags = 0, .margin_b = 0, .margin_r = 0,
|
||||||
|
};
|
||||||
|
auto n = ncplane_create(n_, &nopts);
|
||||||
|
struct ncvisual_options vopts = {
|
||||||
|
.n = n,
|
||||||
|
.scaling = NCSCALE_NONE,
|
||||||
|
.y = 0,
|
||||||
|
.x = 0,
|
||||||
|
.begy = 0, .begx = 0,
|
||||||
|
.leny = 0, .lenx = 0,
|
||||||
|
.blitter = NCBLIT_PIXEL,
|
||||||
|
.flags = NCVISUAL_OPTION_NODEGRADE,
|
||||||
|
.transcolor = 0,
|
||||||
|
};
|
||||||
|
CHECK(nullptr == ncvisual_render(nc_, ncv, &vopts));
|
||||||
|
CHECK(0 == notcurses_render(nc_));
|
||||||
|
sleep(2);
|
||||||
|
ncvisual_destroy(ncv);
|
||||||
|
CHECK(0 == ncplane_destroy(n));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NOTCURSES_USE_MULTIMEDIA
|
#ifdef NOTCURSES_USE_MULTIMEDIA
|
||||||
SUBCASE("PixelRender") {
|
SUBCASE("PixelRender") {
|
||||||
auto ncv = ncvisual_from_file(find_data("worldmap.png"));
|
auto ncv = ncvisual_from_file(find_data("worldmap.png"));
|
||||||
@ -294,8 +326,6 @@ TEST_CASE("Bitmaps") {
|
|||||||
CHECK(0 == ncplane_destroy(n));
|
CHECK(0 == ncplane_destroy(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
// too much output -- OOMs ctest FIXME
|
|
||||||
/*
|
|
||||||
#ifdef NOTCURSES_USE_MULTIMEDIA
|
#ifdef NOTCURSES_USE_MULTIMEDIA
|
||||||
SUBCASE("PixelWipeImage") {
|
SUBCASE("PixelWipeImage") {
|
||||||
uint64_t channels = 0;
|
uint64_t channels = 0;
|
||||||
@ -315,7 +345,8 @@ TEST_CASE("Bitmaps") {
|
|||||||
for(int y = 0 ; y < s->dimy ; ++y){
|
for(int y = 0 ; y < s->dimy ; ++y){
|
||||||
for(int x = 0 ; x < s->dimx ; ++x){
|
for(int x = 0 ; x < s->dimx ; ++x){
|
||||||
CHECK(1 == ncplane_putchar_yx(n_, y, x, 'x'));
|
CHECK(1 == ncplane_putchar_yx(n_, y, x, 'x'));
|
||||||
CHECK(0 == notcurses_render(nc_));
|
// FIXME generates too much output, OOMing ctest
|
||||||
|
// CHECK(0 == notcurses_render(nc_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECK(0 == ncplane_destroy(newn));
|
CHECK(0 == ncplane_destroy(newn));
|
||||||
@ -323,7 +354,6 @@ TEST_CASE("Bitmaps") {
|
|||||||
ncvisual_destroy(ncv);
|
ncvisual_destroy(ncv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
|
|
||||||
CHECK(!notcurses_stop(nc_));
|
CHECK(!notcurses_stop(nc_));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user