[ncvgeom] add begy/begx and leny/lenx to ncvgeom

This commit is contained in:
nick black 2021-10-31 09:54:42 -04:00 committed by nick black
parent 4fb4b7ebbb
commit 17b06b1180
8 changed files with 90 additions and 65 deletions

View File

@ -3322,6 +3322,8 @@ typedef struct ncvgeom {
int rcelly, rcellx; // rendered cell geometry (per visual_options) int rcelly, rcellx; // rendered cell geometry (per visual_options)
int scaley, scalex; // pixels per filled cell (scale == c for bitmaps) int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
int begy, begx; // upper-left corner of used section
int leny, lenx; // geometry of used section
ncblitter_e blitter;// blitter that will be used ncblitter_e blitter;// blitter that will be used
} ncvgeom; } ncvgeom;

View File

@ -59,6 +59,8 @@ typedef struct ncvgeom {
int rcelly, rcellx; // rendered cell geometry (per visual_options) int rcelly, rcellx; // rendered cell geometry (per visual_options)
int scaley, scalex; // pixels per filled cell (scale == c for bitmaps) int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
int begy, begx; // upper-left corner of used section
int leny, lenx; // geometry of used section
ncblitter_e blitter;// blitter that will be used ncblitter_e blitter;// blitter that will be used
} ncvgeom; } ncvgeom;
``` ```

View File

@ -2904,6 +2904,8 @@ typedef struct ncvgeom {
int rcelly, rcellx; // rendered cell geometry (per visual_options) int rcelly, rcellx; // rendered cell geometry (per visual_options)
int scaley, scalex; // pixels per filled cell (scale == c for bitmaps) int scaley, scalex; // pixels per filled cell (scale == c for bitmaps)
int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL int maxpixely, maxpixelx; // only defined for NCBLIT_PIXEL
int begy, begx; // upper-left corner of used section
int leny, lenx; // geometry of used section
ncblitter_e blitter;// blitter that will be used ncblitter_e blitter;// blitter that will be used
} ncvgeom; } ncvgeom;

View File

