[HarfBuzz] harfbuzz: Branch 'master' - 8 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Nov 3 12:17:23 PST 2015


 src/hb-ot-font.cc                                                       |    4 
 src/hb-ot-layout-gsubgpos-private.hh                                    |    2 
 src/hb-ot-layout-private.hh                                             |   61 +++++-----
 src/hb-ot-shape-complex-thai.cc                                         |    2 
 test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf |binary
 test/shaping/fonts/sha1sum/MANIFEST                                     |    1 
 test/shaping/tests/fuzzed.tests                                         |    1 
 util/helper-cairo.cc                                                    |    7 -
 util/main-font-text.hh                                                  |   22 +++
 util/options.cc                                                         |   24 ++-
 util/options.hh                                                         |   53 +++++---
 11 files changed, 114 insertions(+), 63 deletions(-)

New commits:
commit df698f3299d92867e3305715f675b2621c316acd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Nov 3 12:15:12 2015 -0800

    [ot-font] Fix hmtx table length checking, *again*
    
    Exactly the same problem that I fixed in
    63ef0b41dc48d6112d1918c1b1de9de8ea90adb5
    
    I rewrote the table checking yesterday in
    67f8821fb25d9bd55719f5e29a582ae1af4b02b3
    and introduced the exact same issue again. :(
    Good thing we have ongoing fuzzing going now.  Was discovered
    immediately by libFuzzer.  Thanks kcc!
    
    https://github.com/behdad/harfbuzz/issues/139#issuecomment-153449473
    Fixes https://github.com/behdad/harfbuzz/issues/156

diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index bde63fa..94c31b3 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -59,11 +59,11 @@ struct hb_ot_face_metrics_accelerator_t
 
     /* Cap num_metrics() and num_advances() based on table length. */
     unsigned int len = hb_blob_get_length (this->blob);
-    if (unlikely (this->num_advances * 4 < len))
+    if (unlikely (this->num_advances * 4 > len))
       this->num_advances = len / 4;
     this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2;
 
-    /* We MUSt set num_metrics to zero if num_advances is zero.
+    /* We MUST set num_metrics to zero if num_advances is zero.
      * Our get_advance() depends on that. */
     if (unlikely (!this->num_advances))
     {
diff --git a/test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf b/test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf
new file mode 100644
index 0000000..8eed14d
Binary files /dev/null and b/test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf differ
diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST
index 902fa00..785e6ef 100644
--- a/test/shaping/fonts/sha1sum/MANIFEST
+++ b/test/shaping/fonts/sha1sum/MANIFEST
@@ -17,6 +17,7 @@
 757ebd573617a24aa9dfbf0b885c54875c6fe06b.ttf
 7e14e7883ed152baa158b80e207b66114c823a8b.ttf
 813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf
+8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf
 8454d22037f892e76614e1645d066689a0200e61.ttf
 8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf
 a919b33197965846f21074b24e30250d67277bce.ttf
diff --git a/test/shaping/tests/fuzzed.tests b/test/shaping/tests/fuzzed.tests
index 6bb30b0..64e96d7 100644
--- a/test/shaping/tests/fuzzed.tests
+++ b/test/shaping/tests/fuzzed.tests
@@ -3,3 +3,4 @@ fonts/sha1sum/5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8.ttf:--font-funcs=ot:U+004
 fonts/sha1sum/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf:--font-funcs=ot:U+0041:[gid0=0+1000]
 fonts/sha1sum/641bd9db850193064d17575053ae2bf8ec149ddc.ttf:--font-funcs=ot:U+0041:[gid0=0+1000]
 fonts/sha1sum/375d6ae32a3cbe52fbf81a4e5777e3377675d5a3.ttf:--font-funcs=ot:U+0041:[gid0=0+4352]
+fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf:--font-funcs=ot:U+0041:[gid0=0+2304]
commit 3530cc2d7c3b7102902cb0e38b0bf9f46188078d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Nov 3 11:34:47 2015 -0800

    [util] Fix option-parsing leaks

diff --git a/util/helper-cairo.cc b/util/helper-cairo.cc
index d576c3f..8960df9 100644
--- a/util/helper-cairo.cc
+++ b/util/helper-cairo.cc
@@ -349,10 +349,13 @@ helper_cairo_create_context (double w, double h,
 
 
   unsigned int fr, fg, fb, fa, br, bg, bb, ba;
+  const char *color;
   br = bg = bb = 0; ba = 255;
-  sscanf (view_opts->back + (*view_opts->back=='#'), "%2x%2x%2x%2x", &br, &bg, &bb, &ba);
+  color = view_opts->back ? view_opts->back : DEFAULT_BACK;
+  sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &br, &bg, &bb, &ba);
   fr = fg = fb = 0; fa = 255;
-  sscanf (view_opts->fore + (*view_opts->fore=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa);
+  color = view_opts->fore ? view_opts->fore : DEFAULT_FORE;
+  sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa);
 
   cairo_content_t content;
   if (!view_opts->annotate && ba == 255 && br == bg && bg == bb && fr == fg && fg == fb)
diff --git a/util/main-font-text.hh b/util/main-font-text.hh
index 628cdf9..7e8bffe 100644
--- a/util/main-font-text.hh
+++ b/util/main-font-text.hh
@@ -31,6 +31,22 @@
 
 /* main() body for utilities taking font and processing text.*/
 
+static char *
+locale_to_utf8 (char *s)
+{
+  char *t;
+  GError *error = NULL;
+
+  t = g_locale_to_utf8 (s, -1, NULL, NULL, &error);
+  if (!t)
+  {
+     fail (true, "Failed converting text to UTF-8");
+  }
+
+  return t;
+}
+
+
 template <typename consumer_t, int default_font_size, int subpixel_bits>
 struct main_font_text_t
 {
@@ -46,14 +62,14 @@ struct main_font_text_t
     options.parse (&argc, &argv);
 
     argc--, argv++;
-    if (argc && !font_opts.font_file) font_opts.font_file = argv[0], argc--, argv++;
-    if (argc && !input.text && !input.text_file) input.text = argv[0], argc--, argv++;
+    if (argc && !font_opts.font_file) font_opts.font_file = locale_to_utf8 (argv[0]), argc--, argv++;
+    if (argc && !input.text && !input.text_file) input.text = locale_to_utf8 (argv[0]), argc--, argv++;
     if (argc)
       fail (true, "Too many arguments on the command line");
     if (!font_opts.font_file)
       options.usage ();
     if (!input.text && !input.text_file)
-      input.text_file = "-";
+      input.text_file = g_strdup ("-");
 
     consumer.init (&font_opts);
 
diff --git a/util/options.cc b/util/options.cc
index 60f5268..ca8f906 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -601,25 +601,26 @@ const char *
 text_options_t::get_line (unsigned int *len)
 {
   if (text) {
-    if (text_len == (unsigned int) -1)
-      text_len = strlen (text);
+    if (!line) line = text;
+    if (line_len == (unsigned int) -1)
+      line_len = strlen (line);
 
-    if (!text_len) {
+    if (!line_len) {
       *len = 0;
       return NULL;
     }
 
-    const char *ret = text;
-    const char *p = (const char *) memchr (text, '\n', text_len);
+    const char *ret = line;
+    const char *p = (const char *) memchr (line, '\n', line_len);
     unsigned int ret_len;
     if (!p) {
-      ret_len = text_len;
-      text += ret_len;
-      text_len = 0;
+      ret_len = line_len;
+      line += ret_len;
+      line_len = 0;
     } else {
       ret_len = p - ret;
-      text += ret_len + 1;
-      text_len -= ret_len + 1;
+      line += ret_len + 1;
+      line_len -= ret_len + 1;
     }
 
     *len = ret_len;
diff --git a/util/options.hh b/util/options.hh
index f1ec8cf..9dc4433 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -150,19 +150,24 @@ struct view_options_t : option_group_t
 {
   view_options_t (option_parser_t *parser) {
     annotate = false;
-    fore = DEFAULT_FORE;
-    back = DEFAULT_BACK;
+    fore = NULL;
+    back = NULL;
     line_space = 0;
     margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
 
     add_options (parser);
   }
+  ~view_options_t (void)
+  {
+    g_free (fore);
+    g_free (back);
+  }
 
   void add_options (option_parser_t *parser);
 
   hb_bool_t annotate;
-  const char *fore;
-  const char *back;
+  char *fore;
+  char *back;
   double line_space;
   struct margin_t {
     double t, r, b, l;
@@ -188,6 +193,9 @@ struct shape_options_t : option_group_t
   }
   ~shape_options_t (void)
   {
+    g_free (direction);
+    g_free (language);
+    g_free (script);
     free (features);
     g_strfreev (shapers);
   }
@@ -254,9 +262,9 @@ struct shape_options_t : option_group_t
   }
 
   /* Buffer properties */
-  const char *direction;
-  const char *language;
-  const char *script;
+  char *direction;
+  char *language;
+  char *script;
 
   /* Buffer flags */
   hb_bool_t bot;
@@ -290,6 +298,8 @@ struct font_options_t : option_group_t
     add_options (parser);
   }
   ~font_options_t (void) {
+    g_free (font_file);
+    g_free (font_funcs);
     hb_font_destroy (font);
   }
 
@@ -297,13 +307,13 @@ struct font_options_t : option_group_t
 
   hb_font_t *get_font (void) const;
 
-  const char *font_file;
+  char *font_file;
   int face_index;
   int default_font_size;
   unsigned int subpixel_bits;
   mutable double font_size_x;
   mutable double font_size_y;
-  const char *font_funcs;
+  char *font_funcs;
 
   private:
   mutable hb_font_t *font;
@@ -321,11 +331,16 @@ struct text_options_t : option_group_t
 
     fp = NULL;
     gs = NULL;
-    text_len = (unsigned int) -1;
+    line = NULL;
+    line_len = (unsigned int) -1;
 
     add_options (parser);
   }
   ~text_options_t (void) {
+    g_free (text_before);
+    g_free (text_after);
+    g_free (text);
+    g_free (text_file);
     if (gs)
       g_string_free (gs, true);
     if (fp)
@@ -339,21 +354,21 @@ struct text_options_t : option_group_t
       g_set_error (error,
 		   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
 		   "Only one of text and text-file can be set");
-
   };
 
   const char *get_line (unsigned int *len);
 
-  const char *text_before;
-  const char *text_after;
+  char *text_before;
+  char *text_after;
 
-  const char *text;
-  const char *text_file;
+  char *text;
+  char *text_file;
 
   private:
   FILE *fp;
   GString *gs;
-  unsigned int text_len;
+  char *line;
+  unsigned int line_len;
 };
 
 struct output_options_t : option_group_t
@@ -370,6 +385,8 @@ struct output_options_t : option_group_t
     add_options (parser);
   }
   ~output_options_t (void) {
+    g_free (output_file);
+    g_free (output_format);
     if (fp)
       fclose (fp);
   }
@@ -393,8 +410,8 @@ struct output_options_t : option_group_t
 
   FILE *get_file_handle (void);
 
-  const char *output_file;
-  const char *output_format;
+  char *output_file;
+  char *output_format;
   const char **supported_formats;
   bool explicit_output_format;
 
commit 642135f3b2d6d6eb800153c76c4718239733c0e6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Nov 3 11:26:34 2015 -0800

    [util] In --debug mode, duplicate font data
    
    This has the effect that the font data will end up in a memory
    section malloc()ed exactly to its size.  This gives us better
    valgrind detection of out-of-bounds access.
    
    Previously, the font data was placed in a mmap()ed section or
    GString-allocated area, which didn't have proper protections
    at the end when running under valgrind.

diff --git a/util/options.cc b/util/options.cc
index 0005f5c..60f5268 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -538,6 +538,9 @@ font_options_t::get_font (void) const
       }
     }
 
