[bitmaps] introduce sprixcell_e enum #1457

pull/1480/head
nick black 3 years ago committed by Nick Black
parent 85d0df491e
commit 4ee0582321

@ -35,7 +35,7 @@ relies on the font. Patches to correct/complete this table are very welcome!
| st ("suckless") | ✅ | ✅ |? |`TERM=st-256color` `COLORTERM=24bit` | |
| Terminator | ✅ | ? |? | ? | |
| Terminology | ❌ | ? |? | ? | |
| Tilda | | ? |? | ? | |
| [Tilda](https://github.com/lanoxx/tilda) | | ? |? | ? | |
| [tmux](https://github.com/tmux/tmux/wiki) | | ❌ |n/a |`TERM=tmux-256color` `COLORTERM=24bit` | `tmux.conf` must apply `Tc`; see below. `bce` is available with the `tmux-256color-bce` definition. |
| [wezterm](https://github.com/wez/wezterm) | | ✅ |? |`TERM=wezterm` `COLORTERM=24bit` | |
| [Windows Terminal](https://github.com/microsoft/terminal)| | ? |? | ? | |

@ -46,27 +46,34 @@ struct ncvisual_details;
// and we can't go throwing C++ syntax into this header. so it goes.
typedef enum {
SPRIXEL_NOCHANGE,
SPRIXEL_INVALIDATED,
SPRIXEL_HIDE,
SPRIXEL_QUIESCENT, // sprixel has been drawn
SPRIXEL_INVALIDATED, // sprixel needs to be redrawn
SPRIXEL_HIDE, // sprixel queued for destruction
} sprixel_e;
// elements of the T-A matrix
typedef enum {
SPRIXCELL_NORMAL, // no transparent pixels in this cell
SPRIXCELL_CONTAINS_TRANS, // this cell has transparent pixels
SPRIXCELL_ANNIHILATED, // this cell has been wiped
} sprixcell_e;
// there is a context-wide set of displayed pixel glyphs ("sprixels"); i.e.
// these are independent of particular piles. there should never be very many
// associated with a context (a dozen or so at max). with the kitty protocol,
// we can register them, and then manipulate them by id. with the sixel
// protocol, we just have to rewrite them.
typedef struct sprixel {
char* glyph; // glyph; can be quite large
int glyphlen;
uint32_t id; // embedded into glusters field of nccell, 24 bits
struct ncplane* n; // associated ncplane
sprixel_e invalidated;
char* glyph; // glyph; can be quite large
int glyphlen; // length of the glyph in bytes
uint32_t id; // embedded into glusters field of nccell, 24 bits
struct ncplane* n; // associated ncplane
sprixel_e invalidated;// sprixel invalidation state
struct sprixel* next;
int y, x;
int dimy, dimx; // cell geometry
int pixy, pixx; // pixel geometry (might be smaller than cell geo)
int* tacache; // transparency-annihilation cache (dimy * dimx)
int dimy, dimx; // cell geometry
int pixy, pixx; // pixel geometry (might be smaller than cell geo)
sprixcell_e* tacache; // transparency-annihilation cache (dimy * dimx)
// each tacache entry is one of 0 (standard opaque cell), 1 (cell with
// some transparency), 2 (annihilated, excised)
int parse_start; // where to start parsing for cell wipes
@ -755,9 +762,10 @@ void sprixel_free(sprixel* s);
void sprixel_invalidate(sprixel* s);
void sprixel_hide(sprixel* s);
// dimy and dimx are cell geometry, not pixel
sprixel* sprixel_update(sprixel* s, char* g, int bytes);
sprixel* sprixel_create(ncplane* n, char* s, int bytes, int placey, int placex,
int sprixelid, int dimy, int dimx, int pixy, int pixx,
int parse_start, int* tacache);
int parse_start, sprixcell_e* tacache);
API int sprite_wipe_cell(const notcurses* nc, sprixel* s, int y, int x);
int sprite_kitty_annihilate(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s);
int sprite_kitty_init(int fd);
@ -1162,7 +1170,7 @@ egc_rtl(const char* egc, int* bytes){
static inline int
plane_blit_sixel(ncplane* n, char* s, int bytes, int placey, int placex,
int leny, int lenx, int sprixelid, int dimy, int dimx,
int parse_start, int* tacache){
int parse_start, sprixcell_e * tacache){
sprixel* spx = sprixel_create(n, s, bytes, placey, placex, sprixelid,
leny, lenx, dimy, dimx, parse_start, tacache);
if(spx == NULL){

@ -222,13 +222,13 @@ int sprite_kitty_cell_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell
// we can only write 4KiB at a time. we're writing base64-encoded RGBA. each
// pixel is 4B raw (32 bits). each chunk of three pixels is then 12 bytes, or
// 16 base64-encoded bytes. 4096 / 16 == 256 3-pixel groups, or 768 pixels.
static int*
static sprixcell_e*
write_kitty_data(FILE* fp, int rows, int cols, int linesize, int leny, int lenx,
const uint32_t* data, int sprixelid, int* parse_start){
if(linesize % sizeof(*data)){
return NULL;
}
int* tacache = malloc(sizeof(*tacache) * rows * cols);
sprixcell_e* tacache = malloc(sizeof(*tacache) * rows * cols);
if(tacache == NULL){
return NULL;
}
@ -296,8 +296,8 @@ int kitty_blit(ncplane* nc, int linesize, const void* data,
return -1;
}
int parse_start = 0;
int* tacache = write_kitty_data(fp, rows, cols, linesize, leny, lenx, data,
bargs->u.pixel.sprixelid, &parse_start);
sprixcell_e* tacache = write_kitty_data(fp, rows, cols, linesize, leny, lenx, data,
bargs->u.pixel.sprixelid, &parse_start);
if(tacache == NULL){
fclose(fp);
free(buf);

@ -965,7 +965,7 @@ rasterize_sprixels(notcurses* nc, const ncpile* p, FILE* out){
if(fwrite(s->glyph, s->glyphlen, 1, out) != 1){
return -1;
}
s->invalidated = SPRIXEL_NOCHANGE;
s->invalidated = SPRIXEL_QUIESCENT;
nc->rstate.hardcursorpos = true;
parent = &s->next;
}else if(s->invalidated == SPRIXEL_HIDE){

@ -415,7 +415,7 @@ write_rle(int* printed, int color, FILE* fp, int seenrle, unsigned char crle){
// Emit the sprixel in its entirety, plus enable and disable pixel mode.
static int
write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start, int* tacache){
write_sixel_data(FILE* fp, int lenx, sixeltable* stab, int* parse_start, sprixcell_e* tacache){
*parse_start = fprintf(fp, "\ePq");
// Set Raster Attributes - pan/pad=1 (pixel aspect ratio), Ph=lenx, Pv=leny
// using Ph/Pv causes a background to be drawn using color register 0 for all
@ -496,7 +496,7 @@ int sixel_blit_inner(ncplane* nc, int leny, int lenx, sixeltable* stab,
int parse_start = 0;
unsigned cols = lenx / bargs->u.pixel.celldimx + !!(lenx % bargs->u.pixel.celldimx);
unsigned rows = leny / bargs->u.pixel.celldimy + !!(leny % bargs->u.pixel.celldimy);
int* tacache = malloc(sizeof(*tacache) * rows * cols);
sprixcell_e* tacache = malloc(sizeof(*tacache) * rows * cols);
memset(tacache, 0, sizeof(*tacache) * rows * cols);
if(tacache == NULL){
free(buf);

@ -29,10 +29,18 @@ sprixel* sprixel_by_id(notcurses* nc, uint32_t id){
return NULL;
}
// s ought already have been scrubbed according to the T-A matrix
sprixel* sprixel_update(sprixel* s, const char* g, int bytes){
free(s->glyph);
s->glyph = g;
s->glyphlen = bytes;
s->invalidated = SPRIXEL_INVALIDATED;
}
// y and x are the cell geometry, not the pixel geometry
sprixel* sprixel_create(ncplane* n, char* s, int bytes, int placey, int placex,
int sprixelid, int dimy, int dimx, int pixy, int pixx,
int parse_start, int* tacache){
int parse_start, sprixcell_e* tacache){
sprixel* ret = malloc(sizeof(sprixel));
if(ret){
ret->glyph = s;
@ -73,11 +81,11 @@ int sprite_wipe_cell(const notcurses* nc, sprixel* s, int ycell, int xcell){
return -1;
}
if(s->tacache[s->dimx * ycell + xcell] == 2){
//fprintf(stderr, "CACHED WIPE %d %d/%d\n", s->id, ycell, xcell);
fprintf(stderr, "CACHED WIPE %d %d/%d\n", s->id, ycell, xcell);
return 0; // already annihilated
}
s->tacache[s->dimx * ycell + xcell] = 2;
//fprintf(stderr, "WIPING %d %d/%d\n", s->id, ycell, xcell);
fprintf(stderr, "WIPING %d %d/%d\n", s->id, ycell, xcell);
int r = nc->tcache.pixel_cell_wipe(nc, s, ycell, xcell);
if(r == 0){
s->invalidated = SPRIXEL_INVALIDATED;

Loading…
Cancel
Save