[GSUB] Finish ContextSubstFormat1
authorBehdad Esfahbod <behdad@behdad.org>
Fri, 15 May 2009 22:54:53 +0000 (18:54 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 2 Nov 2009 19:40:08 +0000 (14:40 -0500)
src/hb-ot-layout-gsub-private.h
src/hb-ot-layout-private.h
src/hb-ot-layout.cc

index 568f14d..2bf1e9f 100644 (file)
@@ -539,6 +539,13 @@ DEFINE_NULL (LigatureSubst, 2);
 
 
 struct SubstLookupRecord {
+
+  friend struct SubRule;
+
+  private:
+  inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const;
+
+  private:
   USHORT       sequenceIndex;          /* Index into current glyph
                                         * sequence--first glyph = 0 */
   USHORT       lookupListIndex;        /* Lookup to apply to that
@@ -563,6 +570,9 @@ struct SubRule {
                     context_length < count))
       return false; /* Not enough glyphs in input or context */
 
+    /* XXX context_length should also be checked when skipping glyphs, right?
+     * What does context_length really mean, anyway? */
+
     for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++) {
       while (!_hb_ot_layout_check_glyph_property (layout, IN_ITEM (j), lookup_flag, &property)) {
        if (HB_UNLIKELY (j + count - i == buffer->in_length))
@@ -574,12 +584,35 @@ struct SubRule {
         return false;
     }
 
-    /*
-    return Do_ContextSubst( gsub, sr[k].GlyphCount,
-                           sr[k].SubstCount, sr[k].SubstLookupRecord,
-                           buffer,
-                           nesting_level );
-                           */
+    /* XXX right? or j - buffer_inpos? */
+    context_length = count;
+
+    unsigned int subst_count = substCount;
+    const SubstLookupRecord *subst = (const SubstLookupRecord *) ((const char *) input + sizeof (input[0]) * glyphCount);
+    for (i = 0; i < count;)
+    {
+      if ( subst_count && i == subst->sequenceIndex )
+      {
+       unsigned int old_pos = buffer->in_pos;
+
+       /* Do a substitution */
+       bool done = subst->substitute (SUBTABLE_SUBSTITUTE_ARGS);
+
+       subst++;
+       subst_count--;
+       i += buffer->in_pos - old_pos;
+
+       if (!done)
+         goto no_subst;
+      }
+      else
+      {
+      no_subst:
+       /* No substitution for this index */
+       _hb_buffer_copy_output_glyph (buffer);
+       i++;
+      }
+    }
   }
 
 
@@ -1038,17 +1071,6 @@ struct SubstLookupSubTable {
 };
 
 
-/* Out-of-class implementation for methods chaining */
-
-inline bool ExtensionSubstFormat1::substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
-  /* XXX either check in sanitize or here that the lookuptype is not 7 again,
-   * or we can loop indefinitely. */
-  return (*(SubstLookupSubTable *)(((char *) this) + extensionOffset)).substitute (SUBTABLE_SUBSTITUTE_ARGS,
-                                                                                  get_type ());
-}
-
-
-
 struct SubstLookup : Lookup {
 
   inline const SubstLookupSubTable& get_subtable (unsigned int i) const {
@@ -1140,6 +1162,7 @@ struct SubstLookup : Lookup {
 };
 DEFINE_NULL_ALIAS (SubstLookup, Lookup);
 
+
 /*
  * GSUB
  */
@@ -1159,4 +1182,24 @@ struct GSUB : GSUBGPOS {
 DEFINE_NULL_ALIAS (GSUB, GSUBGPOS);
 
 
+
+
+/* Out-of-class implementation for methods chaining */
+
+inline bool ExtensionSubstFormat1::substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
+  /* XXX either check in sanitize or here that the lookuptype is not 7 again,
+   * or we can loop indefinitely. */
+  return (*(SubstLookupSubTable *)(((char *) this) + extensionOffset)).substitute (SUBTABLE_SUBSTITUTE_ARGS,
+                                                                                  get_type ());
+}
+
+inline bool SubstLookupRecord::substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
+  const GSUB &gsub = *(layout->gsub);
+  const SubstLookup &l = gsub.get_lookup (lookupListIndex);
+
+  return l.substitute_once (layout, buffer, context_length, nesting_level_left);
+}
+
+
+
 #endif /* HB_OT_LAYOUT_GSUB_PRIVATE_H */
index c152edc..d7809d1 100644 (file)
 
 typedef unsigned int hb_ot_layout_class_t;
 
+struct _hb_ot_layout_t {
+  const struct GDEF *gdef;
+  const struct GSUB *gsub;
+  const struct /*XXX*/GSUBGPOS *gpos;
+
+  struct {
+    unsigned char *klasses;
+    unsigned int len;
+  } new_gdef;
+
+  /* TODO add max-nesting-level here? */
+};
+
+
 /* XXX #define HB_OT_LAYOUT_INTERNAL static */
 #define HB_OT_LAYOUT_INTERNAL
 
index 6b7d47b..0cbc1bf 100644 (file)
 #include <string.h>
 
 
-struct _hb_ot_layout_t {
-  const GDEF *gdef;
-  const GSUB *gsub;
-  const /*XXX*/GSUBGPOS *gpos;
-
-  struct {
-    unsigned char *klasses;
-    unsigned int len;
-  } new_gdef;
-
-  /* TODO add max-nesting-level here? */
-};
-
 hb_ot_layout_t *
 hb_ot_layout_create (void)
 {