From 0c1b287b72e91e0898d75acb5d5acf1c6b9a7498 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 21 Jul 2018 21:14:48 +0430 Subject: [PATCH] Add a new API, hb_ot_layout_get_feature_name_ids (#976) 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 | 1 + src/hb-ot-layout-common-private.hh | 14 +++++ src/hb-ot-layout.cc | 86 ++++++++++++++++++++++++++++++ src/hb-ot-layout.h | 8 +++ 4 files changed, 109 insertions(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 5715d7716..b93cd1d60 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -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 diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 2ae1157dc..21caf9e95 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -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; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 3a0823073..3bfa19127 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -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 diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 027879622..f8597673f 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -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