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

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Sep 5 12:22:57 PDT 2012


 src/hb-open-type-private.hh        |   60 ++++++++++-
 src/hb-ot-layout-common-private.hh |   28 ++++-
 src/hb-ot-layout-gpos-table.hh     |    2 
 src/hb-ot-layout-gsub-table.hh     |  196 +++++++++++++++++++++++++++++++------
 src/hb-ot-map-private.hh           |    7 -
 src/hb-ot-map.cc                   |    6 -
 src/hb-ot-shape-complex-indic.cc   |   10 -
 7 files changed, 258 insertions(+), 51 deletions(-)

New commits:
commit 27bd55bd2ca599d501f10c2fae81861137517e46
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Sep 5 15:11:14 2012 -0400

    [Indic] Tamil does not have half-forms either
    
    The Win7 Tamil font does not realy on this behavior, but the WinXP
    version does.  Handle Tamil like Malayalam: Matras always move to
    before base.
    
    WinXP Tamil failures went down from 168964 (15.4752%) to 167
    (0.0152953%) (two orders of magnitude reduction!).
    
    Included in this is a minor fixup that actually fixed a few tests
    with non-Tamil too.  Numbers at:
    
    BENGALI: 353997 out of 354285 tests passed. 288 failed (0.0812905%)
    DEVANAGARI: 707339 out of 707394 tests passed. 55 failed (0.00777502%)
    GUJARATI: 366489 out of 366506 tests passed. 17 failed (0.0046384%)
    GURMUKHI: 60769 out of 60809 tests passed. 40 failed (0.0657797%)
    KANNADA: 951086 out of 951913 tests passed. 827 failed (0.0868777%)
    KHMER: 299106 out of 299124 tests passed. 18 failed (0.00601757%)
    LAO: 53611 out of 53644 tests passed. 33 failed (0.0615167%)
    MALAYALAM: 1048104 out of 1048416 tests passed. 312 failed (0.0297592%)
    ORIYA: 42320 out of 42329 tests passed. 9 failed (0.021262%)
    SINHALA: 271747 out of 271847 tests passed. 100 failed (0.0367854%)
    TAMIL: 1091837 out of 1091837 tests passed. 0 failed (0%)
    TELUGU: 970558 out of 970573 tests passed. 15 failed (0.00154548%)
    TIBETAN: 208469 out of 208469 tests passed. 0 failed (0%)

diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 2417ab7..7f6b79a 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -917,11 +917,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
     /* If we lost track of base, alas, position before last thingy. */
     unsigned int new_pos = base == end ? base - 2 : base - 1;
 
-    /* Malayalam does not have "half" forms or explicit virama forms.
-     * The glyphs formed by 'half' are Chillus.  We want to position
-     * matra after them all.
+    /* Malayalam / Tamil do not have "half" forms or explicit virama forms.
+     * The glyphs formed by 'half' are Chillus or ligated explicit viramas.
+     * We want to position matra after them.
      */
-    if (buffer->props.script != HB_SCRIPT_MALAYALAM)
+    if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
     {
       while (new_pos > start &&
 	     !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H) | FLAG (OT_Coeng)))))
@@ -941,7 +941,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
         new_pos = start; /* No move. */
     }
 
-    if (start < new_pos)
+    if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M)
     {
       /* Now go see if there's actually any matras... */
       for (unsigned int i = new_pos; i > start; i--)
commit 87b75d0a4aa03fe7a03e3bf7baf8ece131aec1bb
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 23:06:38 2012 -0400

    [OT] Allow adding features with fallback implementation

diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index b9c6736..22ea8ba 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -147,10 +147,10 @@ struct hb_ot_map_builder_t
 
   hb_ot_map_builder_t (void) { memset (this, 0, sizeof (*this)); }
 
-  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global);
+  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback = false);
 
-  inline void add_bool_feature (hb_tag_t tag, bool global = true)
-  { add_feature (tag, 1, global); }
+  inline void add_bool_feature (hb_tag_t tag, bool global = true, bool has_fallback = false)
+  { add_feature (tag, 1, global, has_fallback); }
 
   inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
   { add_pause (0, pause_func); }
@@ -174,6 +174,7 @@ struct hb_ot_map_builder_t
     unsigned int seq; /* sequence#, used for stable sorting only */
     unsigned int max_value;
     bool global; /* whether the feature applies value to every glyph in the buffer */
