[HarfBuzz] harfbuzz: Branch 'master' - 9 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Oct 15 10:52:43 PDT 2013


 dev/null                                                                         |binary
 src/hb-ot-shape-complex-indic-machine.rl                                         |    5 
 src/hb-ot-shape-complex-indic-private.hh                                         |    5 
 src/hb-ot-shape-complex-indic.cc                                                 |  103 +++++++---
 src/hb-ot-shape-complex-myanmar.cc                                               |   10 
 test/shaping/tests/context-matching.tests                                        |    1 
 test/shaping/texts/in-tree/shaper-indic/indic/script-devanagari/misc/misc.txt    |    1 
 test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt |    3 
 test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/misc.txt       |    1 
 test/shaping/texts/in-tree/shaper-indic/indic/script-telugu/misc/misc.txt        |    1 
 10 files changed, 98 insertions(+), 32 deletions(-)

New commits:
commit f5299eff5c0065d6329cd536c0ac339abea085b0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 18:13:07 2013 +0200

    [indic] Simplify reph logic
    
    *Shouldn't* break anything.

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index fd61276..e3920d4 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1329,14 +1329,9 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
    *   move it if it did NOT ligate.  If it ligated, it's probably the font trying
    *   to make it work without the reordering.
    */
-  if (start + 1 < end && (
-      (info[start].indic_category() != OT_Repha &&
-       info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
-       info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
-      ||
-      (info[start].indic_category() == OT_Repha &&
-       !is_a_ligature (info[start]))
-     ))
+  if (start + 1 < end &&
+      info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
+      ((info[start].indic_category() == OT_Repha) ^ is_a_ligature (info[start])))
   {
     unsigned int new_reph_pos;
     reph_position_t reph_pos = indic_plan->config->reph_pos;
commit 65a929b1c033e91919c931b495a775f76b6dcbb3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 18:08:05 2013 +0200

    [indic] If Malayalam dot-reph formed a ligature, don't move it
    
    Rachana-0.6 implements dot-reph by ligation, so we shouldn't move it.
    Uniscribe doesn't either.  Test case:
    
      U+0D4E,U+0D1A,U+0D4D,U+0D1A,U+0D4D

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 4df1932..fd61276 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1320,12 +1320,23 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
    *     before post-base consonant forms, and after post-base consonant forms.
    */
 
-  /* If there's anything after the Ra that has the REPH pos, it ought to be halant.
-   * Which means that the font has failed to ligate the Reph.  In which case, we
-   * shouldn't move. */
-  if (start + 1 < end &&
-      info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
-      info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
+  /* Two cases:
+   *
+   * - If repha is encoded as a sequence of characters (Ra,H or Ra,H,ZWJ), then
+   *   we should only move it if the sequence ligated to the repha form.
+   *
+   * - If repha is encoded separately and in the logical position, we should only
+   *   move it if it did NOT ligate.  If it ligated, it's probably the font trying
+   *   to make it work without the reordering.
+   */
+  if (start + 1 < end && (
+      (info[start].indic_category() != OT_Repha &&
+       info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
+       info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
+      ||
+      (info[start].indic_category() == OT_Repha &&
+       !is_a_ligature (info[start]))
+     ))
   {
     unsigned int new_reph_pos;
     reph_position_t reph_pos = indic_plan->config->reph_pos;
diff --git a/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt b/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt
index d158b8f..fc74da9 100644
--- a/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt
+++ b/test/shaping/texts/in-tree/shaper-indic/indic/script-malayalam/misc/dot-reph.txt
@@ -10,3 +10,6 @@
 ഗ്ഗോ
 ഗ്ഗ
 ഗ്രോ
+ൎകു
+ൎക്കു
+ൎച്ച്
commit a01cbf6cbe0021722302cfb58fb638a0a2427b26
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 16:37:53 2013 +0200

    [indic] Harmless reordering of Khmer features!

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index a279ff2..4df1932 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -351,15 +351,17 @@ indic_features[] =
   {HB_TAG('r','k','r','f'), F_GLOBAL},
   {HB_TAG('p','r','e','f'), F_NONE},
   {HB_TAG('b','l','w','f'), F_NONE},
-  {HB_TAG('h','a','l','f'), F_NONE},
   {HB_TAG('a','b','v','f'), F_NONE},
+  {HB_TAG('h','a','l','f'), F_NONE},
   {HB_TAG('p','s','t','f'), F_NONE},
-  {HB_TAG('c','f','a','r'), F_NONE},
   {HB_TAG('v','a','t','u'), F_GLOBAL},
   {HB_TAG('c','j','c','t'), F_GLOBAL},
+  {HB_TAG('c','f','a','r'), F_NONE},
   /*
    * Other features.
    * These features are applied all at once, after final_reordering.
+   * Default Bengali font in Windows for example has intermixed
+   * lookups for init,pres,abvs,blws features.
    */
   {HB_TAG('i','n','i','t'), F_NONE},
   {HB_TAG('p','r','e','s'), F_GLOBAL},
@@ -383,12 +385,12 @@ enum {
   _RKRF,
   PREF,
   BLWF,
-  HALF,
   ABVF,
+  HALF,
   PSTF,
-  CFAR,
   _VATU,
   _CJCT,
+  CFAR,
 
   INIT,
   _PRES,
commit c46f406973024051877e867b93614942ff80c107
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 16:24:21 2013 +0200

    [tests] Remove Myanmar micro-font and test

diff --git a/test/shaping/fonts/sha1sum/ceadd106a8205214fbe7337ef9de32a862b59762.ttf b/test/shaping/fonts/sha1sum/ceadd106a8205214fbe7337ef9de32a862b59762.ttf
deleted file mode 100644
index b37428e..0000000
Binary files a/test/shaping/fonts/sha1sum/ceadd106a8205214fbe7337ef9de32a862b59762.ttf and /dev/null differ
diff --git a/test/shaping/tests/context-matching.tests b/test/shaping/tests/context-matching.tests
index 0d1d8a0..4c7d25f 100644
--- a/test/shaping/tests/context-matching.tests
+++ b/test/shaping/tests/context-matching.tests
@@ -1,4 +1,3 @@
 fonts/sha1sum/4cce528e99f600ed9c25a2b69e32eb94a03b4ae8.ttf:U+1A48,U+1A58,U+1A25,U+1A48,U+1A58,U+1A25,U+1A6E,U+1A63:[uni1A48=0+1212|uni1A25=0+1912|uni1A58=0+0|uni1A48=3+1212|uni1A6E=3+1212|uni1A25=3+1912|uni1A58=3+0|uni1A63=3+1212]
 fonts/sha1sum/d629e7fedc0b350222d7987345fe61613fa3929a.ttf:U+0915,U+093F,U+0915,U+093F:[ivowelsign03deva=0+530|kadeva=0+1561|ivowelsign03deva=2+530|kadeva=2+1561]
 fonts/sha1sum/f499fbc23865022234775c43503bba2e63978fe1.ttf:U+09B0,U+09CD,U+09A5,U+09CD,U+09AF,U+09C0:[gid1=0+1320|gid13=0+523|gid18=0+545]
-fonts/sha1sum/ceadd106a8205214fbe7337ef9de32a862b59762.ttf:U+1014,U+1039,U+1011,U+1014,U+1039,U+1011,U+1014,U+1039,U+1011:[gid4=0+1118|gid5=0 at 97,0+600|gid4=3+1118|gid5=3 at 97,0+600|gid4=6+1118|gid5=6 at 97,0+0]
commit eb10233b267909dee0245f126000e117f3b21c35
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 15:26:44 2013 +0200

    [indic] Apply 'kern' for all scripts except for Khmer in Uniscribe mode
    
    Seems to better match Uniscribe.
    
    Note: NotoSansTelugu-Regular has kern feature, so this fixes most of the
    positioning failures there, except for the kern pairs blocked by a
    (non-)joiner, in which case we (correctly) kern, but Uniscribe doesn't.

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 7986ead..a279ff2 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -451,9 +451,16 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
 static void
 override_features_indic (hb_ot_shape_planner_t *plan)
 {
-  /* Uniscribe does not apply 'kern'. */
+  /* Uniscribe does not apply 'kern' in Khmer. */
   if (hb_options ().uniscribe_bug_compatible)
-    plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+  {
+    switch ((hb_tag_t) plan->props.script)
+    {
+      case HB_SCRIPT_KHMER:
+	  plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+	break;
+    }
+  }
 
   plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
 }
commit 30145272a7d428bc62a903388bd7be43f4da7fc3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 13:47:27 2013 +0200

    [indic] Don't apply presentation features across syllables
    
    More like Uniscribe...  We still allow user-defined features to
    work across syllables, but not pres,blws,abs,psts,etc.
    
    This "regressed" Sinhala numbers by 11.  These are cases were
    there's Consonant followed by Ra,Halant,ZWJ at the of text.
    The Ra,Halant,ZWJ ends up forming reph, which is wrong...
    But before we were also ligating that reph with the previous
    consonant.  That's even more wrong.  That's also what Uniscribe
    does.
    
    Current numbers:
    
    BENGALI: 353732 out of 354188 tests passed. 456 failed (0.128745%)
    DEVANAGARI: 707307 out of 707394 tests passed. 87 failed (0.0122987%)
    GUJARATI: 366349 out of 366457 tests passed. 108 failed (0.0294714%)
    GURMUKHI: 60732 out of 60747 tests passed. 15 failed (0.0246926%)
    KANNADA: 951030 out of 951913 tests passed. 883 failed (0.0927606%)
    KHMER: 299070 out of 299124 tests passed. 54 failed (0.0180527%)
    MALAYALAM: 1048140 out of 1048334 tests passed. 194 failed (0.0185056%)
    ORIYA: 42320 out of 42329 tests passed. 9 failed (0.021262%)
    SINHALA: 271655 out of 271847 tests passed. 192 failed (0.070628%)
    TAMIL: 1091753 out of 1091754 tests passed. 1 failed (9.15957e-05%)
    TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 00e3c45..7986ead 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -416,6 +416,10 @@ static void
 final_reordering (const hb_ot_shape_plan_t *plan,
 		  hb_font_t *font,
 		  hb_buffer_t *buffer);
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan,
+		 hb_font_t *font,
+		 hb_buffer_t *buffer);
 
 static void
 collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -441,6 +445,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
   for (; i < INDIC_NUM_FEATURES; i++) {
     map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
   }
+  map->add_gsub_pause (clear_syllables);
 }
 
 static void
@@ -1558,15 +1563,23 @@ final_reordering (const hb_ot_shape_plan_t *plan,
     }
   final_reordering_syllable (plan, buffer, last, count);
 
-  /* Zero syllables now... */
-  for (unsigned int i = 0; i < count; i++)
-    info[i].syllable() = 0;
-
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
 }
 
 
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+		 hb_font_t *font HB_UNUSED,
+		 hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].syllable() = 0;
+}
+
+
 static hb_ot_shape_normalization_mode_t
 normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
 {
diff --git a/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/misc.txt b/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/misc.txt
index 363fcb6..c43cb95 100644
--- a/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/misc.txt
+++ b/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/misc.txt
@@ -38,3 +38,4 @@
 ර්‍
 ක්‍රා
 කේ
+ගර්‍
commit 3c7b3641cfb00f2c4dcc0768b9854e4f4410d15f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 11:21:01 2013 +0200

    [indic] Handle Avagraha
    
    It can come either at the end(ish!) of the syllable, or independently.
    When independent, it accepts a few bits and pieces.

diff --git a/src/hb-ot-shape-complex-indic-machine.rl b/src/hb-ot-shape-complex-indic-machine.rl
index f9f07d8..fa068c4 100644
--- a/src/hb-ot-shape-complex-indic-machine.rl
+++ b/src/hb-ot-shape-complex-indic-machine.rl
@@ -56,6 +56,7 @@ Coeng = 14;
 Repha = 15;
 Ra    = 16;
 CM    = 17;
+Avag  = 18;
 
 c = (C | Ra)CM*;		# is_consonant
 n = ((ZWNJ?.RS)? (N.N?)?);	# is_consonant_modifier
@@ -66,7 +67,7 @@ reph = (Ra H | Repha);		# possible reph
 cn = c.ZWJ?.n?;
 forced_rakar = ZWJ H ZWJ Ra;
 matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
-syllable_tail =  (Coeng (cn|V))? (SM.ZWNJ?)? (VD VD?)?;
+syllable_tail =  (Coeng (cn|V))? (Avag.N?)? (SM.ZWNJ?)? (VD VD?)?;
 place_holder = NBSP | DOTTEDCIRCLE;
 halant_group = (z?.h.(ZWJ.N?)?);
 final_halant_group = halant_group | h.ZWNJ;
@@ -76,6 +77,7 @@ halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4});
 consonant_syllable =	Repha? (cn.halant_group){0,4} cn A? halant_or_matra_group? syllable_tail;
 vowel_syllable =	reph? V.n? (ZWJ | (halant_group.cn){0,4} halant_or_matra_group? syllable_tail);
 standalone_cluster =	reph? place_holder.n? (halant_group.cn){0,4} halant_or_matra_group? syllable_tail;
