From 587d49fc657c10c8a20f2409a04d72bf80bb361e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 19 Nov 2018 14:27:19 -0500 Subject: [PATCH] [fvar] Add named-instance API Fixes https://github.com/harfbuzz/harfbuzz/issues/1241 --- docs/harfbuzz-sections.txt | 4 +++ src/hb-ot-var-fvar-table.hh | 55 +++++++++++++++++++++++++++++++++++-- src/hb-ot-var.cc | 33 ++++++++++++++++++++++ src/hb-ot-var.h | 32 +++++++++++++++++++++ 4 files changed, 121 insertions(+), 3 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 63594cfcd..63d5f6cef 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -589,6 +589,10 @@ hb_ot_var_get_axis_count hb_ot_var_get_axes hb_ot_var_axis_flags_t 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_coords diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 99d2fd5cd..f61296d1b 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -42,6 +42,11 @@ namespace OT { struct InstanceRecord { + friend struct fvar; + + inline hb_array_t 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 { TRACE_SANITIZE (this); @@ -104,7 +109,7 @@ struct fvar axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && 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 @@ -186,12 +191,56 @@ struct fvar 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 (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 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: inline hb_array_t get_axes (void) const { return hb_array (&(this+firstAxis), axisCount); } - inline const InstanceRecord * get_first_instance (void) const - { return &StructAfter (get_axes ()); } + inline const InstanceRecord &get_instance (unsigned int i) const + { + if (unlikely (i >= instanceCount)) return Null (InstanceRecord); + + return StructAtOffset (&StructAfter (get_axes ()), + i * instanceSize); + } protected: FixedVersion<>version; /* Version of the fvar table diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 14c73cfd8..bb8d26490 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -116,6 +116,39 @@ hb_ot_var_axis_get_flags (hb_face_t *face, 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: diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index d535a078b..e0ac5c4a2 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -63,6 +63,11 @@ typedef struct hb_ot_var_axis_t { HB_EXTERN hb_bool_t hb_ot_var_has_data (hb_face_t *face); + +/* + * Variation axes. + */ + /** * 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, 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_ot_var_normalize_variations (hb_face_t *face, const hb_variation_t *variations, /* IN */