+    bool has_fallback; /* whether to allocate bits even if feature not found */
     unsigned int default_value; /* for non-global features, what should the unset glyphs take */
     unsigned int stage[2]; /* GSUB/GPOS */
 
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index b8b2dbe..aae4d03 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -60,7 +60,7 @@ hb_ot_map_t::add_lookups (hb_face_t    *face,
 }
 
 
-void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global)
+void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback)
 {
   feature_info_t *info = feature_infos.push();
   if (unlikely (!info)) return;
@@ -68,6 +68,7 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool gl
   info->seq = feature_infos.len;
   info->max_value = value;
   info->global = global;
+  info->has_fallback = has_fallback;
   info->default_value = global ? value : 0;
   info->stage[0] = current_stage[0];
   info->stage[1] = current_stage[1];
@@ -175,6 +176,7 @@ hb_ot_map_builder_t::compile (hb_face_t *face,
 	  feature_infos[j].global = false;
 	  feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
 	}
+	feature_infos[j].has_fallback = feature_infos[j].has_fallback || feature_infos[i].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 */
@@ -209,7 +211,7 @@ hb_ot_map_builder_t::compile (hb_face_t *face,
 						   language_index[table_index],
 						   info->tag,
 						   &feature_index[table_index]);
-    if (!found)
+    if (!found && !info->has_fallback)
       continue;
 
 
commit 1d3947a6bda6986c9c7d993589053051c119cc81
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 22:42:17 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 92aa94c..41cb93d 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1535,7 +1535,7 @@ struct PosLookup : Lookup
   {
     bool ret = false;
 
-    if (unlikely (!c->buffer->len))
+    if (unlikely (!c->buffer->len || !c->lookup_mask))
       return false;
 
     c->set_lookup (*this);
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index cbea46d..bbd7214 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1316,7 +1316,7 @@ struct SubstLookup : Lookup
   {
     bool ret = false;
 
-    if (unlikely (!c->buffer->len))
+    if (unlikely (!c->buffer->len || !c->lookup_mask))
       return false;
 
     c->set_lookup (*this);
commit b3b89b66586897a69b410ef02e7434691de84ae6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 21:13:17 2012 -0400

    [OT] Add SubstLookup serialize API

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index dcd4ed1..5c51ee5 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -323,7 +323,7 @@ struct Lookup
     lookupType.set (lookup_type);
     lookupFlag.set (lookup_props & 0xFFFF);
     if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false);
-    if ((lookup_props >> 16) || lookupFlag & LookupFlag::UseMarkFilteringSet)
+    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
       markFilteringSet.set (lookup_props >> 16);
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index c4245ce..cbea46d 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -168,6 +168,7 @@ struct SingleSubstFormat2
 struct SingleSubst
 {
   friend struct SubstLookupSubTable;
+  friend struct SubstLookup;
 
   private:
 
@@ -368,6 +369,7 @@ struct MultipleSubstFormat1
 struct MultipleSubst
 {
   friend struct SubstLookupSubTable;
+  friend struct SubstLookup;
 
   private:
 
@@ -524,6 +526,7 @@ struct AlternateSubstFormat1
 struct AlternateSubst
 {
   friend struct SubstLookupSubTable;
+  friend struct SubstLookup;
 
   private:
 
@@ -827,6 +830,7 @@ struct LigatureSubstFormat1
 struct LigatureSubst
 {
   friend struct SubstLookupSubTable;
+  friend struct SubstLookup;
 
   private:
 
@@ -1355,7 +1359,66 @@ struct SubstLookup : Lookup
     return ret;
   }
 
-  inline bool sanitize (hb_sanitize_context_t *c) {
+  private:
+  inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
+						  unsigned int i)
+  { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); }
+  public:
+
+  inline bool serialize_single (hb_serialize_context_t *c,
+				uint32_t lookup_props,
+			        Supplier<GlyphID> &glyphs,
+			        Supplier<GlyphID> &substitutes,
+			        unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
+  }
+
+  inline bool serialize_multiple (hb_serialize_context_t *c,
+				  uint32_t lookup_props,
+				  Supplier<GlyphID> &glyphs,
+				  Supplier<unsigned int> &substitute_len_list,
+				  unsigned int num_glyphs,
+				  Supplier<GlyphID> &substitute_glyphs_list)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs,
+									 substitute_glyphs_list));
+  }
+
+  inline bool serialize_alternate (hb_serialize_context_t *c,
+				   uint32_t lookup_props,
+				   Supplier<GlyphID> &glyphs,
+				   Supplier<unsigned int> &alternate_len_list,
+				   unsigned int num_glyphs,
+				   Supplier<GlyphID> &alternate_glyphs_list)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs,
+									  alternate_glyphs_list));
+  }
+
+  inline bool serialize_ligature (hb_serialize_context_t *c,
+				  uint32_t lookup_props,
+				  Supplier<GlyphID> &first_glyphs,
+				  Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+				  unsigned int num_first_glyphs,
+				  Supplier<GlyphID> &ligatures_list,
+				  Supplier<unsigned int> &component_count_list,
+				  Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false);
+    return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
+									 ligatures_list, component_count_list, component_list));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c)
+  {
     TRACE_SANITIZE ();
     if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
     OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
commit 715e03bc21d6adaa8e1f647235843839dc47dad1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 20:10:17 2012 -0400

    Minor

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 152105b..c273a97 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -725,11 +725,8 @@ struct GenericArrayOf
 			 unsigned int items_len)
   {
     TRACE_SERIALIZE ();
-    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
-    len.set (items_len); /* TODO(serialize) Overflow? */
-    if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
-    unsigned int count = items_len;
-    for (unsigned int i = 0; i < count; i++)
+    if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false);
+    for (unsigned int i = 0; i < items_len; i++)
       array[i].set (items[i]);
     items.advance (items_len);
     return TRACE_RETURN (true);
