[OTLayout] Add fine-grained control over ZWJ matching
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 14 Feb 2013 15:46:52 +0000 (10:46 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 14 Feb 2013 18:02:13 +0000 (13:02 -0500)
Not used yet.  Next commit...

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

index fe10589..4a6c9c5 100644 (file)
@@ -293,6 +293,7 @@ struct hb_apply_context_t
     inline matcher_t (void) :
             lookup_props (0),
             ignore_zwnj (true),
+            ignore_zwj (true),
             mask (-1),
 #define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
             syllable arg1(0),
@@ -303,6 +304,7 @@ struct hb_apply_context_t
     typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
 
     inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
+    inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
     inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
     inline void set_mask (hb_mask_t mask_) { mask = mask_; }
     inline void set_syllable (uint8_t syllable_)  { syllable = syllable_; }
@@ -335,8 +337,9 @@ struct hb_apply_context_t
       if (!c->match_properties (info.codepoint, property, lookup_props))
        return SKIP_YES;
 
-      if (unlikely ((_hb_glyph_info_is_default_ignorable (&info) &&
-                    (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info))) &&
+      if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
+                   (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
+                   (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
                    !is_a_ligature (info)))
        return SKIP_MAYBE;
 
@@ -346,6 +349,7 @@ struct hb_apply_context_t
     protected:
     unsigned int lookup_props;
     bool ignore_zwnj;
+    bool ignore_zwj;
     hb_mask_t mask;
     uint8_t syllable;
     match_func_t match_func;
@@ -367,6 +371,7 @@ struct hb_apply_context_t
       matcher.set_lookup_props (c->lookup_props);
       /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
       matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+      matcher.set_ignore_zwj (true);
       if (!context_match)
       {
         matcher.set_mask (c->lookup_mask);
@@ -436,6 +441,7 @@ struct hb_apply_context_t
       matcher.set_lookup_props (c->lookup_props);
       /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
       matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+      matcher.set_ignore_zwj (true);
       if (!context_match)
       {
         matcher.set_mask (c->lookup_mask);
index cc4b590..21a79d6 100644 (file)
@@ -53,14 +53,15 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni
 {
   info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
                           (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
-                          (info->codepoint == 0x200C ? 0x40 : 0);
+                          (info->codepoint == 0x200C ? 0x40 : 0) |
+                          (info->codepoint == 0x200D ? 0x20 : 0);
   info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
 }
 
 inline hb_unicode_general_category_t
 _hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
 {
-  return (hb_unicode_general_category_t) (info->unicode_props0() & 0x3F);
+  return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
 }
 
 inline void
@@ -87,6 +88,12 @@ _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
   return !!(info->unicode_props0() & 0x40);
 }
 
+inline hb_bool_t
+_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
+{
+  return !!(info->unicode_props0() & 0x20);
+}
+
 
 #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)