Add a new API, hb_ot_layout_get_feature_name_ids (#976)
authorEbrahim Byagowi <ebrahim@gnu.org>
Sat, 21 Jul 2018 16:44:48 +0000 (21:14 +0430)
committerGitHub <noreply@github.com>
Sat, 21 Jul 2018 16:44:48 +0000 (21:14 +0430)
This new API returns cvXX and ssXX related NameId, things like
featUiLabelNameId, featUiTooltipTextNameId, sampleTextNameId, ... of cvXX
and UINameId of ssXX, in a unified way.

However HarfBuzz currently doesn't expose an API for retrieving the actual
information associated with NameId from the `name` table and that should be
done separately.

docs/harfbuzz-sections.txt
src/hb-ot-layout-common-private.hh
src/hb-ot-layout.cc
src/hb-ot-layout.h

index 5715d77..b93cd1d 100644 (file)
@@ -450,6 +450,7 @@ hb_ot_layout_collect_lookups
 hb_ot_layout_feature_get_lookups
 hb_ot_layout_feature_with_variations_get_lookups
 hb_ot_layout_get_attach_points
+hb_ot_layout_get_feature_name_ids
 hb_ot_layout_get_glyph_class
 hb_ot_layout_get_glyphs_in_class
 hb_ot_layout_get_ligature_carets
index 2ae1157..21caf9e 100644 (file)
@@ -478,6 +478,20 @@ struct FeatureParams
     return Null(FeatureParamsSize);
   }
 
+  inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
+  {
+    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+      return u.stylisticSet;
+    return Null(FeatureParamsStylisticSet);
+  }
+
+  inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
+  {
+    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+      return u.characterVariants;
+    return Null(FeatureParamsCharacterVariants);
+  }
+
   private:
   union {
   FeatureParamsSize                    size;
index 3a08230..3bfa191 100644 (file)
@@ -1016,6 +1016,24 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
   OT::GPOS::position_finish_offsets (font, buffer);
 }
 
+static const OT::FeatureParams&
+_get_gsubgpos_matched_feature_params (hb_face_t *face, hb_tag_t feature)
+{
+  const OT::GSUB &gsub = _get_gsub (face);
+  unsigned int gsub_num_features = gsub.get_feature_count ();
+  for (unsigned int i = 0; i < gsub_num_features; i++)
+    if (feature == gsub.get_feature_tag (i))
+      return gsub.get_feature (i).get_feature_params ();
+
+  const OT::GPOS &gpos = _get_gpos (face);
+  unsigned int gpos_num_features = gpos.get_feature_count ();
+  for (unsigned int i = 0; i < gpos_num_features; i++)
+    if (feature == gpos.get_feature_tag (i))
+      return gpos.get_feature (i).get_feature_params ();
+
+  return Null (OT::FeatureParams);
+}
+
 /**
  * hb_ot_layout_get_size_params:
  *
@@ -1066,6 +1084,74 @@ hb_ot_layout_get_size_params (hb_face_t    *face,
   return false;
 }
 
+/**
+ * hb_ot_layout_get_feature_name_ids:
+ * @face: #hb_face_t to work upon
+ * @feature: ssXX and cvXX tag
+ * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
+ *            for a user-interface label for this feature. (May be NULL.)
+ * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
+ *              that an application can use for tooltip text for this
+ *              feature. (May be NULL.)
+ * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text
+ *             that illustrates the effect of this feature. (May be NULL.)
+ * @num_named_parameters: (out) (allow-none):  Number of named parameters. (May be zero.)
+ * @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify
+ *                  strings for user-interface labels for the feature
+ *                  parameters. (Must be zero if numParameters is zero.)
+ *
+ * Return value: true if could find any feature with the tag, false otherwise
+ *
+ * Since: REPLACEME
+ **/
+hb_bool_t
+hb_ot_layout_get_feature_name_ids (hb_face_t      *face,
+                                  hb_tag_t        feature,
+                                  unsigned int   *label_id,             /* OUT.  May be nullptr  */
+                                  unsigned int   *tooltip_id,           /* OUT.  May be nullptr  */
+                                  unsigned int   *sample_id,            /* OUT.  May be nullptr  */
+                                  unsigned int   *num_named_parameters, /* OUT.  May be nullptr  */
+                                  unsigned int   *first_param_id        /* OUT.  May be nullptr  */)
+{
+  const OT::FeatureParams &feature_params =
+    _get_gsubgpos_matched_feature_params (face, feature);
+  if (&feature_params != &Null (OT::FeatureParams))
+  {
+    const OT::FeatureParamsStylisticSet& ss_params =
+      feature_params.get_stylistic_set_params (feature);
+    if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */
+    {
+#define PARAM(a, A) if (a) *a = A
+      PARAM(label_id, ss_params.uiNameID);
+      // ssXX features don't have the rest
+      PARAM(tooltip_id, 0);
+      PARAM(sample_id, 0);
+      PARAM(num_named_parameters, 0);
+      PARAM(first_param_id, 0);
+      return true;
+    }
+    const OT::FeatureParamsCharacterVariants& cv_params =
+      feature_params.get_character_variants_params (feature);
+    if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */
+    {
+      PARAM(label_id, cv_params.featUILableNameID);
+      PARAM(tooltip_id, cv_params.featUITooltipTextNameID);
+      PARAM(sample_id, cv_params.sampleTextNameID);
+      PARAM(num_named_parameters, cv_params.numNamedParameters);
+      PARAM(first_param_id, cv_params.firstParamUILabelNameID);
+      return true;
+    }
+  }
+
+  PARAM(label_id, 0);
+  PARAM(tooltip_id, 0);
+  PARAM(sample_id, 0);
+  PARAM(num_named_parameters, 0);
+  PARAM(first_param_id, 0);
+#undef PARAM
+  return false;
+}
+
 
 /*
  * Parts of different types are implemented here such that they have direct
index 0278796..f859767 100644 (file)
@@ -322,6 +322,14 @@ hb_ot_layout_get_size_params (hb_face_t    *face,
                              unsigned int *range_start,       /* OUT.  May be NULL */
                              unsigned int *range_end          /* OUT.  May be NULL */);
 
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_feature_name_ids (hb_face_t      *face,
+                                  hb_tag_t        feature,
+                                  unsigned int   *label_id             /* OUT.  May be NULL */,
+                                  unsigned int   *tooltip_id           /* OUT.  May be NULL */,
+                                  unsigned int   *sample_id            /* OUT.  May be NULL */,
+                                  unsigned int   *num_named_parameters /* OUT.  May be NULL */,
+                                  unsigned int   *first_param_id       /* OUT.  May be NULL */);
 
 /*
  * BASE