commit 652d1e0d64e47313ead2fc8318d1236f0e0d80ca
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 20:00:44 2012 -0400

    [OT] Start adding Lookup-level serialize API

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index a0b8b52..dcd4ed1 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -313,11 +313,29 @@ struct Lookup
     return flag;
   }
 
+  inline bool serialize (hb_serialize_context_t *c,
+			 unsigned int lookup_type,
+			 uint32_t lookup_props,
+			 unsigned int num_subtables)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    lookupType.set (lookup_type);
+    lookupFlag.set (lookup_props & 0xFFFF);
+    if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false);
+    if ((lookup_props >> 16) || lookupFlag & LookupFlag::UseMarkFilteringSet)
+    {
+      USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+      markFilteringSet.set (lookup_props >> 16);
+    }
+    return TRACE_RETURN (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
     if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
-    if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet))
+    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
       if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
commit a930c68e9c50aade78c1eb0eef075c9c117e4ef6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 18:17:57 2012 -0400

    [OT] More serialize.  Implements all basic GSUB subtables

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 384cdb7..152105b 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -428,6 +428,40 @@ struct hb_serialize_context_t
   bool ran_out_of_room;
 };
 
+template <typename Type>
+struct Supplier
+{
+  /* For automatic wrapping of bare arrays */
+  inline Supplier (const Type *array)
+  {
+    head = array;
+    len = (unsigned int) -1;
+  }
+
+  inline Supplier (const Type *array, unsigned int len_)
+  {
+    head = array;
+    len = len_;
+  }
+  inline const Type operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len)) return Type ();
+    return head[i];
+  }
+
+  inline void advance (unsigned int count) {
+    if (unlikely (count > len))
+      count = len;
+    len -= count;
+    head += count;
+  }
+
+  private:
+  unsigned int len;
+  const Type *head;
+};
+
+
 
 
 /*
@@ -687,7 +721,7 @@ struct GenericArrayOf
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const Type *items,
+			 Supplier<Type> &items,
 			 unsigned int items_len)
   {
     TRACE_SERIALIZE ();
@@ -697,6 +731,7 @@ struct GenericArrayOf
     unsigned int count = items_len;
     for (unsigned int i = 0; i < count; i++)
       array[i].set (items[i]);
+    items.advance (items_len);
     return TRACE_RETURN (true);
   }
 
@@ -803,6 +838,22 @@ struct HeadlessArrayOf
   inline unsigned int get_size (void) const
   { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
 
+  inline bool serialize (hb_serialize_context_t *c,
+			 Supplier<Type> &items,
+			 unsigned int items_len)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    len.set (items_len); /* TODO(serialize) Overflow? */
+    if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
+    if (unlikely (!items_len)) return TRACE_RETURN (true);
+    unsigned int count = items_len;
+    for (unsigned int i = 1; i < count; i++)
+      array[i-1].set (items[i]);
+    items.advance (items_len - 1);
+    return TRACE_RETURN (true);
+  }
+
   inline bool sanitize_shallow (hb_sanitize_context_t *c) {
     return c->check_struct (this)
 	&& c->check_array (this, Type::static_size, len);
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 6c5e423..a0b8b52 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -356,7 +356,7 @@ struct CoverageFormat1
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
+			 Supplier<GlyphID> &glyphs,
 			 unsigned int num_glyphs)
   {
     TRACE_SERIALIZE ();
@@ -365,6 +365,7 @@ struct CoverageFormat1
     if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false);
     for (unsigned int i = 0; i < num_glyphs; i++)
       glyphArray[i].set (glyphs[i]);
