summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh523
1 files changed, 246 insertions, 277 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
index cc10634759b..0e1966e98e8 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
@@ -34,10 +34,12 @@
namespace OT {
+typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
+template<typename Iterator>
static inline void SingleSubst_serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
- hb_array_t<const GlyphID> substitutes);
+ Iterator it);
+
struct SingleSubstFormat1
{
@@ -46,35 +48,28 @@ struct SingleSubstFormat1
void closure (hb_closure_context_t *c) const
{
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- /* TODO Switch to range-based API to work around malicious fonts.
- * https://github.com/harfbuzz/harfbuzz/issues/363 */
- hb_codepoint_t glyph_id = iter.get_glyph ();
- if (c->glyphs->has (glyph_id))
- c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
- }
+ unsigned d = deltaGlyphID;
+ + hb_iter (this+coverage)
+ | hb_filter (*c->glyphs)
+ | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+ | hb_sink (c->output)
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- /* TODO Switch to range-based API to work around malicious fonts.
- * https://github.com/harfbuzz/harfbuzz/issues/363 */
- hb_codepoint_t glyph_id = iter.get_glyph ();
- c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
- }
+ unsigned d = deltaGlyphID;
+ + hb_iter (this+coverage)
+ | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+ | hb_sink (c->output)
+ ;
}
const Coverage &get_coverage () const { return this+coverage; }
bool would_apply (hb_would_apply_context_t *c) const
- {
- TRACE_WOULD_APPLY (this);
- return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
- }
+ { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
bool apply (hb_ot_apply_context_t *c) const
{
@@ -91,34 +86,39 @@ struct SingleSubstFormat1
return_trace (true);
}
+ template<typename Iterator,
+ hb_requires (hb_is_sorted_source_of (Iterator,
+ hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
- int delta)
+ Iterator glyphs,
+ unsigned delta)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
- deltaGlyphID.set (delta); /* TODO(serialize) overflow? */
+ c->check_assign (deltaGlyphID, delta);
return_trace (true);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
- hb_vector_t<GlyphID> from;
- hb_vector_t<GlyphID> to;
+
hb_codepoint_t delta = deltaGlyphID;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (!glyphset.has (iter.get_glyph ())) continue;
- from.push ()->set (glyph_map[iter.get_glyph ()]);
- to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]);
- }
- c->serializer->propagate_error (from, to);
- SingleSubst_serialize (c->serializer, from, to);
- return_trace (from.length);
+
+ auto it =
+ + hb_iter (this+coverage)
+ | hb_filter (glyphset)
+ | hb_map_retains_sorting ([&] (hb_codepoint_t g) {
+ return hb_codepoint_pair_t (glyph_map[g],
+ glyph_map[(g + delta) & 0xFFFF]); })
+ ;
+
+ bool ret = bool (it);
+ SingleSubst_serialize (c->serializer, it);
+ return_trace (ret);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -132,8 +132,8 @@ struct SingleSubstFormat1
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- HBINT16 deltaGlyphID; /* Add to original GlyphID to get
- * substitute GlyphID */
+ HBUINT16 deltaGlyphID; /* Add to original GlyphID to get
+ * substitute GlyphID, modulo 0x10000 */
public:
DEFINE_SIZE_STATIC (6);
};
@@ -145,35 +145,26 @@ struct SingleSubstFormat2
void closure (hb_closure_context_t *c) const
{
- unsigned int count = substitute.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- if (c->glyphs->has (iter.get_glyph ()))
- c->out->add (substitute[iter.get_coverage ()]);
- }
+ + hb_zip (this+coverage, substitute)
+ | hb_filter (*c->glyphs, hb_first)
+ | hb_map (hb_second)
+ | hb_sink (c->output)
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
- unsigned int count = substitute.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- c->output->add (substitute[iter.get_coverage ()]);
- }
+ + hb_zip (this+coverage, substitute)
+ | hb_map (hb_second)
+ | hb_sink (c->output)
+ ;
}
const Coverage &get_coverage () const { return this+coverage; }
bool would_apply (hb_would_apply_context_t *c) const
- {
- TRACE_WOULD_APPLY (this);
- return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
- }
+ { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
bool apply (hb_ot_apply_context_t *c) const
{
@@ -188,11 +179,21 @@ struct SingleSubstFormat2
return_trace (true);
}
+ template<typename Iterator,
+ hb_requires (hb_is_sorted_source_of (Iterator,
+ const hb_codepoint_pair_t))>
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
- hb_array_t<const GlyphID> substitutes)
+ Iterator it)
{
TRACE_SERIALIZE (this);
+ auto substitutes =
+ + it
+ | hb_map (hb_second)
+ ;
+ auto glyphs =
+ + it
+ | hb_map_retains_sorting (hb_first)
+ ;
if (unlikely (!c->extend_min (*this))) return_trace (false);
if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
@@ -202,19 +203,19 @@ struct SingleSubstFormat2
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
- hb_vector_t<GlyphID> from;
- hb_vector_t<GlyphID> to;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (!glyphset.has (iter.get_glyph ())) continue;
- from.push ()->set (glyph_map[iter.get_glyph ()]);
- to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]);
- }
- c->serializer->propagate_error (from, to);
- SingleSubst_serialize (c->serializer, from, to);
- return_trace (from.length);
+
+ auto it =
+ + hb_zip (this+coverage, substitute)
+ | hb_filter (glyphset, hb_first)
+ | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const GlyphID &> p) -> hb_codepoint_pair_t
+ { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+ ;
+
+ bool ret = bool (it);
+ SingleSubst_serialize (c->serializer, it);
+ return_trace (ret);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -237,41 +238,45 @@ struct SingleSubstFormat2
struct SingleSubst
{
+
+ template<typename Iterator,
+ hb_requires (hb_is_sorted_source_of (Iterator,
+ const hb_codepoint_pair_t))>
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
- hb_array_t<const GlyphID> substitutes)
+ Iterator glyphs)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false);
- unsigned int format = 2;
- int delta = 0;
- if (glyphs.length)
+ unsigned format = 2;
+ unsigned delta = 0;
+ if (glyphs.len ())
{
format = 1;
- /* TODO(serialize) check for wrap-around */
- delta = substitutes[0] - glyphs[0];
- for (unsigned int i = 1; i < glyphs.length; i++)
- if (delta != (int) (substitutes[i] - glyphs[i])) {
- format = 2;
- break;
- }
+ auto get_delta = [=] (hb_codepoint_pair_t _) {
+ return (unsigned) (_.second - _.first) & 0xFFFF;
+ };
+ delta = get_delta (*glyphs);
+ if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
}
- u.format.set (format);
+ u.format = format;
switch (u.format) {
- case 1: return_trace (u.format1.serialize (c, glyphs, delta));
- case 2: return_trace (u.format2.serialize (c, glyphs, substitutes));
+ case 1: return_trace (u.format1.serialize (c,
+ + glyphs
+ | hb_map_retains_sorting (hb_first),
+ delta));
+ case 2: return_trace (u.format2.serialize (c, glyphs));
default:return_trace (false);
}
}
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1));
- case 2: return_trace (c->dispatch (u.format2));
+ case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+ case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());
}
}
@@ -284,11 +289,11 @@ struct SingleSubst
} u;
};
+template<typename Iterator>
static inline void
SingleSubst_serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
- hb_array_t<const GlyphID> substitutes)
-{ c->start_embed<SingleSubst> ()->serialize (c, glyphs, substitutes); }
+ Iterator it)
+{ c->start_embed<SingleSubst> ()->serialize (c, it); }
struct Sequence
{
@@ -296,7 +301,7 @@ struct Sequence
{
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++)
- c->out->add (substitute[i]);
+ c->output->add (substitute[i]);
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -335,10 +340,10 @@ struct Sequence
}
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs)
+ hb_array_t<const GlyphID> subst)
{
TRACE_SERIALIZE (this);
- return_trace (substitute.serialize (c, glyphs));
+ return_trace (substitute.serialize (c, subst));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -361,31 +366,28 @@ struct MultipleSubstFormat1
void closure (hb_closure_context_t *c) const
{
- unsigned int count = sequence.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- if (c->glyphs->has (iter.get_glyph ()))
- (this+sequence[iter.get_coverage ()]).closure (c);
- }
+ + hb_zip (this+coverage, sequence)
+ | hb_filter (*c->glyphs, hb_first)
+ | hb_map (hb_second)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const Sequence &_) { _.closure (c); })
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
- unsigned int count = sequence.len;
- for (unsigned int i = 0; i < count; i++)
- (this+sequence[i]).collect_glyphs (c);
+ + hb_zip (this+coverage, sequence)
+ | hb_map (hb_second)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
+ ;
}
const Coverage &get_coverage () const { return this+coverage; }
bool would_apply (hb_would_apply_context_t *c) const
- {
- TRACE_WOULD_APPLY (this);
- return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
- }
+ { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
bool apply (hb_ot_apply_context_t *c) const
{
@@ -398,7 +400,7 @@ struct MultipleSubstFormat1
}
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
+ hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const unsigned int> substitute_len_list,
hb_array_t<const GlyphID> substitute_glyphs_list)
{
@@ -444,27 +446,27 @@ struct MultipleSubstFormat1
struct MultipleSubst
{
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
+ hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const unsigned int> substitute_len_list,
hb_array_t<const GlyphID> substitute_glyphs_list)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false);
unsigned int format = 1;
- u.format.set (format);
+ u.format = format;
switch (u.format) {
case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list));
default:return_trace (false);
}
}
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1));
+ case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());
}
}
@@ -482,7 +484,7 @@ struct AlternateSet
{
unsigned int count = alternates.len;
for (unsigned int i = 0; i < count; i++)
- c->out->add (alternates[i]);
+ c->output->add (alternates[i]);
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -502,7 +504,7 @@ struct AlternateSet
unsigned int shift = hb_ctz (lookup_mask);
unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
- /* If alt_index is MAX, randomize feature if it is the rand feature. */
+ /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */
if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
alt_index = c->random_number () % count + 1;
@@ -514,10 +516,10 @@ struct AlternateSet
}
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs)
+ hb_array_t<const GlyphID> alts)
{
TRACE_SERIALIZE (this);
- return_trace (alternates.serialize (c, glyphs));
+ return_trace (alternates.serialize (c, alts));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -541,35 +543,27 @@ struct AlternateSubstFormat1
void closure (hb_closure_context_t *c) const
{
- unsigned int count = alternateSet.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- if (c->glyphs->has (iter.get_glyph ()))
- (this+alternateSet[iter.get_coverage ()]).closure (c);
- }
+ + hb_zip (this+coverage, alternateSet)
+ | hb_map (hb_second)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
- unsigned int count = alternateSet.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- (this+alternateSet[iter.get_coverage ()]).collect_glyphs (c);
- }
+ + hb_zip (this+coverage, alternateSet)
+ | hb_map (hb_second)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
+ ;
}
const Coverage &get_coverage () const { return this+coverage; }
bool would_apply (hb_would_apply_context_t *c) const
- {
- TRACE_WOULD_APPLY (this);
- return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
- }
+ { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
bool apply (hb_ot_apply_context_t *c) const
{
@@ -582,7 +576,7 @@ struct AlternateSubstFormat1
}
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
+ hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const unsigned int> alternate_len_list,
hb_array_t<const GlyphID> alternate_glyphs_list)
{
@@ -628,27 +622,27 @@ struct AlternateSubstFormat1
struct AlternateSubst
{
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> glyphs,
+ hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const unsigned int> alternate_len_list,
hb_array_t<const GlyphID> alternate_glyphs_list)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false);
unsigned int format = 1;
- u.format.set (format);
+ u.format = format;
switch (u.format) {
case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list));
default:return_trace (false);
}
}
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1));
+ case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());
}
}
@@ -668,17 +662,14 @@ struct Ligature
unsigned int count = component.lenP1;
for (unsigned int i = 1; i < count; i++)
if (!glyphs->has (component[i]))
- return false;
+ return false;
return true;
}
void closure (hb_closure_context_t *c) const
{
- unsigned int count = component.lenP1;
- for (unsigned int i = 1; i < count; i++)
- if (!c->glyphs->has (component[i]))
- return;
- c->out->add (ligGlyph);
+ if (!intersects (c->glyphs)) return;
+ c->output->add (ligGlyph);
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -689,15 +680,14 @@ struct Ligature
bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY (this);
if (c->len != component.lenP1)
- return_trace (false);
+ return false;
for (unsigned int i = 1; i < c->len; i++)
if (likely (c->glyphs[i] != component[i]))
- return_trace (false);
+ return false;
- return_trace (true);
+ return true;
}
bool apply (hb_ot_apply_context_t *c) const
@@ -771,38 +761,38 @@ struct LigatureSet
{
bool intersects (const hb_set_t *glyphs) const
{
- unsigned int num_ligs = ligature.len;
- for (unsigned int i = 0; i < num_ligs; i++)
- if ((this+ligature[i]).intersects (glyphs))
- return true;
- return false;
+ return
+ + hb_iter (ligature)
+ | hb_map (hb_add (this))
+ | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
+ | hb_any
+ ;
}
void closure (hb_closure_context_t *c) const
{
- unsigned int num_ligs = ligature.len;
- for (unsigned int i = 0; i < num_ligs; i++)
- (this+ligature[i]).closure (c);
+ + hb_iter (ligature)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const Ligature &_) { _.closure (c); })
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
- unsigned int num_ligs = ligature.len;
- for (unsigned int i = 0; i < num_ligs; i++)
- (this+ligature[i]).collect_glyphs (c);
+ + hb_iter (ligature)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
+ ;
}
bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY (this);
- unsigned int num_ligs = ligature.len;
- for (unsigned int i = 0; i < num_ligs; i++)
- {
- const Ligature &lig = this+ligature[i];
- if (lig.would_apply (c))
- return_trace (true);
- }
- return_trace (false);
+ return
+ + hb_iter (ligature)
+ | hb_map (hb_add (this))
+ | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
+ | hb_any
+ ;
}
bool apply (hb_ot_apply_context_t *c) const
@@ -828,7 +818,7 @@ struct LigatureSet
if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
for (unsigned int i = 0; i < ligatures.length; i++)
{
- unsigned int component_count = MAX<int> (component_count_list[i] - 1, 0);
+ unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
if (unlikely (!ligature[i].serialize (c, this)
.serialize (c,
ligatures[i],
@@ -857,52 +847,46 @@ struct LigatureSubstFormat1
{
bool intersects (const hb_set_t *glyphs) const
{
- unsigned int count = ligatureSet.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- if (glyphs->has (iter.get_glyph ()) &&
- (this+ligatureSet[iter.get_coverage ()]).intersects (glyphs))
- return true;
- }
- return false;
+ return
+ + hb_zip (this+coverage, ligatureSet)
+ | hb_filter (*glyphs, hb_first)
+ | hb_map (hb_second)
+ | hb_map ([this, glyphs] (const OffsetTo<LigatureSet> &_)
+ { return (this+_).intersects (glyphs); })
+ | hb_any
+ ;
}
void closure (hb_closure_context_t *c) const
{
- unsigned int count = ligatureSet.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- if (c->glyphs->has (iter.get_glyph ()))
- (this+ligatureSet[iter.get_coverage ()]).closure (c);
- }
+ + hb_zip (this+coverage, ligatureSet)
+ | hb_filter (*c->glyphs, hb_first)
+ | hb_map (hb_second)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
- unsigned int count = ligatureSet.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
- }
+
+ + hb_zip (this+coverage, ligatureSet)
+ | hb_map (hb_second)
+ | hb_map (hb_add (this))
+ | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
+ ;
}
const Coverage &get_coverage () const { return this+coverage; }
bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
- if (likely (index == NOT_COVERED)) return_trace (false);
+ if (likely (index == NOT_COVERED)) return false;
const LigatureSet &lig_set = this+ligatureSet[index];
- return_trace (lig_set.would_apply (c));
+ return lig_set.would_apply (c);
}
bool apply (hb_ot_apply_context_t *c) const
@@ -917,7 +901,7 @@ struct LigatureSubstFormat1
}
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> first_glyphs,
+ hb_sorted_array_t<const GlyphID> first_glyphs,
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
hb_array_t<const GlyphID> ligatures_list,
hb_array_t<const unsigned int> component_count_list,
@@ -968,7 +952,7 @@ struct LigatureSubstFormat1
struct LigatureSubst
{
bool serialize (hb_serialize_context_t *c,
- hb_array_t<const GlyphID> first_glyphs,
+ hb_sorted_array_t<const GlyphID> first_glyphs,
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
hb_array_t<const GlyphID> ligatures_list,
hb_array_t<const unsigned int> component_count_list,
@@ -977,7 +961,7 @@ struct LigatureSubst
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false);
unsigned int format = 1;
- u.format.set (format);
+ u.format = format;
switch (u.format) {
case 1: return_trace (u.format1.serialize (c,
first_glyphs,
@@ -989,13 +973,13 @@ struct LigatureSubst
}
}
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1));
+ case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());
}
}
@@ -1027,48 +1011,35 @@ struct ReverseChainSingleSubstFormat1
if (!(this+coverage).intersects (glyphs))
return false;
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
unsigned int count;
count = backtrack.len;
for (unsigned int i = 0; i < count; i++)
if (!(this+backtrack[i]).intersects (glyphs))
- return false;
+ return false;
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
if (!(this+lookahead[i]).intersects (glyphs))
- return false;
+ return false;
return true;
}
void closure (hb_closure_context_t *c) const
{
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ if (!intersects (c->glyphs)) return;
- unsigned int count;
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
- count = backtrack.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+backtrack[i]).intersects (c->glyphs))
- return;
-
- count = lookahead.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+lookahead[i]).intersects (c->glyphs))
- return;
-
- const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
- count = substitute.len;
- for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
- {
- if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
- if (c->glyphs->has (iter.get_glyph ()))
- c->out->add (substitute[iter.get_coverage ()]);
- }
+ + hb_zip (this+coverage, substitute)
+ | hb_filter (*c->glyphs, hb_first)
+ | hb_map (hb_second)
+ | hb_sink (c->output)
+ ;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1081,12 +1052,12 @@ struct ReverseChainSingleSubstFormat1
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return;
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
- const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
count = substitute.len;
c->output->add_array (substitute.arrayZ, substitute.len);
}
@@ -1094,10 +1065,7 @@ struct ReverseChainSingleSubstFormat1
const Coverage &get_coverage () const { return this+coverage; }
bool would_apply (hb_would_apply_context_t *c) const
- {
- TRACE_WOULD_APPLY (this);
- return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
- }
+ { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
bool apply (hb_ot_apply_context_t *c) const
{
@@ -1108,15 +1076,15 @@ struct ReverseChainSingleSubstFormat1
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
- const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
unsigned int start_index = 0, end_index = 0;
if (match_backtrack (c,
backtrack.len, (HBUINT16 *) backtrack.arrayZ,
match_coverage, this,
&start_index) &&
- match_lookahead (c,
+ match_lookahead (c,
lookahead.len, (HBUINT16 *) lookahead.arrayZ,
match_coverage, this,
1, &end_index))
@@ -1144,10 +1112,10 @@ struct ReverseChainSingleSubstFormat1
TRACE_SANITIZE (this);
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
return_trace (false);
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
if (!lookahead.sanitize (c, this))
return_trace (false);
- const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
return_trace (substitute.sanitize (c));
}
@@ -1173,13 +1141,13 @@ struct ReverseChainSingleSubstFormat1
struct ReverseChainSingleSubst
{
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
TRACE_DISPATCH (this, u.format);
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
- case 1: return_trace (c->dispatch (u.format1));
+ case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
default:return_trace (c->default_return_value ());
}
}
@@ -1213,19 +1181,19 @@ struct SubstLookupSubTable
ReverseChainSingle = 8
};
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
{
TRACE_DISPATCH (this, lookup_type);
switch (lookup_type) {
- case Single: return_trace (u.single.dispatch (c));
- case Multiple: return_trace (u.multiple.dispatch (c));
- case Alternate: return_trace (u.alternate.dispatch (c));
- case Ligature: return_trace (u.ligature.dispatch (c));
- case Context: return_trace (u.context.dispatch (c));
- case ChainContext: return_trace (u.chainContext.dispatch (c));
- case Extension: return_trace (u.extension.dispatch (c));
- case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c));
+ case Single: return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
+ case Multiple: return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...));
+ case Alternate: return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...));
+ case Ligature: return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...));
+ case Context: return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
+ case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
+ case Extension: return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
+ case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...));
default: return_trace (c->default_return_value ());
}
}
@@ -1253,7 +1221,7 @@ struct SubstLookup : Lookup
const SubTable& get_subtable (unsigned int i) const
{ return Lookup::get_subtable<SubTable> (i); }
- static bool lookup_type_is_reverse (unsigned int lookup_type)
+ HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type)
{ return lookup_type == SubTable::ReverseChainSingle; }
bool is_reverse () const
@@ -1306,13 +1274,12 @@ struct SubstLookup : Lookup
bool would_apply (hb_would_apply_context_t *c,
const hb_ot_layout_lookup_accelerator_t *accel) const
{
- TRACE_WOULD_APPLY (this);
- if (unlikely (!c->len)) return_trace (false);
- if (!accel->may_have (c->glyphs[0])) return_trace (false);
- return_trace (dispatch (c));
+ if (unlikely (!c->len)) return false;
+ if (!accel->may_have (c->glyphs[0])) return false;
+ return dispatch (c);
}
- static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+ HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
SubTable& serialize_subtable (hb_serialize_context_t *c,
unsigned int i)
@@ -1320,17 +1287,19 @@ struct SubstLookup : Lookup
bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props,
- hb_array_t<const GlyphID> glyphs,
- hb_array_t<const GlyphID> substitutes)
+ hb_sorted_array_t<const GlyphID> glyphs,
+ hb_array_t<const GlyphID> substitutes)
{
TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
- return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes));
+
+ return_trace (serialize_subtable (c, 0).u.single
+ .serialize (c, hb_zip (glyphs, substitutes)));
}
bool serialize_multiple (hb_serialize_context_t *c,
uint32_t lookup_props,
- hb_array_t<const GlyphID> glyphs,
+ hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const unsigned int> substitute_len_list,
hb_array_t<const GlyphID> substitute_glyphs_list)
{
@@ -1344,7 +1313,7 @@ struct SubstLookup : Lookup
bool serialize_alternate (hb_serialize_context_t *c,
uint32_t lookup_props,
- hb_array_t<const GlyphID> glyphs,
+ hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const unsigned int> alternate_len_list,
hb_array_t<const GlyphID> alternate_glyphs_list)
{
@@ -1358,7 +1327,7 @@ struct SubstLookup : Lookup
bool serialize_ligature (hb_serialize_context_t *c,
uint32_t lookup_props,
- hb_array_t<const GlyphID> first_glyphs,
+ hb_sorted_array_t<const GlyphID> first_glyphs,
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
hb_array_t<const GlyphID> ligatures_list,
hb_array_t<const unsigned int> component_count_list,
@@ -1375,12 +1344,12 @@ struct SubstLookup : Lookup
}
template <typename context_t>
- static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+ HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
- static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
+ HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
{
if (!c->should_visit_lookup (lookup_index))
- return HB_VOID;
+ return hb_empty_t ();
hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);
@@ -1392,9 +1361,9 @@ struct SubstLookup : Lookup
return ret;
}
- template <typename context_t>
- typename context_t::return_t dispatch (context_t *c) const
- { return Lookup::dispatch<SubTable> (c); }
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
bool subset (hb_subset_context_t *c) const
{ return Lookup::subset<SubTable> (c); }