[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