+    glyphs.advance (num_glyphs);
     return TRACE_RETURN (true);
   }
 
@@ -420,7 +421,7 @@ struct CoverageFormat2
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
+			 Supplier<GlyphID> &glyphs,
 			 unsigned int num_glyphs)
   {
     TRACE_SERIALIZE ();
@@ -446,6 +447,7 @@ struct CoverageFormat2
       } else {
         rangeRecord[range].end = glyphs[i];
       }
+    glyphs.advance (num_glyphs);
     return TRACE_RETURN (true);
   }
 
@@ -526,7 +528,7 @@ struct Coverage
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
+			 Supplier<GlyphID> &glyphs,
 			 unsigned int num_glyphs)
   {
     TRACE_SERIALIZE ();
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 2ab54e4..c4245ce 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -73,7 +73,7 @@ struct SingleSubstFormat1
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
+			 Supplier<GlyphID> &glyphs,
 			 unsigned int num_glyphs,
 			 int delta)
   {
@@ -137,8 +137,8 @@ struct SingleSubstFormat2
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
-			 const USHORT *substitutes,
+			 Supplier<GlyphID> &glyphs,
+			 Supplier<GlyphID> &substitutes,
 			 unsigned int num_glyphs)
   {
     TRACE_SERIALIZE ();
@@ -201,8 +201,8 @@ struct SingleSubst
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
-			 const USHORT *substitutes,
+			 Supplier<GlyphID> &glyphs,
+			 Supplier<GlyphID> &substitutes,
 			 unsigned int num_glyphs)
   {
     TRACE_SERIALIZE ();
@@ -277,7 +277,7 @@ struct Sequence
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
+			 Supplier<GlyphID> &glyphs,
 			 unsigned int num_glyphs)
   {
     TRACE_SERIALIZE ();
@@ -331,19 +331,20 @@ struct MultipleSubstFormat1
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
-			 unsigned int *substitute_len_list,
+			 Supplier<GlyphID> &glyphs,
+			 Supplier<unsigned int> &substitute_len_list,
 			 unsigned int num_glyphs,
-			 const USHORT *substitute_glyphs_list)
+			 Supplier<GlyphID> &substitute_glyphs_list)
   {
     TRACE_SERIALIZE ();
     if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
     if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false);
-    for (unsigned int i = 0; i < num_glyphs; i++) {
-      if (unlikely (!sequence[i].serialize (c, this).serialize (c, substitute_glyphs_list, substitute_len_list[i]))) return TRACE_RETURN (false);
-      substitute_glyphs_list += substitute_len_list[i];
-    }
+    for (unsigned int i = 0; i < num_glyphs; i++)
+      if (unlikely (!sequence[i].serialize (c, this).serialize (c,
+								substitute_glyphs_list,
+								substitute_len_list[i]))) return TRACE_RETURN (false);
+    substitute_len_list.advance (num_glyphs);
     return TRACE_RETURN (true);
   }
 
@@ -397,10 +398,10 @@ struct MultipleSubst
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
-			 unsigned int *substitute_len_list,
+			 Supplier<GlyphID> &glyphs,
+			 Supplier<unsigned int> &substitute_len_list,
 			 unsigned int num_glyphs,
-			 const USHORT *substitute_glyphs_list)
+			 Supplier<GlyphID> &substitute_glyphs_list)
   {
     TRACE_SERIALIZE ();
     if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
@@ -486,19 +487,20 @@ struct AlternateSubstFormat1
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
-			 unsigned int *alternate_len_list,
+			 Supplier<GlyphID> &glyphs,
+			 Supplier<unsigned int> &alternate_len_list,
 			 unsigned int num_glyphs,
-			 const USHORT *alternate_glyphs_list)
+			 Supplier<GlyphID> &alternate_glyphs_list)
   {
     TRACE_SERIALIZE ();
     if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
     if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false);
