mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-14 17:13:40 +00:00
[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
This commit is contained in:
parent
a0f810effc
commit
eb116e163e
5 changed files with 126 additions and 34 deletions
|
@ -103,6 +103,63 @@ struct Glyph
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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
|
||||
{};
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_width_vec)
|
|||
//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
|
||||
|
|
|
@ -1045,6 +1045,36 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan)
|
|||
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 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
|
|||
|
||||
#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)
|
||||
|
|
|
@ -67,6 +67,40 @@ struct head_maxp_info_t
|
|||
|
||||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue