[instancer] Add new_gid->contour_points vector map in subset plan
- Add an API in Glyph to export original contour_points vector, which is
needed by infer_deltas when merging tuple variations with the same
tent
diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh
index 2611c1e..2b2184f 100644
--- a/src/OT/glyf/Glyph.hh
+++ b/src/OT/glyf/Glyph.hh
@@ -103,6 +103,63 @@
}
}
+ bool get_all_points_without_var (const hb_face_t *face,
+ contour_point_vector_t &points /* OUT */) const
+ {
+ switch (type) {
+ case SIMPLE:
+ if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points)))
+ return false;
+ break;
+ case COMPOSITE:
+ {
+ for (auto &item : get_composite_iterator ())
+ if (unlikely (!item.get_points (points))) return false;
+ break;
+ }
+#ifndef HB_NO_VAR_COMPOSITES
+ case VAR_COMPOSITE:
+ {
+ for (auto &item : get_var_composite_iterator ())
+ if (unlikely (!item.get_points (points))) return false;
+ break;
+ }
+#endif
+ case EMPTY:
+ break;
+ }
+
+ /* Init phantom points */
+ if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
+ hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+ {
+ int lsb = 0;
+ int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
+ (int) header->xMin - lsb : 0;
+ HB_UNUSED int tsb = 0;
+ int v_orig = (int) header->yMax +
+#ifndef HB_NO_VERTICAL
+ ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
+#else
+ 0
+#endif
+ ;
+ unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid);
+ unsigned v_adv =
+#ifndef HB_NO_VERTICAL
+ face->table.vmtx->get_advance_without_var_unscaled (gid)
+#else
+ - face->get_upem ()
+#endif
+ ;
+ phantoms[PHANTOM_LEFT].x = h_delta;
+ phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
+ phantoms[PHANTOM_TOP].y = v_orig;
+ phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
+ }
+ return true;
+ }
+
void update_mtx (const hb_subset_plan_t *plan,
int xMin, int xMax,
int yMin, int yMax,
diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh
index 66da682..180d905 100644
--- a/src/hb-ot-var-gvar-table.hh
+++ b/src/hb-ot-var-gvar-table.hh
@@ -39,40 +39,6 @@
namespace OT {
-struct contour_point_t
-{
- void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
- { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
-
- void transform (const float (&matrix)[4])
- {
- float x_ = x * matrix[0] + y * matrix[2];
- y = x * matrix[1] + y * matrix[3];
- x = x_;
- }
- HB_ALWAYS_INLINE
- void translate (const contour_point_t &p) { x += p.x; y += p.y; }
-
-
- float x;
- float y;
- uint8_t flag;
- bool is_end_point;
-};
-
-struct contour_point_vector_t : hb_vector_t<contour_point_t>
-{
- void extend (const hb_array_t<contour_point_t> &a)
- {
- unsigned int old_len = length;
- if (unlikely (!resize (old_len + a.length, false)))
- return;
- auto arrayZ = this->arrayZ + old_len;
- unsigned count = a.length;
- hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
- }
-};
-
struct GlyphVariationData : TupleVariationData
{};
diff --git a/src/hb-subset-plan-member-list.hh b/src/hb-subset-plan-member-list.hh
index 8e61055..01d8b0f 100644
--- a/src/hb-subset-plan-member-list.hh
+++ b/src/hb-subset-plan-member-list.hh
@@ -123,6 +123,9 @@
//boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_height_vec)
+//map: new_gid -> contour points vector
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, contour_point_vector_t>), new_gid_contour_points_map)
+
#ifdef HB_EXPERIMENTAL_API
// name table overrides map: hb_ot_name_record_ids_t-> name string new value or
// None to indicate should remove
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index a2090b7..c293ba3 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -1045,6 +1045,36 @@
if (vvar_store_cache)
_vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache);
}
+
+static bool
+_get_instance_glyphs_contour_points (hb_subset_plan_t *plan)
+{
+ /* contour_points vector only needed for updating gvar table (infer delta)
+ * during partial instancing */
+ if (plan->user_axes_location.is_empty () || plan->all_axes_pinned)
+ return true;
+
+ OT::glyf_accelerator_t glyf (plan->source);
+
+ for (auto &_ : plan->new_to_old_gid_list)
+ {
+ hb_codepoint_t new_gid = _.first;
+ contour_point_vector_t all_points;
+ if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+ {
+ if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points)))
+ return false;
+ continue;
+ }
+
+ hb_codepoint_t old_gid = _.second;
+ if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points)))
+ return false;
+ if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points)))
+ return false;
+ }
+ return true;
+}
#endif
hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
@@ -1148,6 +1178,8 @@
#ifndef HB_NO_VAR
_update_instance_metrics_map_from_cff2 (this);
+ if (!check_success (_get_instance_glyphs_contour_points (this)))
+ return;
#endif
if (attach_accelerator_data)
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index d156de0..a05d1d1 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -67,6 +67,40 @@
typedef struct head_maxp_info_t head_maxp_info_t;
+struct contour_point_t
+{
+ void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
+ { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
+
+ void transform (const float (&matrix)[4])
+ {
+ float x_ = x * matrix[0] + y * matrix[2];
+ y = x * matrix[1] + y * matrix[3];
+ x = x_;
+ }
+ HB_ALWAYS_INLINE
+ void translate (const contour_point_t &p) { x += p.x; y += p.y; }
+
+
+ float x;
+ float y;
+ uint8_t flag;
+ bool is_end_point;
+};
+
+struct contour_point_vector_t : hb_vector_t<contour_point_t>
+{
+ void extend (const hb_array_t<contour_point_t> &a)
+ {
+ unsigned int old_len = length;
+ if (unlikely (!resize (old_len + a.length, false)))
+ return;
+ auto arrayZ = this->arrayZ + old_len;
+ unsigned count = a.length;
+ hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
+ }
+};
+
namespace OT {
struct cff1_subset_accelerator_t;
struct cff2_subset_accelerator_t;