+avagraha_cluster = 	Avag.N? (SM.ZWNJ?)? (VD VD?)?;
 broken_cluster =	reph? n? (halant_group.cn){0,4} halant_or_matra_group syllable_tail;
 other =			any;
 
@@ -83,6 +85,7 @@ main := |*
 	consonant_syllable	=> { found_syllable (consonant_syllable); };
 	vowel_syllable		=> { found_syllable (vowel_syllable); };
 	standalone_cluster	=> { found_syllable (standalone_cluster); };
+	avagraha_cluster	=> { found_syllable (avagraha_cluster); };
 	broken_cluster		=> { found_syllable (broken_cluster); };
 	other			=> { found_syllable (non_indic_cluster); };
 *|;
diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh
index 39268b1..552a121 100644
--- a/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/hb-ot-shape-complex-indic-private.hh
@@ -59,7 +59,8 @@ enum indic_category_t {
   OT_Coeng,
   OT_Repha,
   OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
-  OT_CM
+  OT_CM,
+  OT_Avag
 };
 
 /* Visual positions in a syllable from left to right. */
@@ -93,7 +94,7 @@ enum indic_position_t {
 enum indic_syllabic_category_t {
   INDIC_SYLLABIC_CATEGORY_OTHER			= OT_X,
 
-  INDIC_SYLLABIC_CATEGORY_AVAGRAHA		= OT_X,
+  INDIC_SYLLABIC_CATEGORY_AVAGRAHA		= OT_Avag,
   INDIC_SYLLABIC_CATEGORY_BINDU			= OT_SM,
   INDIC_SYLLABIC_CATEGORY_CONSONANT		= OT_C,
   INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD	= OT_C,
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index a624267..00e3c45 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -249,7 +249,7 @@ set_indic_properties (hb_glyph_info_t &info)
   {
     pos = matra_position (u, pos);
   }
-  else if (cat == OT_SM || cat == OT_VD)
+  else if (cat == OT_SM || cat == OT_VD || cat == OT_Avag)
   {
     pos = POS_SMVD;
   }
@@ -584,6 +584,7 @@ enum syllable_type_t {
   consonant_syllable,
   vowel_syllable,
   standalone_cluster,
+  avagraha_cluster,
   broken_cluster,
   non_indic_cluster,
 };
@@ -1082,6 +1083,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
 }
 
 static void
+initial_reordering_avagraha_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+				     hb_face_t *face HB_UNUSED,
+				     hb_buffer_t *buffer HB_UNUSED,
+				     unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+  /* Nothing to do right now.  If we ever switch to using the output
+   * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+static void
 initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
 				      hb_face_t *face HB_UNUSED,
 				      hb_buffer_t *buffer HB_UNUSED,
@@ -1103,6 +1114,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
   case consonant_syllable:	initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
   case vowel_syllable:		initial_reordering_vowel_syllable     (plan, face, buffer, start, end); return;
   case standalone_cluster:	initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
+  case avagraha_cluster:	initial_reordering_avagraha_cluster   (plan, face, buffer, start, end); return;
   case broken_cluster:		initial_reordering_broken_cluster     (plan, face, buffer, start, end); return;
   case non_indic_cluster:	initial_reordering_non_indic_cluster  (plan, face, buffer, start, end); return;
   }
diff --git a/test/shaping/texts/in-tree/shaper-indic/indic/script-devanagari/misc/misc.txt b/test/shaping/texts/in-tree/shaper-indic/indic/script-devanagari/misc/misc.txt
index 83cac77..80bc4a6 100644
--- a/test/shaping/texts/in-tree/shaper-indic/indic/script-devanagari/misc/misc.txt
+++ b/test/shaping/texts/in-tree/shaper-indic/indic/script-devanagari/misc/misc.txt
@@ -30,3 +30,4 @@
 र्अ्‍
 र्आ्र्
 क‌ि
+ऽं
diff --git a/test/shaping/texts/in-tree/shaper-indic/indic/script-telugu/misc/misc.txt b/test/shaping/texts/in-tree/shaper-indic/indic/script-telugu/misc/misc.txt
index 43ff3b9..ff522d2 100644
--- a/test/shaping/texts/in-tree/shaper-indic/indic/script-telugu/misc/misc.txt
+++ b/test/shaping/texts/in-tree/shaper-indic/indic/script-telugu/misc/misc.txt
@@ -9,3 +9,4 @@
 క్ష
 క్ష్
 క్ష్ణ
+ఽం
commit 5e7432b8172473aa4dda3d51a79add9e97c2d2c1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 12:28:23 2013 +0200

    [myanmar] Apply abvm/blwm

diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 29f29bb..17811b5 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -60,6 +60,16 @@ other_features[] =
   HB_TAG('p','s','t','s'),
   /* Positioning features, though we don't care about the types. */
   HB_TAG('d','i','s','t'),
+  /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
+   * features.  The released Windows 8 version of the font (as well
+   * as the released spec) used 'mark' instead.  The Windows 8
+   * shaper however didn't apply 'mark' but did apply 'mkmk'.
+   * Perhaps it applied abvm/blwm.  This was fixed in a Windows 8
+   * update, so now it applies mark/mkmk.  We are guessing that
+   * it still applies abvm/blwm too.
+   */
+  HB_TAG('a','b','v','m'),
+  HB_TAG('b','l','w','m'),
 };
 
 static void
