[HB] Start ChainContext and ReverseChainSingleSubst lookups
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 18 May 2009 00:48:27 +0000 (20:48 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 2 Nov 2009 19:40:11 +0000 (14:40 -0500)
src/hb-ot-layout-gsub-private.h
src/hb-ot-layout-gsubgpos-private.h

index adb6f2c..ea7fe68 100644 (file)
@@ -461,6 +461,7 @@ ASSERT_SIZE (LigatureSubst, 2);
 
 static inline bool substitute_lookup (LOOKUP_ARGS_DEF, unsigned int lookup_index);
 
+
 struct ContextSubst : Context {
 
   inline bool substitute (LOOKUP_ARGS_DEF) const {
@@ -470,184 +471,11 @@ struct ContextSubst : Context {
 ASSERT_SIZE (ContextSubst, 2);
 
 
-struct ChainSubRule {
-  /* TODO */
-
-  private:
-  USHORT       backtrackGlyphCount;    /* Total number of glyphs in the
-                                        * backtrack sequence (number of
-                                        * glyphs to be matched before the
-                                        * first glyph) */
-  GlyphID      backtrack[];            /* Array of backtracking GlyphID's
-                                        * (to be matched before the input
-                                        * sequence) */
-  USHORT       inputGlyphCount;        /* Total number of glyphs in the input
-                                        * sequence (includes the first  glyph) */
-  GlyphID      input[];                /* Array of input GlyphIDs (start with
-                                        * second glyph) */
-  USHORT       lookaheadGlyphCount;    /* Total number of glyphs in the look
-                                        * ahead sequence (number of  glyphs to
-                                        * be matched after the input sequence) */
-  GlyphID      lookAhead[];            /* Array of lookahead GlyphID's (to be
-                                        * matched after  the input sequence) */
-  USHORT       substCount;             /* Number of LookupRecords */
-  LookupRecord substLookupRecord[];    /* Array of LookupRecords--in
-                                        * design order) */
-};
-ASSERT_SIZE (ChainSubRule, 8);
-
-struct ChainSubRuleSet {
-  /* TODO */
-
-  private:
-  USHORT       chainSubRuleCount;      /* Number of ChainSubRule tables */
-  Offset       chainSubRule[];         /* Array of offsets to ChainSubRule
-                                        * tables--from beginning of
-                                        * ChainSubRuleSet table--ordered
-                                        * by preference */
-};
-ASSERT_SIZE (ChainSubRuleSet, 2);
-
-struct ChainContextSubstFormat1 {
-  /* TODO */
-  inline bool substitute (LOOKUP_ARGS_DEF) const {
-    return false;
-  }
-
-  private:
-  USHORT       format;                 /* Format identifier--format = 1 */
-  Offset       coverage;               /* Offset to Coverage table--from
-                                        * beginning of Substitution table */
-  USHORT       chainSubRuleSetCount;   /* Number of ChainSubRuleSet
-                                        * tables--must equal GlyphCount in
-                                        * Coverage table */
-  Offset       chainSubRuleSet[];      /* Array of offsets to ChainSubRuleSet
-                                        * tables--from beginning of
-                                        * Substitution table--ordered by
-                                        * Coverage Index */
-};
-ASSERT_SIZE (ChainContextSubstFormat1, 6);
-
-struct ChainSubClassRule {
-  /* TODO */
-
-  private:
-  USHORT       backtrackGlyphCount;    /* Total number of glyphs in the
-                                        * backtrack sequence (number of
-                                        * glyphs to be matched before the
-                                        * first glyph) */
-  USHORT       backtrack[];            /* Array of backtracking classes (to be
-                                        * matched before the input  sequence) */
-  USHORT       inputGlyphCount;        /* Total number of classes in the input
-                                        * sequence (includes the  first class) */
-  USHORT       input[];                /* Array of input classes(start with
-                                        * second class; to  be matched with
-                                        * the input glyph sequence) */
-  USHORT       lookaheadGlyphCount;    /* Total number of classes in the
-                                        * look ahead sequence (number of
-                                        * classes to be matched after the
-                                        * input sequence) */
-  USHORT       lookAhead[];            /* Array of lookahead classes (to be
-                                        * matched after the  input sequence) */
-  USHORT       substCount;             /* Number of LookupRecords */
-  LookupRecord substLookupRecord[];    /* Array of LookupRecords--in
-                                        * design order) */
-};
-ASSERT_SIZE (ChainSubClassRule, 8);
-
-struct ChainSubClassSet {
-  /* TODO */
-
-  private:
-  USHORT       chainSubClassRuleCnt;   /* Number of ChainSubClassRule tables */
-  Offset       chainSubClassRule[];    /* Array of offsets
-                                        * to ChainSubClassRule
-                                        * tables--from beginning of
-                                        * ChainSubClassSet--ordered by
-                                        * preference */
-};
-ASSERT_SIZE (ChainSubClassSet, 2);
-
-struct ChainContextSubstFormat2 {
-  /* TODO */
-  inline bool substitute (LOOKUP_ARGS_DEF) const {
-    return false;
-  }
-
-  private:
-  USHORT       format;                 /* Format identifier--format = 2 */
-  Offset       coverage;               /* Offset to Coverage table--from
-                                        * beginning of Substitution table */
-  Offset       backtrackClassDef;      /* Offset to glyph ClassDef table
-                                        * containing backtrack sequence
-                                        * data--from beginning of Substitution
-                                        * table */
-  Offset       inputClassDef;          /* Offset to glyph ClassDef
-                                        * table containing input sequence
-                                        * data--from beginning of Substitution
-                                        * table */
-  Offset       lookaheadClassDef;      /* Offset to glyph ClassDef table
-                                        * containing lookahead sequence
-                                        * data--from beginning of Substitution
-                                        * table */
-  USHORT       chainSubClassSetCnt;    /* Number of ChainSubClassSet tables */
-  Offset       chainSubClassSet[];     /* Array of offsets to ChainSubClassSet
-                                        * tables--from beginning of
-                                        * Substitution table--ordered by input
-                                        * class--may be NULL */
-};
-ASSERT_SIZE (ChainContextSubstFormat2, 12);
-
-struct ChainContextSubstFormat3 {
-  /* TODO */
-  inline bool substitute (LOOKUP_ARGS_DEF) const {
-    return false;
-  }
-
-  private:
-  USHORT       format;                 /* Format identifier--format = 3 */
-  USHORT       backtrackGlyphCount;    /* Number of glyphs in the backtracking
-                                        * sequence */
-  Offset       backtrackCoverage[];    /* Array of offsets to coverage tables
-                                        * in backtracking sequence, in  glyph
-                                        * sequence order */
-  USHORT       inputGlyphCount;        /* Number of glyphs in input sequence */
-  Offset       inputCoverage[];        /* Array of offsets to coverage
-                                        * tables in input sequence, in glyph
-                                        * sequence order */
-  USHORT       lookaheadGlyphCount;    /* Number of glyphs in lookahead
-                                        * sequence */
-  Offset       lookaheadCoverage[];    /* Array of offsets to coverage tables
-                                        * in lookahead sequence, in  glyph
-                                        * sequence order */
-  USHORT       substCount;             /* Number of LookupRecords */
-  LookupRecord substLookupRecord[];    /* Array of LookupRecords--in
-                                        * design order */
-};
-ASSERT_SIZE (ChainContextSubstFormat3, 10);
-
-struct ChainContextSubst {
-
-  friend struct SubstLookupSubTable;
-
-  private:
+struct ChainContextSubst : ChainContext {
 
   inline bool substitute (LOOKUP_ARGS_DEF) const {
-    switch (u.format) {
-    case 1: return u.format1->substitute (LOOKUP_ARGS);
-    case 2: return u.format2->substitute (LOOKUP_ARGS);
-    case 3: return u.format3->substitute (LOOKUP_ARGS);
-    default:return false;
-    }
+    return this->apply (LOOKUP_ARGS, substitute_lookup);
   }
-
-  private:
-  union {
-  USHORT                       format; /* Format identifier */
-  ChainContextSubstFormat1     format1[];
-  ChainContextSubstFormat2     format2[];
-  ChainContextSubstFormat3     format3[];
-  } u;
 };
 ASSERT_SIZE (ChainContextSubst, 2);
 
@@ -703,9 +531,11 @@ struct ExtensionSubst {
 ASSERT_SIZE (ExtensionSubst, 2);
 
 
-
 struct ReverseChainSingleSubstFormat1 {
   /* TODO */
+  inline bool substitute (LOOKUP_ARGS_DEF) const {
+    return false;
+  }
 
   private:
   USHORT       format;                 /* Format identifier--format = 1 */
@@ -723,24 +553,47 @@ struct ReverseChainSingleSubstFormat1 {
                                         * sequence order */
   USHORT       glyphCount;             /* Number of GlyphIDs in the Substitute
                                         * array */
-  GlyphID      substitute[];           /* Array of substitute
+  GlyphID      substituteGlyphs[];     /* Array of substitute
                                         * GlyphIDs--ordered by Coverage  Index */
 };
 ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10);
 
+struct ReverseChainSingleSubst {
+
+  friend struct SubstLookupSubTable;
+
+  private:
+
+  inline bool substitute (LOOKUP_ARGS_DEF) const {
+    switch (u.format) {
+    case 1: return u.format1->substitute (LOOKUP_ARGS);
+    default:return false;
+    }
+  }
+
+  private:
+  union {
+  USHORT                               format;         /* Format identifier */
+  ReverseChainSingleSubstFormat1       format1[];
+  } u;
+};
+ASSERT_SIZE (ReverseChainSingleSubst, 2);
+
+
+
 /*
  * SubstLookup
  */
 
 enum {
-  GSUB_Single                          = 1,
-  GSUB_Multiple                                = 2,
-  GSUB_Alternate                       = 3,
-  GSUB_Ligature                                = 4,
-  GSUB_Context                         = 5,
-  GSUB_ChainingContext                 = 6,
-  GSUB_Extension                       = 7,
-  GSUB_ReverseChainingContextSingle    = 8,
+  GSUB_Single                  = 1,
+  GSUB_Multiple                        = 2,
+  GSUB_Alternate               = 3,
+  GSUB_Ligature                        = 4,
+  GSUB_Context                 = 5,
+  GSUB_ChainContext            = 6,
+  GSUB_Extension               = 7,
+  GSUB_ReverseChainSingle      = 8,
 };
 
 struct SubstLookupSubTable {
@@ -751,37 +604,29 @@ struct SubstLookupSubTable {
                          unsigned int lookup_type) const {
 
     switch (lookup_type) {
-    case GSUB_Single:                          return u.single->substitute (LOOKUP_ARGS);
-    case GSUB_Multiple:                                return u.multiple->substitute (LOOKUP_ARGS);
-    case GSUB_Alternate:                       return u.alternate->substitute (LOOKUP_ARGS);
-    case GSUB_Ligature:                                return u.ligature->substitute (LOOKUP_ARGS);
-    case GSUB_Context:                         return u.context->substitute (LOOKUP_ARGS);
-    /*
-    case GSUB_ChainingContext:                 return u.chainingContext->substitute (LOOKUP_ARGS);
-    */
-    case GSUB_Extension:                       return u.extension->substitute (LOOKUP_ARGS);
-                       /*
-    case GSUB_ReverseChainingContextSingle:    return u.reverseChainingContextSingle->substitute (LOOKUP_ARGS);
-    */
+    case GSUB_Single:                  return u.single->substitute (LOOKUP_ARGS);
+    case GSUB_Multiple:                        return u.multiple->substitute (LOOKUP_ARGS);
+    case GSUB_Alternate:               return u.alternate->substitute (LOOKUP_ARGS);
+    case GSUB_Ligature:                        return u.ligature->substitute (LOOKUP_ARGS);
+    case GSUB_Context:                 return u.context->substitute (LOOKUP_ARGS);
+    case GSUB_ChainContext:            return u.chainingContext->substitute (LOOKUP_ARGS);
+    case GSUB_Extension:               return u.extension->substitute (LOOKUP_ARGS);
+    case GSUB_ReverseChainSingle:      return u.reverseChainContextSingle->substitute (LOOKUP_ARGS);
     default:return false;
     }
   }
 
   private:
   union {
-  USHORT                               format;
-  SingleSubst                          single[];
-  MultipleSubst                                multiple[];
-  AlternateSubst                       alternate[];
-  LigatureSubst                                ligature[];
-  ContextSubst                         context[];
-  /*
-  ChainingContextSubst                 chainingContext[];
-  */
-  ExtensionSubst                       extension[];
-  /*
-  ReverseChainingContextSingleSubst    reverseChainingContextSingle[];
-  */
+  USHORT                       format;
+  SingleSubst                  single[];
+  MultipleSubst                        multiple[];
+  AlternateSubst               alternate[];
+  LigatureSubst                        ligature[];
+  ContextSubst                 context[];
+  ChainContextSubst            chainingContext[];
+  ExtensionSubst               extension[];
+  ReverseChainSingleSubst      reverseChainContextSingle[];
   } u;
 };
 ASSERT_SIZE (SubstLookupSubTable, 2);
@@ -810,8 +655,8 @@ struct SubstLookup : Lookup {
 
   inline bool is_reverse (void) const {
     switch (get_effective_type ()) {
-    case GSUB_ReverseChainingContextSingle:    return true;
-    default:                                   return false;
+    case GSUB_ReverseChainSingle:      return true;
+    default:                           return false;
     }
   }
 
index befb3ac..a7e8d33 100644 (file)
@@ -47,7 +47,7 @@
        property
 
 
-/* Context lookups */
+/* Contextual lookups */
 
 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, char *data);
 typedef bool (*apply_lookup_func_t) (LOOKUP_ARGS_DEF, unsigned int lookup_index);
@@ -197,7 +197,6 @@ struct ContextFormat1 {
   friend struct Context;
 
   private:
-
   inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
 
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -231,7 +230,6 @@ struct ContextFormat2 {
   friend struct Context;
 
   private:
-
   inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
 
     unsigned int index = (this+coverage) (IN_CURGLYPH ());
@@ -333,6 +331,216 @@ struct Context {
 };
 ASSERT_SIZE (Context, 2);
 
+
+/* Chaining Contextual lookups */
+
+struct ChainSubRule {
+  /* TODO */
+
+  private:
+  USHORT       backtrackGlyphCount;    /* Total number of glyphs in the
+                                        * backtrack sequence (number of
+                                        * glyphs to be matched before the
+                                        * first glyph) */
+  GlyphID      backtrack[];            /* Array of backtracking GlyphID's
+                                        * (to be matched before the input
+                                        * sequence) */
+  USHORT       inputGlyphCount;        /* Total number of glyphs in the input
+                                        * sequence (includes the first  glyph) */
+  GlyphID      input[];                /* Array of input GlyphIDs (start with
+                                        * second glyph) */
+  USHORT       lookaheadGlyphCount;    /* Total number of glyphs in the look
+                                        * ahead sequence (number of  glyphs to
+                                        * be matched after the input sequence) */
+  GlyphID      lookAhead[];            /* Array of lookahead GlyphID's (to be
+                                        * matched after  the input sequence) */
+  USHORT       substCount;             /* Number of LookupRecords */
+  LookupRecord substLookupRecord[];    /* Array of LookupRecords--in
+                                        * design order) */
+};
+ASSERT_SIZE (ChainSubRule, 8);
+
+struct ChainSubRuleSet {
+  /* TODO */
+
+  private:
+  USHORT       chainSubRuleCount;      /* Number of ChainSubRule tables */
+  Offset       chainSubRule[];         /* Array of offsets to ChainSubRule
+                                        * tables--from beginning of
+                                        * ChainSubRuleSet table--ordered
+                                        * by preference */
+};
+ASSERT_SIZE (ChainSubRuleSet, 2);
+
+struct ChainContextFormat1 {
+
+  friend struct ChainContext;
+
+  private:
+  inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+  /* TODO */
+
+//    unsigned int index = (this+coverage) (IN_CURGLYPH ());
+//    const RuleSet &rule_set = this+ruleSet[index];
+//    struct ContextLookupContext context = {
+//      glyph_match, NULL,
+//      apply_func
+//    };
+//    return rule_set.apply (LOOKUP_ARGS, context);
+  }
+
+
+  private:
+  USHORT       format;                 /* Format identifier--format = 1 */
+  Offset       coverage;               /* Offset to Coverage table--from
+                                        * beginning of table */
+  USHORT       chainSubRuleSetCount;   /* Number of ChainSubRuleSet
+                                        * tables--must equal GlyphCount in
+                                        * Coverage table */
+  Offset       chainSubRuleSet[];      /* Array of offsets to ChainSubRuleSet
+                                        * tables--from beginning of
+                                        * table--ordered by Coverage Index */
+};
+ASSERT_SIZE (ChainContextFormat1, 6);
+
+struct ChainSubClassRule {
+  /* TODO */
+
+  private:
+  USHORT       backtrackGlyphCount;    /* Total number of glyphs in the
+                                        * backtrack sequence (number of
+                                        * glyphs to be matched before the
+                                        * first glyph) */
+  USHORT       backtrack[];            /* Array of backtracking classes (to be
+                                        * matched before the input  sequence) */
+  USHORT       inputGlyphCount;        /* Total number of classes in the input
+                                        * sequence (includes the  first class) */
+  USHORT       input[];                /* Array of input classes(start with
+                                        * second class; to  be matched with
+                                        * the input glyph sequence) */
+  USHORT       lookaheadGlyphCount;    /* Total number of classes in the
+                                        * look ahead sequence (number of
+                                        * classes to be matched after the
+                                        * input sequence) */
+  USHORT       lookAhead[];            /* Array of lookahead classes (to be
+                                        * matched after the  input sequence) */
+  USHORT       substCount;             /* Number of LookupRecords */
+  LookupRecord substLookupRecord[];    /* Array of LookupRecords--in
+                                        * design order) */
+};
+ASSERT_SIZE (ChainSubClassRule, 8);
+
+struct ChainSubClassSet {
+  /* TODO */
+
+  private:
+  USHORT       chainSubClassRuleCnt;   /* Number of ChainSubClassRule tables */
+  Offset       chainSubClassRule[];    /* Array of offsets
+                                        * to ChainSubClassRule
+                                        * tables--from beginning of
+                                        * ChainSubClassSet--ordered by
+                                        * preference */
+};
+ASSERT_SIZE (ChainSubClassSet, 2);
+
+struct ChainContextFormat2 {
+
+  friend struct ChainContext;
+
+  private:
+  inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+
+//    unsigned int index = (this+coverage) (IN_CURGLYPH ());
+//    const RuleSet &rule_set = this+ruleSet[index];
+    /* LONGTERMTODO: Old code fetches glyph classes at most once and caches
+     * them across subrule lookups.  Not sure it's worth it.
+     */
+//    struct ContextLookupContext context = {
+//      class_match, (char *) &(this+classDef),
+//      apply_func
+//    };
+//    return rule_set.apply (LOOKUP_ARGS, context);
+  }
+
+  private:
+  USHORT       format;                 /* Format identifier--format = 2 */
+  Offset       coverage;               /* Offset to Coverage table--from
+                                        * beginning of table */
+  Offset       backtrackClassDef;      /* Offset to glyph ClassDef table
+                                        * containing backtrack sequence
+                                        * data--from beginning of table */
+  Offset       inputClassDef;          /* Offset to glyph ClassDef
+                                        * table containing input sequence
+                                        * data--from beginning of table */
+  Offset       lookaheadClassDef;      /* Offset to glyph ClassDef table
+                                        * containing lookahead sequence
+                                        * data--from beginning of table */
+  USHORT       chainSubClassSetCnt;    /* Number of ChainSubClassSet tables */
+  Offset       chainSubClassSet[];     /* Array of offsets to ChainSubClassSet
+                                        * tables--from beginning of
+                                        * table--ordered by input
+                                        * class--may be NULL */
+};
+ASSERT_SIZE (ChainContextFormat2, 12);
+
+struct ChainContextFormat3 {
+
+  friend struct ChainContext;
+
+  private:
+  inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+
+//    if ((*this)[0].get_coverage (IN_CURGLYPH () == NOT_COVERED))
+//      return false;
+
+//    return apply_coverage (LOOKUP_ARGS, apply_func);
+  }
+
+  private:
+  USHORT       format;                 /* Format identifier--format = 3 */
+  USHORT       backtrackGlyphCount;    /* Number of glyphs in the backtracking
+                                        * sequence */
+  Offset       backtrackCoverage[];    /* Array of offsets to coverage tables
+                                        * in backtracking sequence, in  glyph
+                                        * sequence order */
+  USHORT       inputGlyphCount;        /* Number of glyphs in input sequence */
+  Offset       inputCoverage[];        /* Array of offsets to coverage
+                                        * tables in input sequence, in glyph
+                                        * sequence order */
+  USHORT       lookaheadGlyphCount;    /* Number of glyphs in lookahead
+                                        * sequence */
+  Offset       lookaheadCoverage[];    /* Array of offsets to coverage tables
+                                        * in lookahead sequence, in glyph
+                                        * sequence order */
+  USHORT       substCount;             /* Number of LookupRecords */
+  LookupRecord substLookupRecord[];    /* Array of LookupRecords--in
+                                        * design order */
+};
+ASSERT_SIZE (ChainContextFormat3, 10);
+
+struct ChainContext {
+
+  protected:
+  bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+    switch (u.format) {
+    case 1: return u.format1->apply (LOOKUP_ARGS, apply_func);
+    case 2: return u.format2->apply (LOOKUP_ARGS, apply_func);
+    case 3: return u.format3->apply (LOOKUP_ARGS, apply_func);
+    default:return false;
+    }
+  }
+
+  private:
+  union {
+  USHORT               format; /* Format identifier */
+  ChainContextFormat1  format1[];
+  ChainContextFormat2  format2[];
+  ChainContextFormat3  format3[];
+  } u;
+};
+ASSERT_SIZE (ChainContext, 2);
+
+
 /*
  * GSUB/GPOS Common
  */