[HarfBuzz] harfbuzz-ng: Branch 'master' - 17 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Sat Jun 9 00:23:04 PDT 2012


 src/hb-cache-private.hh              |    2 +
 src/hb-open-type-private.hh          |   21 +++++++++-----
 src/hb-ot-layout-common-private.hh   |   26 +++++++++++++++++-
 src/hb-ot-layout-gpos-table.hh       |   28 +++++++++++++++++--
 src/hb-ot-layout-gsub-table.hh       |   28 ++++++++++++++++++-
 src/hb-ot-layout-gsubgpos-private.hh |   15 +++++-----
 src/hb-ot-layout-private.hh          |    4 --
 src/hb-ot-layout.cc                  |   50 +++++++++++++++++++++--------------
 src/hb-set-private.hh                |    5 +++
 util/shape-consumer.hh               |    2 +
 10 files changed, 137 insertions(+), 44 deletions(-)

New commits:
commit f211d5c291b4c947cfd732e873627567173057e4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 03:11:22 2012 -0400

    More Oops!  Fix fast-path with sub-type==0

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 48f0a9d..c8020d8 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1311,7 +1311,7 @@ struct PosLookupSubTable
   inline bool can_use_fast_path (unsigned int lookup_type) const
   {
     /* Fast path, for those that have coverage in the same place. */
-    return likely (lookup_type < Context) ||
+    return likely (lookup_type && lookup_type < Context) ||
 	   (hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
 	    hb_in_range<unsigned int> (u.header.sub_format, 1, 2));
   }
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index e62be98..f5f38cc 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -970,7 +970,7 @@ struct SubstLookupSubTable
     /* Fast path, for those that have coverage in the same place.
      * Note that ReverseChainSingle can also go through this but
      * it's not worth the effort. */
-    return likely (lookup_type < Context) ||
+    return likely (lookup_type && lookup_type < Context) ||
 	   (hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
 	    hb_in_range<unsigned int> (u.header.sub_format, 1, 2));
   }
diff --git a/util/shape-consumer.hh b/util/shape-consumer.hh
index 220daa4..11e4cc3 100644
--- a/util/shape-consumer.hh
+++ b/util/shape-consumer.hh
@@ -49,6 +49,7 @@ struct shape_consumer_t
   {
     output.new_line ();
 
+    for (unsigned int i = 0; i < 10000; i++) {
     shaper.populate_buffer (buffer, text, text_len);
     output.consume_text (buffer, text, text_len, shaper.utf8_clusters);
 
@@ -58,6 +59,7 @@ struct shape_consumer_t
       output.shape_failed (buffer, text, text_len, shaper.utf8_clusters);
       return;
     }
+    }
 
     output.consume_glyphs (buffer, text, text_len, shaper.utf8_clusters);
   }
commit b1de6aa1f33b228afe231c8209aef90a5fa1ee5d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 03:07:59 2012 -0400

    Oops!

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index ad403d5..48f0a9d 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1343,7 +1343,7 @@ struct PosLookupSubTable
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
     TRACE_SANITIZE ();
     if (!u.header.sub_format.sanitize (c) ||
-	(can_use_fast_path (lookup_type)) && !u.header.coverage.sanitize (c, this))
+	(can_use_fast_path (lookup_type) && !u.header.coverage.sanitize (c, this)))
       return TRACE_RETURN (false);
     switch (lookup_type) {
     case Single:		return TRACE_RETURN (u.single.sanitize (c));
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 75e38b9..e62be98 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1000,7 +1000,7 @@ struct SubstLookupSubTable
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
     TRACE_SANITIZE ();
     if (!u.header.sub_format.sanitize (c) ||
-	(can_use_fast_path (lookup_type)) && !u.header.coverage.sanitize (c, this))
+	(can_use_fast_path (lookup_type) && !u.header.coverage.sanitize (c, this)))
       return TRACE_RETURN (false);
     switch (lookup_type) {
     case Single:		return TRACE_RETURN (u.single.sanitize (c));
commit b12e2549cbcd4f1ef46e66c75533686ee560f59b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 03:05:20 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 4ac724c..98d4e0a 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -144,7 +144,7 @@ struct hb_apply_context_t
     {
       return unlikely (num_items && idx + num_items >= end);
     }
-    inline bool reject (void)
+    inline void reject (void)
     {
       num_items++;
     }
@@ -193,7 +193,7 @@ struct hb_apply_context_t
     {
       return unlikely (idx < num_items);
     }
-    inline bool reject (void)
+    inline void reject (void)
     {
       num_items++;
     }
commit faf0f20253d954cc4cfa4c967ece7573a5ddae3b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 03:02:36 2012 -0400

    Add sanitize() logic for fast-paths

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index b826264..ad403d5 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1308,12 +1308,18 @@ struct PosLookupSubTable
     Extension		= 9
   };
 