-    for (unsigned int i = 0; i < num_glyphs; i++) {
-      if (unlikely (!alternateSet[i].serialize (c, this).serialize (c, alternate_glyphs_list, alternate_len_list[i]))) return TRACE_RETURN (false);
-      alternate_glyphs_list += alternate_len_list[i];
-    }
+    for (unsigned int i = 0; i < num_glyphs; i++)
+      if (unlikely (!alternateSet[i].serialize (c, this).serialize (c,
+								    alternate_glyphs_list,
+								    alternate_len_list[i]))) return TRACE_RETURN (false);
+    alternate_len_list.advance (num_glyphs);
     return TRACE_RETURN (true);
   }
 
@@ -552,10 +554,10 @@ struct AlternateSubst
   }
 
   inline bool serialize (hb_serialize_context_t *c,
-			 const USHORT *glyphs,
-			 unsigned int *alternate_len_list,
+			 Supplier<GlyphID> &glyphs,
+			 Supplier<unsigned int> &alternate_len_list,
 			 unsigned int num_glyphs,
-			 const USHORT *alternate_glyphs_list)
+			 Supplier<GlyphID> &alternate_glyphs_list)
   {
     TRACE_SERIALIZE ();
     if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
@@ -646,6 +648,18 @@ struct Ligature
     return TRACE_RETURN (true);
   }
 
+  inline bool serialize (hb_serialize_context_t *c,
+			 GlyphID ligature,
+			 Supplier<GlyphID> &components, /* Starting from second */
+			 unsigned int num_components /* Including first component */)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    ligGlyph.set (ligature);
+    if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false);
+    return TRACE_RETURN (true);
+  }
+
   public:
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
@@ -701,6 +715,24 @@ struct LigatureSet
     return TRACE_RETURN (false);
   }
 
+  inline bool serialize (hb_serialize_context_t *c,
+			 Supplier<GlyphID> &ligatures,
+			 Supplier<unsigned int> &component_count_list,
+			 unsigned int num_ligatures,
+			 Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false);
+    for (unsigned int i = 0; i < num_ligatures; i++)
+      if (unlikely (!ligature[i].serialize (c, this).serialize (c,
+								ligatures[i],
+								component_list,
+								component_count_list[i]))) return TRACE_RETURN (false);
+    component_count_list.advance (num_ligatures);
+    return TRACE_RETURN (true);
+  }
+
   public:
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
@@ -753,6 +785,28 @@ struct LigatureSubstFormat1
     return TRACE_RETURN (lig_set.apply (c));
   }
 
+  inline bool serialize (hb_serialize_context_t *c,
+			 Supplier<GlyphID> &first_glyphs,
+			 Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+			 unsigned int num_first_glyphs,
+			 Supplier<GlyphID> &ligatures_list,
+			 Supplier<unsigned int> &component_count_list,
+			 Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false);
+    if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false);
+    for (unsigned int i = 0; i < num_first_glyphs; i++)
+      if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c,
+								   ligatures_list,
+								   component_count_list,
+								   ligature_per_first_glyph_count_list[i],
+								   component_list))) return TRACE_RETURN (false);
+    ligature_per_first_glyph_count_list.advance (num_first_glyphs);
+    return TRACE_RETURN (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
     return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
@@ -810,6 +864,25 @@ struct LigatureSubst
     }
   }
 
+  inline bool serialize (hb_serialize_context_t *c,
+			 Supplier<GlyphID> &first_glyphs,
+			 Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+			 unsigned int num_first_glyphs,
+			 Supplier<GlyphID> &ligatures_list,
+			 Supplier<unsigned int> &component_count_list,
+			 Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE ();
+    if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
+    unsigned int format = 1;
+    u.format.set (format);
+    switch (u.format) {
+    case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
+						      ligatures_list, component_count_list, component_list));
+    default:return TRACE_RETURN (false);
+    }
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE ();
     if (!u.format.sanitize (c)) return TRACE_RETURN (false);
commit 1b38b4e817d871b9549be65af6030bd0eea7f775
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Sep 4 18:17:21 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 890e9c8..2ab54e4 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -75,7 +75,7 @@ struct SingleSubstFormat1
   inline bool serialize (hb_serialize_context_t *c,
 			 const USHORT *glyphs,
 			 unsigned int num_glyphs,
-			 unsigned int delta)
+			 int delta)
   {
     TRACE_SERIALIZE ();
     if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
@@ -208,7 +208,7 @@ struct SingleSubst
     TRACE_SERIALIZE ();
     if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
     unsigned int format = 2;
-    unsigned int delta;
+    int delta;
     if (num_glyphs) {
       format = 1;
       /* TODO(serialize) check for wrap-around */



More information about the HarfBuzz mailing list