[HB] ChainContext complete
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 18 May 2009 07:56:39 +0000 (03:56 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 2 Nov 2009 19:40:12 +0000 (14:40 -0500)
IranNastaliq renders perfectly again!

src/hb-ot-layout-gsubgpos-private.h

index b2c29ec..df9dd9b 100644 (file)
@@ -71,6 +71,34 @@ static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
 }
 
 
+static inline bool match_input (LOOKUP_ARGS_DEF,
+                               unsigned int count, /* Including the first glyph (not matched) */
+                               const USHORT input[], /* Array of input values--start with second glyph */
+                               match_func_t match_func,
+                               char *match_data,
+                               unsigned int *context_length_out)
+{
+  unsigned int i, j;
+
+  /* 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))
+       return false;
+      j++;
+    }
+
+    if (HB_LIKELY (!match_func (IN_GLYPH(j), input[i - 1], match_data)))
+      return false;
+  }
+
+  *context_length_out = j - buffer->in_pos;
+
+  return true;
+}
+
 static inline bool match_backtrack (LOOKUP_ARGS_DEF,
                                    unsigned int count,
                                    const USHORT backtrack[],
@@ -86,39 +114,33 @@ static inline bool match_backtrack (LOOKUP_ARGS_DEF,
       j--;
     }
 
-    if (HB_LIKELY (match_func (OUT_GLYPH(j), backtrack[i], match_data)))
+    if (HB_LIKELY (!match_func (OUT_GLYPH(j), backtrack[i], match_data)))
       return false;
   }
 
   return true;
 }
 
-static inline bool match_input (LOOKUP_ARGS_DEF,
-                               unsigned int count, /* Including the first glyph (not matched) */
-                               const USHORT input[], /* Array of input values--start with second glyph */
-                               match_func_t match_func,
-                               char *match_data,
-                               unsigned int *context_length_out)
+static inline bool match_lookahead (LOOKUP_ARGS_DEF,
+                                   unsigned int count,
+                                   const USHORT lookahead[],
+                                   match_func_t match_func,
+                                   char *match_data,
+                                   unsigned int offset)
 {
   unsigned int i, j;
 
-  /* 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)) {
+  for (i = 0, j = buffer->in_pos + offset; i < count; i++, j++) {
+    while (!_hb_ot_layout_check_glyph_property (layout, OUT_ITEM (j), lookup_flag, &property)) {
       if (HB_UNLIKELY (j + count - i == buffer->in_length))
        return false;
       j++;
     }
 
-    if (HB_LIKELY (match_func (IN_GLYPH(j), input[i - 1], match_data)))
+    if (HB_LIKELY (!match_func (IN_GLYPH(j), lookahead[i], match_data)))
       return false;
   }
 
-  /* XXX right? or j - buffer_inpos? */
-  *context_length_out = count;
-
   return true;
 }
 
@@ -406,13 +428,20 @@ static inline bool chain_context_lookup (LOOKUP_ARGS_DEF,
                   buffer->in_pos + inputCount + lookaheadCount > buffer->in_length))
     return false;
 
+  unsigned int offset;
   return match_backtrack (LOOKUP_ARGS,
                          backtrackCount, backtrack,
                          context.funcs.match, context.match_data[0]) &&
         match_input (LOOKUP_ARGS,
                      inputCount, input,
                      context.funcs.match, context.match_data[1],
-                     &context_length) &&
+                     &offset) &&
+        (context_length -= offset, true) &&
+        match_lookahead (LOOKUP_ARGS,
+                         lookaheadCount, lookahead,
+                         context.funcs.match, context.match_data[2],
+                         offset) &&
+        (context_length = offset, true) &&
         apply_lookup (LOOKUP_ARGS,
                       inputCount,
                       lookupCount, lookupRecord,