@ -222,6 +222,7 @@ int luigi_demo(struct notcurses* nc){
ncvgeom geom; ncvgeom geom;
ncvisual_geom(nc, wmncv, NULL, &geom); ncvisual_geom(nc, wmncv, NULL, &geom);
geom.pixy /= geom.scaley; geom.pixy /= geom.scaley;
// FIXME what the fuck is this
ncplane_move_yx(wmplane, rows * 4 / 5 - geom.pixy + 1 + (i % 2), i - 60); ncplane_move_yx(wmplane, rows * 4 / 5 - geom.pixy + 1 + (i % 2), i - 60);
DEMO_RENDER(nc); DEMO_RENDER(nc);
demo_nanosleep(nc, &stepdelay); demo_nanosleep(nc, &stepdelay);

View File

@ -1,7 +1,9 @@
#ifndef NOTCURSES_BLITSET #ifndef NOTCURSES_BLITSET
#define NOTCURSES_BLITSET #define NOTCURSES_BLITSET
#include "notcurses/notcurses.h" #ifdef __cplusplus
extern "C" {
#endif
// number of pixels that map to a single cell, height-wise // number of pixels that map to a single cell, height-wise
static inline int static inline int
@ -50,4 +52,8 @@ ncplot_defblitter(const notcurses* nc){
void set_pixel_blitter(ncblitter blitfxn); void set_pixel_blitter(ncblitter blitfxn);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -1590,24 +1590,8 @@ ncdirectv* ncdirectf_render(ncdirect* n, ncdirectf* frame, const struct ncvisual
int ncdirectf_geom(ncdirect* n, ncdirectf* frame, int ncdirectf_geom(ncdirect* n, ncdirectf* frame,
const struct ncvisual_options* vopts, ncvgeom* geom){ const struct ncvisual_options* vopts, ncvgeom* geom){
geom->cdimy = n->tcache.cellpixy;
geom->cdimx = n->tcache.cellpixx;
geom->maxpixely = n->tcache.sixel_maxy;
geom->maxpixelx = n->tcache.sixel_maxx;
const struct blitset* bset; const struct blitset* bset;
int r = ncvisual_blitset_geom(NULL, &n->tcache, frame, vopts, return ncvisual_geom_inner(&n->tcache, frame, vopts, geom, &bset);
&geom->pixy, &geom->pixx,
&geom->scaley, &geom->scalex,
&geom->rpixy, &geom->rpixx, &bset);
if(r == 0){
// FIXME ncvisual_blitset_geom() ought calculate these two for us; until
// then, derive them ourselves. the row count might be short by one if
// we're using sixel, and we're not a multiple of 6
geom->rcelly = geom->pixy / geom->scaley;
geom->rcellx = geom->pixx / geom->scalex;
geom->blitter = bset->geom;
}
return r;
} }
unsigned ncdirect_supported_styles(const ncdirect* nc){ unsigned ncdirect_supported_styles(const ncdirect* nc){

View File

@ -388,12 +388,6 @@ struct blitset {
#include "blitset.h" #include "blitset.h"
int ncvisual_blitset_geom(const notcurses* nc, const tinfo* tcache,
const struct ncvisual* n,
const struct ncvisual_options* vopts,
int* y, int* x, int* scaley, int* scalex,
int* leny, int* lenx, const struct blitset** blitter);
void reset_stats(ncstats* stats); void reset_stats(ncstats* stats);
void summarize_stats(notcurses* nc); void summarize_stats(notcurses* nc);
@ -1561,6 +1555,10 @@ rgba_blit_dispatch(ncplane* nc, const struct blitset* bset,
return bset->blit(nc, linesize, data, leny, lenx, bargs); return bset->blit(nc, linesize, data, leny, lenx, bargs);
} }
int ncvisual_geom_inner(const tinfo* ti, const struct ncvisual* n,
const struct ncvisual_options* vopts, ncvgeom* geom,
const struct blitset** bset);
static inline const struct blitset* static inline const struct blitset*
rgba_blitter_low(const tinfo* tcache, ncscale_e scale, bool maydegrade, rgba_blitter_low(const tinfo* tcache, ncscale_e scale, bool maydegrade,
ncblitter_e blitrec) { ncblitter_e blitrec) {

View File

@ -128,14 +128,13 @@ ncvisual_origin(const struct ncvisual_options* vopts, int* restrict begy, int* r
// 'leny' and 'lenx' get the number of pixels to actually be rendered, 'y' and // 'leny' and 'lenx' get the number of pixels to actually be rendered, 'y' and
// 'x' get the original size of the visual in pixels, and 'scaley' and 'scalex' // 'x' get the original size of the visual in pixels, and 'scaley' and 'scalex'
// get the number of pixels per cell with the selected 'blitter'. // get the number of pixels per cell with the selected 'blitter'. this is the
// FIXME we ought also do the output calculations here (how many rows x cols, // first part of real geometry calculation.
// given the input plane vopts->n and scaling vopts->scaling)--but do not static int
// perform any actual scaling, nor create any planes! ncvisual_blitset_geom(const notcurses* nc, const tinfo* tcache,
int ncvisual_blitset_geom(const notcurses* nc, const tinfo* tcache, const ncvisual* n, const struct ncvisual_options* vopts,
const ncvisual* n, const struct ncvisual_options* vopts, int* y, int* x, int* scaley, int* scalex,
int* y, int* x, int* scaley, int* scalex, int* leny, int* lenx, const struct blitset** blitter){
int* leny, int* lenx, const struct blitset** blitter){
int fakeleny, fakelenx; int fakeleny, fakelenx;
if(leny == NULL){ if(leny == NULL){
leny = &fakeleny; leny = &fakeleny;
@ -288,7 +287,8 @@ int ncvisual_blitter_geom(const notcurses* nc, const ncvisual* n,
} }
int ncvisual_geom_inner(const tinfo* ti, const ncvisual* n, int ncvisual_geom_inner(const tinfo* ti, const ncvisual* n,
const struct ncvisual_options* vopts, ncvgeom* geom){ const struct ncvisual_options* vopts, ncvgeom* geom,
const struct blitset** bset){
if(ti == NULL && n == NULL){ if(ti == NULL && n == NULL){
logerror("got NULL for both sources\n"); logerror("got NULL for both sources\n");
return -1; return -1;
@ -301,34 +301,65 @@ int ncvisual_geom_inner(const tinfo* ti, const ncvisual* n,
return 0; return 0;
} }
// determine our blitter // determine our blitter
const struct blitset* bset = rgba_blitter(ti, vopts); *bset = rgba_blitter(ti, vopts);
if(!bset){ if(!*bset){
logerror("Couldn't get a blitter for %d\n", vopts ? vopts->blitter : NCBLIT_DEFAULT); logerror("Couldn't get a blitter for %d\n", vopts ? vopts->blitter : NCBLIT_DEFAULT);
return -1; return -1;
} }
geom->cdimy = ti->cellpixy; geom->cdimy = ti->cellpixy;
geom->cdimx = ti->cellpixx; geom->cdimx = ti->cellpixx;
if((geom->blitter = bset->geom) == NCBLIT_PIXEL){ if((geom->blitter = (*bset)->geom) == NCBLIT_PIXEL){
geom->maxpixely = ti->sixel_maxy_pristine; geom->maxpixely = ti->sixel_maxy_pristine;
geom->maxpixelx = ti->sixel_maxx; geom->maxpixelx = ti->sixel_maxx;
geom->scaley = ti->cellpixy; geom->scaley = ti->cellpixy;
geom->scalex = ti->cellpixx; geom->scalex = ti->cellpixx;
}else{ }else{
geom->scaley = bset->height; geom->scaley = (*bset)->height;
geom->scalex = bset->width; geom->scalex = (*bset)->width;
} }
// when n is NULL, we only report properties unrelated to the ncvisual, // when n is NULL, we only report properties unrelated to the ncvisual,
// i.e. the cell-pixel geometry, max bitmap geometry, blitter, and scaling. // i.e. the cell-pixel geometry, max bitmap geometry, blitter, and scaling.
if(n == NULL){ if(n == NULL){
return 0; return 0;
} }
// FIXME now work with full variant // determine how much of the original image we're using (leny/lenx)
ncvisual_origin(vopts, &geom->begy, &geom->begx);
geom->lenx = vopts ? vopts->lenx : 0;
geom->leny = vopts ? vopts->leny : 0;
logdebug("blit %dx%d+%dx%d %p\n", geom->begy, geom->begx, geom->leny, geom->lenx, n->data);
if(geom->begy < 0 || geom->begx < 0){
logerror("invalid geometry for visual %d %d %d %d\n", geom->begy, geom->begx, geom->leny, geom->lenx);
return -1;
}
if(n->data == NULL){
logerror("no data in visual\n");
return -1;
}
if(geom->begx >= n->pixx || geom->begy >= n->pixy){
logerror("visual too large %d > %d or %d > %d\n", geom->begy, n->pixy, geom->begx, n->pixx);
return -1;
}
if(geom->lenx == 0){ // 0 means "to the end"; use all available source material
geom->lenx = n->pixx - geom->begx;
}
if(geom->leny == 0){
geom->leny = n->pixy - geom->begy;
}
if(geom->lenx <= 0 || geom->leny <= 0){ // no need to draw zero-size object, exit
logerror("zero-size object %d %d\n", geom->leny, geom->lenx);
return -1;
}
if(geom->begx + geom->lenx > n->pixx || geom->begy + geom->leny > n->pixy){
logerror("geometry too large %d > %d or %d > %d\n", geom->begy + geom->leny, n->pixy, geom->begx + geom->lenx, n->pixx);
return -1;
}
return 0; return 0;
} }
int ncvisual_geom(const notcurses* nc, const ncvisual* n, int ncvisual_geom(const notcurses* nc, const ncvisual* n,
const struct ncvisual_options* vopts, ncvgeom* geom){ const struct ncvisual_options* vopts, ncvgeom* geom){
return ncvisual_geom_inner(nc ? &nc->tcache : NULL, n, vopts, geom); const struct blitset* bset;
return ncvisual_geom_inner(nc ? &nc->tcache : NULL, n, vopts, geom, &bset);
} }
void* rgb_loose_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha){ void* rgb_loose_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha){
@ -845,7 +876,8 @@ int ncvisual_resize_noninterpolative(ncvisual* n, int rows, int cols){
// the origin of the source region to draw (in pixels). leny/lenx define the // the origin of the source region to draw (in pixels). leny/lenx define the
// geometry of the source region to draw, again in pixels. ncv->pixy and // geometry of the source region to draw, again in pixels. ncv->pixy and
// ncv->pixx define the source geometry in pixels. // ncv->pixx define the source geometry in pixels.
ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitset* bset, ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, int scaley, int scalex,
const struct blitset* bset,
int placey, int placex, int begy, int begx, int placey, int placex, int begy, int begx,
int leny, int lenx, ncplane* n, ncscale_e scaling, int leny, int lenx, ncplane* n, ncscale_e scaling,
uint64_t flags, uint32_t transcolor){ uint64_t flags, uint32_t transcolor){
@ -862,8 +894,8 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse
}else{ }else{
ncplane_dim_yx(n, &disprows, &dispcols); ncplane_dim_yx(n, &disprows, &dispcols);
} }
dispcols *= encoding_x_scale(&nc->tcache, bset); dispcols *= scalex;
disprows *= encoding_y_scale(&nc->tcache, bset); disprows *= scaley;
if(scaling == NCSCALE_SCALE || scaling == NCSCALE_SCALE_HIRES){ if(scaling == NCSCALE_SCALE || scaling == NCSCALE_SCALE_HIRES){
scale_visual(ncv, &disprows, &dispcols); scale_visual(ncv, &disprows, &dispcols);
} // else stretch } // else stretch
@ -872,10 +904,8 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse
struct ncplane_options nopts = { struct ncplane_options nopts = {
.y = placey, .y = placey,
.x = placex, .x = placex,
.rows = disprows / encoding_y_scale(&nc->tcache, bset) + .rows = disprows / scaley + !!(disprows % scaley),
!!(disprows % encoding_y_scale(&nc->tcache, bset)), .cols = dispcols / scalex + !!(dispcols % scalex),
.cols = dispcols / encoding_x_scale(&nc->tcache, bset) +
!!(dispcols % encoding_x_scale(&nc->tcache, bset)),
.userptr = NULL, .userptr = NULL,
.name = "cvis", .name = "cvis",
.resizecb = NULL, .resizecb = NULL,
@ -904,8 +934,8 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse
disprows = leny; disprows = leny;
}else{ }else{
ncplane_dim_yx(n, &disprows, &dispcols); ncplane_dim_yx(n, &disprows, &dispcols);
dispcols *= encoding_x_scale(&nc->tcache, bset); dispcols *= scalex;
disprows *= encoding_y_scale(&nc->tcache, bset); disprows *= scaley;
if(!(flags & NCVISUAL_OPTION_HORALIGNED)){ if(!(flags & NCVISUAL_OPTION_HORALIGNED)){
dispcols -= placex; dispcols -= placex;
} }
@ -917,10 +947,10 @@ ncplane* ncvisual_render_cells(notcurses* nc, ncvisual* ncv, const struct blitse
} // else stretch } // else stretch
} }
if(flags & NCVISUAL_OPTION_HORALIGNED){ if(flags & NCVISUAL_OPTION_HORALIGNED){
placex = ncplane_halign(n, placex, dispcols / encoding_x_scale(&nc->tcache, bset)); placex = ncplane_halign(n, placex, dispcols / scalex);
} }
if(flags & NCVISUAL_OPTION_VERALIGNED){ if(flags & NCVISUAL_OPTION_VERALIGNED){
placey = ncplane_valign(n, placey, disprows / encoding_y_scale(&nc->tcache, bset)); placey = ncplane_valign(n, placey, disprows / scaley);
} }
} }
//fprintf(stderr, "blit: %dx%d:%d+%d of %d/%d stride %u %p\n", begy, begx, leny, lenx, ncv->pixy, ncv->pixx, ncv->rowstride, ncv->data); //fprintf(stderr, "blit: %dx%d:%d+%d of %d/%d stride %u %p\n", begy, begx, leny, lenx, ncv->pixy, ncv->pixx, ncv->rowstride, ncv->data);
@ -1187,32 +1217,32 @@ ncplane* ncvisual_render_pixels(notcurses* nc, ncvisual* ncv, const struct blits
} }
ncplane* ncvisual_blit(notcurses* nc, ncvisual* ncv, const struct ncvisual_options* vopts){ ncplane* ncvisual_blit(notcurses* nc, ncvisual* ncv, const struct ncvisual_options* vopts){
//fprintf(stderr, "beg/len: %d %d %d %d place: %d/%d scale: %d/%d\n", begy, leny, begx, lenx, placey, placex, encoding_y_scale(&nc->tcache, bset), encoding_x_scale(&nc->tcache, bset));
//fprintf(stderr, "%p tacache: %p\n", n, n->tacache);
ncvgeom geom;
const struct blitset* bset; const struct blitset* bset;
int leny, lenx; if(ncvisual_geom_inner(&nc->tcache, ncv, vopts, &geom, &bset)){
if(ncvisual_blitset_geom(nc, &nc->tcache, ncv, vopts, NULL, NULL, NULL, NULL,
&leny, &lenx, &bset) < 0){
// ncvisual_blitset_geom() emits its own diagnostics, no need for an error here // ncvisual_blitset_geom() emits its own diagnostics, no need for an error here
return NULL; return NULL;
} }
int begy, begx;
ncvisual_origin(vopts, &begy, &begx);
int placey = vopts ? vopts->y : 0;
int placex = vopts ? vopts->x : 0;
//fprintf(stderr, "beg/len: %d %d %d %d place: %d/%d scale: %d/%d\n", begy, leny, begx, lenx, placey, placex, encoding_y_scale(&nc->tcache, bset), encoding_x_scale(&nc->tcache, bset));
ncplane* n = (vopts ? vopts->n : NULL); ncplane* n = (vopts ? vopts->n : NULL);
//fprintf(stderr, "%p tacache: %p\n", n, n->tacache);
ncscale_e scaling = vopts ? vopts->scaling : NCSCALE_NONE; ncscale_e scaling = vopts ? vopts->scaling : NCSCALE_NONE;
uint32_t transcolor = 0; uint32_t transcolor = 0;
if(vopts && vopts->flags & NCVISUAL_OPTION_ADDALPHA){ if(vopts && vopts->flags & NCVISUAL_OPTION_ADDALPHA){
transcolor = 0x1000000ull | vopts->transcolor; transcolor = 0x1000000ull | vopts->transcolor;
} }
if(bset->geom != NCBLIT_PIXEL){ int placey = vopts ? vopts->y : 0;
n = ncvisual_render_cells(nc, ncv, bset, placey, placex, begy, begx, int placex = vopts ? vopts->x : 0;
leny, lenx, n, scaling, if(geom.blitter != NCBLIT_PIXEL){
n = ncvisual_render_cells(nc, ncv, geom.scaley, geom.scalex,
bset, placey, placex,
geom.begy, geom.begx,
geom.leny, geom.lenx, n, scaling,
vopts ? vopts->flags : 0, transcolor); vopts ? vopts->flags : 0, transcolor);
}else{ }else{
n = ncvisual_render_pixels(nc, ncv, bset, placey, placex, begy, begx, n = ncvisual_render_pixels(nc, ncv, bset, placey, placex,
leny, lenx, n, scaling, geom.begy, geom.begx,
geom.leny, geom.lenx, n, scaling,
vopts ? vopts->flags : 0, transcolor, vopts ? vopts->flags : 0, transcolor,
vopts ? vopts->pxoffy : 0, vopts ? vopts->pxoffy : 0,
vopts ? vopts->pxoffx : 0); vopts ? vopts->pxoffx : 0);