mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
pool_load_direct: call egc_rtl() for RTL U200E forcings #850
This commit is contained in:
parent
955c4b9baa
commit
4466f1aaff
@ -8,10 +8,6 @@ problematic_unicode(char32_t wc){
|
|||||||
if(wc >= 0xd800 && wc <= 0xdfff){
|
if(wc >= 0xd800 && wc <= 0xdfff){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// right-to-left text fucks with us hard
|
|
||||||
if(uc_bidi_category(wc)){ // FIXME
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// these are broken in several terminals ㉈ ㉉ ㉊ ㉋ ㉌ ㉍ ㉎ ㉏
|
// these are broken in several terminals ㉈ ㉉ ㉊ ㉋ ㉌ ㉍ ㉎ ㉏
|
||||||
// https://github.com/dankamongmen/notcurses/issues/881
|
// https://github.com/dankamongmen/notcurses/issues/881
|
||||||
if(wc >= 0x3248 && wc <= 0x324f){
|
if(wc >= 0x3248 && wc <= 0x324f){
|
||||||
|
@ -75,11 +75,6 @@ draw_block(struct ncplane* nn, uint32_t blockstart){
|
|||||||
if(wcwidth(w) < 2){
|
if(wcwidth(w) < 2){
|
||||||
utf8arr[bwc++] = ' ';
|
utf8arr[bwc++] = ' ';
|
||||||
}
|
}
|
||||||
if(uc_bidi_category(w)){
|
|
||||||
utf8arr[bwc++] = 0xe2;
|
|
||||||
utf8arr[bwc++] = 0x80;
|
|
||||||
utf8arr[bwc++] = 0x8e;
|
|
||||||
}
|
|
||||||
utf8arr[bwc++] = '\0';
|
utf8arr[bwc++] = '\0';
|
||||||
}else{ // don't dump non-printing codepoints
|
}else{ // don't dump non-printing codepoints
|
||||||
strcpy(utf8arr, " ");
|
strcpy(utf8arr, " ");
|
||||||
|
@ -289,8 +289,6 @@ int witherworm_demo(struct notcurses* nc){
|
|||||||
"ብርሃነ ዘርኣይ",
|
"ብርሃነ ዘርኣይ",
|
||||||
"ኃይሌ ገብረሥላሴ",
|
"ኃይሌ ገብረሥላሴ",
|
||||||
"ᓱᒻᒪᓂᒃᑯᐊ ᐃᓄᑦᑎᑐᑐᐃᓐᓇᔭᙱᓚᑦ",
|
"ᓱᒻᒪᓂᒃᑯᐊ ᐃᓄᑦᑎᑐᑐᐃᓐᓇᔭᙱᓚᑦ",
|
||||||
"∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β)"
|
|
||||||
"2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200mm",
|
|
||||||
"ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn",
|
"ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn",
|
||||||
"((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈",
|
"((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈",
|
||||||
"Eڿᛯℇ✈ಅΐʐ𝍇Щঅ℻ ⌬⌨ ⌣₰ ⠝ ‱ ‽ ח ֆ ∜ ⨀ IJႪ ⇠ ਐ ῼ இ ╁ ଠ ୭ ⅙ ㈣⧒ ₔ ⅷ ﭗ ゛〃・ ↂ ﻩ ✞ ℼ ⌧",
|
"Eڿᛯℇ✈ಅΐʐ𝍇Щঅ℻ ⌬⌨ ⌣₰ ⠝ ‱ ‽ ח ֆ ∜ ⨀ IJႪ ⇠ ਐ ῼ இ ╁ ଠ ୭ ⅙ ㈣⧒ ₔ ⅷ ﭗ ゛〃・ ↂ ﻩ ✞ ℼ ⌧",
|
||||||
@ -501,10 +499,6 @@ int witherworm_demo(struct notcurses* nc){
|
|||||||
idx += eaten;
|
idx += eaten;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(uc_bidi_category(wcs)){ // FIXME
|
|
||||||
idx += eaten;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int ulen = 0;
|
int ulen = 0;
|
||||||
int r;
|
int r;
|
||||||
if(wcwidth(wcs) <= maxx - x){
|
if(wcwidth(wcs) <= maxx - x){
|
||||||
|
@ -898,6 +898,30 @@ cell_blend_bchannel(cell* cl, unsigned channel, unsigned* blends){
|
|||||||
return cell_set_bchannel(cl, channels_blend(cell_bchannel(cl), channel, blends));
|
return cell_set_bchannel(cl, channels_blend(cell_bchannel(cl), channel, blends));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// examine the UTF-8 EGC in the first |*bytes| bytes of |egc|. if the EGC is
|
||||||
|
// right-to-left, we make a copy, appending an U+200E to force left-to-right.
|
||||||
|
// only the first unicode char of the EGC is currently checked FIXME. if the
|
||||||
|
// EGC is not RTL, we return NULL.
|
||||||
|
static char*
|
||||||
|
egc_rtl(const char* egc, int* bytes){
|
||||||
|
wchar_t w;
|
||||||
|
mbstate_t mbstate = { };
|
||||||
|
size_t r = mbrtowc(&w, egc, *bytes, &mbstate);
|
||||||
|
if(r == (size_t)-1 || r == (size_t)-2){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!uc_bidi_category(w)){ // FIXME too aggressive, counts punctuation etc
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// insert U+200E, "LEFT-TO-RIGHT MARK". This ought reset the text direction
|
||||||
|
// after emitting a potentially RTL EGC.
|
||||||
|
const char LTRMARK[] = "\xe2\x80\x8e";
|
||||||
|
char* s = (char*)malloc(*bytes + sizeof(LTRMARK)); // cast for C++ callers
|
||||||
|
memcpy(s, egc, *bytes);
|
||||||
|
memcpy(s + *bytes, LTRMARK, sizeof(LTRMARK));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
pool_load_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int cols){
|
pool_load_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int cols){
|
||||||
if(bytes < 0 || cols < 0){
|
if(bytes < 0 || cols < 0){
|
||||||
@ -923,15 +947,26 @@ pool_load_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int co
|
|||||||
c->channels |= CELL_NOBACKGROUND_MASK;
|
c->channels |= CELL_NOBACKGROUND_MASK;
|
||||||
c->channels &= ~CELL_WIDEASIAN_MASK;
|
c->channels &= ~CELL_WIDEASIAN_MASK;
|
||||||
}
|
}
|
||||||
|
// checks for RTL and adds U+200E if so FIXME
|
||||||
|
char* rtl = egc_rtl(gcluster, &bytes);
|
||||||
|
if(rtl){
|
||||||
|
gcluster = rtl;
|
||||||
|
}
|
||||||
if(bytes <= 4){
|
if(bytes <= 4){
|
||||||
if(strcmp(gcluster, (const char*)&c->gcluster)){
|
if(strcmp(gcluster, (const char*)&c->gcluster)){
|
||||||
pool_release(pool, c);
|
pool_release(pool, c);
|
||||||
c->gcluster = 0;
|
c->gcluster = 0;
|
||||||
memcpy(&c->gcluster, gcluster, bytes);
|
memcpy(&c->gcluster, gcluster, bytes);
|
||||||
}
|
}
|
||||||
|
if(rtl){
|
||||||
|
free(rtl);
|
||||||
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
int eoffset = egcpool_stash(pool, gcluster, bytes);
|
int eoffset = egcpool_stash(pool, gcluster, bytes);
|
||||||
|
if(rtl){
|
||||||
|
free(rtl);
|
||||||
|
}
|
||||||
if(eoffset < 0){
|
if(eoffset < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -899,12 +899,6 @@ notcurses_rasterize_inner(notcurses* nc, const struct crender* rvec, FILE* out){
|
|||||||
++nc->rstate.x;
|
++nc->rstate.x;
|
||||||
++x;
|
++x;
|
||||||
}
|
}
|
||||||
// if the terminal's own motion carried us down to the next line,
|
|
||||||
// we need update our concept of the cursor's true y
|
|
||||||
/*if(nc->rstate.x >= nc->truecols){
|
|
||||||
++nc->rstate.y; // FIXME not if on last line, right?
|
|
||||||
nc->rstate.x = 0;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
//fprintf(stderr, "damageidx: %ld\n", damageidx);
|
//fprintf(stderr, "damageidx: %ld\n", damageidx);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user