From 2ab0de9fbd03231b647345b01e31b136e2e00978 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 17 Dec 2015 11:59:15 +0000 Subject: [PATCH] [use] Fix halant detection Before, we were just checking the use_category(). This detects as halant a ligature that had the halant as first glyph (as seen in NotoSansBalinese.) Change that to use the is_ligated() glyph prop bit. The font is forming this ligature in ccmp, which is before the rphf / pref tests. So we need to make sure the "ligated" bit survives those tests. Since those only check the "substituted" bit, we now only clear that bit for them and "ligated" survives. Fixes https://github.com/behdad/harfbuzz/issues/180 --- src/hb-ot-layout-private.hh | 6 ++---- src/hb-ot-shape-complex-use.cc | 19 +++++++++++------- test/shaping/Makefile.am | 1 + test/shaping/fonts/sha1sum/MANIFEST | 1 + ...b6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf | Bin 0 -> 2616 bytes test/shaping/tests/MANIFEST | 1 + test/shaping/tests/use.tests | 1 + 7 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf create mode 100644 test/shaping/tests/use.tests diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 45897ed5a..f48184fd3 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -517,11 +517,9 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info) } static inline void -_hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *info) +_hb_glyph_info_clear_substituted (hb_glyph_info_t *info) { - info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | - HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | - HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); + info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED); } diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index a1b63d5b0..3e7003a24 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -360,7 +360,7 @@ clear_substitution_flags (const hb_ot_shape_plan_t *plan, hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) - _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]); + _hb_glyph_info_clear_substituted (&info[i]); } static void @@ -405,6 +405,12 @@ record_pref (const hb_ot_shape_plan_t *plan, } } +static inline bool +is_halant (const hb_glyph_info_t &info) +{ + return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info); +} + static void reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) { @@ -420,7 +426,6 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) hb_glyph_info_t *info = buffer->info; -#define HALANT_FLAGS FLAG(USE_H) #define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV)) /* Move things forward. */ @@ -428,12 +433,12 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) { /* Got a repha. Reorder it to after first base, before first halant. */ for (unsigned int i = start + 1; i < end; i++) - if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS)) + if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i])) { /* If we hit a halant, move before it; otherwise it's a base: move to it's * place, and shift things in between backward. */ - if (info[i].use_category() == USE_H) + if (is_halant (info[i])) i--; buffer->merge_clusters (start, i + 1); @@ -450,11 +455,11 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) for (unsigned int i = start; i < end; i++) { uint32_t flag = FLAG_UNSAFE (info[i].use_category()); - if (flag & (HALANT_FLAGS | BASE_FLAGS)) + if ((flag & (BASE_FLAGS)) || is_halant (info[i])) { - /* If we hit a halant, move before it; otherwise it's a base: move to it's + /* If we hit a halant, move after it; otherwise it's a base: move to it's * place, and shift things in between backward. */ - if (info[i].use_category() == USE_H) + if (is_halant (info[i])) j = i + 1; else j = i; diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index a8e485e7f..f381ac5dc 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -55,6 +55,7 @@ TESTS = \ tests/mongolian-variation-selector.tests \ tests/spaces.tests \ tests/simple.tests \ + tests/use.tests \ tests/vertical.tests \ tests/zero-width-marks.tests \ $(NULL) diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST index 8e46c3abc..615da3a52 100644 --- a/test/shaping/fonts/sha1sum/MANIFEST +++ b/test/shaping/fonts/sha1sum/MANIFEST @@ -36,3 +36,4 @@ e207635780b42f898d58654b65098763e340f5c7.ttf ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf f499fbc23865022234775c43503bba2e63978fe1.ttf fab39d60d758cb586db5a504f218442cd1395725.ttf +fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf diff --git a/test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf b/test/shaping/fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d49432dd824a0e11a9d9fbdca9c2d88f4c574086 GIT binary patch literal 2616 zcmZ`*4Ny~87C!eSd3iy8l9+%c=mJ5o%7V=wwX!bdN5sMs4FXbI4Gd_8Oqo)?3(+2yQn@Sg@9(hj-~)K(%rQs+7~e|1Fq5KQBc0dRF} zp@ojUb3Xm&VBd%?Y?y0BQU(m=;)8Nr>j>%z_YC&=XNL_3Gzn`$&jmOf>;w*uLg-J{ z#Yl_UUa|`$X!jcuJ*xbLFp55dwe%QfnuHNc#0(=A?lhr1x3Dl5G5~nLa0jkc;>A^J z3y4R=BRIqYBfbhBbN>Rf>>!v$eUQ%d_!tUG zU8B(~(q#Mn02A~6@B6>)|D^vT;T+r@d|Jp{Qbt}SgG@ei7nve3`v*9y_*p!o49WrG z6mqRrp<=c1iAJL#Q5(;y)nc)lG7^kNX<(9QG?>zaMJcOIGMMzbNQIiR67)KyTCIxI z>r6%kawF9WB2b2eBniu^ReGI*Q?x~w=C6MG+!e2v#FFgSH@EXcE|;^Q{9s#dL0+C{ zW<Ysy*0-@3)$b2Y5o&eW0lzJ<^ukhZ@PRuXK4zclFL&`s&V#cR2Rnm%I5NbYfBR*F!u%G}3G}LI*?6c0H@aL--GDBj&M+uJIc~F7@QVW3K_{`3 z9DxSw6>@Y+6m^VRg$aU&Q=d>e;2M+*culQF7pb+VH!+nNceg51>f6&@vE z9P`-ujnykWvYe*kE%wx^CZjP^mlnyOkL)&^tsp0Q*ZZe3vre^lZss5GW!u|Ya*7KU zbI~w<5v)+_bO*1upv_td)=9C6txj1ypw}W?Ga`RUaArJdTJN#Sx8$b^W zAsZQrK=`GR0xA-dv_VwJXA3JqOsGxzK*$jUkr;Q3?`#1ACS&iRQy-iO8zzco+rA$5 z@ddT(3(Co&tYtY*(8$)?YaDTAcJR}GTp#;_eQ%rRHm~zMw=yqt^e^PA_uHB_g`Iu3 z$Z`D`QG9aLQ%a(qcxh|tDvo{Q!sVNy?r-kh=e5N7((a7X7p8@npK@<&!OR}hq0dq< zv-R*R^cu~$q$I`U1ed2pv5G*N{(P1aA?vAM`)EdOdaJUkq@=21_mQ@R8=Bqa>z-U% zTl}&mn00&+&A8{COt+994^Q*AzV>?W{Ed`#r|;))x4wJh#?CWSGl_gpb7*nZBNT~z z@+2e%?mOkW22+AbK#X(>9s{?e*%d$jVWMy}PKKjYN~3@QS;YJwO9j2SMK4)nLdHz{t)TM`LRzMdR-M*9My}ZE&tOJd?2`WfB@s92ERg#|$Pu zRip_W%M1YW!rOa#PhQ-$v{FDLzsB;;m17fNy!=Y-0}}DA*ZbFw>->Fla#my6GHdDz z3qn!k4MK5xM`tQ|^G6iYFFpgaXw?wQ5R|Qg5OPSL5fO?D(&?RpsKOfJqOW3k9(*d+7sN(LJIcuG}_VwToK4& z2EHgS>KmRZj1NiznuUF#phE5}l%+Z(s70u@4F3JlTZ9CfaE=HyhtvI7uklo@&e(Im z<6S62cg}~!Q|yVJV!?zpXj?@^jSIqs9%boC^jr>gET43{Xynpb&tmPD;7D+Wl^;j^ dFTpvL;sVhjFbC&KY*gEXEy4~eCqXXq{|Do@iR=IX literal 0 HcmV?d00001 diff --git a/test/shaping/tests/MANIFEST b/test/shaping/tests/MANIFEST index 0eed98f46..f6a2977ef 100644 --- a/test/shaping/tests/MANIFEST +++ b/test/shaping/tests/MANIFEST @@ -13,5 +13,6 @@ indic-pref-blocking.tests mongolian-variation-selector.tests simple.tests spaces.tests +use.tests vertical.tests zero-width-marks.tests diff --git a/test/shaping/tests/use.tests b/test/shaping/tests/use.tests new file mode 100644 index 000000000..ceb82941e --- /dev/null +++ b/test/shaping/tests/use.tests @@ -0,0 +1 @@ +fonts/sha1sum/fbb6c84c9e1fe0c39e152fbe845e51fd81f6748e.ttf::U+1B1B,U+1B44,U+1B13,U+1B3E:[gid3=0+990|gid7=0+2473|gid5=0@-293,-400+0]