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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Feb 15 09:41:10 PST 2013


 TODO                                                                  |    4 
 src/hb-fallback-shape.cc                                              |    1 
 src/hb-open-type-private.hh                                           |    5 
 src/hb-ot-layout-gsub-table.hh                                        |    4 
 src/hb-ot-layout-gsubgpos-private.hh                                  |    4 
 src/hb-ot-map.cc                                                      |    5 
 src/hb-ot-shape-complex-arabic.cc                                     |   40 +---
 src/hb-ot-shape-complex-myanmar.cc                                    |   36 +--
 src/hb-ot-shape-complex-sea.cc                                        |   37 +--
 src/hb-ot-shape.cc                                                    |   70 +++----
 src/hb-shape-plan.cc                                                  |    8 
 src/hb-shape.cc                                                       |    2 
 test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/MANIFEST  |    1 
 test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/alaph.txt |   98 ++++++++++
 util/options.hh                                                       |    1 
 15 files changed, 190 insertions(+), 126 deletions(-)

New commits:
commit 99fa9ea020f26ed2697f38a7690ee1e1b5d946c4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 11:47:24 2013 -0500

    Minor

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 40ee5f2..065d0f1 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1316,9 +1316,7 @@ struct SubstLookup : Lookup
     {
       /* The spec says all subtables of an Extension lookup should
        * have the same type.  This is specially important if one has
-       * a reverse type!
-       *
-       * We just check that they are all either forward, or reverse. */
+       * a reverse type! */
       unsigned int type = get_subtable (0).u.extension.get_type ();
       unsigned int count = get_subtable_count ();
       for (unsigned int i = 1; i < count; i++)
commit 27589620ba2dcf356fd7fa21cd80221a07803202
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 11:47:09 2013 -0500

    [OTLayout] Remove unused code

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 90f2836..090f3fc 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -684,11 +684,6 @@ struct GenericOffsetTo : OffsetType
     if (unlikely (!offset)) return Null(Type);
     return StructAtOffset<Type> (base, offset);
   }
-  inline Type& operator () (void *base)
-  {
-    unsigned int offset = *this;
-    return StructAtOffset<Type> (base, offset);
-  }
 
   inline Type& serialize (hb_serialize_context_t *c, void *base)
   {
commit ebb77b9c5e357ff7c9badb0f4bf1c3a965c3e91d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 09:33:10 2013 -0500

    Remove TODO items that don't make sense
    
    The spec says those features need to be disabled by default.

diff --git a/TODO b/TODO
index c7a72de..31b44b8 100644
--- a/TODO
+++ b/TODO
@@ -18,8 +18,6 @@ General fixes:
 
 - Misc features:
   * init/medi/fina/isol for non-cursive scripts
-  * vkna,hkna etc for kana, etc
-  * smpl,trad for ZHS / ZHT
 
 
 API issues to fix before 1.0:
commit c2a1cdc4c4cc51f4680ebc4ec2c462cb660f9492
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 09:27:02 2013 -0500

    [Arabic] Fix shaping of left-joining 'Phags-Pa U+A872
    
    This is the first character in Unicode to have Arabic left-joining
    behavior.  Update the machine to recognize that.
    
    Test case: U+A840,U+A872,U+A840.

diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 3a69f06..18b3d02 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -37,17 +37,16 @@
  */
 enum {
   JOINING_TYPE_U		= 0,
-  JOINING_TYPE_R		= 1,
-  JOINING_TYPE_D		= 2,
+  JOINING_TYPE_L		= 1,
+  JOINING_TYPE_R		= 2,
+  JOINING_TYPE_D		= 3,
   JOINING_TYPE_C		= JOINING_TYPE_D,
-  JOINING_GROUP_ALAPH		= 3,
-  JOINING_GROUP_DALATH_RISH	= 4,
-  NUM_STATE_MACHINE_COLS	= 5,
+  JOINING_GROUP_ALAPH		= 4,
+  JOINING_GROUP_DALATH_RISH	= 5,
+  NUM_STATE_MACHINE_COLS	= 6,
 
-  /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */
-
-  JOINING_TYPE_T = 6,
-  JOINING_TYPE_X = 7  /* means: use general-category to choose between U or T. */
+  JOINING_TYPE_T = 7,
+  JOINING_TYPE_X = 8  /* means: use general-category to choose between U or T. */
 };
 
 /*
@@ -81,8 +80,7 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
   if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872)))
   {
       if (unlikely (u == 0xA872))
-	/* XXX Looks like this should be TYPE_L, but we don't support that yet! */
-	return JOINING_TYPE_R;
+	return JOINING_TYPE_L;
 
       return JOINING_TYPE_D;
   }
