diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index a74bc0a7b..1df35a4e8 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -678,30 +678,22 @@ cell_wide_left_p(const cell* c){ return cell_double_wide_p(c) && c->gcluster; } -// Is the cell simple (a lone ASCII character, encoded as such)? +// Is the cell simple (a UTF8-encoded EGC of four bytes or fewer)? static inline bool cell_simple_p(const cell* c){ return (c->gcluster >> 24u) != 0x01; } // return a pointer to the NUL-terminated EGC referenced by 'c'. this pointer -// is invalidated by any further operation on the plane 'n', so...watch out! +// can be invalidated by any further operation on the plane 'n', so...watch out! +// works on both simple and non-simple cells. API const char* cell_extended_gcluster(const struct ncplane* n, const cell* c); // copy the UTF8-encoded EGC out of the cell, whether simple or complex. the // result is not tied to the ncplane, and persists across erases / destruction. static inline char* cell_strdup(const struct ncplane* n, const cell* c){ - char* ret; - if(cell_simple_p(c)){ - if( (ret = (char*)malloc(sizeof(c->gcluster) + 1)) ){ // cast is here for C++ clients - memset(ret, 0, sizeof(c->gcluster) + 1); - memcpy(ret, &c->gcluster, sizeof(c->gcluster)); - } - }else{ - ret = strdup(cell_extended_gcluster(n, c)); - } - return ret; + return strdup(cell_extended_gcluster(n, c)); } // Extract the three elements of a cell. diff --git a/src/lib/fill.c b/src/lib/fill.c index 6a56dcc64..b6dedb6fc 100644 --- a/src/lib/fill.c +++ b/src/lib/fill.c @@ -28,13 +28,11 @@ ncplane_polyfill_recurse(ncplane* n, int y, int x, const cell* c, const char* ta return 0; // not fillable } cell* cur = &n->fb[nfbcellidx(n, y, x)]; - char* glust = cell_strdup(n, cur); -//fprintf(stderr, "checking %d/%d (%s) for [%s]\n", y, x, glust, targ); - if(strcmp(glust, targ)){ - free(glust); + const char* glust = cell_extended_gcluster(n, cur); +fprintf(stderr, "checking %d/%d (%s) for [%s]\n", y, x, glust, targ); + if(strcmp(glust, targ) == 0){ return 0; } - free(glust); if(cell_duplicate(n, cur, c) < 0){ return -1; } @@ -70,16 +68,13 @@ int ncplane_polyfill_yx(ncplane* n, int y, int x, const cell* c){ return -1; // not fillable } cell* cur = &n->fb[nfbcellidx(n, y, x)]; - char* targ = cell_strdup(n, cur); - char* fillegc = cell_strdup(n, c); + const char* targ = cell_extended_gcluster(n, cur); + const char* fillegc = cell_extended_gcluster(n, c); +fprintf(stderr, "checking %d/%d (%s) for [%s]\n", y, x, fillegc, targ); if(strcmp(fillegc, targ) == 0){ - free(targ); - free(fillegc); return 0; } - free(fillegc); ret = ncplane_polyfill_recurse(n, y, x, c, targ); - free(targ); } } return ret; @@ -309,23 +304,20 @@ int ncplane_format(struct ncplane* n, int ystop, int xstop, uint32_t attrword){ // the background. if we're a full block, set both to the foreground. static int rotate_channels(ncplane* src, const cell* c, uint32_t* fchan, uint32_t* bchan){ - if(cell_simple_p(c)){ - if(!isgraph(c->gcluster)){ - *fchan = *bchan; - } + const char* egc = cell_extended_gcluster(src, c); + if(egc[0] == ' ' || egc[0] == 0){ + *fchan = *bchan; return 0; - } - const char* origc = cell_extended_gcluster(src, c); - if(strcmp(origc, "▄") == 0 || strcmp(origc, "▀") == 0){ + }else if(strcmp(egc, "▄") == 0 || strcmp(egc, "▀") == 0){ uint32_t tmp = *fchan; *fchan = *bchan; *bchan = tmp; return 0; - }else if(strcmp(origc, "█") == 0){ + }else if(strcmp(egc, "█") == 0){ *bchan = *fchan; return 0; } - logerror(src->nc, "Invalid EGC for rotation [%s]\n", origc); + logerror(src->nc, "Invalid EGC for rotation [%s]\n", egc); return -1; } diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 16ca4c2b1..c1ee973bf 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1187,7 +1187,10 @@ int ncplane_base(ncplane* ncp, cell* c){ } const char* cell_extended_gcluster(const ncplane* n, const cell* c){ - return extended_gcluster(n, c); + if(cell_simple_p(c)){ + return (const char*)&c->gcluster; + } + return egcpool_extended_gcluster(&n->pool, c); } // 'n' ends up above 'above'