+    if (debug)
+      mm = HB_MEMORY_MODE_DUPLICATE;
+
     blob = hb_blob_create (font_data, len, mm, user_data, destroy);
   }
 
commit ed2024ef93ac3af214082016e5aa8c14db9d7515
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Nov 2 17:58:12 2015 -0800

    [perf] Micro-optimize

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index f1a101c..e13eaae 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -223,19 +223,24 @@ enum {
 static inline void
 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
 {
-  unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint);
+  unsigned int u = info->codepoint;
+  unsigned int gen_cat = (unsigned int) unicode->general_category (u);
   unsigned int props = gen_cat;
 
-  if (unlikely (unicode->is_default_ignorable (info->codepoint)))
+  if (u >= 0x80)
   {
-    props |=  UPROPS_MASK_IGNORABLE;
-    if (info->codepoint == 0x200Cu) props |= UPROPS_MASK_ZWNJ;
-    if (info->codepoint == 0x200Du) props |= UPROPS_MASK_ZWJ;
-  }
-  else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
-  {
-    props |= unicode->modified_combining_class (info->codepoint)<<8;
+    if (unlikely (unicode->is_default_ignorable (u)))
+    {
+      props |=  UPROPS_MASK_IGNORABLE;
+      if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ;
+      if (u == 0x200Du) props |= UPROPS_MASK_ZWJ;
+    }
+    else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
+    {
+      props |= unicode->modified_combining_class (info->codepoint)<<8;
+    }
   }
+
   info->unicode_props() = props;
 }
 
