summaryrefslogtreecommitdiff
path: root/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/harfbuzz/src/OT/glyf/glyf.hh')
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/glyf.hh103
1 files changed, 75 insertions, 28 deletions
diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
index bcaf44fc1e..5fb32f67f3 100644
--- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
+++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
@@ -24,7 +24,6 @@ namespace OT {
*/
#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
-
struct glyf
{
friend struct glyf_accelerator_t;
@@ -73,7 +72,13 @@ struct glyf
if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
- _populate_subset_glyphs (c->plan, &glyphs);
+ _populate_subset_glyphs (c->plan, glyphs);
+
+ if (!c->plan->pinned_at_default)
+ {
+ if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs))
+ return_trace (false);
+ }
auto padded_offsets =
+ hb_iter (glyphs)
@@ -93,6 +98,8 @@ struct glyf
}
+ if (!c->plan->pinned_at_default)
+ _free_compiled_subset_glyphs (&glyphs);
if (unlikely (c->serializer->in_error ())) return_trace (false);
return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
padded_offsets,
@@ -101,7 +108,17 @@ struct glyf
void
_populate_subset_glyphs (const hb_subset_plan_t *plan,
- hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
+ hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
+
+ bool
+ _compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
+ hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
+
+ void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> *glyphs) const
+ {
+ for (auto _ : *glyphs)
+ _.free_compiled_bytes ();
+ }
protected:
UnsizedArrayOf<HBUINT8>
@@ -166,7 +183,7 @@ struct glyf_accelerator_t
contour_point_vector_t all_points;
bool phantom_only = !consumer.is_consuming_contour_points ();
- if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, phantom_only)))
+ if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, true, phantom_only)))
return false;
if (consumer.is_consuming_contour_points ())
@@ -360,35 +377,65 @@ struct glyf_accelerator_t
inline void
glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
- hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
+ hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
{
OT::glyf_accelerator_t glyf (plan->source);
+ unsigned num_glyphs = plan->num_output_glyphs ();
+ if (!glyphs.resize (num_glyphs)) return;
- + hb_range (plan->num_output_glyphs ())
- | hb_map ([&] (hb_codepoint_t new_gid)
- {
- glyf_impl::SubsetGlyph subset_glyph = {0};
- subset_glyph.new_gid = new_gid;
-
- /* should never fail: all old gids should be mapped */
- if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
- return subset_glyph;
-
- if (new_gid == 0 &&
- !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
- subset_glyph.source_glyph = glyf_impl::Glyph ();
- else
- subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
- if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
- subset_glyph.drop_hints_bytes ();
- else
- subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
- return subset_glyph;
- })
- | hb_sink (glyphs)
- ;
+ for (auto p : plan->glyph_map->iter ())
+ {
+ unsigned new_gid = p.second;
+ glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid];
+ subset_glyph.old_gid = p.first;
+
+ if (unlikely (new_gid == 0 &&
+ !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
+ plan->pinned_at_default)
+ subset_glyph.source_glyph = glyf_impl::Glyph ();
+ else
+ subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
+
+ if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ subset_glyph.drop_hints_bytes ();
+ else
+ subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
+ }
}
+inline bool
+glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
+ hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
+{
+ OT::glyf_accelerator_t glyf (plan->source);
+ hb_font_t *font = hb_font_create (plan->source);
+ if (unlikely (!font)) return false;
+
+ hb_vector_t<hb_variation_t> vars;
+ if (unlikely (!vars.alloc (plan->user_axes_location->get_population ())))
+ return false;
+
+ for (auto _ : *plan->user_axes_location)
+ {
+ hb_variation_t var;
+ var.tag = _.first;
+ var.value = _.second;
+ vars.push (var);
+ }
+
+ hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
+ for (auto& subset_glyph : *glyphs)
+ {
+ if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf))
+ {
+ hb_font_destroy (font);
+ return false;
+ }
+ }
+
+ hb_font_destroy (font);
+ return true;
+}
} /* namespace OT */