summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh86
1 files changed, 78 insertions, 8 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
index 185b324b35..08665438c4 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
@@ -6,12 +6,13 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
+template <typename Types>
struct LigatureSet
{
protected:
- Array16OfOffset16To<Ligature>
+ Array16OfOffset16To<Ligature<Types>>
ligature; /* Array LigatureSet tables
* ordered by preference */
public:
@@ -28,7 +29,19 @@ struct LigatureSet
return
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
+ | hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); })
+ | hb_any
+ ;
+ }
+
+ bool intersects_lig_glyph (const hb_set_t *glyphs) const
+ {
+ return
+ + hb_iter (ligature)
+ | hb_map (hb_add (this))
+ | hb_map ([glyphs] (const Ligature<Types> &_) {
+ return _.intersects_lig_glyph (glyphs) && _.intersects (glyphs);
+ })
| hb_any
;
}
@@ -37,7 +50,7 @@ struct LigatureSet
{
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_apply ([c] (const Ligature &_) { _.closure (c); })
+ | hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); })
;
}
@@ -45,7 +58,7 @@ struct LigatureSet
{
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
+ | hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); })
;
}
@@ -54,7 +67,7 @@ struct LigatureSet
return
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
+ | hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); })
| hb_any
;
}
@@ -62,12 +75,69 @@ struct LigatureSet
bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
+
unsigned int num_ligs = ligature.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+ if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4)
+#endif
+ {
+ slow:
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const auto &lig = this+ligature.arrayZ[i];
+ if (lig.apply (c)) return_trace (true);
+ }
+ return_trace (false);
+ }
+
+ /* This version is optimized for speed by matching the first component
+ * of the ligature here, instead of calling into the ligation code.
+ *
+ * This is replicated in ChainRuleSet and RuleSet. */
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (c->buffer->idx);
+ skippy_iter.set_match_func (match_always, nullptr);
+ skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+ unsigned unsafe_to;
+ hb_codepoint_t first = (unsigned) -1;
+ bool matched = skippy_iter.next (&unsafe_to);
+ if (likely (matched))
+ {
+ first = c->buffer->info[skippy_iter.idx].codepoint;
+ unsafe_to = skippy_iter.idx + 1;
+
+ if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+ {
+ /* Can't use the fast path if eg. the next char is a default-ignorable
+ * or other skippable. */
+ goto slow;
+ }
+ }
+ else
+ goto slow;
+
+ bool unsafe_to_concat = false;
+
for (unsigned int i = 0; i < num_ligs; i++)
{
- const Ligature &lig = this+ligature[i];
- if (lig.apply (c)) return_trace (true);
+ const auto &lig = this+ligature.arrayZ[i];
+ if (unlikely (lig.component.lenP1 <= 1) ||
+ lig.component.arrayZ[0] == first)
+ {
+ if (lig.apply (c))
+ {
+ if (unsafe_to_concat)
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+ return_trace (true);
+ }
+ }
+ else if (likely (lig.component.lenP1 > 1))
+ unsafe_to_concat = true;
}
+ if (likely (unsafe_to_concat))
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
return_trace (false);
}