diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2018-10-19 23:02:01 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2018-10-19 23:02:01 +0000 |
commit | 4ca29e7f53a6b8a57f2f64c3c3e9a0b423e76429 (patch) | |
tree | d9b59fe0f8f0a178fc2f4aac4f26ddca36434038 /Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc | |
parent | bd0c56dddccc51f470df742260cb6137223d1dda (diff) |
harfbuzz 2.0.0
git-svn-id: svn://tug.org/texlive/trunk@48949 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc | 392 |
1 files changed, 244 insertions, 148 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index a1220f4dd3b..fb1d9b11f25 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -45,17 +45,15 @@ #include "hb-ot-color-cpal-table.hh" #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-svg-table.hh" +#include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" -// static inline const OT::BASE& -// _get_base (hb_face_t *face) -// { -// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); -// hb_ot_face_data_t *data = hb_ot_face_data (face); -// return *(data->base.get ()); -// } - +static const OT::kern::accelerator_t& _get_kern (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t); + return *hb_ot_face_data (face)->kern; +} const OT::GDEF& _get_gdef (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); @@ -92,6 +90,25 @@ const OT::GPOS& _get_gpos_relaxed (hb_face_t *face) /* + * kern + */ + +hb_bool_t +hb_ot_layout_has_kerning (hb_face_t *face) +{ + return _get_kern (face).has_data (); +} + +void +hb_ot_layout_kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) +{ + _get_kern (font->face).apply (font, buffer, kern_mask); +} + + +/* * GDEF */ @@ -305,7 +322,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *script_count /* IN/OUT */, - hb_tag_t *script_tags /* OUT */) + hb_tag_t *script_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -351,17 +368,36 @@ hb_ot_layout_table_choose_script (hb_face_t *face, unsigned int *script_index, hb_tag_t *chosen_script) { + const hb_tag_t *t; + for (t = script_tags; *t; t++); + return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script); +} + +/** + * hb_ot_layout_table_select_script: + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_table_select_script (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_count, + const hb_tag_t *script_tags, + unsigned int *script_index /* OUT */, + hb_tag_t *chosen_script /* OUT */) +{ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), ""); const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + unsigned int i; - while (*script_tags) + for (i = 0; i < script_count; i++) { - if (g.find_script_index (*script_tags, script_index)) { + if (g.find_script_index (script_tags[i], script_index)) + { if (chosen_script) - *chosen_script = *script_tags; + *chosen_script = script_tags[i]; return true; } - script_tags++; } /* try finding 'DFLT' */ @@ -397,7 +433,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */) + hb_tag_t *feature_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -433,7 +469,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, unsigned int script_index, unsigned int start_offset, unsigned int *language_count /* IN/OUT */, - hb_tag_t *language_tags /* OUT */) + hb_tag_t *language_tags /* OUT */) { const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); @@ -447,13 +483,33 @@ hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t language_tag, unsigned int *language_index) { + return hb_ot_layout_script_select_language (face, table_tag, script_index, 1, &language_tag, language_index); +} + +/** + * hb_ot_layout_script_select_language: + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_script_select_language (hb_face_t *face, + hb_tag_t table_tag, + unsigned int script_index, + unsigned int language_count, + const hb_tag_t *language_tags, + unsigned int *language_index /* OUT */) +{ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), ""); const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); + unsigned int i; - if (s.find_lang_sys_index (language_tag, language_index)) - return true; + for (i = 0; i < language_count; i++) + { + if (s.find_lang_sys_index (language_tags[i], language_index)) + return true; + } - /* try with 'dflt'; MS site has had typos and many fonts use it now :( */ + /* try finding 'dflt' */ if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) return false; @@ -518,7 +574,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, unsigned int script_index, unsigned int language_index, unsigned int start_offset, - unsigned int *feature_count /* IN/OUT */, + unsigned int *feature_count /* IN/OUT */, unsigned int *feature_indexes /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -534,7 +590,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, unsigned int language_index, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */) + hb_tag_t *feature_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); @@ -588,7 +644,7 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, unsigned int start_offset, - unsigned int *lookup_count /* IN/OUT */, + unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_indexes /* OUT */) { return hb_ot_layout_feature_with_variations_get_lookups (face, @@ -726,11 +782,12 @@ _hb_ot_layout_collect_features_languages (hb_face_t *face, for (; *languages; languages++) { unsigned int language_index; - if (hb_ot_layout_script_find_language (face, - table_tag, - script_index, - *languages, - &language_index)) + if (hb_ot_layout_script_select_language (face, + table_tag, + script_index, + 1, + languages, + &language_index)) _hb_ot_layout_collect_features_features (face, table_tag, script_index, @@ -815,10 +872,10 @@ void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, - hb_set_t *glyphs_before, /* OUT. May be nullptr */ - hb_set_t *glyphs_input, /* OUT. May be nullptr */ - hb_set_t *glyphs_after, /* OUT. May be nullptr */ - hb_set_t *glyphs_output /* OUT. May be nullptr */) + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output /* OUT. May be NULL */) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; @@ -1016,11 +1073,11 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) **/ hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be nullptr */ - unsigned int *subfamily_id, /* OUT. May be nullptr */ - unsigned int *subfamily_name_id, /* OUT. May be nullptr */ - unsigned int *range_start, /* OUT. May be nullptr */ - unsigned int *range_end /* OUT. May be nullptr */) + unsigned int *design_size, /* OUT. May be NULL */ + unsigned int *subfamily_id, /* OUT. May be NULL */ + unsigned int *subfamily_name_id, /* OUT. May be NULL */ + unsigned int *range_start, /* OUT. May be NULL */ + unsigned int *range_end /* OUT. May be NULL */) { const OT::GPOS &gpos = _get_gpos (face); const hb_tag_t tag = HB_TAG ('s','i','z','e'); @@ -1035,30 +1092,152 @@ hb_ot_layout_get_size_params (hb_face_t *face, if (params.designSize) { -#define PARAM(a, A) if (a) *a = params.A - PARAM (design_size, designSize); - PARAM (subfamily_id, subfamilyID); - PARAM (subfamily_name_id, subfamilyNameID); - PARAM (range_start, rangeStart); - PARAM (range_end, rangeEnd); -#undef PARAM + if (design_size) *design_size = params.designSize; + if (subfamily_id) *subfamily_id = params.subfamilyID; + if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID; + if (range_start) *range_start = params.rangeStart; + if (range_end) *range_end = params.rangeEnd; return true; } } } -#define PARAM(a, A) if (a) *a = 0 - PARAM (design_size, designSize); - PARAM (subfamily_id, subfamilyID); - PARAM (subfamily_name_id, subfamilyNameID); - PARAM (range_start, rangeStart); - PARAM (range_end, rangeEnd); -#undef PARAM + if (design_size) *design_size = 0; + if (subfamily_id) *subfamily_id = 0; + if (subfamily_name_id) *subfamily_name_id = 0; + if (range_start) *range_start = 0; + if (range_end) *range_end = 0; + + return false; +} + +/** + * hb_ot_layout_feature_get_name_ids: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @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.) + * + * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or + * "Character Variant" ('cvXX') features. + * + * Return value: true if data found, false otherwise + * + * Since: 2.0.0 + **/ +hb_bool_t +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_name_id_t *label_id, /* OUT. May be NULL */ + hb_name_id_t *tooltip_id, /* OUT. May be NULL */ + hb_name_id_t *sample_id, /* OUT. May be NULL */ + unsigned int *num_named_parameters, /* OUT. May be NULL */ + hb_name_id_t *first_param_id /* OUT. May be NULL */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + hb_tag_t feature_tag = g.get_feature_tag (feature_index); + const OT::Feature &f = g.get_feature (feature_index); + + const OT::FeatureParams &feature_params = f.get_feature_params (); + if (&feature_params != &Null (OT::FeatureParams)) + { + const OT::FeatureParamsStylisticSet& ss_params = + feature_params.get_stylistic_set_params (feature_tag); + if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */ + { + if (label_id) *label_id = ss_params.uiNameID; + // ssXX features don't have the rest + if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (num_named_parameters) *num_named_parameters = 0; + if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; + return true; + } + const OT::FeatureParamsCharacterVariants& cv_params = + feature_params.get_character_variants_params (feature_tag); + if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */ + { + if (label_id) *label_id = cv_params.featUILableNameID; + if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID; + if (sample_id) *sample_id = cv_params.sampleTextNameID; + if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters; + if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID; + return true; + } + } + if (label_id) *label_id = HB_NAME_ID_INVALID; + if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (num_named_parameters) *num_named_parameters = 0; + if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; return false; } +/** + * hb_ot_layout_feature_get_characters:: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @start_offset: In case the resulting char_count was equal to its input value, there + * is a chance there were more characters on the tag so this API can be + * called with an offset till resulting char_count gets to a number + * lower than input buffer (or consider using just a bigger buffer for + * one shot copying). + * @char_count: (inout) (allow-none): The count of characters for which this feature + * provides glyph variants. (May be zero.) + * @characters: (out) (allow-none): A buffer pointer. The Unicode Scalar Value + * of the characters for which this feature provides glyph variants. + * + * Fetches characters listed by designer under feature parameters for "Character + * Variant" ("cvXX") features. + * + * Return value: Number of total sample characters in the cvXX feature. + * + * Since: 2.0.0 + **/ +unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int start_offset, + unsigned int *char_count, /* IN/OUT. May be NULL */ + hb_codepoint_t *characters /* OUT. May be NULL */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + hb_tag_t feature_tag = g.get_feature_tag (feature_index); + const OT::Feature &f = g.get_feature (feature_index); + + const OT::FeatureParams &feature_params = f.get_feature_params (); + + const OT::FeatureParamsCharacterVariants& cv_params = + feature_params.get_character_variants_params(feature_tag); + + unsigned int len = 0; + if (char_count && characters && start_offset < cv_params.characters.len) + { + len = MIN (cv_params.characters.len - start_offset, *char_count); + for (unsigned int i = 0; i < len; ++i) + characters[i] = cv_params.characters[start_offset + i]; + } + if (char_count) *char_count = len; + return cv_params.characters.len; +} + /* * Parts of different types are implemented here such that they have direct @@ -1077,7 +1256,7 @@ struct GSUBProxy accels (hb_ot_face_data (face)->GSUB->accels) {} const OT::GSUB &table; - const hb_ot_layout_lookup_accelerator_t *accels; + const OT::hb_ot_layout_lookup_accelerator_t *accels; }; struct GPOSProxy @@ -1091,63 +1270,13 @@ struct GPOSProxy accels (hb_ot_face_data (face)->GPOS->accels) {} const OT::GPOS &table; - const hb_ot_layout_lookup_accelerator_t *accels; + const OT::hb_ot_layout_lookup_accelerator_t *accels; }; -struct hb_get_subtables_context_t : - hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> -{ - template <typename Type> - static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) - { - const Type *typed_obj = (const Type *) obj; - return typed_obj->apply (c); - } - - typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); - - struct hb_applicable_t - { - inline void init (const void *obj_, hb_apply_func_t apply_func_) - { - obj = obj_; - apply_func = apply_func_; - } - - inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); } - - private: - const void *obj; - hb_apply_func_t apply_func; - }; - - typedef hb_auto_t<hb_vector_t<hb_applicable_t> > array_t; - - /* Dispatch interface. */ - inline const char *get_name (void) { return "GET_SUBTABLES"; } - template <typename T> - inline return_t dispatch (const T &obj) - { - hb_applicable_t *entry = array.push(); - entry->init (&obj, apply_to<T>); - return HB_VOID; - } - static return_t default_return_value (void) { return HB_VOID; } - bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } - - hb_get_subtables_context_t (array_t &array_) : - array (array_), - debug_depth (0) {} - - array_t &array; - unsigned int debug_depth; -}; - static inline bool apply_forward (OT::hb_ot_apply_context_t *c, - const hb_ot_layout_lookup_accelerator_t &accel, - const hb_get_subtables_context_t::array_t &subtables) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -1158,12 +1287,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { - for (unsigned int i = 0; i < subtables.len; i++) - if (subtables[i].apply (c)) - { - applied = true; - break; - } + applied = accel.apply (c); } if (applied) @@ -1176,8 +1300,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, static inline bool apply_backward (OT::hb_ot_apply_context_t *c, - const hb_ot_layout_lookup_accelerator_t &accel, - const hb_get_subtables_context_t::array_t &subtables) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -1187,12 +1310,8 @@ apply_backward (OT::hb_ot_apply_context_t *c, (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) { - for (unsigned int i = 0; i < subtables.len; i++) - if (subtables[i].apply (c)) - { - ret = true; - break; - } + if (accel.apply (c)) + ret = true; } /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -1206,7 +1325,7 @@ template <typename Proxy> static inline void apply_string (OT::hb_ot_apply_context_t *c, const typename Proxy::Lookup &lookup, - const hb_ot_layout_lookup_accelerator_t &accel) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { hb_buffer_t *buffer = c->buffer; @@ -1215,10 +1334,6 @@ apply_string (OT::hb_ot_apply_context_t *c, c->set_lookup_props (lookup.get_props ()); - hb_get_subtables_context_t::array_t subtables; - hb_get_subtables_context_t c_get_subtables (subtables); - lookup.dispatch (&c_get_subtables); - if (likely (!lookup.is_reverse ())) { /* in/out forward substitution/positioning */ @@ -1227,7 +1342,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->idx = 0; bool ret; - ret = apply_forward (c, accel, subtables); + ret = apply_forward (c, accel); if (ret) { if (!Proxy::inplace) @@ -1243,7 +1358,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->remove_output (); buffer->idx = buffer->len - 1; - apply_backward (c, accel, subtables); + apply_backward (c, accel); } } @@ -1268,6 +1383,11 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, c.set_lookup_mask (lookups[table_index][i].mask); c.set_auto_zwj (lookups[table_index][i].auto_zwj); c.set_auto_zwnj (lookups[table_index][i].auto_zwnj); + if (lookups[table_index][i].random) + { + c.set_random (true); + buffer->unsafe_to_break_all (); + } apply_string<Proxy> (&c, proxy.table.get_lookup (lookup_index), proxy.accels[lookup_index]); @@ -1297,31 +1417,7 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_ void hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, const OT::SubstLookup &lookup, - const hb_ot_layout_lookup_accelerator_t &accel) + const OT::hb_ot_layout_lookup_accelerator_t &accel) { apply_string<GSUBProxy> (c, lookup, accel); } - - - - -/* - * OT::BASE - */ - -// /** -// * hb_ot_base_has_data: -// * @face: #hb_face_t to test -// * -// * This function allows to verify the presence of an OpenType BASE table on the -// * face. -// * -// * Return value: true if face has a BASE table, false otherwise -// * -// * Since: XXX -// **/ -// hb_bool_t -// hb_ot_base_has_data (hb_face_t *face) -// { -// return _get_base (face).has_data (); -// } |