+  inline bool can_use_fast_path (unsigned int lookup_type) const
+  {
+    /* Fast path, for those that have coverage in the same place. */
+    return likely (lookup_type < Context) ||
+	   (hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
+	    hb_in_range<unsigned int> (u.header.sub_format, 1, 2));
+  }
+
   inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
   {
     TRACE_APPLY ();
-    if (likely (lookup_type < Context) ||
-	(hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
-	 hb_in_range<unsigned int> (u.header.sub_format, 1, 2)))
+    if (can_use_fast_path (lookup_type))
     {
       /* Fast path, for most that have coverage in the same place. */
       hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@@ -1336,6 +1342,9 @@ struct PosLookupSubTable
 
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
     TRACE_SANITIZE ();
+    if (!u.header.sub_format.sanitize (c) ||
+	(can_use_fast_path (lookup_type)) && !u.header.coverage.sanitize (c, this))
+      return TRACE_RETURN (false);
     switch (lookup_type) {
     case Single:		return TRACE_RETURN (u.single.sanitize (c));
     case Pair:			return TRACE_RETURN (u.pair.sanitize (c));
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index caaaa85..75e38b9 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -965,16 +965,21 @@ struct SubstLookupSubTable
     }
   }
 
+  inline bool can_use_fast_path (unsigned int lookup_type) const
+  {
+    /* Fast path, for those that have coverage in the same place.
+     * Note that ReverseChainSingle can also go through this but
+     * it's not worth the effort. */
+    return likely (lookup_type < Context) ||
+	   (hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
+	    hb_in_range<unsigned int> (u.header.sub_format, 1, 2));
+  }
+
   inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
   {
     TRACE_APPLY ();
-    if (likely (lookup_type < Context) ||
-	(hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
-	 hb_in_range<unsigned int> (u.header.sub_format, 1, 2)))
+    if (can_use_fast_path (lookup_type))
     {
-      /* Fast path, for most that have coverage in the same place.
-       * Note that ReverseChainSingle can also go through this but
-       * it's not worth the effort. */
       hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
       unsigned int index = (this+u.header.coverage) (glyph_id);
       if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
@@ -994,6 +999,9 @@ struct SubstLookupSubTable
 
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
     TRACE_SANITIZE ();
+    if (!u.header.sub_format.sanitize (c) ||
+	(can_use_fast_path (lookup_type)) && !u.header.coverage.sanitize (c, this))
+      return TRACE_RETURN (false);
     switch (lookup_type) {
     case Single:		return TRACE_RETURN (u.single.sanitize (c));
     case Multiple:		return TRACE_RETURN (u.multiple.sanitize (c));
commit 4e766ff28d1fb831ded20666799787478129c07c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 02:53:57 2012 -0400

    Add fast-path for GPOS too
    
    Shaves another 3% for DejaVu Sans long Latin strings.

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 0b7f548..b826264 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1311,6 +1311,15 @@ struct PosLookupSubTable
   inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
   {
     TRACE_APPLY ();
+    if (likely (lookup_type < Context) ||
+	(hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
+	 hb_in_range<unsigned int> (u.header.sub_format, 1, 2)))
+    {
+      /* Fast path, for most that have coverage in the same place. */
+      hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+      unsigned int index = (this+u.header.coverage) (glyph_id);
+      if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+    }
     switch (lookup_type) {
     case Single:		return TRACE_RETURN (u.single.apply (c));
     case Pair:			return TRACE_RETURN (u.pair.apply (c));
@@ -1343,7 +1352,10 @@ struct PosLookupSubTable
 
   private:
   union {
-  USHORT		sub_format;
+  struct {
+    USHORT			sub_format;
+    OffsetTo<Coverage>		coverage;
+  } header;
   SinglePos		single;
   PairPos		pair;
   CursivePos		cursive;
@@ -1355,7 +1367,7 @@ struct PosLookupSubTable
   ExtensionPos		extension;
   } u;
   public:
-  DEFINE_SIZE_UNION (2, sub_format);
+  DEFINE_SIZE_UNION (2, header.sub_format);
 };
 
 
commit 993c51915f503f74ee00eee646b67bf2e3f73596
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 02:48:16 2012 -0400

    Add fast-path to GSUB to check coverage
    
    Shaves a good 10% off DejaVu Sans with simple Latin text for me.
    Now, DejaVu is very ChainContext-intensive, but it's also a very
    popular font!

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 6a4199d..caaaa85 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -968,6 +968,17 @@ struct SubstLookupSubTable
   inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
   {
     TRACE_APPLY ();
+    if (likely (lookup_type < Context) ||
+	(hb_in_range<unsigned int> (lookup_type, Context, ChainContext) &&
+	 hb_in_range<unsigned int> (u.header.sub_format, 1, 2)))
+    {
+      /* Fast path, for most that have coverage in the same place.
+       * Note that ReverseChainSingle can also go through this but
+       * it's not worth the effort. */
+      hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+      unsigned int index = (this+u.header.coverage) (glyph_id);
+      if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+    }
     switch (lookup_type) {
     case Single:		return TRACE_RETURN (u.single.apply (c));
     case Multiple:		return TRACE_RETURN (u.multiple.apply (c));
@@ -998,7 +1009,10 @@ struct SubstLookupSubTable
 
   private:
   union {
-  USHORT			sub_format;
+  struct {
+    USHORT			sub_format;
+    OffsetTo<Coverage>		coverage;
+  } header;
   SingleSubst			single;
   MultipleSubst			multiple;
   AlternateSubst		alternate;
@@ -1009,7 +1023,7 @@ struct SubstLookupSubTable
   ReverseChainSingleSubst	reverseChainContextSingle;
   } u;
   public:
-  DEFINE_SIZE_UNION (2, sub_format);
+  DEFINE_SIZE_UNION (2, header.sub_format);
 };
 
 
commit f19e0b0099ec73b8fedccacff4902403f5eabc42
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 02:26:57 2012 -0400

    Match input before backtrack
    
    Makes more sense, optimization-wise.

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index fee026a..4ac724c 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -882,13 +882,13 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
 					       ChainContextApplyLookupContext &lookup_context)
 {
   unsigned int lookahead_offset;
-  return match_backtrack (c,
-			  backtrackCount, backtrack,
-			  lookup_context.funcs.match, lookup_context.match_data[0])
-      && match_input (c,
+  return match_input (c,
 		      inputCount, input,
 		      lookup_context.funcs.match, lookup_context.match_data[1],
 		      &lookahead_offset)
+      && match_backtrack (c,
+			  backtrackCount, backtrack,
+			  lookup_context.funcs.match, lookup_context.match_data[0])
       && match_lookahead (c,
 			  lookaheadCount, lookahead,
 			  lookup_context.funcs.match, lookup_context.match_data[2],
commit 67bb9e8cea49a44be6996515e1c7d8cdc95a77e6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 02:02:46 2012 -0400

    Add set add_coverage() to Coverage()

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index a3afb08..a990b15 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -134,6 +134,10 @@ struct RangeRecord
     return glyphs->intersects (start, end);
   }
 
+  inline void add_coverage (hb_set_t *glyphs) const {
+    glyphs->add_range (start, end);
+  }
+
   GlyphID	start;		/* First GlyphID in the range */
   GlyphID	end;		/* Last GlyphID in the range */
   USHORT	value;		/* Value */
@@ -357,6 +361,12 @@ struct CoverageFormat1
     return glyphs->has (glyphArray[index]);
   }
 
+  inline void add_coverage (hb_set_t *glyphs) const {
+    unsigned int count = glyphArray.len;
+    for (unsigned int i = 0; i < count; i++)
+      glyphs->add (glyphArray[i]);
+  }
+
   struct Iter {
     inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
     inline bool more (void) { return i < c->glyphArray.len; }
@@ -412,6 +422,12 @@ struct CoverageFormat2
     return false;
   }
 
+  inline void add_coverage (hb_set_t *glyphs) const {
+    unsigned int count = rangeRecord.len;
+    for (unsigned int i = 0; i < count; i++)
+      rangeRecord[i].add_coverage (glyphs);
+  }
+
   struct Iter {
     inline void init (const CoverageFormat2 &c_) {
       c = &c_;
@@ -489,6 +505,14 @@ struct Coverage
     }
   }
 
+  inline void add_coverage (hb_set_t *glyphs) const {
+    switch (u.format) {
+    case 1: u.format1.add_coverage (glyphs); break;
+    case 2: u.format2.add_coverage (glyphs); break;
+    default:                                 break;
+    }
+  }
+
   struct Iter {
     Iter (void) : format (0) {};
     inline void init (const Coverage &c_) {
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 5cdf8a0..7f478e4 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -60,6 +60,11 @@ struct _hb_set_t
     if (unlikely (g > MAX_G)) return;
     elt (g) |= mask (g);
   }
+  inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
+  {
+    for (unsigned int i = a; i < b + 1; i++)
+      add (i);
+  }
   inline void del (hb_codepoint_t g)
   {
     if (unlikely (g > MAX_G)) return;
commit 4952f0aa5b2f4368d9e3418252e0a1b9294cd5ee
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 01:39:11 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index ced6f32..6a4199d 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1063,6 +1063,8 @@ struct SubstLookup : Lookup
     if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->lookup_props, &c->property))
       return false;
 
+    /* TODO: For the most common case this can move out of the main
+     * loop, but it's not a big deal for now. */
     if (unlikely (lookup_type == SubstLookupSubTable::Extension))
     {
       /* The spec says all subtables should have the same type.
commit ad6a6f22401d6256e34521d0f52e91348c5ed4c9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 01:21:02 2012 -0400

    Minor

diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 86550ca..7a613b2 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -94,7 +94,7 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
   return _get_gdef (face).has_glyph_classes ();
 }
 
-static unsigned int
+static inline unsigned int
 _hb_ot_layout_get_glyph_property (hb_face_t       *face,
 				  hb_glyph_info_t *info)
 {
commit 46617a42133fbab151de4111a74dcbdc4e769c74
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 01:18:58 2012 -0400

    Fix cache implementation

diff --git a/src/hb-cache-private.hh b/src/hb-cache-private.hh
index a0928a0..19b70b7 100644
--- a/src/hb-cache-private.hh
+++ b/src/hb-cache-private.hh
@@ -49,6 +49,8 @@ struct hb_cache_t
     unsigned int v = values[k];
     if ((v >> value_bits) != (key >> cache_bits))
       return false;
+    *value = v & ((1<<value_bits)-1);
+    return true;
   }
 
   inline bool set (unsigned int key, unsigned int value)
commit ce47613889aa3ff9b0067d3e51ba63cfdb139adb
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 01:10:26 2012 -0400

    Micro-optimize
    
    I know...

diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 4cf6150..fee026a 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -225,7 +225,8 @@ struct hb_apply_context_t
 
   inline bool should_mark_skip_current_glyph (void) const
   {
-    return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, NULL);
+    unsigned int property;
+    return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, &property);
   }
 
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index da65cda..86550ca 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -107,9 +107,31 @@ _hb_ot_layout_get_glyph_property (hb_face_t       *face,
   return info->props_cache();
 }
 
-static hb_bool_t
+static inline hb_bool_t
+_hb_ot_layout_match_properties_mark (hb_face_t      *face,
+				     hb_codepoint_t  glyph,
+				     unsigned int    glyph_props,
+				     unsigned int    lookup_props)
+{
+  /* If using mark filtering sets, the high short of
+   * lookup_props has the set index.
+   */
+  if (lookup_props & LookupFlag::UseMarkFilteringSet)
+    return _get_gdef (face).mark_set_covers (lookup_props >> 16, glyph);
+
+  /* The second byte of lookup_props has the meaning
+   * "ignore marks of attachment type different than
+   * the attachment type specified."
+   */
+  if (lookup_props & LookupFlag::MarkAttachmentType && glyph_props & LookupFlag::MarkAttachmentType)
+    return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+
+  return true;
+}
+
+static inline hb_bool_t
 _hb_ot_layout_match_properties (hb_face_t      *face,
-				hb_codepoint_t  codepoint,
+				hb_codepoint_t  glyph,
 				unsigned int    glyph_props,
 				unsigned int    lookup_props)
 {
@@ -119,21 +141,8 @@ _hb_ot_layout_match_properties (hb_face_t      *face,
   if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
     return false;
 
-  if (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
-  {
-    /* If using mark filtering sets, the high short of
-     * lookup_props has the set index.
-     */
-    if (lookup_props & LookupFlag::UseMarkFilteringSet)
-      return _get_gdef (face).mark_set_covers (lookup_props >> 16, codepoint);
-
-    /* The second byte of lookup_props has the meaning
-     * "ignore marks of attachment type different than
-     * the attachment type specified."
-     */
-    if (lookup_props & LookupFlag::MarkAttachmentType && glyph_props & LookupFlag::MarkAttachmentType)
-      return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
-  }
+  if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+    return _hb_ot_layout_match_properties_mark (face, glyph, glyph_props, lookup_props);
 
   return true;
 }
@@ -161,7 +170,8 @@ _hb_ot_layout_skip_mark (hb_face_t    *face,
   unsigned int property;
 
   property = _hb_ot_layout_get_glyph_property (face, ginfo);
-  (void) (property_out && (*property_out = property));
+  if (property_out)
+    *property_out = property;
 
   /* If it's a mark, skip it we don't accept it. */
   if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
commit 70416de298b811ab6be53a1c67f0d2531d99cd46
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 00:56:41 2012 -0400

    Minor

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 5d681e2..4d8c507 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -342,8 +342,6 @@ struct Sanitizer
 
 template <typename Type, int Bytes> struct BEInt;
 
-/* LONGTERMTODO: On machines allowing unaligned access, we can make the
- * following tighter by using byteswap instructions on ints directly. */
 template <typename Type>
 struct BEInt<Type, 2>
 {
commit 99159e52a3c9d5ae6c0fbdec64e7ed684fa70b61
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 00:50:40 2012 -0400

    Use linear search for small counts
    
    I see about 8% speedup with long strings with DejaVu Sans.

diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 5f097f0..5d681e2 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -698,11 +698,20 @@ struct SortedArrayOf : ArrayOf<Type> {
 
   template <typename SearchType>
   inline int search (const SearchType &x) const {
-    struct Cmp {
-      static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); }
-    };
-    const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (this->array[0]), (hb_compare_func_t) Cmp::cmp);
-    return p ? p - this->array : -1;
+    unsigned int count = this->len;
+    /* Linear search is *much* faster for small counts. */
+    if (likely (count < 32)) {
+      for (unsigned int i = 0; i < count; i++)
+	if (this->array[i].cmp (x) == 0)
+	  return i;
+      return -1;
+    } else {
+      struct Cmp {
+	static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); }
+      };
+      const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (this->array[0]), (hb_compare_func_t) Cmp::cmp);
+      return p ? p - this->array : -1;
+    }
   }
 };
 
commit caf0412690542e58e23246dccc4b2fb83bd652ec
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 00:26:32 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 2943a7f..a3afb08 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -558,7 +558,7 @@ struct ClassDefFormat1
   private:
   inline unsigned int get_class (hb_codepoint_t glyph_id) const
   {
-    if ((unsigned int) (glyph_id - startGlyph) < classValue.len)
+    if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len))
       return classValue[glyph_id - startGlyph];
     return 0;
   }
commit 0f8fea71a66b1e01ee4398967db464393f478d42
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 00:24:38 2012 -0400

    Minor.  Hide _hb_ot_layout_get_glyph_property()

diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index f860e7b..366b061 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -51,10 +51,6 @@ typedef enum {
 } hb_ot_layout_glyph_class_t;
 
 
-HB_INTERNAL unsigned int
-_hb_ot_layout_get_glyph_property (hb_face_t       *face,
-				  hb_glyph_info_t *info);
-
 HB_INTERNAL hb_bool_t
 _hb_ot_layout_check_glyph_property (hb_face_t    *face,
 				    hb_glyph_info_t *ginfo,
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 1cec8b4..da65cda 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -94,7 +94,7 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
   return _get_gdef (face).has_glyph_classes ();
 }
 
-unsigned int
+static unsigned int
 _hb_ot_layout_get_glyph_property (hb_face_t       *face,
 				  hb_glyph_info_t *info)
 {
commit 44b8ee0c90d7b1dd91e5848114141e3186534a0f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 9 00:23:24 2012 -0400

    Minor

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index c9e10bd..0b7f548 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1371,7 +1371,8 @@ struct PosLookup : Lookup
     if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->lookup_props, &c->property))
       return false;
 
-    for (unsigned int i = 0; i < get_subtable_count (); i++)
+    unsigned int count = get_subtable_count ();
+    for (unsigned int i = 0; i < count; i++)
       if (get_subtable (i).apply (c, lookup_type))
 	return true;
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 0621f86..1cec8b4 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -147,7 +147,7 @@ _hb_ot_layout_check_glyph_property (hb_face_t    *face,
   unsigned int property;
 
   property = _hb_ot_layout_get_glyph_property (face, ginfo);
-  (void) (property_out && (*property_out = property));
+  *property_out = property;
 
   return _hb_ot_layout_match_properties (face, ginfo->codepoint, property, lookup_props);
 }



More information about the HarfBuzz mailing list