[GSUB] Generalize would_apply()
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 8 Aug 2012 02:25:24 +0000 (22:25 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 8 Aug 2012 02:25:24 +0000 (22:25 -0400)
Fixes logic also, where before we were always matching if glyphs_len==1
and a ligature started with the glyph.

src/hb-ot-layout-gsub-table.hh
src/hb-ot-layout-gsubgpos-private.hh
src/hb-ot-layout.cc

index b69af4c..1114418 100644 (file)
@@ -473,7 +473,14 @@ struct Ligature
 
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
-    return c->len == 1 || (c->len == 2 && component.len == 2 && component[1] == c->second);
+    if (c->len != component.len)
+      return false;
+
+    for (unsigned int i = 1; i < c->len; i++)
+      if (likely (c->glyphs[i] != component[i]))
+       return false;
+
+    return true;
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -706,7 +713,7 @@ struct LigatureSubstFormat1
 
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
-    return (this+ligatureSet[(this+coverage) (c->first)]).would_apply (c);
+    return (this+ligatureSet[(this+coverage) (c->glyphs[0])]).would_apply (c);
   }
 
   inline bool apply (hb_apply_context_t *c) const
@@ -1064,8 +1071,16 @@ struct SubstLookupSubTable
                           unsigned int lookup_type) const
   {
     TRACE_WOULD_APPLY ();
-    if (get_coverage (lookup_type).get_coverage (c->first) == NOT_COVERED) return false;
-    if (c->len == 1) return true; /* Done! */
+    if (get_coverage (lookup_type).get_coverage (c->glyphs[0]) == NOT_COVERED) return false;
+    if (c->len == 1) {
+      switch (lookup_type) {
+      case Single:
+      case Multiple:
+      case Alternate:
+      case ReverseChainSingle:
+        return true;
+      }
+    }
 
     /* Only need to look further for lookups that support substitutions
      * of input longer than 1. */
@@ -1170,7 +1185,8 @@ struct SubstLookup : Lookup
 
   inline bool would_apply (hb_would_apply_context_t *c) const
   {
-    if (!c->digest.may_have (c->first)) return false;
+    if (unlikely (!c->len)) return false;
+    if (!c->digest.may_have (c->glyphs[0])) return false;
     unsigned int lookup_type = get_type ();
     unsigned int count = get_subtable_count ();
     for (unsigned int i = 0; i < count; i++)
index d91686d..fd5fb19 100644 (file)
        hb_auto_trace_t<HB_DEBUG_CLOSURE> trace (&c->debug_depth, "CLOSURE", this, HB_FUNC, "");
 
 
-/* TODO Add TRACE_RETURN annotation to gsub. */
-#ifndef HB_DEBUG_WOULD_APPLY
-#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
-#endif
-
-#define TRACE_WOULD_APPLY() \
-       hb_auto_trace_t<HB_DEBUG_WOULD_APPLY> trace (&c->debug_depth, "WOULD_APPLY", this, HB_FUNC, "first %u second %u", c->first, c->second);
-
-
 struct hb_closure_context_t
 {
   hb_face_t *face;
@@ -71,23 +62,31 @@ struct hb_closure_context_t
 
 
 
+/* TODO Add TRACE_RETURN annotation to gsub. */
+#ifndef HB_DEBUG_WOULD_APPLY
+#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
+#endif
+
+#define TRACE_WOULD_APPLY() \
+       hb_auto_trace_t<HB_DEBUG_WOULD_APPLY> trace (&c->debug_depth, "WOULD_APPLY", this, HB_FUNC, "%d glyphs", c->len);
+
 
 struct hb_would_apply_context_t
 {
   hb_face_t *face;
-  hb_codepoint_t first;
-  hb_codepoint_t second;
+  const hb_codepoint_t *glyphs;
   unsigned int len;
   const hb_set_digest_t digest;
   unsigned int debug_depth;
 
   hb_would_apply_context_t (hb_face_t *face_,
-                           hb_codepoint_t first_,
-                           hb_codepoint_t second_,
+                           const hb_codepoint_t *glyphs_,
+                           unsigned int len_,
                            const hb_set_digest_t *digest_
                            ) :
                              face (face_),
-                             first (first_), second (second_), len (second == (hb_codepoint_t) -1 ? 1 : 2),
+                             glyphs (glyphs_),
+                             len (len_),
                              digest (*digest_),
                              debug_depth (0) {};
 };
@@ -407,7 +406,7 @@ static inline bool would_match_input (hb_would_apply_context_t *c,
     return false;
 
   for (unsigned int i = 1; i < count; i++)
-    if (likely (!match_func (c->second, input[i - 1], match_data)))
+    if (likely (!match_func (c->glyphs[i], input[i - 1], match_data)))
       return false;
 
   return true;
@@ -757,7 +756,7 @@ struct ContextFormat1
   {
     TRACE_WOULD_APPLY ();
 
-    const RuleSet &rule_set = this+ruleSet[(this+coverage) (c->first)];
+    const RuleSet &rule_set = this+ruleSet[(this+coverage) (c->glyphs[0])];
     struct ContextApplyLookupContext lookup_context = {
       {match_glyph, NULL},
       NULL
@@ -830,7 +829,7 @@ struct ContextFormat2
     TRACE_WOULD_APPLY ();
 
     const ClassDef &class_def = this+classDef;
-    unsigned int index = class_def (c->first);
+    unsigned int index = class_def (c->glyphs[0]);
     const RuleSet &rule_set = this+ruleSet[index];
     struct ContextApplyLookupContext lookup_context = {
       {match_class, NULL},
@@ -1253,7 +1252,7 @@ struct ChainContextFormat1
   {
     TRACE_WOULD_APPLY ();
 
-    const ChainRuleSet &rule_set = this+ruleSet[(this+coverage) (c->first)];
+    const ChainRuleSet &rule_set = this+ruleSet[(this+coverage) (c->glyphs[0])];
     struct ChainContextApplyLookupContext lookup_context = {
       {match_glyph, NULL},
       {NULL, NULL, NULL}
@@ -1329,7 +1328,7 @@ struct ChainContextFormat2
 
     const ClassDef &input_class_def = this+inputClassDef;
 
-    unsigned int index = input_class_def (c->first);
+    unsigned int index = input_class_def (c->glyphs[0]);
     const ChainRuleSet &rule_set = this+ruleSet[index];
     struct ChainContextApplyLookupContext lookup_context = {
       {match_class, NULL},
index 0280f0b..91deaa2 100644 (file)
@@ -415,9 +415,8 @@ hb_ot_layout_would_substitute_lookup_fast (hb_face_t            *face,
                                           unsigned int          glyphs_length,
                                           unsigned int          lookup_index)
 {
-  if (unlikely (glyphs_length < 1 || glyphs_length > 2)) return false;
   if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false;
-  hb_would_apply_context_t c (face, glyphs[0], glyphs_length == 2 ? glyphs[1] : -1, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]);
+  hb_would_apply_context_t c (face, glyphs, glyphs_length, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]);
   return hb_ot_layout_from_face (face)->gsub->would_substitute_lookup (&c, lookup_index);
 }