commit 8acbb6be271817c12d2ee0066b355e2fb0f9a934
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 15 12:15:49 2013 +0200

    [indic] Some scripts like blwf applied to pre-base characters
    
    ...while some don't!
    
    Improved Bengali, Devanagari, Gurmukhi, Malayalam.
    
    Updated numbers:
    
    BENGALI: 353732 out of 354188 tests passed. 456 failed (0.128745%)
    DEVANAGARI: 707307 out of 707394 tests passed. 87 failed (0.0122987%)
    GUJARATI: 366349 out of 366457 tests passed. 108 failed (0.0294714%)
    GURMUKHI: 60732 out of 60747 tests passed. 15 failed (0.0246926%)
    KANNADA: 951030 out of 951913 tests passed. 883 failed (0.0927606%)
    KHMER: 299070 out of 299124 tests passed. 54 failed (0.0180527%)
    MALAYALAM: 1048134 out of 1048334 tests passed. 200 failed (0.0190779%)
    ORIYA: 42320 out of 42329 tests passed. 9 failed (0.021262%)
    SINHALA: 271666 out of 271847 tests passed. 181 failed (0.0665816%)
    TAMIL: 1091753 out of 1091754 tests passed. 1 failed (9.15957e-05%)
    TELUGU: 970555 out of 970573 tests passed. 18 failed (0.00185457%)

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index d3c475b..a624267 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -294,6 +294,10 @@ enum reph_mode_t {
   REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
   REPH_MODE_LOG_REPHA  /* Encoded Repha character, needs reordering. */
 };