commit 76a5310a830c7ae12037b768c5043bef0ff733a0
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Nov 2 17:52:45 2015 -0800

    Remove irrelevant comment
    
    I tried moving the is_default_ignorable() function to an INTERNAL
    function.  That made the binary size grow by 5k AND things got a
    tad bit slower!

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index eab4ac6..f1a101c 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -226,7 +226,6 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni
   unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint);
   unsigned int props = gen_cat;
 
-  /* XXX This wouldn't be inlined, or at least not while is_default_ignorable() is inline. */
   if (unlikely (unicode->is_default_ignorable (info->codepoint)))
   {
     props |=  UPROPS_MASK_IGNORABLE;
commit 8259669fbd1b070fc02287325894caf1bc4d590e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Nov 2 17:44:05 2015 -0800

    Minor

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index fb411db..1390a2e 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -835,8 +835,8 @@ static inline bool ligate_input (hb_apply_context_t *c,
     _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
     if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
     {
-      _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
       _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
+      _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
     }
   }
   c->replace_glyph_with_ligature (lig_glyph, klass);
diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc
index 8a8f2f7..51a1a10 100644
--- a/src/hb-ot-shape-complex-thai.cc
+++ b/src/hb-ot-shape-complex-thai.cc
@@ -330,7 +330,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
     if (unlikely (buffer->in_error))
       return;
 
-    /* Make Nikhahit be recognized as a mark when zeroing widths. */
+    /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */
     unsigned int end = buffer->out_len;
     _hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK);
 
