Skip to content

Commit

Permalink
[render] non-transparent backgrounds override bitmaps #1388
Browse files Browse the repository at this point in the history
  • Loading branch information
dankamongmen committed Mar 22, 2021
1 parent d8c3da7 commit cd86715
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 140 deletions.
126 changes: 64 additions & 62 deletions src/lib/blit.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,30 @@ trilerp(uint32_t c0, uint32_t c1, uint32_t c2){

// Retarded RGBA blitter (ASCII only).
static inline int
tria_blit_ascii(ncplane* nc, int linesize, const void* data, int begy, int begx,
tria_blit_ascii(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs){
//fprintf(stderr, "ASCII %d X %d @ %d X %d (%p) place: %d X %d\n", leny, lenx, begy, begx, data, bargs->cell.placey, bargs->cell.placex);
//fprintf(stderr, "ASCII %d X %d @ %d X %d (%p) place: %d X %d\n", leny, lenx, bargs->begy, begx, data, bargs->placey, bargs->placex);
const int bpp = 32;
int dimy, dimx, x, y;
int total = 0; // number of cells written
ncplane_dim_yx(nc, &dimy, &dimx);
// FIXME not going to necessarily be safe on all architectures hrmmm
const unsigned char* dat = data;
int visy = begy;
for(y = bargs->cell.placey ; visy < (begy + leny) && y < dimy ; ++y, ++visy){
if(ncplane_cursor_move_yx(nc, y, bargs->cell.placex)){
int visy = bargs->begy;
for(y = bargs->placey ; visy < (bargs->begy + leny) && y < dimy ; ++y, ++visy){
if(ncplane_cursor_move_yx(nc, y, bargs->placex)){
return -1;
}
int visx = begx;
for(x = bargs->cell.placex ; visx < (begx + lenx) && x < dimx ; ++x, ++visx){
int visx = bargs->begx;
for(x = bargs->placex ; visx < (bargs->begx + lenx) && x < dimx ; ++x, ++visx){
const unsigned char* rgbbase_up = dat + (linesize * visy) + (visx * bpp / CHAR_BIT);
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
// use the default for the background, as that's the only way it's
// effective in that case anyway
c->channels = 0;
c->stylemask = 0;
if(bargs->cell.blendcolors){
if(bargs->u.cell.blendcolors){
cell_set_bg_alpha(c, CELL_ALPHA_BLEND);
cell_set_fg_alpha(c, CELL_ALPHA_BLEND);
}
Expand All @@ -81,25 +81,25 @@ tria_blit_ascii(ncplane* nc, int linesize, const void* data, int begy, int begx,
// RGBA half-block blitter. Best for most images/videos. Full fidelity
// combined with 1:1 pixel aspect ratio.
static inline int
tria_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
tria_blit(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs){
//fprintf(stderr, "HALF %d X %d @ %d X %d (%p) place: %d X %d\n", leny, lenx, begy, begx, data, bargs->cell.placey, bargs->cell.placex);
//fprintf(stderr, "HALF %d X %d @ %d X %d (%p) place: %d X %d\n", leny, lenx, bargs->begy, bargs->begx, data, bargs->placey, bargs->placex);
const int bpp = 32;
int dimy, dimx, x, y;
int total = 0; // number of cells written
ncplane_dim_yx(nc, &dimy, &dimx);
// FIXME not going to necessarily be safe on all architectures hrmmm
const unsigned char* dat = data;
int visy = begy;
for(y = bargs->cell.placey ; visy < (begy + leny) && y < dimy ; ++y, visy += 2){
if(ncplane_cursor_move_yx(nc, y, bargs->cell.placex)){
int visy = bargs->begy;
for(y = bargs->placey ; visy < (bargs->begy + leny) && y < dimy ; ++y, visy += 2){
if(ncplane_cursor_move_yx(nc, y, bargs->placex)){
return -1;
}
int visx = begx;
for(x = bargs->cell.placex ; visx < (begx + lenx) && x < dimx ; ++x, ++visx){
int visx = bargs->begx;
for(x = bargs->placex ; visx < (bargs->begx + lenx) && x < dimx ; ++x, ++visx){
const unsigned char* rgbbase_up = dat + (linesize * visy) + (visx * bpp / CHAR_BIT);
const unsigned char* rgbbase_down = zeroes;
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
rgbbase_down = dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT);
}
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_up[0], rgbbase_up[1], rgbbase_up[2], rgbbase_up[3]);
Expand All @@ -108,7 +108,7 @@ tria_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
// effective in that case anyway
c->channels = 0;
c->stylemask = 0;
if(bargs->cell.blendcolors){
if(bargs->u.cell.blendcolors){
cell_set_bg_alpha(c, CELL_ALPHA_BLEND);
cell_set_fg_alpha(c, CELL_ALPHA_BLEND);
}
Expand Down Expand Up @@ -403,40 +403,40 @@ qtrans_check(nccell* c, unsigned blendcolors,
// quadrant blitter. maps 2x2 to each cell. since we only have two colors at
// our disposal (foreground and background), we lose some fidelity.
static inline int
quadrant_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
quadrant_blit(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs){
const int bpp = 32;
int dimy, dimx, x, y;
int total = 0; // number of cells written
ncplane_dim_yx(nc, &dimy, &dimx);
//fprintf(stderr, "quadblitter %dx%d -> %d/%d+%d/%d\n", leny, lenx, dimy, dimx, bargs->cell.placey, bargs->cell.placex);
//fprintf(stderr, "quadblitter %dx%d -> %d/%d+%d/%d\n", leny, lenx, dimy, dimx, bargs->placey, bargs->placex);
// FIXME not going to necessarily be safe on all architectures hrmmm
const unsigned char* dat = data;
int visy = begy;
for(y = bargs->cell.placey ; visy < (begy + leny) && y < dimy ; ++y, visy += 2){
if(ncplane_cursor_move_yx(nc, y, bargs->cell.placex)){
int visy = bargs->begy;
for(y = bargs->placey ; visy < (bargs->begy + leny) && y < dimy ; ++y, visy += 2){
if(ncplane_cursor_move_yx(nc, y, bargs->placex)){
return -1;
}
int visx = begx;
for(x = bargs->cell.placex ; visx < (begx + lenx) && x < dimx ; ++x, visx += 2){
int visx = bargs->begx;
for(x = bargs->placex ; visx < (bargs->begx + lenx) && x < dimx ; ++x, visx += 2){
const unsigned char* rgbbase_tl = dat + (linesize * visy) + (visx * bpp / CHAR_BIT);
const unsigned char* rgbbase_tr = zeroes;
const unsigned char* rgbbase_bl = zeroes;
const unsigned char* rgbbase_br = zeroes;
if(visx < begx + lenx - 1){
if(visx < bargs->begx + lenx - 1){
rgbbase_tr = dat + (linesize * visy) + ((visx + 1) * bpp / CHAR_BIT);
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
rgbbase_br = dat + (linesize * (visy + 1)) + ((visx + 1) * bpp / CHAR_BIT);
}
}
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
rgbbase_bl = dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT);
}
//fprintf(stderr, "[%04d/%04d] bpp: %d lsize: %d %02x %02x %02x %02x\n", y, x, bpp, linesize, rgbbase_tl[0], rgbbase_tr[1], rgbbase_bl[2], rgbbase_br[3]);
nccell* c = ncplane_cell_ref_yx(nc, y, x);
c->channels = 0;
c->stylemask = 0;
const char* egc = qtrans_check(c, bargs->cell.blendcolors, rgbbase_tl, rgbbase_tr, rgbbase_bl, rgbbase_br);
const char* egc = qtrans_check(c, bargs->u.cell.blendcolors, rgbbase_tl, rgbbase_tr, rgbbase_bl, rgbbase_br);
if(egc == NULL){
uint32_t tl = 0, tr = 0, bl = 0, br = 0;
channel_set_rgb8(&tl, rgbbase_tl[0], rgbbase_tl[1], rgbbase_tl[2]);
Expand All @@ -450,7 +450,7 @@ quadrant_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
//fprintf(stderr, "%d/%d %08x/%08x\n", y, x, fg, bg);
cell_set_fchannel(c, fg);
cell_set_bchannel(c, bg);
if(bargs->cell.blendcolors){
if(bargs->u.cell.blendcolors){
cell_set_bg_alpha(c, CELL_ALPHA_BLEND);
cell_set_fg_alpha(c, CELL_ALPHA_BLEND);
}
Expand Down Expand Up @@ -625,44 +625,44 @@ sex_trans_check(cell* c, const uint32_t rgbas[6], unsigned blendcolors){
// sextant blitter. maps 3x2 to each cell. since we only have two colors at
// our disposal (foreground and background), we lose some fidelity.
static inline int
sextant_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
sextant_blit(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs){
const int bpp = 32;
int dimy, dimx, x, y;
int total = 0; // number of cells written
ncplane_dim_yx(nc, &dimy, &dimx);
//fprintf(stderr, "sexblitter %dx%d -> %d/%d+%d/%d\n", leny, lenx, dimy, dimx, bargs->cell.placey, bargs->cell.placex);
//fprintf(stderr, "sexblitter %dx%d -> %d/%d+%d/%d\n", leny, lenx, dimy, dimx, bargs->placey, bargs->placex);
const unsigned char* dat = data;
int visy = begy;
for(y = bargs->cell.placey ; visy < (begy + leny) && y < dimy ; ++y, visy += 3){
if(ncplane_cursor_move_yx(nc, y, bargs->cell.placex)){
int visy = bargs->begy;
for(y = bargs->placey ; visy < (bargs->begy + leny) && y < dimy ; ++y, visy += 3){
if(ncplane_cursor_move_yx(nc, y, bargs->placex)){
return -1;
}
int visx = begx;
for(x = bargs->cell.placex ; visx < (begx + lenx) && x < dimx ; ++x, visx += 2){
int visx = bargs->begx;
for(x = bargs->placex ; visx < (bargs->begx + lenx) && x < dimx ; ++x, visx += 2){
uint32_t rgbas[6] = { 0, 0, 0, 0, 0, 0 };
memcpy(&rgbas[0], (dat + (linesize * visy) + (visx * bpp / CHAR_BIT)), sizeof(*rgbas));
if(visx < begx + lenx - 1){
if(visx < bargs->begx + lenx - 1){
memcpy(&rgbas[1], (dat + (linesize * visy) + ((visx + 1) * bpp / CHAR_BIT)), sizeof(*rgbas));
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
memcpy(&rgbas[3], (dat + (linesize * (visy + 1)) + ((visx + 1) * bpp / CHAR_BIT)), sizeof(*rgbas));
if(visy < begy + leny - 2){
if(visy < bargs->begy + leny - 2){
memcpy(&rgbas[5], (dat + (linesize * (visy + 2)) + ((visx + 1) * bpp / CHAR_BIT)), sizeof(*rgbas));
}
}
}
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
memcpy(&rgbas[2], (dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT)), sizeof(*rgbas));
if(visy < begy + leny - 2){
if(visy < bargs->begy + leny - 2){
memcpy(&rgbas[4], (dat + (linesize * (visy + 2)) + (visx * bpp / CHAR_BIT)), sizeof(*rgbas));
}
}
nccell* c = ncplane_cell_ref_yx(nc, y, x);
c->channels = 0;
c->stylemask = 0;
const char* egc = sex_trans_check(c, rgbas, bargs->cell.blendcolors);
const char* egc = sex_trans_check(c, rgbas, bargs->u.cell.blendcolors);
if(egc == NULL){
egc = sex_solver(rgbas, &c->channels, bargs->cell.blendcolors);
egc = sex_solver(rgbas, &c->channels, bargs->u.cell.blendcolors);
cell_set_blitquadrants(c, 1, 1, 1, 1);
}
//fprintf(stderr, "sex EGC: %s channels: %016lx\n", egc, c->channels);
Expand Down Expand Up @@ -693,21 +693,21 @@ fold_rgb8(unsigned* restrict r, unsigned* restrict g, unsigned* restrict b,
// visuals with only two colors in a given area, as it packs lots of
// resolution. always transparent background.
static inline int
braille_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
braille_blit(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs){
const int bpp = 32;
int dimy, dimx, x, y;
int total = 0; // number of cells written
ncplane_dim_yx(nc, &dimy, &dimx);
// FIXME not going to necessarily be safe on all architectures hrmmm
const unsigned char* dat = data;
int visy = begy;
for(y = bargs->cell.placey ; visy < (begy + leny) && y < dimy ; ++y, visy += 4){
if(ncplane_cursor_move_yx(nc, y, bargs->cell.placex)){
int visy = bargs->begy;
for(y = bargs->placey ; visy < (bargs->begy + leny) && y < dimy ; ++y, visy += 4){
if(ncplane_cursor_move_yx(nc, y, bargs->placex)){
return -1;
}
int visx = begx;
for(x = bargs->cell.placex ; visx < (begx + lenx) && x < dimx ; ++x, visx += 2){
int visx = bargs->begx;
for(x = bargs->placex ; visx < (bargs->begx + lenx) && x < dimx ; ++x, visx += 2){
const uint32_t* rgbbase_l0 = (const uint32_t*)(dat + (linesize * visy) + (visx * bpp / CHAR_BIT));
const uint32_t* rgbbase_r0 = &zeroes32;
const uint32_t* rgbbase_l1 = &zeroes32;
Expand All @@ -719,23 +719,23 @@ braille_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
unsigned r = 0, g = 0, b = 0;
unsigned blends = 0;
unsigned egcidx = 0;
if(visx < begx + lenx - 1){
if(visx < bargs->begx + lenx - 1){
rgbbase_r0 = (const uint32_t*)(dat + (linesize * visy) + ((visx + 1) * bpp / CHAR_BIT));
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
rgbbase_r1 = (const uint32_t*)(dat + (linesize * (visy + 1)) + ((visx + 1) * bpp / CHAR_BIT));
if(visy < begy + leny - 2){
if(visy < bargs->begy + leny - 2){
rgbbase_r2 = (const uint32_t*)(dat + (linesize * (visy + 2)) + ((visx + 1) * bpp / CHAR_BIT));
if(visy < begy + leny - 3){
if(visy < bargs->begy + leny - 3){
rgbbase_r3 = (const uint32_t*)(dat + (linesize * (visy + 3)) + ((visx + 1) * bpp / CHAR_BIT));
}
}
}
}
if(visy < begy + leny - 1){
if(visy < bargs->begy + leny - 1){
rgbbase_l1 = (const uint32_t*)(dat + (linesize * (visy + 1)) + (visx * bpp / CHAR_BIT));
if(visy < begy + leny - 2){
if(visy < bargs->begy + leny - 2){
rgbbase_l2 = (const uint32_t*)(dat + (linesize * (visy + 2)) + (visx * bpp / CHAR_BIT));
if(visy < begy + leny - 3){
if(visy < bargs->begy + leny - 3){
rgbbase_l3 = (const uint32_t*)(dat + (linesize * (visy + 3)) + (visx * bpp / CHAR_BIT));
}
}
Expand Down Expand Up @@ -779,7 +779,7 @@ braille_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
// effective in that case anyway
c->channels = 0;
c->stylemask = 0;
if(bargs->cell.blendcolors){
if(bargs->u.cell.blendcolors){
cell_set_fg_alpha(c, CELL_ALPHA_BLEND);
}
// FIXME for now, we just sample, color-wise, and always draw crap.
Expand Down Expand Up @@ -960,13 +960,15 @@ int ncblit_rgba(const void* data, int linesize, const struct ncvisual_options* v
return -1;
}
blitterargs bargs = {
.cell = {
.placey = vopts->y,
.placex = vopts->x,
.blendcolors = (vopts->flags & NCVISUAL_OPTION_BLEND),
.placey = vopts->y,
.placex = vopts->x,
.u = {
.cell = {
.blendcolors = (vopts->flags & NCVISUAL_OPTION_BLEND),
},
},
};
return bset->blit(nc, linesize, data, begy, begx, leny, lenx, &bargs);
return bset->blit(nc, linesize, data, leny, lenx, &bargs);
}

ncblitter_e ncvisual_media_defblitter(const notcurses* nc, ncscale_e scale){
Expand Down
11 changes: 5 additions & 6 deletions src/lib/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,13 +524,12 @@ ncdirectv* ncdirect_render_frame(ncdirect* n, const char* file,
}
blitterargs bargs = {};
if(bset->geom == NCBLIT_PIXEL){
bargs.pixel.celldimx = n->tcache.cellpixx;
bargs.pixel.celldimy = n->tcache.cellpixy;
bargs.pixel.colorregs = n->tcache.color_registers;
bargs.pixel.sprixelid = n->tcache.sprixelnonce++;
bargs.u.pixel.celldimx = n->tcache.cellpixx;
bargs.u.pixel.celldimy = n->tcache.cellpixy;
bargs.u.pixel.colorregs = n->tcache.color_registers;
bargs.u.pixel.sprixelid = n->tcache.sprixelnonce++;
}
if(ncvisual_blit(ncv, disprows, dispcols, ncdv, bset,
0, 0, leny, lenx, &bargs)){
if(ncvisual_blit(ncv, disprows, dispcols, ncdv, bset, leny, lenx, &bargs)){
ncvisual_destroy(ncv);
free_plane(ncdv);
return NULL;
Expand Down
48 changes: 24 additions & 24 deletions src/lib/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,26 +413,26 @@ typedef struct notcurses {
unsigned stdio_blocking_save; // was stdio blocking at entry? restore on stop.
} notcurses;

// cell vs pixel-specific arguments
typedef union {
struct {
int blendcolors; // use CELL_ALPHA_BLEND
int placey; // placement within ncplane
int placex;
} cell; // for cells
struct {
int celldimx; // horizontal pixels per cell
int celldimy; // vertical pixels per cell
int colorregs; // number of color registers
int sprixelid; // unqie 24-bit id into sprixel cache
int placey; // placement within ncplane
int placex;
} pixel; // for pixels
typedef struct {
int begy; // upper left start within visual
int begx;
int placey; // placement within ncplane
int placex;
union { // cell vs pixel-specific arguments
struct {
int blendcolors; // use CELL_ALPHA_BLEND
} cell; // for cells
struct {
int celldimx; // horizontal pixels per cell
int celldimy; // vertical pixels per cell
int colorregs; // number of color registers
int sprixelid; // unqie 24-bit id into sprixel cache
} pixel; // for pixels
} u;
} blitterargs;

typedef int (*blitter)(struct ncplane* n, int linesize, const void* data,
int begy, int begx, int leny, int lenx,
const blitterargs* bargs);
int leny, int lenx, const blitterargs* bargs);

// a system for rendering RGBA pixels as text glyphs
struct blitset {
Expand Down Expand Up @@ -920,7 +920,7 @@ ALLOC char* ncplane_vprintf_prep(const char* format, va_list ap);
// change the internals of the ncvisual. Uses oframe.
int ncvisual_blit(struct ncvisual* ncv, int rows, int cols,
ncplane* n, const struct blitset* bset,
int begy, int begx, int leny, int lenx, const blitterargs* bargs);
int leny, int lenx, const blitterargs* bargs);

void nclog(const char* fmt, ...);

Expand Down Expand Up @@ -1299,10 +1299,10 @@ ncdirect_bg_default_p(const struct ncdirect* nc){
int sprite_sixel_cell_wipe(const notcurses* nc, sprixel* s, int y, int x);
int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int y, int x);

int sixel_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
int sixel_blit(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs);

int kitty_blit(ncplane* nc, int linesize, const void* data, int begy, int begx,
int kitty_blit(ncplane* nc, int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs);

int term_fg_rgb8(bool RGBflag, const char* setaf, int colors, FILE* out,
Expand All @@ -1312,9 +1312,9 @@ API const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid,

static inline int
rgba_blit_dispatch(ncplane* nc, const struct blitset* bset,
int linesize, const void* data, int begy,
int begx, int leny, int lenx, const blitterargs* bargs){
return bset->blit(nc, linesize, data, begy, begx, leny, lenx, bargs);
int linesize, const void* data,
int leny, int lenx, const blitterargs* bargs){
return bset->blit(nc, linesize, data, leny, lenx, bargs);
}

static inline const struct blitset*
Expand All @@ -1339,7 +1339,7 @@ typedef struct ncvisual_implementation {
int (*visual_init)(int loglevel);
void (*visual_printbanner)(const struct notcurses* nc);
int (*visual_blit)(struct ncvisual* ncv, int rows, int cols, ncplane* n,
const struct blitset* bset, int begy, int begx,
const struct blitset* bset,
int leny, int lenx, const blitterargs* barg);
struct ncvisual* (*visual_create)(void);
struct ncvisual* (*visual_from_file)(const char* fname);
Expand Down
Loading

0 comments on commit cd86715

Please sign in to comment.