From 02e5e5d939be36d8f108029601a1ce1f533e5ccb Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 13 May 2019 09:38:42 -0700 Subject: [PATCH] [subset] retian nameids from STAT and fvar tables --- src/hb-ot-stat-table.hh | 76 ++++++++++++++++++++++++++++++++++--- src/hb-ot-var-fvar-table.hh | 21 ++++++++++ src/hb-subset-plan.cc | 26 +++++++++++++ 3 files changed, 117 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index e29d1ced7..0f75cd329 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -65,6 +65,8 @@ struct AxisValueFormat1 return_trace (likely (c->check_struct (this))); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + protected: HBUINT16 format; /* Format identifier — set to 1. */ HBUINT16 axisIndex; /* Zero-base index into the axis record array @@ -88,6 +90,8 @@ struct AxisValueFormat2 return_trace (likely (c->check_struct (this))); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + protected: HBUINT16 format; /* Format identifier — set to 2. */ HBUINT16 axisIndex; /* Zero-base index into the axis record array @@ -115,6 +119,8 @@ struct AxisValueFormat3 return_trace (likely (c->check_struct (this))); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + protected: HBUINT16 format; /* Format identifier — set to 3. */ HBUINT16 axisIndex; /* Zero-base index into the axis record array @@ -157,6 +163,8 @@ struct AxisValueFormat4 return_trace (likely (c->check_struct (this))); } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + protected: HBUINT16 format; /* Format identifier — set to 4. */ HBUINT16 axisCount; /* The total number of axes contributing to @@ -191,6 +199,18 @@ struct AxisValue } } + hb_ot_name_id_t get_value_name_id () const + { + switch (u.format) + { + case 1: return u.format1.get_value_name_id (); + case 2: return u.format2.get_value_name_id (); + case 3: return u.format3.get_value_name_id (); + case 4: return u.format4.get_value_name_id (); + default: return HB_OT_NAME_ID_INVALID; + } + } + protected: union { @@ -212,6 +232,8 @@ struct StatAxisRecord return_trace (likely (c->check_struct (this))); } + hb_ot_name_id_t get_name_id () const { return nameID; } + protected: Tag tag; /* A tag identifying the axis of design variation. */ NameID nameID; /* The name ID for entries in the 'name' table that @@ -231,17 +253,59 @@ struct STAT { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - majorVersion == 1 && - minorVersion > 0 && + version.major == 1 && + version.minor > 0 && designAxesOffset.sanitize (c, this, designAxisCount) && offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets)))); } + + bool has_data () const { return version.to_int (); } + + unsigned get_design_axis_count () const { return designAxisCount; } + + hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const + { + if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID; + const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index]; + return axis_record.get_name_id (); + } + + unsigned get_axis_value_count () const { return axisValueCount; } + + hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const + { + if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID; + const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]); + return axis_value.get_value_name_id (); + } + + void collect_name_ids (hb_set_t *nameids_to_retain) const + { + if (!has_data ()) return; + + + get_design_axes () + | hb_map (&StatAxisRecord::get_name_id) + | hb_sink (nameids_to_retain) + ; + + + get_axis_value_offsets () + | hb_map ([&] (const OffsetTo& _) -> const AxisValue* { return hb_addressof (this + _); }) + | hb_map (&AxisValue::get_value_name_id) + | hb_sink (nameids_to_retain) + ; + } protected: - HBUINT16 majorVersion; /* Major version number of the style attributes - * table — set to 1. */ - HBUINT16 minorVersion; /* Minor version number of the style attributes - * table — set to 2. */ + hb_array_t const get_design_axes () const + { return (this+designAxesOffset).as_array (designAxisCount); } + + hb_array_t> const get_axis_value_offsets () const + { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); } + + + protected: + FixedVersion<>version; /* Version of the stat table + * initially set to 0x00010002u */ HBUINT16 designAxisSize; /* The size in bytes of each axis record. */ HBUINT16 designAxisCount;/* The number of design axis records. In a * font with an 'fvar' table, this value must be diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index aa89dce26..3c6a95aa6 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -280,6 +280,27 @@ struct fvar return axisCount; } + void collect_name_ids (hb_set_t *nameids) const + { + if (!has_data ()) return; + + + get_axes () + | hb_map (&AxisRecord::axisNameID) + | hb_sink (nameids) + ; + + + hb_range ((unsigned) instanceCount) + | hb_map ([&] (const unsigned _) -> unsigned { return get_instance_subfamily_name_id (_); }) + | hb_sink (nameids) + ; + + + hb_range ((unsigned) instanceCount) + | hb_map ([&] (const unsigned _) -> unsigned { return get_instance_postscript_name_id (_); }) + | hb_sink (nameids) + ; + } + + protected: hb_array_t get_axes () const { return hb_array (&(this+firstAxis), axisCount); } diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index e475676a5..0c1c7a254 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -31,6 +31,8 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-cff1-table.hh" +#include "hb-ot-var-fvar-table.hh" +#include "hb-ot-stat-table.hh" static inline void _add_gid_and_children (const OT::glyf::accelerator_t &glyf, @@ -192,6 +194,29 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, ; } +static void +_nameid_closure (hb_face_t *face, + hb_set_t *nameids) +{ + hb_tag_t table_tags[32]; + unsigned count = ARRAY_LENGTH (table_tags); + hb_face_get_table_tags (face, 0, &count, table_tags); + for (unsigned int i = 0; i < count; i++) + { + hb_tag_t tag = table_tags[i]; + switch (tag) { + case HB_OT_TAG_STAT: + face->table.STAT->collect_name_ids (nameids); + break; + case HB_OT_TAG_fvar: + face->table.fvar->collect_name_ids (nameids); + break; + default: + break; + } + } +} + /** * hb_subset_plan_create: * Computes a plan for subsetting the supplied face according @@ -217,6 +242,7 @@ hb_subset_plan_create (hb_face_t *face, /* TODO Clean this up... */ if (hb_set_is_empty (plan->name_ids)) hb_set_add_range (plan->name_ids, 0, 0x7FFF); + _nameid_closure (face, plan->name_ids); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); plan->codepoint_to_glyph = hb_map_create ();