From 68c86af187ff645a1305ac3b64832f3bb2350519 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Oct 2018 21:18:20 -0400 Subject: [PATCH 01/18] Always compile deprecated symbols We haven't been keeping this updated. So, while we don't expose the symbols in the headers if HB_DISABLE_DEPRECATED is defined, we still always build them. --- src/hb-font.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index fd0e097a8..c9656cee7 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1910,8 +1910,6 @@ hb_font_get_var_coords_normalized (hb_font_t *font, } -#ifndef HB_DISABLE_DEPRECATED - /* * Deprecated get_glyph_func(): */ @@ -2034,5 +2032,3 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, trampoline, trampoline_destroy); } - -#endif /* HB_DISABLE_DEPRECATED */ From c9413d7bb575093411b39ac21974795b6ad91454 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Oct 2018 21:19:39 -0400 Subject: [PATCH 02/18] [graphite] Add HB_DEPRECATED annotation --- src/hb-graphite2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h index 05c55debe..acf1dfa8f 100644 --- a/src/hb-graphite2.h +++ b/src/hb-graphite2.h @@ -41,7 +41,7 @@ hb_graphite2_face_get_gr_face (hb_face_t *face); #ifndef HB_DISABLE_DEPRECATED -HB_EXTERN gr_font * +HB_EXTERN HB_DEPRECATED gr_font * hb_graphite2_font_get_gr_font (hb_font_t *font); #endif From 1a6b5ac6c300ed2ccdcd8eadde433120f6e07f2a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Oct 2018 21:22:49 -0400 Subject: [PATCH 03/18] Add HB_DEPRECATED_FOR and mark relevant symbols --- src/hb-common.h | 8 ++++++++ src/hb-deprecated.h | 10 +++++----- src/hb-graphite2.h | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/hb-common.h b/src/hb-common.h index 4f91a1761..c601b1f66 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -71,6 +71,14 @@ typedef unsigned __int64 uint64_t; #define HB_DEPRECATED #endif +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define HB_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) +#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) +#define HB_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) +#else +#define HB_DEPRECATED_FOR(f) HB_DEPRECATED +#endif + HB_BEGIN_DECLS diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index 46590731b..52ee49e2b 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -50,7 +50,7 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t *glyph, void *user_data); -HB_EXTERN HB_DEPRECATED void +HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or hb_font_funcs_set_variation_glyph_func) void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -212,26 +212,26 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, hb_position_t *x, hb_position_t *y); /* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */ -HB_EXTERN HB_DEPRECATED hb_bool_t +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t hb_ot_layout_table_choose_script (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *script_tags, unsigned int *script_index, hb_tag_t *chosen_script); -HB_EXTERN HB_DEPRECATED hb_bool_t +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, hb_tag_t language_tag, unsigned int *language_index); -HB_EXTERN HB_DEPRECATED void +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void hb_ot_tags_from_script (hb_script_t script, hb_tag_t *script_tag_1, hb_tag_t *script_tag_2); -HB_EXTERN HB_DEPRECATED hb_tag_t +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t hb_ot_tag_from_language (hb_language_t language); diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h index acf1dfa8f..1720191b4 100644 --- a/src/hb-graphite2.h +++ b/src/hb-graphite2.h @@ -41,7 +41,7 @@ hb_graphite2_face_get_gr_face (hb_face_t *face); #ifndef HB_DISABLE_DEPRECATED -HB_EXTERN HB_DEPRECATED gr_font * +HB_EXTERN HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face) gr_font * hb_graphite2_font_get_gr_font (hb_font_t *font); #endif From e9f9c0d81c73d8b6d87700aadb5b886bd289769a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Oct 2018 21:37:45 -0400 Subject: [PATCH 04/18] [sanitize] Reorder condition to silence bogus gcc warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was givin a dozen of: ../../src/hb-machinery.hh: In member function ‘bool AAT::ankr::sanitize(hb_sanitize_context_t*) const’: ../../src/hb-machinery.hh:307:23: warning: missed loop optimization, the loop counter may overflow [-Wunsafe-loop-optimizations] bool ok = --this->max_ops > 0 && ~~~~~~~~~~~~~~~~~~~~~~ this->start <= p && ~~~~~~~~~~~~~~~~~~~ p <= this->end && ~~~~~~~~~~~~~~~^~ (unsigned int) (this->end - p) >= len; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I believe those are bogus, but this silences them and does not introduce logic issues I believe. --- src/hb-machinery.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 56914beae..a6ff6e7b9 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -302,10 +302,10 @@ struct hb_sanitize_context_t : inline bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base; - bool ok = this->max_ops-- > 0 && - this->start <= p && + bool ok = this->start <= p && p <= this->end && - (unsigned int) (this->end - p) >= len; + (unsigned int) (this->end - p) >= len && + this->max_ops-- > 0; DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s", From dc49bd8d813571fe16d9e5342e4a3926ff947bd6 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 12 Oct 2018 03:00:59 +0330 Subject: [PATCH 05/18] Add two APIs for getting stylistic set labels * hb_ot_layout_feature_get_characters * hb_ot_layout_feature_get_name_ids 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 | 2 + src/hb-ot-layout-common.hh | 14 ++++ src/hb-ot-layout.cc | 133 +++++++++++++++++++++++++++++++++++++ src/hb-ot-layout.h | 29 ++++++++ test/api/CMakeLists.txt | 2 + test/api/Makefile.am | 1 + test/api/fonts/cv01.otf | Bin 0 -> 1956 bytes test/api/test-ot-nameid.c | 96 ++++++++++++++++++++++++++ 8 files changed, 277 insertions(+) create mode 100644 test/api/fonts/cv01.otf create mode 100644 test/api/test-ot-nameid.c diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 9472af4f1..fccfcb0ed 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -479,7 +479,9 @@ HB_OT_TAG_GSUB HB_OT_TAG_JSTF hb_ot_layout_collect_lookups hb_ot_layout_collect_features +hb_ot_layout_feature_get_characters hb_ot_layout_feature_get_lookups +hb_ot_layout_feature_get_name_ids hb_ot_layout_feature_with_variations_get_lookups hb_ot_layout_get_attach_points hb_ot_layout_get_glyph_class diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index e5e996d4d..bf0a9c1ed 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -521,6 +521,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 aa36954d0..4c751e641 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1116,6 +1116,139 @@ hb_ot_layout_get_size_params (hb_face_t *face, return false; } +/** + * hb_ot_layout_feature_get_name_ids: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @feature_tag: 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_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_tag_t feature_tag, + 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 */) +{ + static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), ""); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + 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 */ + { +#define PARAM(a, A) if (a) *a = A + PARAM(label_id, ss_params.uiNameID); + // ssXX features don't have the rest + PARAM(tooltip_id, HB_NAME_ID_INVALID); + PARAM(sample_id, HB_NAME_ID_INVALID); + PARAM(num_named_parameters, 0); + PARAM(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 */ + { + 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, HB_NAME_ID_INVALID); + PARAM(tooltip_id, HB_NAME_ID_INVALID); + PARAM(sample_id, HB_NAME_ID_INVALID); + PARAM(num_named_parameters, 0); + PARAM(first_param_id, HB_NAME_ID_INVALID); +#undef PARAM + return false; +} + +/** + * hb_ot_layout_feature_get_characters:: + * @face: #hb_face_t to work upon + * @feature_tag: cvXX tag + * @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: (in/out) (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. + * + * Return value: Number of total sample characters in the cvXX feature. + * + * Since: REPLACEME + **/ +unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_tag_t feature_tag, + unsigned int start_offset, + unsigned int *char_count, /* IN/OUT. May be NULL */ + hb_codepoint_t *characters /* OUT. May be NULL */) +{ + static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), ""); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + 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); + if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) + { + 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]; + } +#define PARAM(a, A) if (a) *a = A + PARAM(char_count, len); + return cv_params.characters.len; + } + PARAM(char_count, 0); + PARAM(characters, 0); +#undef PARAM + return 0; +} + /* * 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 eb0df8936..0be85cb2e 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -330,6 +330,35 @@ 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_name_id_t: + * + * Since: REPLACEME + */ +typedef unsigned int hb_name_id_t; + +#define HB_NAME_ID_INVALID 0xFFFF + +HB_EXTERN hb_bool_t +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_tag_t feature_tag, + 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 */); + + +HB_EXTERN unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_tag_t feature_tag, + unsigned int start_offset, + unsigned int *char_count /* IN/OUT. May be NULL */, + hb_codepoint_t *characters /* OUT. May be NULL */); /* * BASE diff --git a/test/api/CMakeLists.txt b/test/api/CMakeLists.txt index b540eb505..77cb35771 100644 --- a/test/api/CMakeLists.txt +++ b/test/api/CMakeLists.txt @@ -3,6 +3,8 @@ if (HB_HAVE_GLIB) extract_make_variable (TEST_PROGS ${MAKEFILEAM}) list (APPEND TEST_PROGS + test-ot-color + test-ot-nameid test-ot-tag test-c test-cplusplus diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 3ff7f5a8a..0e3f9a406 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -71,6 +71,7 @@ endif TEST_PROGS += \ test-ot-color \ + test-ot-nameid \ test-ot-tag \ $(NULL) diff --git a/test/api/fonts/cv01.otf b/test/api/fonts/cv01.otf new file mode 100644 index 0000000000000000000000000000000000000000..01dbf01f3b45626a151dcb96bcb88ce541804519 GIT binary patch literal 1956 zcmdT_U1%It7(I7pche@@{51(%84OA)vC)^d5Bi`FzPM!{eH2j&Vx0MQ+fC&n*lX1)RHdI5AkJNd%!r#*MB z(;lKdH8J^kZ0fz4C#cnE&&+0woN_?<2?(r_8=g0fWOM1k8}xn7dtjbKa7lTU_*dS& z^BHS7RKXX__b%;l##qilJxwSg>_Ur1#*9AsVUqR=pmyc51&gj;Z{=tu7f=SN>W@! zkg7Ko`4m^YQQSpTFrR{;RC!IVXS=RIBswBRKlD`-R7$13rPj|0T- z@X1ABKi6^;H+(Gk{=V|Df<}DnV-*9q=i|UGO%R&s^7+sX&-G~HX^-c6dc=7jE9m1_ zcIOo;u|KZ}5Pvz6&0Wf;=H@M}Z}x~5)1!mOG%aBktTX0ZF>U1I*+na!&Ci+I376&& z?H}xy!n0<+kjgG$+AXB8GMBAwE@$M8 zOjO&;#s17;1X<*833;S2hk021R(+Vo5soqFh++`Oh&3c&qCo!{j&msTTNsRrGk%e* z9P{K&Do^ZEdsY{)^P5X-j2>>rA`(4bGS4 zB|R2BxxY{p7`+o=F>aaKy_s_EQ%G&p&GzrQ*gxu6f~*Pe?(`}YCuNn8>tvN{9OW*M z_ORoyKjk=1)mK79M~wm@L{RQ13A*hj*oTGPso0&W z9SKy*_D375!S9-G)K**Xwm=c0X94h)Shat*Dg_yVt(C z*&C{CmfG#nT6J@@u5oQ?W3?pici7LBA1-XHo+}3%AAGRXdf$$0MryYXuGOsCFYOLy z!b1+m*QX77)~nqQn|~jxErbqIw-YfU!xq9r-DL-F%a|1z(?!-Ptyiz? zYb;&c82>udwbpteyuTc-w<8U;TR(;mY_zo5MR_E9^>q9E$5*AX^M85qGuKm(E(}3D z6CX?Pqzgz5Yf;vum|fDNXdT_ovE#Q9aImPu{CudAR literal 0 HcmV?d00001 diff --git a/test/api/test-ot-nameid.c b/test/api/test-ot-nameid.c new file mode 100644 index 000000000..1389129fe --- /dev/null +++ b/test/api/test-ot-nameid.c @@ -0,0 +1,96 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + */ + +#include +#include +#include + +static const char *font_path = "fonts/cv01.otf"; + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#if GLIB_CHECK_VERSION(2,37,2) + gchar *default_path = g_test_build_filename (G_TEST_DIST, font_path, NULL); +#else + gchar *default_path = g_strdup (font_path); +#endif + + hb_blob_t *blob; + hb_face_t *face; + hb_font_t *font; + + char *path = argc > 1 && *argv[1] ? argv[1] : (char *) default_path; + blob = hb_blob_create_from_file (path); + if (hb_blob_get_length (blob) == 0) + g_error ("Font not found."); + + face = hb_face_create (blob, 0); + font = hb_font_create (face); + + hb_tag_t cv01 = HB_TAG ('c','v','0','1'); + unsigned int feature_index = 0; + // FIXME: See why below doesn't work + // if (!hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, 0, 0, cv01, &feature_index)) + // g_error ("Failed to find feature index"); + + hb_name_id_t label_id; + hb_name_id_t tooltip_id; + hb_name_id_t sample_id; + unsigned int num_named_parameters; + hb_name_id_t first_param_id; + if (!hb_ot_layout_feature_get_name_ids (face, HB_OT_TAG_GSUB, feature_index, + cv01, &label_id, &tooltip_id, &sample_id, + &num_named_parameters, &first_param_id)) + g_error ("Failed to get name ids"); + + g_assert (label_id == 256); + g_assert (tooltip_id == 257); + g_assert (sample_id == 258); + g_assert (num_named_parameters == 2); + g_assert (first_param_id == 259); + + hb_codepoint_t characters[100]; + unsigned int char_count = 100; + + unsigned int all_chars; + all_chars = hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, feature_index, + cv01, 0, &char_count, characters); + + g_assert (all_chars == 2); + g_assert (char_count == 2); + g_assert (characters[0] == 10); + g_assert (characters[1] == 24030); + + hb_font_destroy (font); + hb_face_destroy (face); + hb_blob_destroy (blob); + + g_free (default_path); + + return 0; +} From 477bc9aafeaf89708d13a436869126351e2d9b50 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Oct 2018 15:52:31 -0400 Subject: [PATCH 06/18] Add hb-ot-name.h Actual name-fetching API to come later. New API: hb_name_id_t HB_NAME_ID_INVALID --- src/Makefile.sources | 1 + src/hb-ot-layout-common.hh | 2 +- src/hb-ot-layout.h | 12 ++------- src/hb-ot-name.h | 54 ++++++++++++++++++++++++++++++++++++++ src/hb-ot.h | 1 + 5 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 src/hb-ot-name.h diff --git a/src/Makefile.sources b/src/Makefile.sources index db0a4138d..59cde6bd1 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -173,6 +173,7 @@ HB_OT_headers = \ hb-ot-font.h \ hb-ot-layout.h \ hb-ot-math.h \ + hb-ot-name.h \ hb-ot-shape.h \ hb-ot-tag.h \ hb-ot-var.h \ diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index bf0a9c1ed..4ebebb152 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -400,7 +400,7 @@ struct FeatureParamsSize * same subfamily value. If this value is * zero, the remaining fields in the array * will be ignored. */ - HBUINT16 subfamilyNameID;/* If the preceding value is non-zero, this + NameID subfamilyNameID;/* If the preceding value is non-zero, this * value must be set in the range 256 - 32767 * (inclusive). It records the value of a * field in the name table, which must diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 0be85cb2e..001d77b20 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -34,6 +34,7 @@ #include "hb.h" #include "hb-ot-tag.h" +#include "hb-ot-name.h" HB_BEGIN_DECLS @@ -326,19 +327,10 @@ HB_EXTERN hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, 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 */ + hb_name_id_t *subfamily_name_id, /* OUT. May be NULL */ unsigned int *range_start, /* OUT. May be NULL */ unsigned int *range_end /* OUT. May be NULL */); -/** - * hb_name_id_t: - * - * Since: REPLACEME - */ -typedef unsigned int hb_name_id_t; - -#define HB_NAME_ID_INVALID 0xFFFF - HB_EXTERN hb_bool_t hb_ot_layout_feature_get_name_ids (hb_face_t *face, hb_tag_t table_tag, diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h new file mode 100644 index 000000000..0694b3965 --- /dev/null +++ b/src/hb-ot-name.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Ebrahim Byagowi. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_H_IN +#error "Include instead." +#endif + +#ifndef HB_OT_NAME_H +#define HB_OT_NAME_H + +#include "hb.h" + +HB_BEGIN_DECLS + + +/** + * hb_name_id_t: + * + * Since: REPLACEME + */ +typedef unsigned int hb_name_id_t; + +/** + * HB_NAME_ID_INVALID + * + * Since: REPLACEME + **/ +#define HB_NAME_ID_INVALID 0xFFFF + + +HB_END_DECLS + +#endif /* HB_OT_NAME_H */ diff --git a/src/hb-ot.h b/src/hb-ot.h index 2120a3efa..4b6e3cf74 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -33,6 +33,7 @@ #include "hb-ot-font.h" #include "hb-ot-layout.h" #include "hb-ot-math.h" +#include "hb-ot-name.h" #include "hb-ot-tag.h" #include "hb-ot-shape.h" #include "hb-ot-var.h" From c0a6814b49e376984a0cae9d385a6f6ba8c73579 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Oct 2018 16:05:56 -0400 Subject: [PATCH 07/18] Touch up new API New API: +hb_ot_layout_feature_get_name_ids() +hb_ot_layout_feature_get_characters() --- src/hb-ot-layout.cc | 16 +++++++++------- src/hb-ot-layout.h | 2 -- test/api/test-ot-nameid.c | 16 ++++++++++------ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 4c751e641..1e547a7a2 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1121,7 +1121,6 @@ hb_ot_layout_get_size_params (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: * @feature_index: - * @feature_tag: 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 @@ -1134,7 +1133,10 @@ hb_ot_layout_get_size_params (hb_face_t *face, * 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 + * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or + * "Character Variant" ('cvXX') features. + * + * Return value: true if data found, false otherwise * * Since: REPLACEME **/ @@ -1142,16 +1144,15 @@ hb_bool_t hb_ot_layout_feature_get_name_ids (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, - hb_tag_t feature_tag, 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 */) { - static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), ""); 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 (); @@ -1195,7 +1196,6 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, /** * hb_ot_layout_feature_get_characters:: * @face: #hb_face_t to work upon - * @feature_tag: cvXX tag * @table_tag: * @feature_index: * @start_offset: In case the resulting char_count was equal to its input value, there @@ -1208,6 +1208,9 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * @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: REPLACEME @@ -1216,14 +1219,13 @@ unsigned int hb_ot_layout_feature_get_characters (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, - hb_tag_t feature_tag, unsigned int start_offset, unsigned int *char_count, /* IN/OUT. May be NULL */ hb_codepoint_t *characters /* OUT. May be NULL */) { - static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), ""); 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 (); diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 001d77b20..a2e5b5155 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -335,7 +335,6 @@ HB_EXTERN hb_bool_t hb_ot_layout_feature_get_name_ids (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, - hb_tag_t feature_tag, 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 */, @@ -347,7 +346,6 @@ HB_EXTERN unsigned int hb_ot_layout_feature_get_characters (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, - hb_tag_t feature_tag, unsigned int start_offset, unsigned int *char_count /* IN/OUT. May be NULL */, hb_codepoint_t *characters /* OUT. May be NULL */); diff --git a/test/api/test-ot-nameid.c b/test/api/test-ot-nameid.c index 1389129fe..1205190d2 100644 --- a/test/api/test-ot-nameid.c +++ b/test/api/test-ot-nameid.c @@ -53,10 +53,14 @@ main (int argc, char **argv) font = hb_font_create (face); hb_tag_t cv01 = HB_TAG ('c','v','0','1'); - unsigned int feature_index = 0; - // FIXME: See why below doesn't work - // if (!hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, 0, 0, cv01, &feature_index)) - // g_error ("Failed to find feature index"); + unsigned int feature_index; + if (!hb_ot_layout_language_find_feature (face, + HB_OT_TAG_GSUB, + 0, + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + cv01, + &feature_index)) + g_error ("Failed to find feature index"); hb_name_id_t label_id; hb_name_id_t tooltip_id; @@ -64,7 +68,7 @@ main (int argc, char **argv) unsigned int num_named_parameters; hb_name_id_t first_param_id; if (!hb_ot_layout_feature_get_name_ids (face, HB_OT_TAG_GSUB, feature_index, - cv01, &label_id, &tooltip_id, &sample_id, + &label_id, &tooltip_id, &sample_id, &num_named_parameters, &first_param_id)) g_error ("Failed to get name ids"); @@ -79,7 +83,7 @@ main (int argc, char **argv) unsigned int all_chars; all_chars = hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, feature_index, - cv01, 0, &char_count, characters); + 0, &char_count, characters); g_assert (all_chars == 2); g_assert (char_count == 2); From 63109432cf61333e01af4ef5163d4202bb43f84d Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 13 Oct 2018 14:00:05 +0330 Subject: [PATCH 08/18] Cosmetic and minor changes --- src/hb-buffer-serialize.cc | 4 +- src/hb-ot-cmap-table.hh | 4 +- src/hb-ot-layout-common.hh | 4 +- src/hb-ot-layout-gsubgpos.hh | 8 +-- src/hb-ot-layout.cc | 127 ++++++++++++++++------------------- src/hb-ot-layout.h | 25 +++---- src/hb-ot-math-table.hh | 8 +-- src/hb-ot-name.h | 1 - src/hb-ot-shape-complex.hh | 18 ++--- 9 files changed, 93 insertions(+), 106 deletions(-) diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc index 1b6d14731..c1d82ab8d 100644 --- a/src/hb-buffer-serialize.cc +++ b/src/hb-buffer-serialize.cc @@ -440,8 +440,8 @@ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, const char *buf, int buf_len, /* -1 means nul-terminated */ - const char **end_ptr, /* May be nullptr */ - hb_font_t *font, /* May be nullptr */ + const char **end_ptr, /* May be NULL */ + hb_font_t *font, /* May be NULL */ hb_buffer_serialize_format_t format) { const char *end; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 52b4db6a9..e5793c387 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -709,9 +709,9 @@ struct VariationSelectorRecord HBUINT24 varSelector; /* Variation selector. */ LOffsetTo - defaultUVS; /* Offset to Default UVS Table. May be 0. */ + defaultUVS; /* Offset to Default UVS Table. May be 0. */ LOffsetTo - nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ + nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ public: DEFINE_SIZE_STATIC (11); }; diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 4ebebb152..0c60a1304 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -473,7 +473,7 @@ struct FeatureParamsCharacterVariants * specifies a string (or strings, * for multiple languages) for a * user-interface label for this - * feature. (May be nullptr.) */ + * feature. (May be NULL.) */ NameID featUITooltipTextNameID;/* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) that an @@ -483,7 +483,7 @@ struct FeatureParamsCharacterVariants NameID sampleTextNameID; /* The ‘name’ table name ID that * specifies sample text that * illustrates the effect of this - * feature. (May be nullptr.) */ + * feature. (May be NULL.) */ HBUINT16 numNamedParameters; /* Number of named parameters. (May * be zero.) */ NameID firstParamUILabelNameID;/* The first ‘name’ table name ID diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3a09803ee..695a5df99 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -214,10 +214,10 @@ struct hb_collect_glyphs_context_t : unsigned int debug_depth; hb_collect_glyphs_context_t (hb_face_t *face_, - 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 */ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), before (glyphs_before ? glyphs_before : hb_set_get_empty ()), diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 1e547a7a2..d279b868d 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -322,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); @@ -383,7 +383,7 @@ 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 */, + unsigned int *script_index /* OUT */, hb_tag_t *chosen_script /* OUT */) { static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), ""); @@ -433,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); @@ -469,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); @@ -574,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); @@ -590,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); @@ -644,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, @@ -872,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; @@ -1073,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'); @@ -1092,26 +1092,22 @@ 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; } @@ -1141,14 +1137,14 @@ hb_ot_layout_get_size_params (hb_face_t *face, * Since: REPLACEME **/ 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 */) +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); @@ -1162,34 +1158,32 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, feature_params.get_stylistic_set_params (feature_tag); if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */ { -#define PARAM(a, A) if (a) *a = A - PARAM(label_id, ss_params.uiNameID); + if (label_id) *label_id = ss_params.uiNameID; // ssXX features don't have the rest - PARAM(tooltip_id, HB_NAME_ID_INVALID); - PARAM(sample_id, HB_NAME_ID_INVALID); - PARAM(num_named_parameters, 0); - PARAM(first_param_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 true; } const OT::FeatureParamsCharacterVariants& cv_params = feature_params.get_character_variants_params (feature_tag); 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); + 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; } } - PARAM(label_id, HB_NAME_ID_INVALID); - PARAM(tooltip_id, HB_NAME_ID_INVALID); - PARAM(sample_id, HB_NAME_ID_INVALID); - PARAM(num_named_parameters, 0); - PARAM(first_param_id, HB_NAME_ID_INVALID); -#undef PARAM + 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; } @@ -1232,23 +1226,16 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, const OT::FeatureParamsCharacterVariants& cv_params = feature_params.get_character_variants_params(feature_tag); - if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) + + unsigned int len = 0; + if (char_count && characters && start_offset < cv_params.characters.len) { - 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]; - } -#define PARAM(a, A) if (a) *a = A - PARAM(char_count, len); - return 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]; } - PARAM(char_count, 0); - PARAM(characters, 0); -#undef PARAM - return 0; + if (char_count) *char_count = len; + return cv_params.characters.len; } diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index a2e5b5155..9bd18c8af 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -216,10 +216,10 @@ HB_EXTERN 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 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 */); + 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 */); #ifdef HB_NOT_IMPLEMENTED typedef struct @@ -331,15 +331,16 @@ 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_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 */); +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 */); HB_EXTERN unsigned int diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index 87ebdc7d7..2f871124c 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -50,7 +50,7 @@ struct MathValueRecord protected: HBINT16 value; /* The X or Y value in design units */ OffsetTo deviceTable; /* Offset to the device table - from the - * beginning of parent table. May be nullptr. + * beginning of parent table. May be NULL. * Suggested format for device table is 1. */ public: @@ -318,7 +318,7 @@ struct MathKernInfoRecord protected: /* Offset to MathKern table for each corner - - * from the beginning of MathKernInfo table. May be nullptr. */ + * from the beginning of MathKernInfo table. May be NULL. */ OffsetTo mathKern[4]; public: @@ -401,7 +401,7 @@ struct MathGlyphInfo * from the beginning of MathGlyphInfo table. When the left or right glyph of * a box is an extended shape variant, the (ink) box (and not the default * position defined by values in MathConstants table) should be used for - * vertical positioning purposes. May be nullptr.. */ + * vertical positioning purposes. May be NULL.. */ OffsetTo extendedShapeCoverage; /* Offset to MathKernInfo table - @@ -570,7 +570,7 @@ struct MathGlyphConstruction protected: /* Offset to MathGlyphAssembly table for this shape - from the beginning of - MathGlyphConstruction table. May be nullptr. */ + MathGlyphConstruction table. May be NULL. */ OffsetTo glyphAssembly; /* MathGlyphVariantRecords for alternative variants of the glyphs. */ diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h index 0694b3965..0fdd63bbd 100644 --- a/src/hb-ot-name.h +++ b/src/hb-ot-name.h @@ -48,7 +48,6 @@ typedef unsigned int hb_name_id_t; **/ #define HB_NAME_ID_INVALID 0xFFFF - HB_END_DECLS #endif /* HB_OT_NAME_H */ diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index 216966d2e..2944d745c 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -69,7 +69,7 @@ struct hb_ot_complex_shaper_t /* collect_features() * Called during shape_plan(). * Shapers should use plan->map to add their features and callbacks. - * May be nullptr. + * May be NULL. */ void (*collect_features) (hb_ot_shape_planner_t *plan); @@ -77,7 +77,7 @@ struct hb_ot_complex_shaper_t * Called during shape_plan(). * Shapers should use plan->map to override features and add callbacks after * common features are added. - * May be nullptr. + * May be NULL. */ void (*override_features) (hb_ot_shape_planner_t *plan); @@ -93,7 +93,7 @@ struct hb_ot_complex_shaper_t * Called when the shape_plan is being destroyed. * plan->data is passed here for destruction. * If nullptr is returned, means a plan failure. - * May be nullptr. + * May be NULL. */ void (*data_destroy) (void *data); @@ -101,7 +101,7 @@ struct hb_ot_complex_shaper_t /* preprocess_text() * Called during shape(). * Shapers can use to modify text before shaping starts. - * May be nullptr. + * May be NULL. */ void (*preprocess_text) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -110,7 +110,7 @@ struct hb_ot_complex_shaper_t /* postprocess_glyphs() * Called during shape(). * Shapers can use to modify glyphs after shaping ends. - * May be nullptr. + * May be NULL. */ void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -121,7 +121,7 @@ struct hb_ot_complex_shaper_t /* decompose() * Called during shape()'s normalization. - * May be nullptr. + * May be NULL. */ bool (*decompose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, @@ -130,7 +130,7 @@ struct hb_ot_complex_shaper_t /* compose() * Called during shape()'s normalization. - * May be nullptr. + * May be NULL. */ bool (*compose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t a, @@ -141,7 +141,7 @@ struct hb_ot_complex_shaper_t * Called during shape(). * Shapers should use map to get feature masks and set on buffer. * Shapers may NOT modify characters. - * May be nullptr. + * May be NULL. */ void (*setup_masks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -156,7 +156,7 @@ struct hb_ot_complex_shaper_t /* reorder_marks() * Called during shape(). * Shapers can use to modify ordering of combining marks. - * May be nullptr. + * May be NULL. */ void (*reorder_marks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, From ed2ee78136c40de8e7b915dfdfd3ca92880912c3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 09:47:51 -0400 Subject: [PATCH 09/18] [hangul] Fix use-after-free issue out_info might have moved since we copied it's position into local info var. Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=894937 --- src/hb-ot-shape-complex-hangul.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 0e7abadbe..959540258 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc @@ -345,13 +345,6 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, { unsigned int s_len = tindex ? 3 : 2; buffer->replace_glyphs (1, s_len, decomposed); - if (unlikely (!buffer->successful)) - return; - - /* We decomposed S: apply jamo features to the individual glyphs - * that are now in buffer->out_info. - */ - hb_glyph_info_t *info = buffer->out_info; /* If we decomposed an LV because of a non-combining T following, * we want to include this T in the syllable. @@ -361,6 +354,14 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, buffer->next_glyph (); s_len++; } + + if (unlikely (!buffer->successful)) + return; + + /* We decomposed S: apply jamo features to the individual glyphs + * that are now in buffer->out_info. + */ + hb_glyph_info_t *info = buffer->out_info; end = start + s_len; unsigned int i = start; @@ -368,6 +369,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, info[i++].hangul_shaping_feature() = VJMO; if (i < end) info[i++].hangul_shaping_feature() = TJMO; + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) buffer->merge_out_clusters (start, end); continue; From fc45e698f2d8a6d577f33b1e69a83714aceae528 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 11:39:12 -0400 Subject: [PATCH 10/18] [kerx] Protext against overflows --- src/hb-aat-layout-kerx-table.hh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index cd1129128..ef6d02db4 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -233,7 +233,7 @@ struct KerxSubTableFormat2 unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+array), offset); if (unlikely ((const char *) v < (const char *) &array || - (const char *) v + v->static_size - (const char *) this > header.length)) + (const char *) v - (const char *) this > header.length - v->static_size)) return 0; return *v; } @@ -480,9 +480,11 @@ struct KerxSubTableFormat6 unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; + if (unlikely (offset < l)) return 0; /* Addition overflow. */ + if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely ((const char *) v < (const char *) &t.array || - (const char *) v + v->static_size - (const char *) this > header.length)) + (const char *) v - (const char *) this > header.length - v->static_size)) return 0; return *v; } @@ -494,7 +496,7 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); if (unlikely ((const char *) v < (const char *) &t.array || - (const char *) v + v->static_size - (const char *) this > header.length)) + (const char *) v - (const char *) this > header.length - v->static_size)) return 0; return *v; } From c4502833b711a76cce1af0c5bf075692b965c991 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 11:48:49 -0400 Subject: [PATCH 11/18] [kerx] Use sanitizer.get_num_glyphs() instead of face->get_num_glyphs() --- src/hb-aat-layout-kerx-table.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index ef6d02db4..d59d6374a 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -246,7 +246,7 @@ struct KerxSubTableFormat2 return false; accelerator_t accel (*this, - c->face->get_num_glyphs ()); + c->sanitizer.get_num_glyphs ()); hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -383,11 +383,11 @@ struct KerxSubTableFormat4 unsigned int currAnchorPoint = *data++; const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint, markAnchorPoint, - c->face->get_num_glyphs (), + c->sanitizer.get_num_glyphs (), c->ankr_end); const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint, currAnchorPoint, - c->face->get_num_glyphs (), + c->sanitizer.get_num_glyphs (), c->ankr_end); o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate); @@ -510,7 +510,7 @@ struct KerxSubTableFormat6 return false; accelerator_t accel (*this, - c->face->get_num_glyphs ()); + c->sanitizer.get_num_glyphs ()); hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); From 5733113662e668a25187e0042935d955e44fb488 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 12:16:12 -0400 Subject: [PATCH 12/18] [kerx] Wire up context down to get_kerning --- src/hb-aat-layout-kerx-table.hh | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index d59d6374a..2004e579e 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -226,8 +226,9 @@ struct KerxSubTableFormat1 struct KerxSubTableFormat2 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - unsigned int num_glyphs) const + hb_aat_apply_context_t *c) const { + unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; @@ -245,8 +246,7 @@ struct KerxSubTableFormat2 if (!c->plan->requested_kerning) return false; - accelerator_t accel (*this, - c->sanitizer.get_num_glyphs ()); + accelerator_t accel (*this, c); hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -264,16 +264,14 @@ struct KerxSubTableFormat2 struct accelerator_t { const KerxSubTableFormat2 &table; - unsigned int num_glyphs; + hb_aat_apply_context_t *c; inline accelerator_t (const KerxSubTableFormat2 &table_, - unsigned int num_glyphs_) - : table (table_), num_glyphs (num_glyphs_) {} + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - return table.get_kerning (left, right, num_glyphs); - } + { return table.get_kerning (left, right, c); } }; protected: @@ -472,8 +470,9 @@ struct KerxSubTableFormat6 inline bool is_long (void) const { return flags & ValuesAreLong; } inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - unsigned int num_glyphs) const + hb_aat_apply_context_t *c) const { + unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); if (is_long ()) { const U::Long &t = u.l; @@ -509,8 +508,7 @@ struct KerxSubTableFormat6 if (!c->plan->requested_kerning) return false; - accelerator_t accel (*this, - c->sanitizer.get_num_glyphs ()); + accelerator_t accel (*this, c); hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -534,16 +532,14 @@ struct KerxSubTableFormat6 struct accelerator_t { const KerxSubTableFormat6 &table; - unsigned int num_glyphs; + hb_aat_apply_context_t *c; inline accelerator_t (const KerxSubTableFormat6 &table_, - unsigned int num_glyphs_) - : table (table_), num_glyphs (num_glyphs_) {} + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - return table.get_kerning (left, right, num_glyphs); - } + { return table.get_kerning (left, right, c); } }; protected: From 6d4b054234b4736ca9927268ee3e2d9a0f8f6ead Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 12:20:33 -0400 Subject: [PATCH 13/18] [kerx] Use sanitizer instead of handcoded runtime sanitization --- src/hb-aat-layout-kerx-table.hh | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 2004e579e..d65f30935 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -232,11 +232,9 @@ struct KerxSubTableFormat2 unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; - const FWORD *v = &StructAtOffset (&(this+array), offset); - if (unlikely ((const char *) v < (const char *) &array || - (const char *) v - (const char *) this > header.length - v->static_size)) - return 0; - return *v; + const FWORD v = StructAtOffset (&(this+array), offset); + if (unlikely (!v.sanitize (&c->sanitizer))) return 0; + return v; } inline bool apply (hb_aat_apply_context_t *c) const @@ -481,11 +479,9 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; if (unlikely (offset < l)) return 0; /* Addition overflow. */ if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; - const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); - if (unlikely ((const char *) v < (const char *) &t.array || - (const char *) v - (const char *) this > header.length - v->static_size)) - return 0; - return *v; + const FWORD32 &v = StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); + if (unlikely (!v.sanitize (&c->sanitizer))) return 0; + return v; } else { @@ -493,11 +489,9 @@ struct KerxSubTableFormat6 unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; - const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); - if (unlikely ((const char *) v < (const char *) &t.array || - (const char *) v - (const char *) this > header.length - v->static_size)) - return 0; - return *v; + const FWORD &v = StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); + if (unlikely (!v.sanitize (&c->sanitizer))) return 0; + return v; } } From 71f76f2f39c88998b430b171c99b85818d4fa0ab Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 13:36:27 -0400 Subject: [PATCH 14/18] [kerx] Fix-up previous commit A "&" was missing. Go back to using pointers that are less error-prone. --- src/hb-aat-layout-kerx-table.hh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index d65f30935..95dd50ddd 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -232,9 +232,9 @@ struct KerxSubTableFormat2 unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; - const FWORD v = StructAtOffset (&(this+array), offset); - if (unlikely (!v.sanitize (&c->sanitizer))) return 0; - return v; + const FWORD *v = &StructAtOffset (&(this+array), offset); + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return *v; } inline bool apply (hb_aat_apply_context_t *c) const @@ -479,9 +479,9 @@ struct KerxSubTableFormat6 unsigned int offset = l + r; if (unlikely (offset < l)) return 0; /* Addition overflow. */ if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; - const FWORD32 &v = StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); - if (unlikely (!v.sanitize (&c->sanitizer))) return 0; - return v; + const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return *v; } else { @@ -489,9 +489,9 @@ struct KerxSubTableFormat6 unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; - const FWORD &v = StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); - if (unlikely (!v.sanitize (&c->sanitizer))) return 0; - return v; + const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return *v; } } From de6e414c565de5f27b9da8c7b8b11f88659a4c42 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 13:48:22 -0400 Subject: [PATCH 15/18] [kerx] Sanitize more --- src/hb-aat-layout-kerx-table.hh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 95dd50ddd..52923a8da 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -256,7 +256,8 @@ struct KerxSubTableFormat2 TRACE_SANITIZE (this); return_trace (likely (rowWidth.sanitize (c) && leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this))); + rightClassTable.sanitize (c, this) && + c->check_range (this, array))); } struct accelerator_t @@ -516,10 +517,12 @@ struct KerxSubTableFormat6 is_long () ? ( u.l.rowIndexTable.sanitize (c, this) && - u.l.columnIndexTable.sanitize (c, this) + u.l.columnIndexTable.sanitize (c, this) && + c->check_range (this, u.l.array) ) : ( u.s.rowIndexTable.sanitize (c, this) && - u.s.columnIndexTable.sanitize (c, this) + u.s.columnIndexTable.sanitize (c, this) && + c->check_range (this, u.s.array) ))); } From cb057749131826dd89bc3b92527116a974ae3bbe Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 17:03:32 -0400 Subject: [PATCH 16/18] [coretext] Prepare AAT feature mapping to be moved --- src/hb-coretext.cc | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 9bebb2be6..eee1d3469 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -515,12 +515,21 @@ struct range_record_t { #define kUpperCaseType 38 /* Table data courtesy of Apple. */ -static const struct feature_mapping_t +static const struct hb_aat_feature_mapping_t { - hb_tag_t otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; + hb_tag_t otFeatureTag; + uint16_t aatFeatureType; + uint16_t selectorToEnable; + uint16_t selectorToDisable; + + static inline int cmp (const void *key_, const void *entry_) + { + hb_tag_t key = * (unsigned int *) key_; + const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; + return key < entry->otFeatureTag ? -1 : + key > entry->otFeatureTag ? 1 : + 0; + } } feature_mappings[] = { { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, @@ -600,14 +609,14 @@ static const struct feature_mapping_t { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, }; -static int -_hb_feature_mapping_cmp (const void *key_, const void *entry_) +HB_INTERNAL const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag) { - hb_tag_t key = * (unsigned int *) key_; - const feature_mapping_t * entry = (const feature_mapping_t *) entry_; - return key < entry->otFeatureTag ? -1 : - key > entry->otFeatureTag ? 1 : - 0; + return bsearch (&tag, + feature_mappings, + ARRAY_LENGTH (feature_mappings), + sizeof (feature_mappings[0]), + hb_aat_feature_mapping_t::cmp); } hb_bool_t @@ -655,11 +664,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_auto_t > feature_events; for (unsigned int i = 0; i < num_features; i++) { - const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag, - feature_mappings, - ARRAY_LENGTH (feature_mappings), - sizeof (feature_mappings[0]), - _hb_feature_mapping_cmp); + const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); if (!mapping) continue; From e0c5e0d91bbc0c8b2bb547ba5cb118989affc617 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 18:37:14 -0400 Subject: [PATCH 17/18] [aat] WIP remove feature mapping here from hb-coretext Need to map enum values to numerics since we don't have CoreText headers. --- src/hb-aat-layout.cc | 94 +++++++++++++++++++++ src/hb-aat-layout.hh | 22 +++++ src/hb-coretext.cc | 189 +------------------------------------------ 3 files changed, 117 insertions(+), 188 deletions(-) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 2b86ba8c7..e15531ccf 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -36,6 +36,100 @@ #include "hb-aat-layout-trak-table.hh" #include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise. + +/* Table data courtesy of Apple. Converted from mnemonics to integers + * when moving to this file. See hb-coretext.cc before 2018-10-13 for + * more verbose version. */ +static const hb_aat_feature_mapping_t feature_mappings[] = +{ + { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, + { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, + { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, + { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, + { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, + { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, + { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, + { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, + { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, + { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, + { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, + { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, + { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, + { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, + { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, + { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, + { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, + { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, + { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, + { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, + { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, + { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, + { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, + { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, + { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, + { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, + { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, + { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, + { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, + { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, + { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, + { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, + { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, + { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, + { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, + { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, + { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, + { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, + { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, + { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, + { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, + { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, + { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, + { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, + { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, + { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, + { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, + { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, + { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, + { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, + { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, + { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, + { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, + { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, + { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, + { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, + { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, + { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, + { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, + { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, + { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, + { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, + { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, + { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, + { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, + { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, + { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, + { 'unic', kLetterCaseType, 14, 15 }, + { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, + { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, + { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, + { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, + { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, + { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, + { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, +}; + +const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag) +{ + return bsearch (&tag, + feature_mappings, + ARRAY_LENGTH (feature_mappings), + sizeof (feature_mappings[0]), + hb_aat_feature_mapping_t::cmp); +} + + /* * morx/kerx/trak */ diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 897c26aa0..d0eb0190d 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -31,6 +31,28 @@ #include "hb-ot-shape.hh" + +struct hb_aat_feature_mapping_t +{ + hb_tag_t otFeatureTag; + uint16_t aatFeatureType; + uint16_t selectorToEnable; + uint16_t selectorToDisable; + + static inline int cmp (const void *key_, const void *entry_) + { + hb_tag_t key = * (unsigned int *) key_; + const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; + return key < entry->otFeatureTag ? -1 : + key > entry->otFeatureTag ? 1 : + 0; + } +}; + +HB_INTERNAL const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag); + + HB_INTERNAL hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face); diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index eee1d3469..aa3921a3f 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -32,6 +32,7 @@ #include "hb-shaper-impl.hh" #include "hb-coretext.h" +#include "hb-aat-layout.hh" #include /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ @@ -431,194 +432,6 @@ struct range_record_t { }; -/* The following enum members are added in OS X 10.8. */ -#define kAltHalfWidthTextSelector 6 -#define kAltProportionalTextSelector 5 -#define kAlternateHorizKanaOffSelector 1 -#define kAlternateHorizKanaOnSelector 0 -#define kAlternateKanaType 34 -#define kAlternateVertKanaOffSelector 3 -#define kAlternateVertKanaOnSelector 2 -#define kCaseSensitiveLayoutOffSelector 1 -#define kCaseSensitiveLayoutOnSelector 0 -#define kCaseSensitiveLayoutType 33 -#define kCaseSensitiveSpacingOffSelector 3 -#define kCaseSensitiveSpacingOnSelector 2 -#define kContextualAlternatesOffSelector 1 -#define kContextualAlternatesOnSelector 0 -#define kContextualAlternatesType 36 -#define kContextualLigaturesOffSelector 19 -#define kContextualLigaturesOnSelector 18 -#define kContextualSwashAlternatesOffSelector 5 -#define kContextualSwashAlternatesOnSelector 4 -#define kDefaultLowerCaseSelector 0 -#define kDefaultUpperCaseSelector 0 -#define kHistoricalLigaturesOffSelector 21 -#define kHistoricalLigaturesOnSelector 20 -#define kHojoCharactersSelector 12 -#define kJIS2004CharactersSelector 11 -#define kLowerCasePetiteCapsSelector 2 -#define kLowerCaseSmallCapsSelector 1 -#define kLowerCaseType 37 -#define kMathematicalGreekOffSelector 11 -#define kMathematicalGreekOnSelector 10 -#define kNLCCharactersSelector 13 -#define kQuarterWidthTextSelector 4 -#define kScientificInferiorsSelector 4 -#define kStylisticAltEightOffSelector 17 -#define kStylisticAltEightOnSelector 16 -#define kStylisticAltEighteenOffSelector 37 -#define kStylisticAltEighteenOnSelector 36 -#define kStylisticAltElevenOffSelector 23 -#define kStylisticAltElevenOnSelector 22 -#define kStylisticAltFifteenOffSelector 31 -#define kStylisticAltFifteenOnSelector 30 -#define kStylisticAltFiveOffSelector 11 -#define kStylisticAltFiveOnSelector 10 -#define kStylisticAltFourOffSelector 9 -#define kStylisticAltFourOnSelector 8 -#define kStylisticAltFourteenOffSelector 29 -#define kStylisticAltFourteenOnSelector 28 -#define kStylisticAltNineOffSelector 19 -#define kStylisticAltNineOnSelector 18 -#define kStylisticAltNineteenOffSelector 39 -#define kStylisticAltNineteenOnSelector 38 -#define kStylisticAltOneOffSelector 3 -#define kStylisticAltOneOnSelector 2 -#define kStylisticAltSevenOffSelector 15 -#define kStylisticAltSevenOnSelector 14 -#define kStylisticAltSeventeenOffSelector 35 -#define kStylisticAltSeventeenOnSelector 34 -#define kStylisticAltSixOffSelector 13 -#define kStylisticAltSixOnSelector 12 -#define kStylisticAltSixteenOffSelector 33 -#define kStylisticAltSixteenOnSelector 32 -#define kStylisticAltTenOffSelector 21 -#define kStylisticAltTenOnSelector 20 -#define kStylisticAltThirteenOffSelector 27 -#define kStylisticAltThirteenOnSelector 26 -#define kStylisticAltThreeOffSelector 7 -#define kStylisticAltThreeOnSelector 6 -#define kStylisticAltTwelveOffSelector 25 -#define kStylisticAltTwelveOnSelector 24 -#define kStylisticAltTwentyOffSelector 41 -#define kStylisticAltTwentyOnSelector 40 -#define kStylisticAltTwoOffSelector 5 -#define kStylisticAltTwoOnSelector 4 -#define kStylisticAlternativesType 35 -#define kSwashAlternatesOffSelector 3 -#define kSwashAlternatesOnSelector 2 -#define kThirdWidthTextSelector 3 -#define kTraditionalNamesCharactersSelector 14 -#define kUpperCasePetiteCapsSelector 2 -#define kUpperCaseSmallCapsSelector 1 -#define kUpperCaseType 38 - -/* Table data courtesy of Apple. */ -static const struct hb_aat_feature_mapping_t -{ - hb_tag_t otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; - - static inline int cmp (const void *key_, const void *entry_) - { - hb_tag_t key = * (unsigned int *) key_; - const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; - return key < entry->otFeatureTag ? -1 : - key > entry->otFeatureTag ? 1 : - 0; - } -} feature_mappings[] = -{ - { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, - { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, - { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, - { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, - { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, - { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, - { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, - { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, - { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, - { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, - { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, - { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, - { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, - { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, - { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, - { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, - { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, - { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, - { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, - { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, - { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, - { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, - { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, - { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, - { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, - { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, - { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, - { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, - { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, - { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, - { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, - { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, - { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, - { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, - { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, - { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, - { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, - { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, - { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, - { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, - { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, - { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, - { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, - { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, - { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, - { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, - { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, - { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, - { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, - { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, - { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, - { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, - { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, - { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, - { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, - { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, - { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, - { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, - { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, - { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, - { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, - { 'unic', kLetterCaseType, 14, 15 }, - { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, - { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, -}; - -HB_INTERNAL const hb_aat_feature_mapping_t * -hb_aat_layout_find_feature_mapping (hb_tag_t tag) -{ - return bsearch (&tag, - feature_mappings, - ARRAY_LENGTH (feature_mappings), - sizeof (feature_mappings[0]), - hb_aat_feature_mapping_t::cmp); -} - hb_bool_t _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, From 56b8dd17f677ffe97e4d917c47924e1ac7632c71 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 13 Oct 2018 19:03:33 -0400 Subject: [PATCH 18/18] [aat] Finish off massaging table --- src/hb-aat-layout.cc | 163 +++++++++++++++++++++---------------------- 1 file changed, 81 insertions(+), 82 deletions(-) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index e15531ccf..e9da850b3 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -38,95 +38,94 @@ /* Table data courtesy of Apple. Converted from mnemonics to integers - * when moving to this file. See hb-coretext.cc before 2018-10-13 for - * more verbose version. */ + * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { - { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, - { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, - { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, - { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, - { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, - { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, - { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, - { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, - { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, - { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, - { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, - { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, - { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, - { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, - { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, - { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, - { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, - { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, - { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, - { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, - { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, - { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, - { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, - { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, - { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, - { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, - { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, - { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, - { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, - { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, - { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, - { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, - { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, - { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, - { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, - { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, - { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, - { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, - { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, - { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, - { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, - { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, - { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, - { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, - { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, - { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, - { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, - { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, - { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, - { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, - { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, - { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, - { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, - { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, - { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, - { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, - { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, - { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, - { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, - { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, - { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, - { 'unic', kLetterCaseType, 14, 15 }, - { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, - { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, + {HB_TAG ('c','2','p','c'), 38/*kUpperCaseType*/, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','2','s','c'), 38/*kUpperCaseType*/, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','a','l','t'), 36/*kContextualAlternatesType*/, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, + {HB_TAG ('c','a','s','e'), 33/*kCaseSensitiveLayoutType*/, 0/*kCaseSensitiveLayoutOnSelector*/, 1/*kCaseSensitiveLayoutOffSelector*/}, + {HB_TAG ('c','l','i','g'), 1/*kLigaturesType*/, 18/*kContextualLigaturesOnSelector*/, 19/*kContextualLigaturesOffSelector*/}, + {HB_TAG ('c','p','s','p'), 33/*kCaseSensitiveLayoutType*/, 2/*kCaseSensitiveSpacingOnSelector*/, 3/*kCaseSensitiveSpacingOffSelector*/}, + {HB_TAG ('c','s','w','h'), 36/*kContextualAlternatesType*/, 4/*kContextualSwashAlternatesOnSelector*/, 5/*kContextualSwashAlternatesOffSelector*/}, + {HB_TAG ('d','l','i','g'), 1/*kLigaturesType*/, 4/*kRareLigaturesOnSelector*/, 5/*kRareLigaturesOffSelector*/}, + {HB_TAG ('e','x','p','t'), 20/*kCharacterShapeType*/, 10/*kExpertCharactersSelector*/, 16}, + {HB_TAG ('f','r','a','c'), 11/*kFractionsType*/, 2/*kDiagonalFractionsSelector*/, 0/*kNoFractionsSelector*/}, + {HB_TAG ('f','w','i','d'), 22/*kTextSpacingType*/, 1/*kMonospacedTextSelector*/, 7}, + {HB_TAG ('h','a','l','t'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('h','i','s','t'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','k','n','a'), 34/*kAlternateKanaType*/, 0/*kAlternateHorizKanaOnSelector*/, 1/*kAlternateHorizKanaOffSelector*/, }, + {HB_TAG ('h','l','i','g'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','n','g','l'), 23/*kTransliterationType*/, 1/*kHanjaToHangulSelector*/, 0/*kNoTransliterationSelector*/}, + {HB_TAG ('h','o','j','o'), 20/*kCharacterShapeType*/, 12/*kHojoCharactersSelector*/, 16}, + {HB_TAG ('h','w','i','d'), 22/*kTextSpacingType*/, 2/*kHalfWidthTextSelector*/, 7}, + {HB_TAG ('i','t','a','l'), 32/*kItalicCJKRomanType*/, 2/*kCJKItalicRomanOnSelector*/, 3/*kCJKItalicRomanOffSelector*/}, + {HB_TAG ('j','p','0','4'), 20/*kCharacterShapeType*/, 11/*kJIS2004CharactersSelector*/, 16}, + {HB_TAG ('j','p','7','8'), 20/*kCharacterShapeType*/, 2/*kJIS1978CharactersSelector*/, 16}, + {HB_TAG ('j','p','8','3'), 20/*kCharacterShapeType*/, 3/*kJIS1983CharactersSelector*/, 16}, + {HB_TAG ('j','p','9','0'), 20/*kCharacterShapeType*/, 4/*kJIS1990CharactersSelector*/, 16}, + {HB_TAG ('l','i','g','a'), 1/*kLigaturesType*/, 2/*kCommonLigaturesOnSelector*/, 3/*kCommonLigaturesOffSelector*/}, + {HB_TAG ('l','n','u','m'), 21/*kNumberCaseType*/, 1/*kUpperCaseNumbersSelector*/, 2}, + {HB_TAG ('m','g','r','k'), 15/*kMathematicalExtrasType*/, 10/*kMathematicalGreekOnSelector*/, 11/*kMathematicalGreekOffSelector*/}, + {HB_TAG ('n','l','c','k'), 20/*kCharacterShapeType*/, 13/*kNLCCharactersSelector*/, 16}, + {HB_TAG ('o','n','u','m'), 21/*kNumberCaseType*/, 0/*kLowerCaseNumbersSelector*/, 2}, + {HB_TAG ('o','r','d','n'), 10/*kVerticalPositionType*/, 3/*kOrdinalsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('p','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('p','c','a','p'), 37/*kLowerCaseType*/, 2/*kLowerCasePetiteCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('p','k','n','a'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('p','n','u','m'), 6/*kNumberSpacingType*/, 1/*kProportionalNumbersSelector*/, 4}, + {HB_TAG ('p','w','i','d'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('q','w','i','d'), 22/*kTextSpacingType*/, 4/*kQuarterWidthTextSelector*/, 7}, + {HB_TAG ('r','u','b','y'), 28/*kRubyKanaType*/, 2/*kRubyKanaOnSelector*/, 3/*kRubyKanaOffSelector*/}, + {HB_TAG ('s','i','n','f'), 10/*kVerticalPositionType*/, 4/*kScientificInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','m','c','p'), 37/*kLowerCaseType*/, 1/*kLowerCaseSmallCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('s','m','p','l'), 20/*kCharacterShapeType*/, 1/*kSimplifiedCharactersSelector*/, 16}, + {HB_TAG ('s','s','0','1'), 35/*kStylisticAlternativesType*/, 2/*kStylisticAltOneOnSelector*/, 3/*kStylisticAltOneOffSelector*/}, + {HB_TAG ('s','s','0','2'), 35/*kStylisticAlternativesType*/, 4/*kStylisticAltTwoOnSelector*/, 5/*kStylisticAltTwoOffSelector*/}, + {HB_TAG ('s','s','0','3'), 35/*kStylisticAlternativesType*/, 6/*kStylisticAltThreeOnSelector*/, 7/*kStylisticAltThreeOffSelector*/}, + {HB_TAG ('s','s','0','4'), 35/*kStylisticAlternativesType*/, 8/*kStylisticAltFourOnSelector*/, 9/*kStylisticAltFourOffSelector*/}, + {HB_TAG ('s','s','0','5'), 35/*kStylisticAlternativesType*/, 10/*kStylisticAltFiveOnSelector*/, 11/*kStylisticAltFiveOffSelector*/}, + {HB_TAG ('s','s','0','6'), 35/*kStylisticAlternativesType*/, 12/*kStylisticAltSixOnSelector*/, 13/*kStylisticAltSixOffSelector*/}, + {HB_TAG ('s','s','0','7'), 35/*kStylisticAlternativesType*/, 14/*kStylisticAltSevenOnSelector*/, 15/*kStylisticAltSevenOffSelector*/}, + {HB_TAG ('s','s','0','8'), 35/*kStylisticAlternativesType*/, 16/*kStylisticAltEightOnSelector*/, 17/*kStylisticAltEightOffSelector*/}, + {HB_TAG ('s','s','0','9'), 35/*kStylisticAlternativesType*/, 18/*kStylisticAltNineOnSelector*/, 19/*kStylisticAltNineOffSelector*/}, + {HB_TAG ('s','s','1','0'), 35/*kStylisticAlternativesType*/, 20/*kStylisticAltTenOnSelector*/, 21/*kStylisticAltTenOffSelector*/}, + {HB_TAG ('s','s','1','1'), 35/*kStylisticAlternativesType*/, 22/*kStylisticAltElevenOnSelector*/, 23/*kStylisticAltElevenOffSelector*/}, + {HB_TAG ('s','s','1','2'), 35/*kStylisticAlternativesType*/, 24/*kStylisticAltTwelveOnSelector*/, 25/*kStylisticAltTwelveOffSelector*/}, + {HB_TAG ('s','s','1','3'), 35/*kStylisticAlternativesType*/, 26/*kStylisticAltThirteenOnSelector*/, 27/*kStylisticAltThirteenOffSelector*/}, + {HB_TAG ('s','s','1','4'), 35/*kStylisticAlternativesType*/, 28/*kStylisticAltFourteenOnSelector*/, 29/*kStylisticAltFourteenOffSelector*/}, + {HB_TAG ('s','s','1','5'), 35/*kStylisticAlternativesType*/, 30/*kStylisticAltFifteenOnSelector*/, 31/*kStylisticAltFifteenOffSelector*/}, + {HB_TAG ('s','s','1','6'), 35/*kStylisticAlternativesType*/, 32/*kStylisticAltSixteenOnSelector*/, 33/*kStylisticAltSixteenOffSelector*/}, + {HB_TAG ('s','s','1','7'), 35/*kStylisticAlternativesType*/, 34/*kStylisticAltSeventeenOnSelector*/, 35/*kStylisticAltSeventeenOffSelector*/}, + {HB_TAG ('s','s','1','8'), 35/*kStylisticAlternativesType*/, 36/*kStylisticAltEighteenOnSelector*/, 37/*kStylisticAltEighteenOffSelector*/}, + {HB_TAG ('s','s','1','9'), 35/*kStylisticAlternativesType*/, 38/*kStylisticAltNineteenOnSelector*/, 39/*kStylisticAltNineteenOffSelector*/}, + {HB_TAG ('s','s','2','0'), 35/*kStylisticAlternativesType*/, 40/*kStylisticAltTwentyOnSelector*/, 41/*kStylisticAltTwentyOffSelector*/}, + {HB_TAG ('s','u','b','s'), 10/*kVerticalPositionType*/, 2/*kInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','u','p','s'), 10/*kVerticalPositionType*/, 1/*kSuperiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','w','s','h'), 36/*kContextualAlternatesType*/, 2/*kSwashAlternatesOnSelector*/, 3/*kSwashAlternatesOffSelector*/}, + {HB_TAG ('t','i','t','l'), 19/*kStyleOptionsType*/, 4/*kTitlingCapsSelector*/, 0/*kNoStyleOptionsSelector*/}, + {HB_TAG ('t','n','a','m'), 20/*kCharacterShapeType*/, 14/*kTraditionalNamesCharactersSelector*/, 16}, + {HB_TAG ('t','n','u','m'), 6/*kNumberSpacingType*/, 0/*kMonospacedNumbersSelector*/, 4}, + {HB_TAG ('t','r','a','d'), 20/*kCharacterShapeType*/, 0/*kTraditionalCharactersSelector*/, 16}, + {HB_TAG ('t','w','i','d'), 22/*kTextSpacingType*/, 3/*kThirdWidthTextSelector*/, 7}, + {HB_TAG ('u','n','i','c'), 3/*kLetterCaseType*/, 14, 15}, + {HB_TAG ('v','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','e','r','t'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('v','h','a','l'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('v','k','n','a'), 34/*kAlternateKanaType*/, 2/*kAlternateVertKanaOnSelector*/, 3/*kAlternateVertKanaOffSelector*/}, + {HB_TAG ('v','p','a','l'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','r','t','2'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('z','e','r','o'), 14/*kTypographicExtrasType*/, 4/*kSlashedZeroOnSelector*/, 5/*kSlashedZeroOffSelector*/}, }; const hb_aat_feature_mapping_t * hb_aat_layout_find_feature_mapping (hb_tag_t tag) { - return bsearch (&tag, - feature_mappings, - ARRAY_LENGTH (feature_mappings), - sizeof (feature_mappings[0]), - hb_aat_feature_mapping_t::cmp); + return (const hb_aat_feature_mapping_t *) bsearch (&tag, + feature_mappings, + ARRAY_LENGTH (feature_mappings), + sizeof (feature_mappings[0]), + hb_aat_feature_mapping_t::cmp); }