+enum blwf_mode_t {
+  BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */
+  BLWF_MODE_POST_ONLY     /* Below-forms feature applied to post-base only. */
+};
 struct indic_config_t
 {
   hb_script_t     script;
@@ -302,24 +306,25 @@ struct indic_config_t
   base_position_t base_pos;
   reph_position_t reph_pos;
   reph_mode_t     reph_mode;
+  blwf_mode_t     blwf_mode;
 };
 
 static const indic_config_t indic_configs[] =
 {
   /* Default.  Should be first. */
-  {HB_SCRIPT_INVALID,	false,     0,BASE_POS_LAST, REPH_POS_DEFAULT,    REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_BENGALI,	true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB,  REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_GURMUKHI,	true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_GUJARATI,	true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_ORIYA,	true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_TAMIL,	true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_TELUGU,	true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT},
-  {HB_SCRIPT_KANNADA,	true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
-  {HB_SCRIPT_MALAYALAM,	true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA},
-  {HB_SCRIPT_SINHALA,	false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT},
-  {HB_SCRIPT_KHMER,	false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT,    REPH_MODE_VIS_REPHA},
-  {HB_SCRIPT_JAVANESE,	false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT,    REPH_MODE_IMPLICIT},
+  {HB_SCRIPT_INVALID,	false,     0,BASE_POS_LAST, REPH_POS_DEFAULT,    REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_BENGALI,	true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB,  REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_GURMUKHI,	true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_GUJARATI,	true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_ORIYA,	true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_TAMIL,	true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_TELUGU,	true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY},
+  {HB_SCRIPT_KANNADA,	true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY},
+  {HB_SCRIPT_MALAYALAM,	true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_SINHALA,	false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_KHMER,	false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT,    REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
+  {HB_SCRIPT_JAVANESE,	false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT,    REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST},
 };
 
 
@@ -943,6 +948,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
 
     /* Pre-base */
     mask = indic_plan->mask_array[HALF];
+    if (indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
+      mask |= indic_plan->mask_array[BLWF];
     for (unsigned int i = start; i < base; i++)
       info[i].mask  |= mask;
     /* Base */



More information about the HarfBuzz mailing list