diff --git a/src/demo/all.c b/src/demo/all.c index 22b503a01..b85dd6380 100644 --- a/src/demo/all.c +++ b/src/demo/all.c @@ -8,10 +8,6 @@ problematic_unicode(char32_t wc){ if(wc >= 0xd800 && wc <= 0xdfff){ return 1; } - // right-to-left text fucks with us hard - if(uc_bidi_category(wc)){ // FIXME - return 1; - } // these are broken in several terminals ㉈ ㉉ ㉊ ㉋ ㉌ ㉍ ㉎ ㉏ // https://github.com/dankamongmen/notcurses/issues/881 if(wc >= 0x3248 && wc <= 0x324f){ diff --git a/src/demo/unicodeblocks.c b/src/demo/unicodeblocks.c index 28c56c1f5..3b7b8426d 100644 --- a/src/demo/unicodeblocks.c +++ b/src/demo/unicodeblocks.c @@ -75,11 +75,6 @@ draw_block(struct ncplane* nn, uint32_t blockstart){ if(wcwidth(w) < 2){ utf8arr[bwc++] = ' '; } - if(uc_bidi_category(w)){ - utf8arr[bwc++] = 0xe2; - utf8arr[bwc++] = 0x80; - utf8arr[bwc++] = 0x8e; - } utf8arr[bwc++] = '\0'; }else{ // don't dump non-printing codepoints strcpy(utf8arr, " "); diff --git a/src/demo/whiteout.c b/src/demo/whiteout.c index 2df19467b..96dc81ac2 100644 --- a/src/demo/whiteout.c +++ b/src/demo/whiteout.c @@ -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", "((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈", "Eڿᛯℇ✈ಅΐʐ𝍇Щঅ℻ ⌬⌨ ⌣₰ ⠝ ‱ ‽ ח ֆ ∜ ⨀ IJႪ ⇠ ਐ ῼ இ ╁ ଠ ୭ ⅙ ㈣⧒ ₔ ⅷ ﭗ ゛〃・ ↂ ﻩ ✞ ℼ ⌧", @@ -501,10 +499,6 @@ int witherworm_demo(struct notcurses* nc){ idx += eaten; continue; } - if(uc_bidi_category(wcs)){ // FIXME - idx += eaten; - continue; - } int ulen = 0; int r; if(wcwidth(wcs) <= maxx - x){ diff --git a/src/lib/internal.h b/src/lib/internal.h index 3c878af92..d999edff7 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -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)); } +// 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 pool_load_direct(egcpool* pool, cell* c, const char* gcluster, int bytes, int cols){ 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_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(strcmp(gcluster, (const char*)&c->gcluster)){ pool_release(pool, c); c->gcluster = 0; memcpy(&c->gcluster, gcluster, bytes); } + if(rtl){ + free(rtl); + } return bytes; } int eoffset = egcpool_stash(pool, gcluster, bytes); + if(rtl){ + free(rtl); + } if(eoffset < 0){ return -1; } diff --git a/src/lib/render.c b/src/lib/render.c index 0661a7fdc..f77f94360 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -899,12 +899,6 @@ notcurses_rasterize_inner(notcurses* nc, const struct crender* rvec, FILE* out){ ++nc->rstate.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); }