commit 9382c471eabce8d36d3a73c97499ab60af422716
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Nov 2 17:36:51 2015 -0800

    Combine unicode_props0/1 into a uint16
    
    Slightly faster.  In prep for more changes.

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 075a568..eab4ac6 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -180,8 +180,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
  */
 
 /* buffer var allocations, used during the entire shaping process */
-#define unicode_props0()	var2.u8[0]
-#define unicode_props1()	var2.u8[1]
+#define unicode_props()		var2.u16[0]
 
 /* buffer var allocations, used during the GSUB/GPOS processing */
 #define glyph_props()		var1.u16[0] /* GDEF glyph properties */
@@ -215,49 +214,56 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start)
 /* unicode_props */
 
 enum {
-  MASK0_ZWJ       = 0x20u,
-  MASK0_ZWNJ      = 0x40u,
-  MASK0_IGNORABLE = 0x80u,
-  MASK0_GEN_CAT   = 0x1Fu
+  UPROPS_MASK_ZWJ       = 0x20u,
+  UPROPS_MASK_ZWNJ      = 0x40u,
+  UPROPS_MASK_IGNORABLE = 0x80u,
+  UPROPS_MASK_GEN_CAT   = 0x1Fu
 };
 
 static inline void
 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
 {
   unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint);
+  unsigned int props = gen_cat;
+
   /* XXX This wouldn't be inlined, or at least not while is_default_ignorable() is inline. */
