mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
egc inlining #830
This commit is contained in:
parent
99d90a4ecf
commit
b0f7f36995
@ -485,7 +485,7 @@ channels_set_bg_default(uint64_t* channels){
|
|||||||
//
|
//
|
||||||
// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
|
// Each cell occupies 16 static bytes (128 bits). The surface is thus ~1.6MB
|
||||||
// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB.
|
// for a (pretty large) 500x200 terminal. At 80x43, it's less than 64KB.
|
||||||
// Dynamic requirements (the egcpool) can add up to 32MB to an ncplane, but
|
// Dynamic requirements (the egcpool) can add up to 16MB to an ncplane, but
|
||||||
// such large pools are unlikely in common use.
|
// such large pools are unlikely in common use.
|
||||||
//
|
//
|
||||||
// We implement some small alpha compositing. Foreground and background both
|
// We implement some small alpha compositing. Foreground and background both
|
||||||
@ -506,9 +506,12 @@ channels_set_bg_default(uint64_t* channels){
|
|||||||
// RGB is used if neither default terminal colors nor palette indexing are in
|
// RGB is used if neither default terminal colors nor palette indexing are in
|
||||||
// play, and fully supports all transparency options.
|
// play, and fully supports all transparency options.
|
||||||
typedef struct cell {
|
typedef struct cell {
|
||||||
// These 32 bits are either a single-byte, single-character grapheme cluster
|
// These 32 bits are either a complete grapheme cluster in 4 bytes or less,
|
||||||
// (values 0--0x7f), or an offset into a per-ncplane attached pool of
|
// or 0x01000000 plus an offset into a per-ncplane attached pool of varying-
|
||||||
// varying-length UTF-8 grapheme clusters. This pool may thus be up to 32MB.
|
// length UTF-8 EGCs (an egcpool). This pool may thus be up to 16MB.
|
||||||
|
// Obviously, this implies that EGCs beginning with 0x01 are disallowed; such
|
||||||
|
// an EGC, if we wanted to support them, could be spilled to the egcpool. If
|
||||||
|
// the EGC is less than four bytes, it will be padded with zeroes.
|
||||||
uint32_t gcluster; // 4B -> 4B
|
uint32_t gcluster; // 4B -> 4B
|
||||||
// 8 bits of zero + 8 reserved bits + NCSTYLE_* attributes (16 bits).
|
// 8 bits of zero + 8 reserved bits + NCSTYLE_* attributes (16 bits).
|
||||||
// (attrword & 0xff000000): reserved, *must be zero*
|
// (attrword & 0xff000000): reserved, *must be zero*
|
||||||
@ -648,7 +651,7 @@ cell_wide_left_p(const cell* c){
|
|||||||
// Is the cell simple (a lone ASCII character, encoded as such)?
|
// Is the cell simple (a lone ASCII character, encoded as such)?
|
||||||
static inline bool
|
static inline bool
|
||||||
cell_simple_p(const cell* c){
|
cell_simple_p(const cell* c){
|
||||||
return c->gcluster < 0x80;
|
return (c->gcluster >> 24u) != 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
|
// return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer
|
||||||
|
@ -249,7 +249,7 @@ egcpool_dump(egcpool* pool){
|
|||||||
// unsafe results if called on a simple cell.
|
// unsafe results if called on a simple cell.
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
cell_egc_idx(const cell* c){
|
cell_egc_idx(const cell* c){
|
||||||
return c->gcluster - 0x80;
|
return c->gcluster & 0x00fffffflu;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((__returns_nonnull__)) static inline const char*
|
__attribute__ ((__returns_nonnull__)) static inline const char*
|
||||||
|
@ -608,7 +608,7 @@ cell_duplicate_far(egcpool* tpool, cell* targ, const ncplane* splane, const cell
|
|||||||
if(eoffset < 0){
|
if(eoffset < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
targ->gcluster = eoffset + 0x80;
|
targ->gcluster = 0x01000000ul + eoffset;
|
||||||
return ulen;
|
return ulen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,36 +1364,30 @@ cell_load_direct(ncplane* n, cell* c, const char* gcluster, int bytes, int cols)
|
|||||||
if(bytes < 0 || cols < 0){
|
if(bytes < 0 || cols < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(bytes <= 1){
|
if(cols < 2){
|
||||||
assert(cols < 2);
|
|
||||||
cell_release(n, c);
|
|
||||||
c->channels &= ~(CELL_WIDEASIAN_MASK | CELL_NOBACKGROUND_MASK);
|
|
||||||
c->gcluster = *gcluster;
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
if(!cell_simple_p(c)){
|
|
||||||
if(strcmp(gcluster, cell_extended_gcluster(n, c)) == 0){
|
|
||||||
return bytes; // reduce, reuse, recycle
|
|
||||||
}else{
|
|
||||||
cell_release(n, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(cols > 1){
|
|
||||||
c->channels |= CELL_WIDEASIAN_MASK;
|
|
||||||
}else{
|
|
||||||
c->channels &= ~CELL_WIDEASIAN_MASK;
|
c->channels &= ~CELL_WIDEASIAN_MASK;
|
||||||
|
}else{
|
||||||
|
c->channels |= CELL_WIDEASIAN_MASK;
|
||||||
}
|
}
|
||||||
// FIXME also shaded blocks! ░ etc
|
// FIXME also shaded blocks! ░ etc. are there combined EGCs involving these?
|
||||||
if(strncmp(gcluster, "\xe2\x96\x88", 3)){
|
if(strncmp(gcluster, "\xe2\x96\x88", 3)){
|
||||||
c->channels &= ~CELL_NOBACKGROUND_MASK;
|
c->channels &= ~CELL_NOBACKGROUND_MASK;
|
||||||
}else{
|
}else{
|
||||||
c->channels |= CELL_NOBACKGROUND_MASK;
|
c->channels |= CELL_NOBACKGROUND_MASK;
|
||||||
}
|
}
|
||||||
|
if(bytes <= 4){
|
||||||
|
cell_release(n, c);
|
||||||
|
c->channels &= ~CELL_WIDEASIAN_MASK;
|
||||||
|
c->gcluster = 0;
|
||||||
|
memcpy(&c->gcluster, gcluster, bytes);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
int eoffset = egcpool_stash(&n->pool, gcluster, bytes);
|
int eoffset = egcpool_stash(&n->pool, gcluster, bytes);
|
||||||
if(eoffset < 0){
|
if(eoffset < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
c->gcluster = eoffset + 0x80;
|
cell_release(n, c);
|
||||||
|
c->gcluster = 0x01000000ul + eoffset;
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1452,6 +1446,7 @@ int ncplane_putegc_yx(ncplane* n, int y, int x, const char* gclust, int* sbytes)
|
|||||||
if(cell_load_direct(n, targ, gclust, bytes, cols) < 0){
|
if(cell_load_direct(n, targ, gclust, bytes, cols) < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
//fprintf(stderr, "%08x %d %d\n", targ->gcluster, bytes, cols);
|
||||||
targ->attrword = n->attrword;
|
targ->attrword = n->attrword;
|
||||||
targ->channels = channels;
|
targ->channels = channels;
|
||||||
if(wide){ // must set our right wide, and check for further damage
|
if(wide){ // must set our right wide, and check for further damage
|
||||||
|
@ -500,16 +500,12 @@ ncfputc(char c, FILE* out){
|
|||||||
static int
|
static int
|
||||||
term_putc(FILE* out, const egcpool* e, const cell* c){
|
term_putc(FILE* out, const egcpool* e, const cell* c){
|
||||||
if(cell_simple_p(c)){
|
if(cell_simple_p(c)){
|
||||||
if(c->gcluster == 0 || iscntrl(c->gcluster)){
|
char egc[5];
|
||||||
// fprintf(stderr, "[ ]\n");
|
memset(egc, 0, sizeof(egc));
|
||||||
if(ncfputc(' ', out) == EOF){
|
memcpy(egc, &c->gcluster, sizeof(c->gcluster));
|
||||||
return -1;
|
//fprintf(stderr, "[%ls]\n", egc);
|
||||||
}
|
if(ncfputs(egc, out) == EOF){
|
||||||
}else{
|
return -1;
|
||||||
//fprintf(stderr, "[%c]\n", c->gcluster);
|
|
||||||
if(ncfputc(c->gcluster, out) == EOF){
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
const char* ext = egcpool_extended_gcluster(e, c);
|
const char* ext = egcpool_extended_gcluster(e, c);
|
||||||
|
Loading…
Reference in New Issue
Block a user