[fvar] Add named-instance API

Fixes https://github.com/harfbuzz/harfbuzz/issues/1241
This commit is contained in:
Behdad Esfahbod 2018-11-19 14:27:19 -05:00
parent 46c0da820f
commit 587d49fc65
4 changed files with 121 additions and 3 deletions

View File

@ -589,6 +589,10 @@ hb_ot_var_get_axis_count
hb_ot_var_get_axes hb_ot_var_get_axes
hb_ot_var_axis_flags_t hb_ot_var_axis_flags_t
hb_ot_var_axis_get_flags hb_ot_var_axis_get_flags
hb_ot_var_get_named_instance_count
hb_ot_var_named_instance_get_subfamily_name_id
hb_ot_var_named_instance_get_postscript_name_id
hb_ot_var_named_instance_get_design_coords
hb_ot_var_normalize_variations hb_ot_var_normalize_variations
hb_ot_var_normalize_coords hb_ot_var_normalize_coords
</SECTION> </SECTION>

View File

@ -42,6 +42,11 @@ namespace OT {
struct InstanceRecord struct InstanceRecord
{ {
friend struct fvar;
inline hb_array_t<const Fixed> get_coordinates (unsigned int axis_count) const
{ return coordinatesZ.as_array (axis_count); }
inline bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const inline bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -104,7 +109,7 @@ struct fvar
axisSize == 20 && /* Assumed in our code. */ axisSize == 20 && /* Assumed in our code. */
instanceSize >= axisCount * 4 + 4 && instanceSize >= axisCount * 4 + 4 &&
get_axes ().sanitize (c) && get_axes ().sanitize (c) &&
c->check_range (get_first_instance (), instanceCount, instanceSize)); c->check_range (&get_instance (0), instanceCount, instanceSize));
} }
inline unsigned int get_axis_count (void) const inline unsigned int get_axis_count (void) const
@ -186,12 +191,56 @@ struct fvar
return (int) (v * 16384.f + (v >= 0.f ? .5f : -.5f)); return (int) (v * 16384.f + (v >= 0.f ? .5f : -.5f));
} }
inline unsigned int get_instance_count (void) const
{ return instanceCount; }
inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int index) const
{
const InstanceRecord &instance = get_instance (index);
return instance.subfamilyNameID;
}
inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int index) const
{
const InstanceRecord &instance = get_instance (index);
if (instanceSize >= axisCount * 4 + 6)
return StructAfter<NameID> (instance.get_coordinates (axisCount));
return HB_OT_NAME_ID_INVALID;
}
inline unsigned int get_instance_coords (unsigned int index,
unsigned int *coords_length, /* IN/OUT */
int *coords /* OUT */) const
{
if (unlikely (index >= instanceCount))
{
if (coords_length)
*coords_length = 0;
return 0;
}
if (coords_length && *coords_length)
{
const InstanceRecord &instance = get_instance (index);
hb_array_t<const Fixed> instanceCoords = instance.get_coordinates (axisCount)
.sub_array (0, *coords_length);
for (unsigned int i = 0; i < instanceCoords.len; i++)
coords[i] = instanceCoords.arrayZ[i].to_float ();
}
return axisCount;
}
protected: protected:
inline hb_array_t<const AxisRecord> get_axes (void) const inline hb_array_t<const AxisRecord> get_axes (void) const
{ return hb_array (&(this+firstAxis), axisCount); } { return hb_array (&(this+firstAxis), axisCount); }
inline const InstanceRecord * get_first_instance (void) const inline const InstanceRecord &get_instance (unsigned int i) const
{ return &StructAfter<InstanceRecord> (get_axes ()); } {
if (unlikely (i >= instanceCount)) return Null (InstanceRecord);
return StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()),
i * instanceSize);
}
protected: protected:
FixedVersion<>version; /* Version of the fvar table FixedVersion<>version; /* Version of the fvar table

View File

@ -116,6 +116,39 @@ hb_ot_var_axis_get_flags (hb_face_t *face,
return face->table.fvar->get_axis_flags (axis_index); return face->table.fvar->get_axis_flags (axis_index);
} }
/*
* Named instances.
*/
unsigned int
hb_ot_var_get_named_instance_count (hb_face_t *face)
{
return face->table.fvar->get_instance_count ();
}
hb_ot_name_id_t
hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face,
unsigned int instance_index)
{
return face->table.fvar->get_instance_subfamily_name_id (instance_index);
}
hb_ot_name_id_t
hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face,
unsigned int instance_index)
{
return face->table.fvar->get_instance_postscript_name_id (instance_index);
}
unsigned int
hb_ot_var_named_instance_get_design_coords (hb_face_t *face,
unsigned int instance_index,
unsigned int *coords_length, /* IN/OUT */
int *coords /* OUT */)
{
return face->table.fvar->get_instance_coords (instance_index, coords_length, coords);
}
/** /**
* hb_ot_var_normalize_variations: * hb_ot_var_normalize_variations:

View File

@ -63,6 +63,11 @@ typedef struct hb_ot_var_axis_t {
HB_EXTERN hb_bool_t HB_EXTERN hb_bool_t
hb_ot_var_has_data (hb_face_t *face); hb_ot_var_has_data (hb_face_t *face);
/*
* Variation axes.
*/
/** /**
* HB_OT_VAR_NO_AXIS_INDEX: * HB_OT_VAR_NO_AXIS_INDEX:
* *
@ -99,6 +104,33 @@ HB_EXTERN hb_ot_var_axis_flags_t
hb_ot_var_axis_get_flags (hb_face_t *face, hb_ot_var_axis_get_flags (hb_face_t *face,
unsigned int axis_index); unsigned int axis_index);
/*
* Named instances.
*/
HB_EXTERN unsigned int
hb_ot_var_get_named_instance_count (hb_face_t *face);
HB_EXTERN hb_ot_name_id_t
hb_ot_var_named_instance_get_subfamily_name_id (hb_face_t *face,
unsigned int instance_index);
HB_EXTERN hb_ot_name_id_t
hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face,
unsigned int instance_index);
HB_EXTERN unsigned int
hb_ot_var_named_instance_get_design_coords (hb_face_t *face,
unsigned int instance_index,
unsigned int *coords_length, /* IN/OUT */
int *coords /* OUT */);
/*
* Conversions.
*/
HB_EXTERN void HB_EXTERN void
hb_ot_var_normalize_variations (hb_face_t *face, hb_ot_var_normalize_variations (hb_face_t *face,
const hb_variation_t *variations, /* IN */ const hb_variation_t *variations, /* IN */