-  info->unicode_props0() = gen_cat |
-       (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
-       (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) |
-       (info->codepoint == 0x200Du ? MASK0_ZWJ : 0);
-  info->unicode_props1() = unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)) ?
-	unicode->modified_combining_class (info->codepoint) : 0;
+  if (unlikely (unicode->is_default_ignorable (info->codepoint)))
+  {
+    props |=  UPROPS_MASK_IGNORABLE;
+    if (info->codepoint == 0x200Cu) props |= UPROPS_MASK_ZWNJ;
+    if (info->codepoint == 0x200Du) props |= UPROPS_MASK_ZWJ;
+  }
+  else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)))
+  {
+    props |= unicode->modified_combining_class (info->codepoint)<<8;
+  }
+  info->unicode_props() = props;
 }
 
 static inline void
 _hb_glyph_info_set_general_category (hb_glyph_info_t *info,
 				     hb_unicode_general_category_t gen_cat)
 {
-  info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
+  info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & ~UPROPS_MASK_GEN_CAT);
 }
 
 static 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() & MASK0_GEN_CAT);
+  return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GEN_CAT);
 }
 
 static inline void
 _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
 					     unsigned int modified_class)
 {
-  info->unicode_props1() = modified_class;
+  info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF);
 }
 
 static inline unsigned int
 _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
 {
-  return info->unicode_props1();
+  return info->unicode_props()>>8;
 }
 
 static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
@@ -265,25 +271,25 @@ static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
 static inline hb_bool_t
 _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
 {
-  return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (info);
+  return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_ligated (info);
 }
 
 static inline hb_bool_t
 _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
 {
-  return !!(info->unicode_props0() & MASK0_ZWNJ);
+  return !!(info->unicode_props() & UPROPS_MASK_ZWNJ);
 }
 
 static inline hb_bool_t
 _hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
 {
-  return !!(info->unicode_props0() & MASK0_ZWJ);
+  return !!(info->unicode_props() & UPROPS_MASK_ZWJ);
 }
 
 static inline void
 _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
 {
-  info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
+  info->unicode_props() ^= UPROPS_MASK_ZWNJ | UPROPS_MASK_ZWJ;
 }
 
 /* lig_props: aka lig_id / lig_comp
@@ -457,22 +463,19 @@ _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *in
 static inline void
 _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
 {
-  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
-  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props);
 }
 
 static inline void
 _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
 {
-  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
-  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props);
 }
 
 static inline void
 _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer)
 {
-  HB_BUFFER_ASSERT_VAR (buffer, unicode_props0);
-  HB_BUFFER_ASSERT_VAR (buffer, unicode_props1);
+  HB_BUFFER_ASSERT_VAR (buffer, unicode_props);
 }
 
 static inline void
commit 71277185454482cff9b0c10b85c416eb4d6e0ed9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Nov 2 17:27:48 2015 -0800

    [perf] Only call combining_class() for marks
    
    Saves some time.  Also preparing for reusing the ccc byte for other stuff.

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index d168e27..075a568 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -224,12 +224,14 @@ enum {
 static inline void
 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
 {
-  /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
-  info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
-			   (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
-			   (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) |
-			   (info->codepoint == 0x200Du ? MASK0_ZWJ : 0);
-  info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
+  unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint);
+  /* XXX This wouldn't be inlined, or at least not while is_default_ignorable() is inline. */
+  info->unicode_props0() = gen_cat |
+       (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
+       (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) |
+       (info->codepoint == 0x200Du ? MASK0_ZWJ : 0);
+  info->unicode_props1() = unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)) ?
+	unicode->modified_combining_class (info->codepoint) : 0;
 }
 
 static inline void


More information about the HarfBuzz mailing list