[pango/harfbuzz-ng: 6/17] [GSUB] Implement Alternate subtables



commit 2d1c3ed6ac99d73df640eaa8245771e32322aab5
Author: Behdad Esfahbod <behdad behdad org>
Date:   Thu Apr 16 14:19:42 2009 -0400

    [GSUB] Implement Alternate subtables
---
 pango/opentype/hb-ot-layout-gsub-private.h |  104 +++++++++++++++++++++++++--
 pango/opentype/hb-ot-layout-open-private.h |    2 +-
 2 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/pango/opentype/hb-ot-layout-gsub-private.h b/pango/opentype/hb-ot-layout-gsub-private.h
index b9204f3..b6083aa 100644
--- a/pango/opentype/hb-ot-layout-gsub-private.h
+++ b/pango/opentype/hb-ot-layout-gsub-private.h
@@ -221,10 +221,12 @@ struct MultipleSubstFormat1 {
     glyph_id = IN_CURGLYPH ();
 
     index = get_glyph_coverage (glyph_id);
-    if (index >= sequenceCount)
-      return false;
 
     const Sequence &seq = (*this)[index];
+
+    if (HB_UNLIKELY (!seq.get_len ()))
+      return false;
+
     _hb_buffer_add_output_glyph_ids (buffer, 1,
 				     seq.glyphCount, seq.substitute,
 				     0xFFFF, 0xFFFF);
@@ -285,7 +287,9 @@ DEFINE_NULL (MultipleSubst, 2);
 
 
 struct AlternateSet {
-  /* TODO */
+
+  /* GlyphIDs, in no particular order */
+  DEFINE_ARRAY_TYPE (GlyphID, alternate, glyphCount);
 
   private:
   USHORT	glyphCount;		/* Number of GlyphIDs in the Alternate
@@ -296,7 +300,62 @@ struct AlternateSet {
 DEFINE_NULL_ASSERT_SIZE (AlternateSet, 2);
 
 struct AlternateSubstFormat1 {
-  /* TODO */
+
+  friend struct AlternateSubst;
+
+  private:
+  /* AlternateSet tables, in Coverage Index order */
+  DEFINE_OFFSET_ARRAY_TYPE (AlternateSet, alternateSet, alternateSetCount);
+  DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
+  DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
+
+  inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
+
+    hb_codepoint_t glyph_id;
+    unsigned int index;
+    unsigned int property;
+
+    HB_UNUSED (nesting_level_left);
+
+    if (HB_UNLIKELY (context_length < 1))
+      return false;
+
+    if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+      return false;
+
+    glyph_id = IN_CURGLYPH ();
+
+    index = get_glyph_coverage (glyph_id);
+
+    const AlternateSet &alt_set = (*this)[index];
+
+    if (HB_UNLIKELY (!alt_set.get_len ()))
+      return false;
+
+    unsigned int alt_index = 0;
+
+    /* XXX callback to user to choose alternate
+    if ( gsub->altfunc )
+      alt_index = (gsub->altfunc)( buffer->out_pos, glyph_id,
+				   aset.GlyphCount, aset.Alternate,
+				   gsub->data );
+				   */
+
+    if (HB_UNLIKELY (alt_index >= alt_set.get_len ()))
+      return false;
+
+    glyph_id = alt_set[alt_index];
+
+    _hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT);
+
+    if ( _hb_ot_layout_has_new_glyph_classes (layout) )
+    {
+      /* we inherit the old glyph class to the substituted glyph */
+      _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
+    }
+
+    return true;
+  }
 
   private:
   USHORT	substFormat;		/* Format identifier--format = 1 */
@@ -310,6 +369,34 @@ struct AlternateSubstFormat1 {
 };
 ASSERT_SIZE (AlternateSubstFormat1, 6);
 
+struct AlternateSubst {
+
+  friend struct SubstLookupSubTable;
+
+  private:
+
+  unsigned int get_size (void) const {
+    switch (u.substFormat) {
+    case 1: return sizeof (u.format1);
+    default:return sizeof (u.substFormat);
+    }
+  }
+
+  inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
+    switch (u.substFormat) {
+    case 1: return u.format1.substitute (SUBTABLE_SUBSTITUTE_ARGS);
+    default:return false;
+    }
+  }
+
+  private:
+  union {
+  USHORT	substFormat;	/* Format identifier */
+  AlternateSubstFormat1	format1;
+  } u;
+};
+DEFINE_NULL (AlternateSubst, 2);
+
 
 struct Ligature {
   /* TODO */
@@ -716,9 +803,9 @@ struct SubstLookupSubTable {
   unsigned int get_size (unsigned int lookup_type) const {
     switch (lookup_type) {
     case GSUB_Single:				return u.single.get_size ();
-    case GSUB_Multiple:			return u.multiple.get_size ();
-  /*
-    case GSUB_Alternate:
+    case GSUB_Multiple:				return u.multiple.get_size ();
+    case GSUB_Alternate:			return u.alternate.get_size ();
+   /*
     case GSUB_Ligature:
     case GSUB_Context:
     case GSUB_ChainingContext:
@@ -736,8 +823,8 @@ struct SubstLookupSubTable {
     switch (lookup_type) {
     case GSUB_Single:				return u.single.substitute (SUBTABLE_SUBSTITUTE_ARGS);
     case GSUB_Multiple:				return u.multiple.substitute (SUBTABLE_SUBSTITUTE_ARGS);
+    case GSUB_Alternate:			return u.alternate.substitute (SUBTABLE_SUBSTITUTE_ARGS);
     /*
-    case GSUB_Alternate:
     case GSUB_Ligature:
     case GSUB_Context:
     case GSUB_ChainingContext:
@@ -755,6 +842,7 @@ struct SubstLookupSubTable {
   USHORT		substFormat;
   SingleSubst		single;
   MultipleSubst		multiple;
+  AlternateSubst	alternate;
 
   ExtensionSubst	extension;
   } u;
diff --git a/pango/opentype/hb-ot-layout-open-private.h b/pango/opentype/hb-ot-layout-open-private.h
index ecd1c08..da2da95 100644
--- a/pango/opentype/hb-ot-layout-open-private.h
+++ b/pango/opentype/hb-ot-layout-open-private.h
@@ -822,7 +822,7 @@ struct ClassDefFormat1 {
   friend struct ClassDef;
 
   private:
-  /* GlyphIDs, in sorted numerical order */
+  /* Class Values, in sorted numerical order */
   DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount);
 
   inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]