summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2018-11-19 14:27:19 -0500
committerBehdad Esfahbod <behdad@behdad.org>2018-11-19 14:51:34 -0500
commit587d49fc657c10c8a20f2409a04d72bf80bb361e (patch)
tree551af5c4d89cc1ad3d06899e91c1aad833be3064
parent46c0da820fc313bad8afaf019d2cd9065fa5f514 (diff)
[fvar] Add named-instance API
Fixes https://github.com/harfbuzz/harfbuzz/issues/1241
-rw-r--r--docs/harfbuzz-sections.txt4
-rw-r--r--src/hb-ot-var-fvar-table.hh55
-rw-r--r--src/hb-ot-var.cc33
-rw-r--r--src/hb-ot-var.h32
4 files changed, 121 insertions, 3 deletions
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 63594cfc..63d5f6ce 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
</SECTION>
diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh
index 99d2fd5c..f61296d1 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<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
{
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<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:
inline hb_array_t<const AxisRecord> get_axes (void) const
{ return hb_array (&(this+firstAxis), axisCount); }
- inline const InstanceRecord * get_first_instance (void) const
- { return &StructAfter<InstanceRecord> (get_axes ()); }
+ inline const InstanceRecord &get_instance (unsigned int i) const
+ {
+ if (unlikely (i >= instanceCount)) return Null (InstanceRecord);
+
+ return StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (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 14c73cfd..bb8d2649 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 d535a078..e0ac5c4a 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 */