diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 051bfda69..f2f3b05f2 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -66,6 +66,60 @@ namespace OT { #define NOT_COVERED ((unsigned int) -1) +template +struct subset_offset_array_t +{ + subset_offset_array_t + (hb_subset_context_t *subset_context, + OutputArray& out, + const void *src_base, + const void *dest_base) + : _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base) {} + + template + bool + operator () + (T&& offset) + { + auto *o = _out.serialize_append (_subset_context->serializer); + if (unlikely (!o)) return false; + auto snap = _subset_context->serializer->snapshot (); + bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base); + if (!ret) + { + _out.pop (); + _subset_context->serializer->revert (snap); + } + return ret; + } + + private: + hb_subset_context_t *_subset_context; + OutputArray &_out; + const void *_src_base; + const void *_dest_base; +}; + +/* + * Helper to subset an array of offsets. Subsets the thing pointed to by each offset + * and discards the offset in the array if the subset operation results in an empty + * thing. + */ +struct +{ + template + subset_offset_array_t + operator () + (hb_subset_context_t *subset_context, + OutputArray& out, + const void *src_base, + const void *dest_base) const + { + return subset_offset_array_t (subset_context, out, src_base, dest_base); + } +} +HB_FUNCOBJ (subset_offset_array); + /* * diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index a2722ade9..f080d682a 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1074,20 +1074,7 @@ struct LigatureSubstFormat1 hb_sorted_vector_t new_coverage; + hb_zip (this+coverage, ligatureSet) | hb_filter (glyphset, hb_first) - | hb_filter ([this, c, out] (const OffsetTo& _) - { - auto *o = out->ligatureSet.serialize_append (c->serializer); - if (unlikely (!o)) return false; - auto snap = c->serializer->snapshot (); - bool ret = o->serialize_subset (c, _, this, out); - if (!ret) - { - out->ligatureSet.pop (); - c->serializer->revert (snap); - } - return ret; - }, - hb_second) + | hb_filter (subset_offset_array (c, out->ligatureSet, this, out), hb_second) | hb_map (hb_first) | hb_map (glyph_map) | hb_sink (new_coverage)