@@ -133,28 +131,28 @@ static const struct arabic_state_table_entry {
 	uint16_t next_state;
 } arabic_state_table[][NUM_STATE_MACHINE_COLS] =
 {
-  /*   jt_U,          jt_R,          jt_D,          jg_ALAPH,      jg_DALATH_RISH */
+  /*   jt_U,          jt_L,          jt_R,          jt_D,          jg_ALAPH,      jg_DALATH_RISH */
 
   /* State 0: prev was U, not willing to join. */
-  { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
 
   /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
-  { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
 
-  /* State 2: prev was D/ISOL, willing to join. */
-  { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
+  /* State 2: prev was D/L in ISOL form, willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
 
-  /* State 3: prev was D/FINA, willing to join. */
-  { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
+  /* State 3: prev was D in FINA form, willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
 
   /* State 4: prev was FINA ALAPH, not willing to join. */
-  { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
 
   /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
-  { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
 
   /* State 6: prev was DALATH/RISH, not willing to join. */
-  { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
 };
 
 
commit 05ac87813d17d9ebbfa315eee3f80f25b53135c5
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 09:26:41 2013 -0500

    [tests] Add Syriac Alaph shaping test cases

diff --git a/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/MANIFEST b/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/MANIFEST
index e69de29..ae45bdf 100644
--- a/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/MANIFEST
+++ b/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/MANIFEST
@@ -0,0 +1 @@
+alaph.txt
diff --git a/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/alaph.txt b/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/alaph.txt
new file mode 100644
index 0000000..27b035f
--- /dev/null
+++ b/test/shaping/texts/in-tree/shaper-arabic/script-syriac/misc/alaph.txt
@@ -0,0 +1,98 @@
+ ܐ
+ ܐܘ
+ ܐܪ
+ ܐܖ
+ ܐܕ
+ ܐܯ
+ ܐܒ
+ܘܐ
+ܘܐܘ
+ܘܐܪ
+ܘܐܖ
+ܘܐܕ
+ܘܐܯ
+ܘܐܒ
+ܪܐ
+ܪܐܘ
+ܪܐܪ
+ܪܐܖ
+ܪܐܕ
+ܪܐܯ
+ܪܐܒ
+ܖܐ
+ܖܐܘ
+ܖܐܪ
+ܖܐܖ
+ܖܐܕ
+ܖܐܯ
+ܖܐܒ
+ܕܐ
+ܕܐܘ
+ܕܐܪ
+ܕܐܖ
+ܕܐܕ
+ܕܐܯ
+ܕܐܒ
+ܯܐ
+ܯܐܘ
+ܯܐܪ
+ܯܐܖ
+ܯܐܕ
+ܯܐܯ
+ܯܐܒ
+ܒܐ
+ܒܐܘ
+ܒܐܪ
+ܒܐܖ
+ܒܐܕ
+ܒܐܯ
+ܒܐܒ
+ ܐܐ
+ ܐܐܘ
+ ܐܐܪ
+ ܐܐܖ
+ ܐܐܕ
+ ܐܐܯ
+ ܐܐܒ
+ܘܐܐ
+ܘܐܐܘ
+ܘܐܐܪ
+ܘܐܐܖ
+ܘܐܐܕ
+ܘܐܐܯ
+ܘܐܐܒ
+ܪܐܐ
+ܪܐܐܘ
+ܪܐܐܪ
+ܪܐܐܖ
+ܪܐܐܕ
+ܪܐܐܯ
+ܪܐܐܒ
+ܖܐܐ
+ܖܐܐܘ
+ܖܐܐܪ
+ܖܐܐܖ
+ܖܐܐܕ
+ܖܐܐܯ
+ܖܐܐܒ
+ܕܐܐ
+ܕܐܐܘ
+ܕܐܐܪ
+ܕܐܐܖ
+ܕܐܐܕ
+ܕܐܐܯ
+ܕܐܐܒ
+ܯܐܐ
+ܯܐܐܘ
+ܯܐܐܪ
+ܯܐܐܖ
+ܯܐܐܕ
+ܯܐܐܯ
+ܯܐܐܒ
+ܒܐܐ
+ܒܐܐܘ
+ܒܐܐܪ
+ܒܐܐܖ
+ܒܐܐܕ
+ܒܐܐܯ
+ܒܐܐܒ
commit c462b32dcb883a7aca066af24c4d28c7a2b7fa28
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 07:51:47 2013 -0500

    Disable automatic segment properties guessing
    
    Before, if one called hb_shape() without setting script, language, and
    direction on the buffer, hb_shape() was calling
    hb_buffer_guess_segment_properties() on the user's behalf to guess
    these.
    
    This is very dangerous, since any serious user of HarfBuzz must set
    these properly (specially important is direction).  So now, we don't
    guess properties by default.  People not setting direction will get
    an abort() now.  If the old behavior is desired (fragile, good for
    simple testing only), users can call
    hb_buffer_guess_segment_properties() on the buffer just before calling
    hb_shape().

diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index bdc8a80..1a1fcfb 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -98,7 +98,6 @@ _hb_fallback_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
   hb_codepoint_t space;
   font->get_glyph (' ', 0, &space);
 
-  buffer->guess_segment_properties ();
   buffer->clear_positions ();
 
   unsigned int count = buffer->len;
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 66d51e3..32d7afc 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -663,8 +663,6 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
 {
   hb_ot_shape_plan_t plan;
 
-  buffer->guess_segment_properties ();
-
   const char *shapers[] = {"ot", NULL};
   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
 							     features, num_features, shapers);
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 7ae56e3..7d748d7 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -255,8 +255,6 @@ hb_shape_full (hb_font_t          *font,
 
   assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
 
-  buffer->guess_segment_properties ();
-
   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
   hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
   hb_shape_plan_destroy (shape_plan);
diff --git a/util/options.hh b/util/options.hh
index 8944067..35ea0bc 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -170,6 +170,7 @@ struct shape_options_t : option_group_t
 			 (bot ? HB_BUFFER_FLAG_BOT : 0) |
 			 (eot ? HB_BUFFER_FLAG_EOT : 0) |
 			 (preserve_default_ignorables ? HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES : 0)));
+    hb_buffer_guess_segment_properties (buffer);
   }
 
   void populate_buffer (hb_buffer_t *buffer, const char *text, int text_len,
commit 7abddbb47a489aaac8e76ac6e700cd815739b1d2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 07:46:57 2013 -0500

    Add assertions for a couple programmer errors

diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 22a226f..a6d2d26 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -27,6 +27,7 @@
 #include "hb-shape-plan-private.hh"
 #include "hb-shaper-private.hh"
 #include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
 
 #define HB_SHAPER_IMPLEMENT(shaper) \
 	HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
@@ -178,9 +179,14 @@ hb_shape_plan_execute (hb_shape_plan_t    *shape_plan,
 		       const hb_feature_t *features,
 		       unsigned int        num_features)
 {
-  if (unlikely (shape_plan->face != font->face))
+  if (unlikely (hb_object_is_inert (shape_plan) ||
+		hb_object_is_inert (font) ||
+		hb_object_is_inert (buffer)))
     return false;
 
+  assert (shape_plan->face == font->face);
+  assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
+
 #define HB_SHAPER_EXECUTE(shaper) \
 	HB_STMT_START { \
 	  return HB_SHAPER_DATA (shaper, shape_plan) && \
commit 038c98f6866fe1177b04bd2ae3bb461b2f0fd1ed
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 07:41:07 2013 -0500

    Allow disabling of TrueType kerning
    
    Responds to the same feature tag that GPOS kerning does:
    'kern' for horizontal and 'vkrn' for vertical.

diff --git a/TODO b/TODO
index c93b33e..c7a72de 100644
--- a/TODO
+++ b/TODO
@@ -7,8 +7,6 @@ General fixes:
 
 - Disable 'vert' if 'vrt2' is available (eg. Motoya fonts with arrow chars).
 
-- Fix TT 'kern' on/off and GPOS interaction (move kerning before GPOS).
-
 - Implement 'rand' feature.
 
 - mask propagation? (when ligation, "or" the masks).
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 6882de1..66d51e3 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -105,10 +105,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
 
   if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
     for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
-      map->add_global_bool_feature (horizontal_features[i]);
+      map->add_feature (horizontal_features[i], 1, F_GLOBAL |
+			(horizontal_features[i] == HB_TAG('k','e','r','n') ?
+			 F_HAS_FALLBACK : F_NONE));
   else
     for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++)
-      map->add_global_bool_feature (vertical_features[i]);
+      map->add_feature (vertical_features[i], 1, F_GLOBAL |
+			(vertical_features[i] == HB_TAG('v','k','r','n') ?
+			 F_HAS_FALLBACK : F_NONE));
 
   if (planner->shaper->override_features)
     planner->shaper->override_features (planner);
@@ -491,25 +495,36 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 static inline void
 hb_ot_truetype_kern (hb_ot_shape_context_t *c)
 {
-  /* TODO Check for kern=0 */
   unsigned int count = c->buffer->len;
-  for (unsigned int i = 1; i < count; i++) {
-    hb_position_t x_kern, y_kern, kern1, kern2;
-    c->font->get_glyph_kerning_for_direction (c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
-					      c->buffer->props.direction,
-					      &x_kern, &y_kern);
-
-    kern1 = x_kern >> 1;
-    kern2 = x_kern - kern1;
-    c->buffer->pos[i - 1].x_advance += kern1;
-    c->buffer->pos[i].x_advance += kern2;
-    c->buffer->pos[i].x_offset += kern2;
-
-    kern1 = y_kern >> 1;
-    kern2 = y_kern - kern1;
-    c->buffer->pos[i - 1].y_advance += kern1;
-    c->buffer->pos[i].y_advance += kern2;
-    c->buffer->pos[i].y_offset += kern2;
+  hb_mask_t kern_mask = c->plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) ?
+						 HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+
+  if (unlikely (!count)) return;
+
+  bool enabled = c->buffer->info[0].mask & kern_mask;
+  for (unsigned int i = 1; i < count; i++)
+  {
+    bool next = c->buffer->info[i].mask & kern_mask;
+    if (enabled && next)
+    {
+      hb_position_t x_kern, y_kern, kern1, kern2;
+      c->font->get_glyph_kerning_for_direction (c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
+						c->buffer->props.direction,
+						&x_kern, &y_kern);
+
+      kern1 = x_kern >> 1;
+      kern2 = x_kern - kern1;
+      c->buffer->pos[i - 1].x_advance += kern1;
+      c->buffer->pos[i].x_advance += kern2;
+      c->buffer->pos[i].x_offset += kern2;
+
+      kern1 = y_kern >> 1;
+      kern2 = y_kern - kern1;
+      c->buffer->pos[i - 1].y_advance += kern1;
+      c->buffer->pos[i].y_advance += kern2;
+      c->buffer->pos[i].y_offset += kern2;
+    }
+    enabled = next;
   }
 }
 
commit 398238a2526d322eb79e255c24634a275473920f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 07:40:10 2013 -0500

    Fix partial disabling of default-on features
    
    Surprisingly, if user ever tried to turn a default feature off partially
    (say, disable liga for a range), the feature was being turned off
    globally!  Fixed now.

diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index 2fbb6ce..28a43a4 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -194,11 +194,11 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
 	} else {
 	  feature_infos[j].flags &= ~F_GLOBAL;
 	  feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
+	  /* Inherit default_value from j */
 	}
 	feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
 	feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
 	feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
-	/* Inherit default_value from j */
       }
     feature_infos.shrink (j + 1);
   }
@@ -252,8 +252,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
       map->shift = next_bit;
       map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
       next_bit += bits_needed;
-      if ((info->flags & F_GLOBAL))
-	m.global_mask |= (info->default_value << map->shift) & map->mask;
+      m.global_mask |= (info->default_value << map->shift) & map->mask;
     }
     map->_1_mask = (1 << map->shift) & map->mask;
     map->needs_fallback = !found;
commit cb90b1bbe6d27ca6968b70d2dbfea7ab7fb73293
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 07:02:08 2013 -0500

    [OTLayout] Respect syllable boundaries for backtrack/lookahead matching
    
    Originally we meant to match backtrack/lookahead across syllable
    boundaries.  But a bug in the code meant that this was NOT done for
    backtrack.  We "fixed" that in 2c7d0b6b80d412de3fddd443ed1a485ea1cbb03c,
    but that broke Myanmar shaping.
    
    We now believe that for Indic-like shapers (which is where syllables are
    used), all basic shaping forms should be fully contained within their
    syllables, so now we limit backtrack/lookahead matching to the syllable
    too.  Unbreaks Myanmar.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index a709c32..a15dd23 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -381,8 +381,8 @@ struct hb_apply_context_t
       if (!context_match)
       {
 	matcher.set_mask (c->lookup_mask);
-	matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
       }
+      matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
     }
     inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
     inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
@@ -454,8 +454,8 @@ struct hb_apply_context_t
       if (!context_match)
       {
 	matcher.set_mask (c->lookup_mask);
-	matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
       }
+      matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
     }
     inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
     inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
commit ee9c3a17d0bf263c5eee479fd778db97cff8e189
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Feb 15 06:22:26 2013 -0500

    Minor refactoring

diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index e766973..8491047 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -36,7 +36,7 @@
  */
 
 static const hb_tag_t
-myanmar_features[] =
+basic_features[] =
 {
   /*
    * Basic features.
@@ -46,6 +46,10 @@ myanmar_features[] =
   HB_TAG('p','r','e','f'),
   HB_TAG('b','l','w','f'),
   HB_TAG('p','s','t','f'),
+};
+static const hb_tag_t
+other_features[] =
+{
   /*
    * Other features.
    * These features are applied all at once, after final_reordering.
@@ -58,25 +62,6 @@ myanmar_features[] =
   HB_TAG('d','i','s','t'),
 };
 
-/*
- * Must be in the same order as the myanmar_features array.
- */
-enum {
-  _RPHF,
-  _PREF,
-  _BLWF,
-  _PSTF,
-
-  _PRES,
-  _ABVS,
-  _BLWS,
-  _PSTS,
-  _DIST,
-
-  MYANMAR_NUM_FEATURES,
-  MYANMAR_BASIC_FEATURES = _PRES /* Don't forget to update this! */
-};
-
 static void
 setup_syllables (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
@@ -104,16 +89,15 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
   map->add_global_bool_feature (HB_TAG('c','c','m','p'));
 
 
-  unsigned int i = 0;
   map->add_gsub_pause (initial_reordering);
-  for (; i < MYANMAR_BASIC_FEATURES; i++) {
-    map->add_feature (myanmar_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+  {
+    map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
     map->add_gsub_pause (NULL);
   }
   map->add_gsub_pause (final_reordering);
-  for (; i < MYANMAR_NUM_FEATURES; i++) {
-    map->add_feature (myanmar_features[i], 1, F_GLOBAL);
-  }
+  for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+    map->add_feature (other_features[i], 1, F_GLOBAL);
 }
 
 static void
diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc
index c06612e..e1debd8 100644
--- a/src/hb-ot-shape-complex-sea.cc
+++ b/src/hb-ot-shape-complex-sea.cc
@@ -38,7 +38,7 @@
  */
 
 static const hb_tag_t
-sea_features[] =
+basic_features[] =
 {
   /*
    * Basic features.
@@ -48,6 +48,10 @@ sea_features[] =
   HB_TAG('a','b','v','f'),
   HB_TAG('b','l','w','f'),
   HB_TAG('p','s','t','f'),
+};
+static const hb_tag_t
+other_features[] =
+{
   /*
    * Other features.
    * These features are applied all at once, after final_reordering.
@@ -60,25 +64,6 @@ sea_features[] =
   HB_TAG('d','i','s','t'),
 };
 
-/*
- * Must be in the same order as the sea_features array.
- */
-enum {
-  _PREF,
-  _ABVF,
-  _BLWF,
-  _PSTF,
-
-  _PRES,
-  _ABVS,
-  _BLWS,
-  _PSTS,
-  _DIST,
-
-  SEA_NUM_FEATURES,
-  SEA_BASIC_FEATURES = _PRES /* Don't forget to update this! */
-};
-
 static void
 setup_syllables (const hb_ot_shape_plan_t *plan,
 		 hb_font_t *font,
@@ -105,17 +90,15 @@ collect_features_sea (hb_ot_shape_planner_t *plan)
    * there is a use of it, it's typically at the beginning. */
   map->add_global_bool_feature (HB_TAG('c','c','m','p'));
 
-
-  unsigned int i = 0;
   map->add_gsub_pause (initial_reordering);
-  for (; i < SEA_BASIC_FEATURES; i++) {
-    map->add_feature (sea_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+  {
+    map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
     map->add_gsub_pause (NULL);
   }
   map->add_gsub_pause (final_reordering);
-  for (; i < SEA_NUM_FEATURES; i++) {
-    map->add_feature (sea_features[i], 1, F_GLOBAL | F_MANUAL_JOINERS);
-  }
+  for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+    map->add_feature (other_features[i], 1, F_GLOBAL);
 }
 
 static void
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 2d78a18..6882de1 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -97,27 +97,22 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       break;
   }
 
-#define ADD_FEATURES(array) \
-  HB_STMT_START { \
-    for (unsigned int i = 0; i < ARRAY_LENGTH (array); i++) \
-      map->add_global_bool_feature (array[i]); \
-  } HB_STMT_END
-
   if (planner->shaper->collect_features)
     planner->shaper->collect_features (planner);
 
-  ADD_FEATURES (common_features);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
+    map->add_global_bool_feature (common_features[i]);
 
   if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
-    ADD_FEATURES (horizontal_features);
+    for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
+      map->add_global_bool_feature (horizontal_features[i]);
   else
-    ADD_FEATURES (vertical_features);
+    for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++)
+      map->add_global_bool_feature (vertical_features[i]);
 
   if (planner->shaper->override_features)
     planner->shaper->override_features (planner);
 
-#undef ADD_FEATURES
-
   for (unsigned int i = 0; i < num_user_features; i++) {
     const hb_feature_t *feature = &user_features[i];
     map->add_feature (feature->tag, feature->value,



More information about the HarfBuzz mailing list