From 3c7792ca326abfb989285f794d6ee71ad9f6bf89 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Sat, 20 Oct 2018 15:02:26 -0400 Subject: [PATCH 001/158] [use] Fix reordering Fixes #1235. --- src/hb-ot-shape-complex-use.cc | 48 ++++++++++++------ src/hb.hh | 2 + ...fb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf | Bin 0 -> 1824 bytes test/shaping/data/in-house/tests/use.tests | 3 ++ 4 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 test/shaping/data/in-house/fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index af25b07f8..4daa27875 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -432,7 +432,8 @@ record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED, static inline bool is_halant (const hb_glyph_info_t &info) { - return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info); + return (info.use_category() == USE_H || info.use_category() == USE_HVM) && + !_hb_glyph_info_ligated (&info); } static void @@ -449,19 +450,38 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) hb_glyph_info_t *info = buffer->info; -#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB)) +#define POST_BASE_FLAGS (FLAG64 (USE_FM) | \ + FLAG64 (USE_FAbv) | \ + FLAG64 (USE_FBlw) | \ + FLAG64 (USE_FPst) | \ + FLAG64 (USE_MAbv) | \ + FLAG64 (USE_MBlw) | \ + FLAG64 (USE_MPst) | \ + FLAG64 (USE_MPre) | \ + FLAG64 (USE_VAbv) | \ + FLAG64 (USE_VBlw) | \ + FLAG64 (USE_VPst) | \ + FLAG64 (USE_VPre) | \ + FLAG64 (USE_VMAbv) | \ + FLAG64 (USE_VMBlw) | \ + FLAG64 (USE_VMPst) | \ + FLAG64 (USE_VMPre)) /* Move things forward. */ if (info[start].use_category() == USE_R && end - start > 1) { - /* Got a repha. Reorder it to after first base, before first halant. */ + /* Got a repha. Reorder it towards the end, but before the first post-base + * glyph. */ for (unsigned int i = start + 1; i < end; i++) - if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i])) + { + bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS) || + is_halant (info[i]); + if (is_post_base_glyph || i == end - 1) { - /* If we hit a halant, move before it; otherwise it's a base: move to it's - * place, and shift things in between backward. */ + /* If we hit a post-base glyph, move before it; otherwise move to the + * end. Shift things in between backward. */ - if (is_halant (info[i])) + if (is_post_base_glyph) i--; buffer->merge_clusters (start, i + 1); @@ -471,21 +491,19 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) break; } + } } /* Move things back. */ - unsigned int j = end; + unsigned int j = start; for (unsigned int i = start; i < end; i++) { uint32_t flag = FLAG_UNSAFE (info[i].use_category()); - if ((flag & (BASE_FLAGS)) || is_halant (info[i])) + if (is_halant (info[i])) { - /* If we hit a halant, move after it; otherwise it's a base: move to it's - * place, and shift things in between backward. */ - if (is_halant (info[i])) - j = i + 1; - else - j = i; + /* If we hit a halant, move after it; otherwise move to the beginning, and + * shift things in between forward. */ + j = i + 1; } else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && /* Only move the first component of a MultipleSubst. */ diff --git a/src/hb.hh b/src/hb.hh index 16ccf87ce..ba857edac 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -446,6 +446,8 @@ typedef uint64_t hb_vector_size_impl_t; #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x))) #define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) +#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned long long)(x) < 64) + (1ULL << (unsigned long long)(x))) +#define FLAG64_UNSAFE(x) ((unsigned long long)(x) < 64 ? (1ULL << (unsigned long long)(x)) : 0) /* Size signifying variable-sized array */ diff --git a/test/shaping/data/in-house/fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf b/test/shaping/data/in-house/fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf new file mode 100644 index 0000000000000000000000000000000000000000..274fc0817ccdfb0d72dd58d382af15f7f63d46f3 GIT binary patch literal 1824 zcmeHI&udgy6#mY8ZzezAWU2a8YUmp|t-%i_p?V5tJ-Nx+u5_2rhJ?3qcnWQx{4dzjNOUShU-&ypMCg^PPL{ zdFR}B?hFJ#46Cp)HIf_7V=q1dqJy-0BV#AW@iE%TC&=R?lpeQZH|d>_u2DFRqnpJ{XM!E zc+I*-y8RxozAk>{|9%+L?3kn{hpfGmo4}DR+9UM*(fW%{mjje1$cT0#BAm@wRTd5^ zW3$5rth$|zhMj3-FlpZO@9Gm~gBHX7L^q|CQYOLv!=XID8=)(6M4t0w)9tm|D zS&W6c^OjG9$$T5yqsD#|3+$H_)NmeiD4~u7dNG6j#59sfv8xiu!N&!96sYTt8oR7W z-#U)t6ty`l@#KBl^IV;$U9m=ckvl%891k(gczukTyu!m zJW(BuuaO~$A#YFo1r#9X_97XkydGwc5x*p9ZgH~=aacqe}LJ65OX08E2fSn zlL4kb3vn>OOg6;+=u#?`Ol1tDa|W^lt{T(1a|$8L4j7iwWI2RgW|^#m{?U4rw^Lkx zv0$y0JQi#)zO6i^FJMpC{1SGRi`5x)RmznNZ=|`rCZ?XnHq$<^r^^>-v8z@s&0>$4 y6Z(Fx=&a|aVzc8s427KCr`^a|V`((ej^zJDfDUuCOs>L?eBZiOz`o_f`rZHmoHow@ literal 0 HcmV?d00001 diff --git a/test/shaping/data/in-house/tests/use.tests b/test/shaping/data/in-house/tests/use.tests index 18d1991e2..dd2a3a27f 100644 --- a/test/shaping/data/in-house/tests/use.tests +++ b/test/shaping/data/in-house/tests/use.tests @@ -9,3 +9,6 @@ ../fonts/2a670df15b73a5dc75a5cc491bde5ac93c5077dc.ttf::U+11124,U+11131,U+11134:[u11124=0+514|u11131=0+0|uni25CC=0+547|u11134=0+0] ../fonts/573d3a3177c9a8646e94c8a0d7b224334340946a.ttf:--font-funcs=ft:U+11410,U+11442,U+11411,U+11440,U+11443,U+11410,U+11442,U+11411,U+11441,U+11443:[E_dv.alt=0+275|Ga.icd=0+367|Gha.diag=0@100,0+386|AA_dv.alt=0+208|Candrabindu=0@17,-8+0|E_dv.alt=5+275|Ga.icd=5+367|Gha.diag=5@100,0+386|AU_dv_part.alt=5+213|Candrabindu.sm=5@-52,179+0] ../fonts/dcf774ca21062e7439f98658b18974ea8b956d0c.ttf::U+11328,U+1134D,U+1CF4:[gid1=0+793|gid2=0+0|gid3=0+0] +../fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf::U+1C00,U+1C27,U+1C28,U+1C34,U+1C35:[uni1C35=0+500|uni1C34=0+500|uni1C28=0+500|uni1C27=0+500|uni1C00=0+500] +../fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf::U+0D4E,U+0D15,U+0D4D,U+0D15,U+0D46:[uni0D15=0+500|uni0D4E=0+500|uni0D4D=0+500|uni0D46=3+500|uni0D15=3+500] +../fonts/4afb0e8b9a86bb9bd73a1247de4e33fbe3c1fd93.ttf::U+1102D,U+11046,U+11013,U+11046,U+11013,U+11046:[u11013=0+500|u11046_u11013=0+500|u1102D_u11046=0+500|u11046=0+500] From eab5d15f6156e771cb606b760dd170b96c5cd398 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 20 Nov 2018 11:33:33 -0500 Subject: [PATCH 002/158] [var] Move code --- src/hb-ot-var.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 79ce7d72b..997be77f1 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -47,19 +47,6 @@ HB_BEGIN_DECLS * fvar / avar */ -/** - * hb_ot_var_axis_t: - * - * Since: 1.4.2 - */ -typedef struct hb_ot_var_axis_t { - hb_tag_t tag; - hb_ot_name_id_t name_id; - float min_value; - float default_value; - float max_value; -} hb_ot_var_axis_t; - HB_EXTERN hb_bool_t hb_ot_var_has_data (hb_face_t *face); @@ -78,6 +65,20 @@ hb_ot_var_has_data (hb_face_t *face); HB_EXTERN unsigned int hb_ot_var_get_axis_count (hb_face_t *face); +/** + * hb_ot_var_axis_t: + * + * Since: 1.4.2 + */ +typedef struct hb_ot_var_axis_t +{ + hb_tag_t tag; + hb_ot_name_id_t name_id; + float min_value; + float default_value; + float max_value; +} hb_ot_var_axis_t; + HB_EXTERN unsigned int hb_ot_var_get_axes (hb_face_t *face, unsigned int start_offset, From 736897d7a1410fd281fbcedc084b85bf4ba1410c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 20 Nov 2018 11:40:43 -0500 Subject: [PATCH 003/158] [var] Make sure hb_ot_var_axis_flags_t is int-sized --- src/hb-ot-var.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 997be77f1..676be9f7b 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -98,7 +98,9 @@ hb_ot_var_find_axis (hb_face_t *face, * Since: REPLACEME */ typedef enum { /*< flags >*/ - HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x0001u, + HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u, + + _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ } hb_ot_var_axis_flags_t; HB_EXTERN hb_ot_var_axis_flags_t From b2d803cef6974519d5892af2c9efeb8dfba87618 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 20 Nov 2018 11:42:25 -0500 Subject: [PATCH 004/158] Remove newly-added -hb_ot_var_axis_get_flags() --- src/hb-ot-var-fvar-table.hh | 6 ------ src/hb-ot-var.cc | 12 ------------ src/hb-ot-var.h | 4 ---- 3 files changed, 22 deletions(-) diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 47c2516f3..0bf9d10d5 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -131,12 +131,6 @@ struct fvar return true; } - inline hb_ot_var_axis_flags_t get_axis_flags (unsigned int index) const - { - const AxisRecord &axis = get_axes ()[index]; - return (hb_ot_var_axis_flags_t) (unsigned int) axis.flags; - } - inline unsigned int get_axis_infos (unsigned int start_offset, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */) const diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 9ad2f861e..279e87233 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -104,18 +104,6 @@ hb_ot_var_find_axis (hb_face_t *face, return face->table.fvar->find_axis (axis_tag, axis_index, axis_info); } -/** - * hb_ot_var_axis_get_flags: - * - * Since: REPLACEME - **/ -hb_ot_var_axis_flags_t -hb_ot_var_axis_get_flags (hb_face_t *face, - unsigned int axis_index) -{ - return face->table.fvar->get_axis_flags (axis_index); -} - /* * Named instances. */ diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 676be9f7b..0114e5c9e 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -103,10 +103,6 @@ typedef enum { /*< flags >*/ _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ } hb_ot_var_axis_flags_t; -HB_EXTERN hb_ot_var_axis_flags_t -hb_ot_var_axis_get_flags (hb_face_t *face, - unsigned int axis_index); - /* * Named instances. From f48bb9a3939067f24a81007e642caaac77cc7167 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 20 Nov 2018 20:40:55 -0500 Subject: [PATCH 005/158] [var] Deprecated axis enumeration API and add new version New version has axis flags. New API: +hb_ot_var_axis_info_t +hb_ot_var_find_axis_info() +hb_ot_var_get_axis_infos() Deprecated API: -HB_OT_VAR_NO_AXIS_INDEX -hb_ot_var_axis_t -hb_ot_var_find_axis() -hb_ot_var_get_axes() --- docs/harfbuzz-sections.txt | 14 +++-- src/hb-deprecated.h | 37 ++++++++++++ src/hb-ot-var-fvar-table.hh | 116 ++++++++++++++++++++++++++---------- src/hb-ot-var.cc | 43 ++++++++++--- src/hb-ot-var.h | 61 +++++++++---------- test/api/test-ot-face.c | 2 +- 6 files changed, 194 insertions(+), 79 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 63d5f6cef..5f5dcef7d 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -161,6 +161,10 @@ hb_ot_layout_table_choose_script hb_ot_layout_table_find_script hb_ot_tag_from_language hb_ot_tags_from_script +HB_OT_VAR_NO_AXIS_INDEX +hb_ot_var_axis_t +hb_ot_var_find_axis +hb_ot_var_get_axes hb_set_invert hb_unicode_eastasian_width_func_t hb_unicode_eastasian_width @@ -581,14 +585,12 @@ HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE HB_OT_TAG_VAR_AXIS_SLANT HB_OT_TAG_VAR_AXIS_WEIGHT HB_OT_TAG_VAR_AXIS_WIDTH -HB_OT_VAR_NO_AXIS_INDEX -hb_ot_var_axis_t hb_ot_var_has_data -hb_ot_var_find_axis -hb_ot_var_get_axis_count -hb_ot_var_get_axes hb_ot_var_axis_flags_t -hb_ot_var_axis_get_flags +hb_ot_var_axis_info_t +hb_ot_var_find_axis_info +hb_ot_var_get_axis_count +hb_ot_var_get_axis_infos hb_ot_var_get_named_instance_count hb_ot_var_named_instance_get_subfamily_name_id hb_ot_var_named_instance_get_postscript_name_id diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index e39b79f74..a74431f05 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -241,6 +241,43 @@ HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t hb_ot_tag_from_language (hb_language_t language); +typedef unsigned int hb_ot_name_id_t; /* Since is in hb-ot.h */ + +/** + * HB_OT_VAR_NO_AXIS_INDEX: + * + * Since: 1.4.2 + * Deprecated: REPLACEME + */ +#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu + +/** + * hb_ot_var_axis_t: + * + * Since: 1.4.2 + * Deprecated: REPLACEME + */ +typedef struct hb_ot_var_axis_t +{ + hb_tag_t tag; + hb_ot_name_id_t name_id; + float min_value; + float default_value; + float max_value; +} hb_ot_var_axis_t; + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos) unsigned int +hb_ot_var_get_axes (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */); + +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_find_axis_info) hb_bool_t +hb_ot_var_find_axis (hb_face_t *face, + hb_tag_t axis_tag, + unsigned int *axis_index, + hb_ot_var_axis_t *axis_info); + #endif HB_END_DECLS diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 0bf9d10d5..5c8832e18 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -115,28 +115,40 @@ struct fvar inline unsigned int get_axis_count (void) const { return axisCount; } - inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const + inline void get_axis_deprecated (unsigned int axis_index, + hb_ot_var_axis_t *info) const { - if (info) - { - const AxisRecord &axis = get_axes ()[index]; - info->tag = axis.axisTag; - info->name_id = axis.axisNameID; - info->default_value = axis.defaultValue / 65536.; - /* Ensure order, to simplify client math. */ - info->min_value = MIN (info->default_value, axis.minValue / 65536.); - info->max_value = MAX (info->default_value, axis.maxValue / 65536.); - } - - return true; + const AxisRecord &axis = get_axes ()[axis_index]; + info->tag = axis.axisTag; + info->name_id = axis.axisNameID; + info->default_value = axis.defaultValue / 65536.; + /* Ensure order, to simplify client math. */ + info->min_value = MIN (info->default_value, axis.minValue / 65536.); + info->max_value = MAX (info->default_value, axis.maxValue / 65536.); } - inline unsigned int get_axis_infos (unsigned int start_offset, - unsigned int *axes_count /* IN/OUT */, - hb_ot_var_axis_t *axes_array /* OUT */) const + inline void get_axis_info (unsigned int axis_index, + hb_ot_var_axis_info_t *info) const + { + const AxisRecord &axis = get_axes ()[axis_index]; + info->axis_index = axis_index; + info->tag = axis.axisTag; + info->name_id = axis.axisNameID; + info->flags = (hb_ot_var_axis_flags_t) (unsigned int) axis.flags; + info->default_value = axis.defaultValue / 65536.; + /* Ensure order, to simplify client math. */ + info->min_value = MIN (info->default_value, axis.minValue / 65536.); + info->max_value = MAX (info->default_value, axis.maxValue / 65536.); + info->reserved = 0; + } + + inline unsigned int get_axes_deprecated (unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_t *axes_array /* OUT */) const { if (axes_count) { + /* TODO Rewrite as hb_array_t<>::sub-array() */ unsigned int count = axisCount; start_offset = MIN (start_offset, count); @@ -147,32 +159,70 @@ struct fvar *axes_count = count; for (unsigned int i = 0; i < count; i++) - get_axis (start_offset + i, axes_array + i); + get_axis_deprecated (start_offset + i, axes_array + i); } return axisCount; } - inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const + inline unsigned int get_axis_infos (unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_info_t *axes_array /* OUT */) const + { + if (axes_count) + { + /* TODO Rewrite as hb_array_t<>::sub-array() */ + unsigned int count = axisCount; + start_offset = MIN (start_offset, count); + + count -= start_offset; + axes_array += start_offset; + + count = MIN (count, *axes_count); + *axes_count = count; + + for (unsigned int i = 0; i < count; i++) + get_axis_info (start_offset + i, axes_array + i); + } + return axisCount; + } + + inline bool find_axis_deprecated (hb_tag_t tag, + unsigned int *axis_index, + hb_ot_var_axis_t *info) const { const AxisRecord *axes = get_axes (); unsigned int count = get_axis_count (); for (unsigned int i = 0; i < count; i++) if (axes[i].axisTag == tag) { - if (index) - *index = i; - return get_axis (i, info); + if (axis_index) + *axis_index = i; + get_axis_deprecated (i, info); + return true; + } + if (axis_index) + *axis_index = HB_OT_VAR_NO_AXIS_INDEX; + return false; + } + + inline bool find_axis_info (hb_tag_t tag, + hb_ot_var_axis_info_t *info) const + { + const AxisRecord *axes = get_axes (); + unsigned int count = get_axis_count (); + for (unsigned int i = 0; i < count; i++) + if (axes[i].axisTag == tag) + { + get_axis_info (i, info); + return true; } - if (index) - *index = HB_OT_VAR_NO_AXIS_INDEX; return false; } inline int normalize_axis_value (unsigned int axis_index, float v) const { - hb_ot_var_axis_t axis; - if (!get_axis (axis_index, &axis)) - return 0; + hb_ot_var_axis_info_t axis; + get_axis_info (axis_index, &axis); v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */ @@ -188,25 +238,25 @@ struct fvar inline unsigned int get_instance_count (void) const { return instanceCount; } - inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int index) const + inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (index); + const InstanceRecord &instance = get_instance (instance_index); return instance.subfamilyNameID; } - inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int index) const + inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (index); + const InstanceRecord &instance = get_instance (instance_index); if (instanceSize >= axisCount * 4 + 6) return StructAfter (instance.get_coordinates (axisCount)); return HB_OT_NAME_ID_INVALID; } - inline unsigned int get_instance_coords (unsigned int index, + inline unsigned int get_instance_coords (unsigned int instance_index, unsigned int *coords_length, /* IN/OUT */ float *coords /* OUT */) const { - if (unlikely (index >= instanceCount)) + if (unlikely (instance_index >= instanceCount)) { if (coords_length) *coords_length = 0; @@ -215,7 +265,7 @@ struct fvar if (coords_length && *coords_length) { - const InstanceRecord &instance = get_instance (index); + const InstanceRecord &instance = get_instance (instance_index); hb_array_t instanceCoords = instance.get_coordinates (axisCount) .sub_array (0, *coords_length); for (unsigned int i = 0; i < instanceCoords.len; i++) diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 279e87233..56d248178 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -53,7 +53,6 @@ * @face: #hb_face_t to test * * This function allows to verify the presence of OpenType variation data on the face. - * Alternatively, use hb_ot_var_get_axis_count(). * * Return value: true if face has a `fvar' table and false otherwise * @@ -80,6 +79,7 @@ hb_ot_var_get_axis_count (hb_face_t *face) * hb_ot_var_get_axes: * * Since: 1.4.2 + * Deprecated: REPLACEME **/ unsigned int hb_ot_var_get_axes (hb_face_t *face, @@ -87,13 +87,14 @@ hb_ot_var_get_axes (hb_face_t *face, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */) { - return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array); + return face->table.fvar->get_axes_deprecated (start_offset, axes_count, axes_array); } /** * hb_ot_var_find_axis: * * Since: 1.4.2 + * Deprecated: REPLACEME **/ hb_bool_t hb_ot_var_find_axis (hb_face_t *face, @@ -101,9 +102,37 @@ hb_ot_var_find_axis (hb_face_t *face, unsigned int *axis_index, hb_ot_var_axis_t *axis_info) { - return face->table.fvar->find_axis (axis_tag, axis_index, axis_info); + return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info); } +/** + * hb_ot_var_get_axis_infos: + * + * Since: REPLACEME + **/ +HB_EXTERN unsigned int +hb_ot_var_get_axis_infos (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_info_t *axes_array /* OUT */) +{ + return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array); +} + +/** + * hb_ot_var_find_axis_info: + * + * Since: REPLACEME + **/ +HB_EXTERN hb_bool_t +hb_ot_var_find_axis_info (hb_face_t *face, + hb_tag_t axis_tag, + hb_ot_var_axis_info_t *axis_info) +{ + return face->table.fvar->find_axis_info (axis_tag, axis_info); +} + + /* * Named instances. */ @@ -156,10 +185,10 @@ hb_ot_var_normalize_variations (hb_face_t *face, const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < variations_length; i++) { - unsigned int axis_index; - if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, nullptr) && - axis_index < coords_length) - coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); + hb_ot_var_axis_info_t info; + if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) && + info.axis_index < coords_length) + coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value); } face->table.avar->map_coords (coords, coords_length); diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 0114e5c9e..779be1043 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -55,42 +55,10 @@ hb_ot_var_has_data (hb_face_t *face); * Variation axes. */ -/** - * HB_OT_VAR_NO_AXIS_INDEX: - * - * Since: 1.4.2 - */ -#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu HB_EXTERN unsigned int hb_ot_var_get_axis_count (hb_face_t *face); -/** - * hb_ot_var_axis_t: - * - * Since: 1.4.2 - */ -typedef struct hb_ot_var_axis_t -{ - hb_tag_t tag; - hb_ot_name_id_t name_id; - float min_value; - float default_value; - float max_value; -} hb_ot_var_axis_t; - -HB_EXTERN unsigned int -hb_ot_var_get_axes (hb_face_t *face, - unsigned int start_offset, - unsigned int *axes_count /* IN/OUT */, - hb_ot_var_axis_t *axes_array /* OUT */); - -HB_EXTERN hb_bool_t -hb_ot_var_find_axis (hb_face_t *face, - hb_tag_t axis_tag, - unsigned int *axis_index, - hb_ot_var_axis_t *axis_info); - /** * hb_ot_var_axis_flags_t: * @HB_OT_VAR_AXIS_FLAG_HIDDEN: The axis should not be exposed directly in user interfaces. @@ -103,6 +71,35 @@ typedef enum { /*< flags >*/ _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ } hb_ot_var_axis_flags_t; +/** + * hb_ot_var_axis_info_t: + * + * Since: REPLACEME + */ +typedef struct hb_ot_var_axis_info_t +{ + unsigned int axis_index; + hb_tag_t tag; + hb_ot_name_id_t name_id; + hb_ot_var_axis_flags_t flags; + float min_value; + float default_value; + float max_value; + /*< private >*/ + unsigned int reserved; +} hb_ot_var_axis_info_t; + +HB_EXTERN unsigned int +hb_ot_var_get_axis_infos (hb_face_t *face, + unsigned int start_offset, + unsigned int *axes_count /* IN/OUT */, + hb_ot_var_axis_info_t *axes_array /* OUT */); + +HB_EXTERN hb_bool_t +hb_ot_var_find_axis_info (hb_face_t *face, + hb_tag_t axis_tag, + hb_ot_var_axis_info_t *axis_info); + /* * Named instances. diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c index d6eefbaaf..757bc1f85 100644 --- a/test/api/test-ot-face.c +++ b/test/api/test-ot-face.c @@ -93,7 +93,7 @@ test_face (hb_face_t *face, hb_ot_name_get_utf32 (face, cp, NULL, NULL, NULL); hb_ot_var_get_axis_count (face); - hb_ot_var_get_axes (face, 0, NULL, NULL); + hb_ot_var_get_axis_infos (face, 0, NULL, NULL); hb_ot_var_normalize_variations (face, NULL, 0, NULL, 0); hb_ot_var_normalize_coords (face, 0, NULL, NULL); From b3d5b0a5d92115ca672b8103999ab7ac88e39a4a Mon Sep 17 00:00:00 2001 From: David Corbett Date: Wed, 21 Nov 2018 11:35:44 -0500 Subject: [PATCH 006/158] Fix USE categories for U+111C9 SHARADA SANDHI MARK --- src/gen-use-table.py | 7 ++++++- src/hb-ot-shape-complex-use-table.cc | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index a8a7a2326..099f6a185 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -50,6 +50,8 @@ data[0][0x20F0] = defaults[0] # TODO https://github.com/roozbehp/unicode-data/issues/9 data[0][0x11C44] = 'Consonant_Placeholder' data[0][0x11C45] = 'Consonant_Placeholder' +# TODO https://github.com/harfbuzz/harfbuzz/pull/1399 +data[0][0x111C8] = 'Consonant_Placeholder' for u in range (0xFE00, 0xFE0F + 1): data[0][u] = defaults[0] @@ -168,7 +170,7 @@ def is_BASE(U, UISC, UGC): def is_BASE_IND(U, UISC, UGC): #SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) return (UISC in [Consonant_Dead, Modifying_Letter] or - (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or + (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or False # SPEC-DRAFT-OUTDATED! U == 0x002D ) def is_BASE_NUM(U, UISC, UGC): @@ -354,6 +356,9 @@ def map_to_use(data): # TODO: https://github.com/harfbuzz/harfbuzz/issues/1105 if U == 0x11134: UISC = Gemination_Mark + # TODO: https://github.com/harfbuzz/harfbuzz/pull/1399 + if U == 0x111C9: UISC = Consonant_Final + values = [k for k,v in items if v(U,UISC,UGC)] assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values) USE = values[0] diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index bfc92d3b5..2f3eb703e 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -544,7 +544,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, - /* 111C0 */ H, B, R, R, O, O, O, O, O, FM, CMBlw, VAbv, VBlw, O, O, O, + /* 111C0 */ H, B, R, R, O, O, O, O, GB, FBlw, CMBlw, VAbv, VBlw, O, O, O, /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Sinhala Archaic Numbers */ From b89c7fd3dc505a958dd4b6acec0e0f8e57224fd8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 12:32:48 -0500 Subject: [PATCH 007/158] Allow defining HB_USE_ATEXIT to 0 That's better use of that value than requiring extra macro HB_NO_ATEXIT --- src/hb-common.cc | 10 +++++----- src/hb-ft.cc | 12 ++++++------ src/hb-glib.cc | 6 +++--- src/hb-icu.cc | 6 +++--- src/hb-ot-font.cc | 6 +++--- src/hb-shape.cc | 6 +++--- src/hb-shaper.cc | 6 +++--- src/hb-ucdn.cc | 6 +++--- src/hb-uniscribe.cc | 4 ++-- src/hb.hh | 5 ++++- 10 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index 37be8a34e..28b0c2b82 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -276,7 +276,7 @@ struct hb_language_item_t { static hb_atomic_ptr_t langs; -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_langs (void) { @@ -323,7 +323,7 @@ retry: goto retry; } -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT if (!first_lang) atexit (free_langs); /* First person registers atexit() callback. */ #endif @@ -780,7 +780,7 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv) #ifdef USE_XLOCALE -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT static void free_static_C_locale (void); #endif @@ -791,7 +791,7 @@ static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_tinit (); -#ifdef HB_USE_ATEXIT +#if HB_USE_ATEXIT atexit (free_static_uniscribe_shaper_funcs); #endif @@ -261,7 +261,7 @@ static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t Date: Wed, 21 Nov 2018 16:33:45 -0500 Subject: [PATCH 008/158] Test U+111C9 SHARADA SANDHI MARK --- .../86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf | Bin 0 -> 968 bytes .../data/in-house/tests/use-syllable.tests | 1 + 2 files changed, 1 insertion(+) create mode 100644 test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf diff --git a/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf b/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5a47a396c2c96edfe8bd534d790acd374aff1311 GIT binary patch literal 968 zcmbVKO=}ZT6g_Wd($u!p6qhPYAVM`&Gm&bPB4X;t#wsczL9o+IniTReOeWGUgn)D- zDp^PubtUvq2o-c!!Daoxg}8KYblLITnTb@o>l^Oed(J)Y-8=UU6o655p(A(m&guNC zYx4o1HptGG8@7w1Yi9t>Ag)*Kwi^UgLVrg*T&=GxzJ6JrW4uYbTdUYk>igO`?w=t( zTO(ntsz1bC;!LgKFKe4vCH9F&>aDVk0*(;p1UKwu7fBo-P7#|;yHQEK&)#Q!S2(xT z_HS%tHP-Jke+dc>wp35`rKdybiL|4pcD7Z2XPfeU=Kur4U==Qz&fYc7o==dLEba5# z7jGUOocWDW{ile({QC4<{MW;evq)3Y)7A+GXM+8v*_}M${xDl2E3mhxrh=jRe2yK=~ zzAi%_VIw@&;B3gtiP8JpblmS4)xc!KnR8fP^jweyZar!)Ru=uY{F`k8uN7Ois zWsipiRH*iGof(hj&~B5fqJw(KU8Sx`g?NvAg?lg1cJGLoJnNjK$$L=s9`zpDtSP6M v%$;IC@|f{|hTsX+|KAKD7jH&sN>@g*(_G3=7mGt3%d(1v$epJ`@h-H#f`*e# literal 0 HcmV?d00001 diff --git a/test/shaping/data/in-house/tests/use-syllable.tests b/test/shaping/data/in-house/tests/use-syllable.tests index d8f1dff14..6a247ed0c 100644 --- a/test/shaping/data/in-house/tests/use-syllable.tests +++ b/test/shaping/data/in-house/tests/use-syllable.tests @@ -9,3 +9,4 @@ ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11042,U+11046:[brm_KA=0+754|brm_vowelEE=0@-383,0+0|brm_virama=0@-524,0+0] ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11044,U+11046:[brm_KA=0+754|brm_vowelOO=0@-647,0+0|brm_virama=0@-524,0+0] ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+1103C:[brm_KA=0+754|brm_vowelU=0@-403,0+0] +../fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf::U+111C8,U+111C9,U+111C9:[u111C8=0+500|u111C9=0@-500,0+0|u111C9=0@-500,0+0] From 6321fdf7040ce48e3de8d34fdcc57caa6433cb66 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:19:00 -0500 Subject: [PATCH 009/158] Whitespace --- src/hb-machinery.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 3c11243f5..3a180a3bc 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -115,8 +115,8 @@ static inline Type& StructAfter(TObject &X) enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ - inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \ - DEFINE_SIZE_ARRAY(size, array) + inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \ + DEFINE_SIZE_ARRAY(size, array) #define DEFINE_SIZE_ARRAY2(size, array1, array2) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ From 2656644887e77a9d814bb12374af3c26b42fd935 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:23:21 -0500 Subject: [PATCH 010/158] Check alignof() structs are 1 --- src/hb-machinery.hh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 3a180a3bc..ccd66d1a8 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -96,21 +96,26 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_STATIC(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ + DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ + sizeof (*this) == (size)); \ inline unsigned int get_size (void) const { return (size); } \ enum { static_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_UNION(size, _member) \ - DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \ + DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ + 0*sizeof(this->u._member.static_size) + \ + sizeof(this->u._member) == (size)); \ static const unsigned int min_size = (size) #define DEFINE_SIZE_MIN(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \ + DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ + sizeof (*this) >= (size)); \ static const unsigned int min_size = (size) #define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ + DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ + sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ enum { min_size = (size) } @@ -119,7 +124,8 @@ static inline Type& StructAfter(TObject &X) DEFINE_SIZE_ARRAY(size, array) #define DEFINE_SIZE_ARRAY2(size, array1, array2) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ + DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ + sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \ static const unsigned int min_size = (size) From a2b6d308a40d737f54a79f00bc7ace226bad5aaf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:23:49 -0500 Subject: [PATCH 011/158] Remove DEFINE_SIZE_ARRAY2 --- src/hb-machinery.hh | 6 ------ src/hb-ot-layout-common.hh | 8 ++++---- src/hb-ot-post-table.hh | 6 +++--- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index ccd66d1a8..acd3aeddd 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -123,12 +123,6 @@ static inline Type& StructAfter(TObject &X) inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \ DEFINE_SIZE_ARRAY(size, array) -#define DEFINE_SIZE_ARRAY2(size, array1, array2) \ - DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ - sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ - DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \ - static const unsigned int min_size = (size) - /* * Dispatch diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 55b05b513..46c2f182d 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -802,11 +802,11 @@ struct Lookup HBUINT16 lookupFlag; /* Lookup qualifiers */ ArrayOf subTable; /* Array of SubTables */ - HBUINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets +/*HBUINT16 markFilteringSetX[VAR];*//* Index (base 0) into GDEF mark glyph sets * structure. This field is only present if bit * UseMarkFilteringSet of lookup flags is set. */ public: - DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); + DEFINE_SIZE_ARRAY (6, subTable); }; typedef OffsetListOf LookupList; @@ -1568,9 +1568,9 @@ struct VarData HBUINT16 itemCount; HBUINT16 shortCount; ArrayOf regionIndices; - UnsizedArrayOfbytesX; +/*UnsizedArrayOfbytesX;*/ public: - DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); + DEFINE_SIZE_ARRAY (6, regionIndices); }; struct VariationStore diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index f80303cc8..98df3e780 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -61,12 +61,12 @@ struct postV2Tail ArrayOf glyphNameIndex; /* This is not an offset, but is the * ordinal number of the glyph in 'post' * string tables. */ - UnsizedArrayOf - namesX; /* Glyph names with length bytes [variable] +/*UnsizedArrayOf + namesX;*/ /* Glyph names with length bytes [variable] * (a Pascal string). */ public: - DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); + DEFINE_SIZE_ARRAY (2, glyphNameIndex); }; struct post From e987059c618e03d2346c31ed64429d67ce0e367a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:25:06 -0500 Subject: [PATCH 012/158] Minor --- src/hb-machinery.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index acd3aeddd..df5023bdf 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -90,7 +90,8 @@ static inline Type& StructAfter(TObject &X) /* Check that _code compiles in a method environment */ #define _DEFINE_COMPILES_ASSERTION1(_line, _code) \ inline void _compiles_assertion_on_line_##_line (void) const \ - { _code; } + { _code; } \ + static_assert (true, "") /* So we require semicolon here. */ # define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code) # define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code) @@ -116,7 +117,7 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ - DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ + DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ From e5d954a2fb0c390ea67e83763e3c3a47caa2eb50 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:30:50 -0500 Subject: [PATCH 013/158] Minor --- src/hb-machinery.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index df5023bdf..c209efe2a 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -104,8 +104,8 @@ static inline Type& StructAfter(TObject &X) enum { min_size = (size) } #define DEFINE_SIZE_UNION(size, _member) \ + DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size); \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ - 0*sizeof(this->u._member.static_size) + \ sizeof(this->u._member) == (size)); \ static const unsigned int min_size = (size) @@ -115,9 +115,9 @@ static inline Type& StructAfter(TObject &X) static const unsigned int min_size = (size) #define DEFINE_SIZE_ARRAY(size, array) \ + DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ - DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ From 8cfeed99486e87c3217dc141bc24b7768a460f32 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:42:31 -0500 Subject: [PATCH 014/158] Minor --- src/hb-machinery.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index c209efe2a..24e454416 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -107,12 +107,12 @@ static inline Type& StructAfter(TObject &X) DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size); \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof(this->u._member) == (size)); \ - static const unsigned int min_size = (size) + enum { min_size = (size) } #define DEFINE_SIZE_MIN(size) \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof (*this) >= (size)); \ - static const unsigned int min_size = (size) + enum { min_size = (size) } #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ From 8d778877b88155dec1808a994416ead0b3d98ae7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 21 Nov 2018 23:46:09 -0500 Subject: [PATCH 015/158] .. --- src/hb-machinery.hh | 8 ++++++-- src/hb-null.hh | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 24e454416..2f57fb6b4 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -100,24 +100,28 @@ static inline Type& StructAfter(TObject &X) DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof (*this) == (size)); \ inline unsigned int get_size (void) const { return (size); } \ - enum { static_size = (size) }; \ - enum { min_size = (size) } + enum { null_size = (size) }; \ + enum { min_size = (size) }; \ + enum { static_size = (size) } #define DEFINE_SIZE_UNION(size, _member) \ DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size); \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof(this->u._member) == (size)); \ + enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_MIN(size) \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof (*this) >= (size)); \ + enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ + enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ diff --git a/src/hb-null.hh b/src/hb-null.hh index 25a24f05c..51f653d2a 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -52,7 +52,7 @@ static inline Type const & Null (void) { /* Specializations for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ } /* Close namespace. */ \ - extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \ template <> \ /*static*/ inline const Namespace::Type& Null (void) { \ return *reinterpret_cast (_hb_Null_##Namespace##_##Type); \ @@ -60,7 +60,7 @@ static inline Type const & Null (void) { namespace Namespace { \ static_assert (true, "Just so we take semicolon after.") #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ - const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] + const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size] /* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ From fb10c021c8a32f8dc054f008caf86af82667e109 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 00:21:49 -0500 Subject: [PATCH 016/158] Revert alignof() == 1 check Bots not happy with using "this" inside assertion... This reverts 2656644887e77a9d814bb12374af3c26b42fd935 --- src/hb-machinery.hh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 2f57fb6b4..f29a02aad 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -97,8 +97,7 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_STATIC(size) \ - DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ - sizeof (*this) == (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ inline unsigned int get_size (void) const { return (size); } \ enum { null_size = (size) }; \ enum { min_size = (size) }; \ @@ -106,21 +105,18 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_UNION(size, _member) \ DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size); \ - DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ - sizeof(this->u._member) == (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)); \ enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_MIN(size) \ - DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ - sizeof (*this) >= (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \ enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ - DEFINE_INSTANCE_ASSERTION (alignof (*this) == 1 && \ - sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ enum { null_size = (size) }; \ enum { min_size = (size) } From d062ad10de6c63d94676660b76526a160cf4299e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 00:39:14 -0500 Subject: [PATCH 017/158] Fix bots happy again, hopefully So, our fallback static_assert cannot be had more than once per line of source. --- src/hb-machinery.hh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index f29a02aad..86eb58d42 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -82,16 +82,14 @@ static inline Type& StructAfter(TObject &X) /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ inline void _instance_assertion_on_line_##_line (void) const \ - { static_assert ((_assertion), ""); } \ - static_assert (true, "") /* So we require semicolon here. */ + { static_assert ((_assertion), ""); } # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion) /* Check that _code compiles in a method environment */ #define _DEFINE_COMPILES_ASSERTION1(_line, _code) \ inline void _compiles_assertion_on_line_##_line (void) const \ - { _code; } \ - static_assert (true, "") /* So we require semicolon here. */ + { _code; } # define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code) # define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code) @@ -104,19 +102,19 @@ static inline Type& StructAfter(TObject &X) enum { static_size = (size) } #define DEFINE_SIZE_UNION(size, _member) \ - DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size); \ - DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)); \ + DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size) \ + DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)) \ enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_MIN(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ enum { null_size = (size) }; \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size); \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ + DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \ enum { null_size = (size) }; \ enum { min_size = (size) } From 7dd945a8764cbbf76f686fd9387918b63f7d2fb4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:05:02 -0500 Subject: [PATCH 018/158] One more time.. --- src/hb-machinery.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 86eb58d42..a8d1ad53c 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -95,7 +95,7 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_STATIC(size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)) \ inline unsigned int get_size (void) const { return (size); } \ enum { null_size = (size) }; \ enum { min_size = (size) }; \ From f2b91d6510face95008151bb0d25837723536f9f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:10:22 -0500 Subject: [PATCH 019/158] Use Type::null_size for our structs in Null(), sizeof() for other types --- src/hb-null.hh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 51f653d2a..92c7a3519 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -38,13 +38,26 @@ #define HB_NULL_POOL_SIZE 1024 +/* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, + * otherwise return sizeof(T). */ +template +struct _hb_null_size +{ enum { value = sizeof (T) }; }; +template +struct _hb_null_size +{ enum { value = T::null_size }; }; + +template +struct hb_null_size +{ enum { value = _hb_null_size::value }; }; + extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; /* Generic nul-content Null objects. */ template static inline Type const & Null (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); return *reinterpret_cast (_hb_NullPool); } #define Null(Type) Null::value>::value>() @@ -85,7 +98,7 @@ extern HB_INTERNAL /* CRAP pool: Common Region for Access Protection. */ template static inline Type& Crap (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); memcpy (obj, &Null(Type), sizeof (*obj)); return *obj; From 3b9fd176e83bbebc4d0b5fc967c15b08fdef7015 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:18:55 -0500 Subject: [PATCH 020/158] Disallow taking Null() of unbounded structs Not sure I've marked all such structs. To be done as we discover. Fixes https://github.com/harfbuzz/harfbuzz/issues/1300 --- src/hb-aat-layout-common.hh | 2 +- src/hb-machinery.hh | 4 ++++ src/hb-ot-kern-table.hh | 2 +- src/hb-ot-var-fvar-table.hh | 31 ++++++++++++++++--------------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 6572b26d8..7340996e5 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -69,7 +69,7 @@ struct LookupFormat0 UnsizedArrayOf arrayZ; /* Array of lookup values, indexed by glyph index. */ public: - DEFINE_SIZE_ARRAY (2, arrayZ); + DEFINE_SIZE_UNBOUNDED (2); }; diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index a8d1ad53c..cb30e9907 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -112,6 +112,10 @@ static inline Type& StructAfter(TObject &X) enum { null_size = (size) }; \ enum { min_size = (size) } +#define DEFINE_SIZE_UNBOUNDED(size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \ + enum { min_size = (size) } + #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \ diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 14e065684..ebb231a10 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -154,7 +154,7 @@ struct KernSubTable KernSubTableFormat3 format3; } u; public: - DEFINE_SIZE_MIN (0); + DEFINE_SIZE_UNBOUNDED (KernSubTableHeader::static_size); }; diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 5c8832e18..fed334e8a 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -65,7 +65,7 @@ struct InstanceRecord // * instance. */ public: - DEFINE_SIZE_ARRAY (4, coordinatesZ); + DEFINE_SIZE_UNBOUNDED (4); }; struct AxisRecord @@ -109,7 +109,7 @@ struct fvar axisSize == 20 && /* Assumed in our code. */ instanceSize >= axisCount * 4 + 4 && get_axes ().sanitize (c) && - c->check_range (&get_instance (0), instanceCount, instanceSize)); + c->check_range (get_instance (0), instanceCount, instanceSize)); } inline unsigned int get_axis_count (void) const @@ -240,15 +240,17 @@ struct fvar inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (instance_index); - return instance.subfamilyNameID; + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID; + return instance->subfamilyNameID; } inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int instance_index) const { - const InstanceRecord &instance = get_instance (instance_index); + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID; if (instanceSize >= axisCount * 4 + 6) - return StructAfter (instance.get_coordinates (axisCount)); + return StructAfter (instance->get_coordinates (axisCount)); return HB_OT_NAME_ID_INVALID; } @@ -256,7 +258,8 @@ struct fvar unsigned int *coords_length, /* IN/OUT */ float *coords /* OUT */) const { - if (unlikely (instance_index >= instanceCount)) + const InstanceRecord *instance = get_instance (instance_index); + if (unlikely (!instance)) { if (coords_length) *coords_length = 0; @@ -265,9 +268,8 @@ struct fvar if (coords_length && *coords_length) { - const InstanceRecord &instance = get_instance (instance_index); - hb_array_t instanceCoords = instance.get_coordinates (axisCount) - .sub_array (0, *coords_length); + hb_array_t instanceCoords = instance->get_coordinates (axisCount) + .sub_array (0, *coords_length); for (unsigned int i = 0; i < instanceCoords.len; i++) coords[i] = instanceCoords.arrayZ[i].to_float (); } @@ -278,12 +280,11 @@ struct fvar inline hb_array_t get_axes (void) const { return hb_array (&(this+firstAxis), axisCount); } - inline const InstanceRecord &get_instance (unsigned int i) const + inline const InstanceRecord *get_instance (unsigned int i) const { - if (unlikely (i >= instanceCount)) return Null (InstanceRecord); - - return StructAtOffset (&StructAfter (get_axes ()), - i * instanceSize); + if (unlikely (i >= instanceCount)) return nullptr; + return &StructAtOffset (&StructAfter (get_axes ()), + i * instanceSize); } protected: From 209b58ef731f102b92179ed76551e2fd6b5ed075 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:22:33 -0500 Subject: [PATCH 021/158] Minor --- src/hb-ot-kern-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index ebb231a10..b2d571404 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -154,7 +154,7 @@ struct KernSubTable KernSubTableFormat3 format3; } u; public: - DEFINE_SIZE_UNBOUNDED (KernSubTableHeader::static_size); + DEFINE_SIZE_MIN (KernSubTableHeader::static_size); }; From fffea5aff7a631eedd13c38c1fb7ea4f5f950930 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:25:34 -0500 Subject: [PATCH 022/158] Minor --- src/hb-open-type.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index b1fcd6877..c5d1aa844 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -231,13 +231,13 @@ struct FixedVersion * Use: (base+offset) */ -template struct assert_has_min_size { static_assert (Type::min_size > 0, ""); }; -template struct assert_has_min_size {}; +template struct assert_has_null_size { static_assert (Type::null_size > 0, ""); }; +template struct assert_has_null_size {}; template struct OffsetTo : Offset { - static_assert (sizeof (assert_has_min_size) || true, ""); + static_assert (sizeof (assert_has_null_size) || true, ""); inline const Type& operator () (const void *base) const { From 2737aa81e5aee721e868bf0c72f19c0245c721fe Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:44:27 -0500 Subject: [PATCH 023/158] Fix up recent change Fixes https://github.com/harfbuzz/harfbuzz/issues/1300 --- src/hb-null.hh | 12 +++++++++--- src/hb-open-type.hh | 5 ----- src/hb-ot-glyf-table.hh | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 92c7a3519..166d20895 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -40,16 +40,22 @@ /* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, * otherwise return sizeof(T). */ -template + +/* The hard way... + * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol + */ +template struct _hb_bool_type {}; + +template struct _hb_null_size { enum { value = sizeof (T) }; }; template -struct _hb_null_size +struct _hb_null_size > { enum { value = T::null_size }; }; template struct hb_null_size -{ enum { value = _hb_null_size::value }; }; +{ enum { value = _hb_null_size >::value }; }; extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index c5d1aa844..411696641 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -231,14 +231,9 @@ struct FixedVersion * Use: (base+offset) */ -template struct assert_has_null_size { static_assert (Type::null_size > 0, ""); }; -template struct assert_has_null_size {}; - template struct OffsetTo : Offset { - static_assert (sizeof (assert_has_null_size) || true, ""); - inline const Type& operator () (const void *base) const { if (unlikely (this->is_null ())) return Null (Type); diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 5d9e7a201..a3ef1ad06 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -56,7 +56,7 @@ struct loca protected: UnsizedArrayOf dataZ; /* Location data. */ public: - DEFINE_SIZE_ARRAY (0, dataZ); + DEFINE_SIZE_UNBOUNDED (0); }; @@ -465,7 +465,7 @@ struct glyf protected: UnsizedArrayOf dataZ; /* Glyphs data. */ public: - DEFINE_SIZE_ARRAY (0, dataZ); + DEFINE_SIZE_UNBOUNDED (0); }; struct glyf_accelerator_t : glyf::accelerator_t {}; From b96ecb9971a9ad089a631d0139f05ae9d880fc55 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:49:12 -0500 Subject: [PATCH 024/158] More This makes more of the gcc spurious warning: ../../src/hb-null.hh:53:39: warning: enum constant in boolean context [-Wint-in-bool-context] But not going to let that defeat correct code. Type to switch to clang as my main compiler... --- src/hb-blob.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-blob.hh b/src/hb-blob.hh index 802b1f07e..4f9d8f040 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -60,7 +60,7 @@ struct hb_blob_t template inline const Type* as (void) const { - return length < Type::min_size ? &Null(Type) : reinterpret_cast (data); + return length < hb_null_size::value ? &Null(Type) : reinterpret_cast (data); } inline hb_bytes_t as_bytes (void) const { From eeed802b1d0f932c61a088d3e0156ae70645b9e2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 01:53:36 -0500 Subject: [PATCH 025/158] Fix spurious gcc warnings ../../src/hb-null.hh:53:39: warning: enum constant in boolean context [-Wint-in-bool-context] --- src/hb-null.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 166d20895..b87775b63 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -50,7 +50,7 @@ template struct _hb_null_size { enum { value = sizeof (T) }; }; template -struct _hb_null_size > +struct _hb_null_size > { enum { value = T::null_size }; }; template From 25f52f58c20715cc0dee2dd2885669078a128b08 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 14:41:01 -0500 Subject: [PATCH 026/158] [myanmar] Remove myanmar_old shaper Over time it has become the same as default shaper. So, remove. --- src/hb-ot-shape-complex-myanmar.cc | 21 --------------------- src/hb-ot-shape-complex.hh | 4 +--- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index ca7b5a9b2..8fdf2f4bc 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -391,27 +391,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = }; -/* Uniscribe seems to have a shaper for 'mymr' that is like the - * generic shaper, except that it zeros mark advances GDEF_LATE. */ -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old = -{ - nullptr, /* collect_features */ - nullptr, /* override_features */ - nullptr, /* data_create */ - nullptr, /* data_destroy */ - nullptr, /* preprocess_text */ - nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, - nullptr, /* decompose */ - nullptr, /* compose */ - nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ - nullptr, /* reorder_marks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, - true, /* fallback_position */ -}; - - /* Ugly Zawgyi encoding. * Disable all auto processing. * https://github.com/harfbuzz/harfbuzz/issues/1162 */ diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index 2944d745c..e69dce77f 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -57,7 +57,6 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ - HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (use) \ @@ -271,8 +270,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_MYANMAR: if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2')) return &_hb_ot_complex_shaper_myanmar; - else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) - return &_hb_ot_complex_shaper_myanmar_old; else return &_hb_ot_complex_shaper_default; @@ -378,6 +375,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ case HB_SCRIPT_MYANMAR_ZAWGYI: + return &_hb_ot_complex_shaper_myanmar_zawgyi; } } From 7dc561984bdb1f29f09ae0793195b5fbf772522b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 14:45:46 -0500 Subject: [PATCH 027/158] [myanmar] If there's no GSUB table, pick myanmar shaper Needed for morx+kern mark-zeroing interaction. All other scripts work this way. --- src/hb-ot-shape-complex.hh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index e69dce77f..752224617 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -268,10 +268,19 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_khmer; case HB_SCRIPT_MYANMAR: - if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2')) - return &_hb_ot_complex_shaper_myanmar; - else + /* If the designer designed the font for the 'DFLT' script, + * (or we ended up arbitrarily pick 'latn'), use the default shaper. + * Otherwise, use the specific shaper. + * + * If designer designed for 'mymr' tag, also send to default + * shaper. That's tag used from before Myanmar shaping spec + * was developed. The shaping spec uses 'mym2' tag. */ + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') || + planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') || + planner->map.chosen_script[0] == HB_TAG ('m','y','m','r')) return &_hb_ot_complex_shaper_default; + else + return &_hb_ot_complex_shaper_myanmar; /* Unicode-2.0 additions */ @@ -373,6 +382,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) else return &_hb_ot_complex_shaper_use; + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ case HB_SCRIPT_MYANMAR_ZAWGYI: From fa0bd8964d110c168a918bc331dcd350c3fed8c1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 14:46:39 -0500 Subject: [PATCH 028/158] [myanmar] Minor move --- src/hb-ot-shape-complex.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index 752224617..a2499de9c 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -283,6 +283,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_myanmar; + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ + case HB_SCRIPT_MYANMAR_ZAWGYI: + + return &_hb_ot_complex_shaper_myanmar_zawgyi; + + /* Unicode-2.0 additions */ case HB_SCRIPT_TIBETAN: @@ -381,12 +387,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_default; else return &_hb_ot_complex_shaper_use; - - - /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ - case HB_SCRIPT_MYANMAR_ZAWGYI: - - return &_hb_ot_complex_shaper_myanmar_zawgyi; } } From a201fa74cd67f36a402a5c8093889c9d793e9fd5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 15:52:29 -0500 Subject: [PATCH 029/158] [aat] Tweak fallback positioning logic when applying morx Such that for Indic-like scripts (eg. Khmer), we don't do any fallback mark advance-zeroing / positioning, but we do for Latin, etc. Reuses preferences of our script-specific OpenType shapers for those. Fixes regression: https://github.com/harfbuzz/harfbuzz/issues/1393 Which means, fixes again: https://github.com/harfbuzz/harfbuzz/issues/1264 While not regressing: https://github.com/harfbuzz/harfbuzz/issues/1357 --- src/hb-ot-shape.cc | 38 +++++++++++++++++++++++--------------- src/hb-ot-shape.hh | 3 +++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index ccee8d343..e87848d29 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -76,10 +76,16 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac props (*props), map (face, props), aat_map (face, props), - apply_morx (_hb_apply_morx (face)), - shaper (apply_morx ? - &_hb_ot_complex_shaper_default : - hb_ot_shape_complex_categorize (this)) {} + apply_morx (_hb_apply_morx (face)) +{ + shaper = hb_ot_shape_complex_categorize (this); + + script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; + script_fallback_mark_positioning = shaper->fallback_position; + + if (apply_morx) + shaper = &_hb_ot_complex_shaper_default; +} void hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, @@ -141,9 +147,11 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, } bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); - plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark; + plan.zero_marks = script_zero_marks && !plan.apply_kerx && !has_kern_mark; plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); - plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks; + + plan.fallback_mark_positioning = script_fallback_mark_positioning && !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; + plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; /* Currently we always apply trak. */ plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); @@ -158,6 +166,7 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face, hb_ot_shape_planner_t planner (face, &key->props); + hb_ot_shape_collect_features (&planner, key->user_features, key->num_user_features); @@ -811,17 +820,16 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) hb_glyph_info_t *info = c->buffer->info; hb_glyph_position_t *pos = c->buffer->pos; - /* If the font has no GPOS, AND, no fallback positioning will - * happen, AND, direction is forward, then when zeroing mark - * widths, we shift the mark with it, such that the mark - * is positioned hanging over the previous glyph. When + /* If the font has no GPOS and direction is forward, then when + * zeroing mark widths, we shift the mark with it, such that the + * mark is positioned hanging over the previous glyph. When * direction is backward we don't shift and it will end up * hanging over the next glyph after the final reordering. - * If fallback positinoing happens or GPOS is present, we don't - * care. + * + * Note: If fallback positinoing happens, we don't care about + * this as it will be overriden. */ - bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning && - !c->plan->shaper->fallback_position && + bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing && HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ @@ -877,7 +885,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) &pos[i].x_offset, &pos[i].y_offset); - if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position) + if (c->plan->fallback_mark_positioning) _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer); } diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh index 397634c25..6e1478d00 100644 --- a/src/hb-ot-shape.hh +++ b/src/hb-ot-shape.hh @@ -77,6 +77,7 @@ struct hb_ot_shape_plan_t bool zero_marks : 1; bool fallback_glyph_classes : 1; bool fallback_mark_positioning : 1; + bool adjust_mark_positioning_when_zeroing : 1; bool apply_gpos : 1; bool apply_kerx : 1; @@ -113,6 +114,8 @@ struct hb_ot_shape_planner_t hb_ot_map_builder_t map; hb_aat_map_builder_t aat_map; bool apply_morx : 1; + bool script_zero_marks : 1; + bool script_fallback_mark_positioning : 1; const struct hb_ot_complex_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, From 62890dee18b88865a2014fb6a1322c1c9218bd49 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 16:20:29 -0500 Subject: [PATCH 030/158] [aat] Zero mark advances if decided so even if there's cross-kerning Cross-kerning can only take care of positioning vertically. It doesn't adjust mark advance... --- src/hb-ot-shape.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index e87848d29..a7ec6b34e 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -147,7 +147,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, } bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); - plan.zero_marks = script_zero_marks && !plan.apply_kerx && !has_kern_mark; + plan.zero_marks = script_zero_marks && !plan.apply_kerx; plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); plan.fallback_mark_positioning = script_fallback_mark_positioning && !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; From 014e4980ed9c8c473001abdb3a44121eb73fd50d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 16:21:49 -0500 Subject: [PATCH 031/158] Move --- src/hb-ot-shape.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index a7ec6b34e..31fb3b7ce 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -146,10 +146,10 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.apply_kern = true; } - bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); plan.zero_marks = script_zero_marks && !plan.apply_kerx; plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); + bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); plan.fallback_mark_positioning = script_fallback_mark_positioning && !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; From 199a0f7b41b691e371487fd569c0d0146da3c3f3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 17:31:07 -0500 Subject: [PATCH 032/158] [ot-shape] Simplify logic --- src/hb-ot-shape.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 31fb3b7ce..8d844807c 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -149,9 +149,12 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.zero_marks = script_zero_marks && !plan.apply_kerx; plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); - bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); - plan.fallback_mark_positioning = script_fallback_mark_positioning && !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; - plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark; + plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && + !plan.apply_kerx && + (!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face)); + + plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing && + script_fallback_mark_positioning; /* Currently we always apply trak. */ plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); From f47a60a7543dbaf41086c25a1a22ae518d8b92a9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 17:53:29 -0500 Subject: [PATCH 033/158] Mark UnsizedArrayOf<> as UNBOUNDED Since min_size is 0, Null() still accepts this type. --- src/hb-open-type.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 411696641..0ecd3c6b6 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -317,6 +317,7 @@ struct OffsetTo : Offset DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; template struct LOffsetTo : OffsetTo {}; + template static inline const Type& operator + (const Base &base, const OffsetTo &offset) { return offset (base); } template @@ -401,7 +402,7 @@ struct UnsizedArrayOf public: Type arrayZ[VAR]; public: - DEFINE_SIZE_ARRAY (0, arrayZ); + DEFINE_SIZE_UNBOUNDED (0); }; /* Unsized array of offset's */ From fa9f585ec53bc7145d3bed1a4bd756d64dae1e55 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 17:56:51 -0500 Subject: [PATCH 034/158] [glyf] Don't mark structs UNBOUNDED See comments. --- src/hb-ot-glyf-table.hh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index a3ef1ad06..c88f43385 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -56,7 +56,9 @@ struct loca protected: UnsizedArrayOf dataZ; /* Location data. */ public: - DEFINE_SIZE_UNBOUNDED (0); + DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always + * check the size externally, allow Null() object of it by + * defining it MIN() instead. */ }; @@ -465,7 +467,9 @@ struct glyf protected: UnsizedArrayOf dataZ; /* Glyphs data. */ public: - DEFINE_SIZE_UNBOUNDED (0); + DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always + * check the size externally, allow Null() object of it by + * defining it MIN() instead. */ }; struct glyf_accelerator_t : glyf::accelerator_t {}; From 4d4fd64ff47da04a7008d410c92e8fb4ad970781 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 18:07:36 -0500 Subject: [PATCH 035/158] Allow non-nullable OffsetTo<> to non-Null'able objects --- src/hb-open-type.hh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 0ecd3c6b6..f4a9a5e87 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -231,17 +231,31 @@ struct FixedVersion * Use: (base+offset) */ +template +struct _hb_has_null +{ + static inline const Type *get_null (void) { return nullptr; } + static inline Type *get_crap (void) { return nullptr; } +}; +template +struct _hb_has_null +{ + static inline const Type *get_null (void) { return &Null(Type); } + static inline Type *get_crap (void) { return &Crap(Type); } +}; + template struct OffsetTo : Offset { inline const Type& operator () (const void *base) const { - if (unlikely (this->is_null ())) return Null (Type); + if (unlikely (this->is_null ())) return *_hb_has_null::get_null (); return StructAtOffset (base, *this); } inline Type& operator () (void *base) const { if (unlikely (this->is_null ())) return Crap (Type); + if (unlikely (this->is_null ())) return *_hb_has_null::get_crap (); return StructAtOffset (base, *this); } From e866910579e9cdc5b1ffa2e401fd0c056d44ca6a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 18:07:59 -0500 Subject: [PATCH 036/158] Enforce requiring null_size even if min_size is 0 This concludes null-size enforcement changes --- src/hb-null.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index b87775b63..58151d72b 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -50,7 +50,7 @@ template struct _hb_null_size { enum { value = sizeof (T) }; }; template -struct _hb_null_size > +struct _hb_null_size > { enum { value = T::null_size }; }; template From d0e81b2cc85d09d01905c5fc5b3382c25eaa3bb3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 21:20:39 -0500 Subject: [PATCH 037/158] [set] Rename --- src/hb-set.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-set.hh b/src/hb-set.hh index bc26ed3c0..cc061a7c8 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -341,11 +341,11 @@ struct hb_set_t { /* TODO perform op even if !successful. */ if (unlikely (!successful)) return; - page_t *p = page_for (g); - if (!p) + page_t *page = page_for (g); + if (!page) return; dirty (); - p->del (g); + page->del (g); } inline void del_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -357,10 +357,10 @@ struct hb_set_t } inline bool has (hb_codepoint_t g) const { - const page_t *p = page_for (g); - if (!p) + const page_t *page = page_for (g); + if (!page) return false; - return p->has (g); + return page->has (g); } inline bool intersects (hb_codepoint_t first, hb_codepoint_t last) const From 8982830d3ec54f50cc951de9569520fafc735e75 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Mon, 19 Nov 2018 13:00:24 -0800 Subject: [PATCH 038/158] [subset] add fuzzer testcase. --- ...se-minimized-hb-subset-fuzzer-5067936541179904 | Bin 0 -> 172 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 new file mode 100644 index 0000000000000000000000000000000000000000..9f57f7beec3ee8c8940f2d85546a2b826e6844b1 GIT binary patch literal 172 zcmZQzWME+6Qa}U$|APdQa}x_dG*E>mh+t;m0dqiX5MWVI_^$w@K}IMrfK&nnav?N` R%t* Date: Thu, 22 Nov 2018 21:30:04 -0500 Subject: [PATCH 039/158] [GSUB] Don't flush glyphset during recursion in closure() See comment. Supercedes https://github.com/harfbuzz/harfbuzz/pull/1401 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11366 --- src/hb-ot-layout-gsub-table.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 715317b59..501f2308c 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1449,7 +1449,10 @@ struct SubstLookup : Lookup hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); - c->flush (); + /* While in theory we should flush here, it will cause timeouts because a recursive + * lookup can keep growing the glyph set. Skip, and outer loop will retry up to + * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */ + //c->flush (); return ret; } From 2c8188bf599e351a4e0804d74612f9643b3d2443 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:02:19 -0500 Subject: [PATCH 040/158] [kerx] Make sure subtables are non-zero-length Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11400 --- src/hb-aat-layout-kerx-table.hh | 1 + src/hb-aat-layout-morx-table.hh | 2 +- ...se-minimized-hb-shape-fuzzer-5722888989048832 | Bin 0 -> 3608 bytes 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index f075a270a..210972767 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -812,6 +812,7 @@ struct KerxSubTable { TRACE_SANITIZE (this); if (!u.header.sanitize (c) || + u.header.length <= u.header.static_size || !c->check_range (this, u.header.length)) return_trace (false); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 430732702..bbe952fa1 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -915,7 +915,7 @@ struct ChainSubtable { TRACE_SANITIZE (this); if (!length.sanitize (c) || - length < min_size || + length <= min_size || !c->check_range (this, length)) return_trace (false); diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 new file mode 100644 index 0000000000000000000000000000000000000000..df1556b53ae58d6938163e6c59faa78e27c3c80b GIT binary patch literal 3608 zcmcInSx{T&6+Zv36;m)m3m8=Oii;%{0otx4FkpffAOa)=3Ucs*3Npf&#X@cno&i$c zl4hp0>%90OZJLKPGtNtOzTd^O=jAeq@L;GPMZhpG<6@)?fI`RwW&!+ zoA%87y60cc`OfyAdj$jlIEl0incN!AR5+S4cB%zf_-Sq%%s{1;e*n~0BKIg!VDbPw zj%LPaMG=&s#-W5J6fELUf&vuvs_U>klh)qQ+yJ0o!K0SN^x6t+KoWq|;+$Jt&aI_i zZQcebTLDnMx|CkbC@2oxNYthn^oCP;=urn--2T?LQISPHiK~}+`4ez4O@8UTrj^q>i zHu9Wg*>Thl)CKMI0wifSxZo5xp$&{LodiEPaPF4$v+O871~8zlOp5^nj=sTt@$Vu< zyE*8DG-NR`OtZ7Zi+9A^;`hZHC0yK*EdZ!kf#={2_&GcvK60A8KyHyc)J^kv0%IUW z^N&yt^#CS8=k-|KMxBATHu`X4))M|~!?)T_O1*KK> z`r-C>hRFR^uer*k>pk(}u8-voZv@rS+bl1ug1?tO5;OG5z*HEmM(0~X)D{T{qs<*H zi=o+kd%}O6%n$vU5O@#?b6`NBKd8yQh8)?;N-MV zXG+xc2Wz7zqEGgCI~(e{Esog{7FWy)ZKA(`GOTDI7zV5ejiR^4$O~41crZO=K|z(; z+Vb}?mC533BtDfTzw!=Q^^T*(Td|j4j*>e?K30u>oRs`{4=ndZtS$qqtVdiBv9|P9 zqg8_?K(@AD*a%Ep8|OM=>8H+^2ThK8a=!Qnovw=~Z!XO)ZyNODreo1qBzi<;CS&ni z3T%`VyogYNk+R^;gz8?3wNzuYVck~Jz0#6kZGuvc7OP~F$6r6Nl`(EYb-O8iTBud1 zYZ85Da#ymUr6-7MG#u`T*c(C~vT?mIs8mJO>h^dRlXNM&vK9K)!p>MS6u0+$tu^Uq z*wF%yWMGX?GMCEfw%c);Tv(pNzL@y|~ z(Lz?qQY4|0mU88B_fl2?rJlfUm&w>DHv?v&ji=iBfoC%YUzObznex?AjN}uiF9qhp zp{2g!FJr-ovlPl<45dmHt!R(UcQtfgnu}iS3O~QFlb8s{?A=`J1nZrZ@H)n`L>7FM zcmmaERf(tgK5@#t5__s&=G9OKV=`ZcJz+uS_2}6e>(I(F)YlCx7mO#+2ye6Ey+nM>}`uA{z!iNmZlGX*%y)mLJ$SL z*?>LF1T|2Lp4VY#HsfANp4AWz<@e;3a(rhqA|eudO0&{WmMeWs$TIK%0hp#H90Aax zMuO6^U3-!xJ+u!k6+!W1J=#P+cK|$!!#-ZH>q-{y$H7I3WDED>9D>1YI0Q$(=Z_3? zus>fO=U;LA?{F{$_-S>pKUJvm@%(%Sj+C~;a&s`w!TH&%oc;OfDb>Mvs6Ti}?Dpq} zS$!}LurfuGasDKIC)2(X&LJ58i9Za3(SCpW{zo{SU$PD!-l_d@`+wY@y+0QCRd^tM R;Xf9Z$NyM7^h2)2e*&f7H8KDI literal 0 HcmV?d00001 From a9fe787a11fc391d9a43a4ea19e6eb1c474199bd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:12:36 -0500 Subject: [PATCH 041/158] [sanitizer] Add reset_object(), make set_object() do bounds-check Affects morx/kerx run-time only currently. Will adjust their sanitize next. --- src/hb-aat-layout-kerx-table.hh | 1 + src/hb-aat-layout-morx-table.hh | 1 + src/hb-machinery.hh | 32 ++++++++++++++++++++------------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 210972767..8292dca67 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -934,6 +934,7 @@ struct KerxTable st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } + c->sanitizer.reset_object (); return ret; } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index bbe952fa1..cb871d2aa 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1041,6 +1041,7 @@ struct Chain subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } + c->sanitizer.reset_object (); } inline unsigned int get_size (void) const { return length; } diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index cb30e9907..edef54053 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -259,26 +259,34 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - /* TODO - * This set_object() thing is to use sanitize at runtime lookup - * application time. This is very distinct from the regular - * sanitizer operation, so, eventually, separate into another - * type and make hb_aat_apply_context_t use that one instead - * of abusing this one. - */ template inline void set_object (const T& obj) { - this->start = (const char *) &obj; - this->end = (const char *) &obj + obj.get_size (); + reset_object (); + + const char *obj_start = (const char *) &obj; + const char *obj_end = (const char *) &obj + obj.get_size (); + assert (obj_start <= obj_end); /* Must not overflow. */ + + if (unlikely (obj_end < this->start || this->end < obj_start)) + this->start = this->end = nullptr; + else + { + this->start = MAX (this->start, obj_start); + this->end = MIN (this->end , obj_end ); + } + } + + inline void reset_object (void) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; assert (this->start <= this->end); /* Must not overflow. */ } inline void start_processing (void) { - this->start = this->blob->data; - this->end = this->start + this->blob->length; - assert (this->start <= this->end); /* Must not overflow. */ + reset_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; From 758c9d68e2143493978d8ac8391f4af2a2abc26a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:16:12 -0500 Subject: [PATCH 042/158] [morx/kerx] Limit range to subtable when sanitizing --- src/hb-aat-layout-kerx-table.hh | 2 ++ src/hb-aat-layout-morx-table.hh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 8292dca67..bb88d9d15 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -953,10 +953,12 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { + c->set_object (*st); if (unlikely (!st->sanitize (c))) return_trace (false); st = &StructAfter (*st); } + c->reset_object (); return_trace (true); } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index cb871d2aa..7a39eea8d 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1061,10 +1061,12 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { + c->set_object (*subtable); if (!subtable->sanitize (c)) return_trace (false); subtable = &StructAfter > (*subtable); } + c->reset_object (); return_trace (true); } From e4a4555d1e40dacdf72452805e9e6b6109627d63 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:17:49 -0500 Subject: [PATCH 043/158] [cmap] Move code around --- src/hb-ot-cmap-table.hh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index b7d17018a..4297550fd 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -863,14 +863,6 @@ struct cmap hb_vector_t format12_groups; }; - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version == 0) && - encodingRecord.sanitize (c, this)); - } - inline bool _create_plan (const hb_subset_plan_t *plan, subset_plan *cmap_plan) const { @@ -1171,6 +1163,16 @@ struct cmap return &(this+encodingRecord[result].subtable); } + public: + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); + } + protected: HBUINT16 version; /* Table version number (0). */ SortedArrayOf From a2d6c1075a5595a08ef09357293919d9df8eb64a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:40:57 -0500 Subject: [PATCH 044/158] Minor tweak to FLAG64 --- src/hb.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index a40e6f2c2..be8b2148f 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -446,11 +446,11 @@ typedef uint64_t hb_vector_size_impl_t; * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x))) -#define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0) +#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (1U << (unsigned)(x))) +#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (1U << (unsigned)(x)) : 0) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) -#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned long long)(x) < 64) + (1ULL << (unsigned long long)(x))) -#define FLAG64_UNSAFE(x) ((unsigned long long)(x) < 64 ? (1ULL << (unsigned long long)(x)) : 0) +#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (1ULL << (unsigned)(x))) +#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (1ULL << (unsigned)(x)) : 0) /* Size signifying variable-sized array */ From 22798e93c414a2655c757a6e41b300f67e04a9a3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Nov 2018 22:47:51 -0500 Subject: [PATCH 045/158] [use] Minor clarification --- src/hb-ot-shape-complex-use.cc | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 4daa27875..2e3f202f5 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -450,22 +450,22 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) hb_glyph_info_t *info = buffer->info; -#define POST_BASE_FLAGS (FLAG64 (USE_FM) | \ - FLAG64 (USE_FAbv) | \ - FLAG64 (USE_FBlw) | \ - FLAG64 (USE_FPst) | \ - FLAG64 (USE_MAbv) | \ - FLAG64 (USE_MBlw) | \ - FLAG64 (USE_MPst) | \ - FLAG64 (USE_MPre) | \ - FLAG64 (USE_VAbv) | \ - FLAG64 (USE_VBlw) | \ - FLAG64 (USE_VPst) | \ - FLAG64 (USE_VPre) | \ - FLAG64 (USE_VMAbv) | \ - FLAG64 (USE_VMBlw) | \ - FLAG64 (USE_VMPst) | \ - FLAG64 (USE_VMPre)) +#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \ + FLAG64 (USE_FAbv) | \ + FLAG64 (USE_FBlw) | \ + FLAG64 (USE_FPst) | \ + FLAG64 (USE_MAbv) | \ + FLAG64 (USE_MBlw) | \ + FLAG64 (USE_MPst) | \ + FLAG64 (USE_MPre) | \ + FLAG64 (USE_VAbv) | \ + FLAG64 (USE_VBlw) | \ + FLAG64 (USE_VPst) | \ + FLAG64 (USE_VPre) | \ + FLAG64 (USE_VMAbv) | \ + FLAG64 (USE_VMBlw) | \ + FLAG64 (USE_VMPst) | \ + FLAG64 (USE_VMPre)) /* Move things forward. */ if (info[start].use_category() == USE_R && end - start > 1) @@ -474,7 +474,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) * glyph. */ for (unsigned int i = start + 1; i < end; i++) { - bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS) || + bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) || is_halant (info[i]); if (is_post_base_glyph || i == end - 1) { From 341851efe158599a34d241a97593058a4333852e Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 23 Nov 2018 15:40:05 +0330 Subject: [PATCH 046/158] [aat] Add macOS specific tests (#1404) --- .circleci/config.yml | 46 ++++++++++++------- test/shaping/CMakeLists.txt | 2 + test/shaping/data/in-house/Makefile.sources | 1 + .../data/in-house/tests/macos-10.12.tests | 10 ++++ test/shaping/run-tests.py | 38 ++++++++++++--- 5 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 test/shaping/data/in-house/tests/macos-10.12.tests diff --git a/.circleci/config.yml b/.circleci/config.yml index 906f4ba85..e56aabb7f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,30 +2,41 @@ version: 2 jobs: - macos-llvm-gcc-4.2: + macos-10.12-aat-fonts: macos: - xcode: "8.3.3" + xcode: "9.2.0" steps: - checkout - run: brew update-reset - run: brew install wget pkg-config libtool ragel freetype glib cairo - - run: wget https://packages.macports.org/llvm-gcc42/llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 - - run: CC=$PWD/opt/local/bin/llvm-gcc-4.2 CXX=$PWD/opt/local/bin/llvm-g++-4.2 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo - # Ignoring assembler complains, https://stackoverflow.com/a/39867021 - - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' + - run: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo + - run: make -j4 - run: make check || .ci/fail.sh - macos-notest-apple-gcc-i686-4.2: - macos: - xcode: "8.3.3" - steps: - - checkout - - run: brew update-reset - - run: brew install wget pkg-config libtool ragel - - run: wget https://packages.macports.org/apple-gcc42/apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 - - run: CPP=$PWD/opt/local/bin/i686-apple-darwin15-cpp-apple-4.2.1 CC=$PWD/opt/local/bin/i686-apple-darwin15-gcc-apple-4.2.1 CXX=$PWD/opt/local/bin/i686-apple-darwin15-g++-apple-4.2.1 ./autogen.sh - # Ignoring assembler complains, https://stackoverflow.com/a/39867021 - - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' + # macos-llvm-gcc-4.2: + # macos: + # xcode: "8.3.3" + # steps: + # - checkout + # - run: brew update-reset + # - run: brew install wget pkg-config libtool ragel freetype glib cairo + # - run: wget https://packages.macports.org/llvm-gcc42/llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 + # - run: CC=$PWD/opt/local/bin/llvm-gcc-4.2 CXX=$PWD/opt/local/bin/llvm-g++-4.2 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo + # # Ignoring assembler complains, https://stackoverflow.com/a/39867021 + # - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' + # - run: make check || .ci/fail.sh + + # macos-notest-apple-gcc-i686-4.2: + # macos: + # xcode: "8.3.3" + # steps: + # - checkout + # - run: brew update-reset + # - run: brew install wget pkg-config libtool ragel + # - run: wget https://packages.macports.org/apple-gcc42/apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 + # - run: CPP=$PWD/opt/local/bin/i686-apple-darwin15-cpp-apple-4.2.1 CC=$PWD/opt/local/bin/i686-apple-darwin15-gcc-apple-4.2.1 CXX=$PWD/opt/local/bin/i686-apple-darwin15-g++-apple-4.2.1 ./autogen.sh + # # Ignoring assembler complains, https://stackoverflow.com/a/39867021 + # - run: make 2>&1 | grep -v -e '^/var/folders/*' -e '^[[:space:]]*\.section' -e '^[[:space:]]*\^[[:space:]]*~*' macos-notest-ios: macos: @@ -302,6 +313,7 @@ workflows: build: jobs: # macOS + - macos-10.12-aat-fonts #- macos-llvm-gcc-4.2 #- macos-notest-apple-gcc-i686-4.2 - macos-notest-ios diff --git a/test/shaping/CMakeLists.txt b/test/shaping/CMakeLists.txt index 7c2c9990e..25f14177e 100644 --- a/test/shaping/CMakeLists.txt +++ b/test/shaping/CMakeLists.txt @@ -5,6 +5,7 @@ if (HB_BUILD_UTILS) add_test (NAME ${test} COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/in-house/${test}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_property(TEST ${test} PROPERTY SKIP_RETURN_CODE 77) endforeach () file (READ "${CMAKE_CURRENT_SOURCE_DIR}/data/text-rendering-tests/Makefile.sources" TEXTRENDERING) @@ -13,5 +14,6 @@ if (HB_BUILD_UTILS) add_test (NAME ${test} COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/text-rendering-tests/${test}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_property(TEST ${test} PROPERTY SKIP_RETURN_CODE 77) endforeach () endif () diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index e5f105c78..209de079c 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -33,6 +33,7 @@ TESTS = \ tests/khmer-misc.tests \ tests/language-tags.tests \ tests/ligature-id.tests \ + tests/macos-10.12.tests \ tests/mark-attachment.tests \ tests/mark-filtering-sets.tests \ tests/mongolian-variation-selector.tests \ diff --git a/test/shaping/data/in-house/tests/macos-10.12.tests b/test/shaping/data/in-house/tests/macos-10.12.tests new file mode 100644 index 000000000..770a70ee1 --- /dev/null +++ b/test/shaping/data/in-house/tests/macos-10.12.tests @@ -0,0 +1,10 @@ +/Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+0|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+0|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+0|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+0|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+0|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+0|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064F:[u064f.damma=0@250,-250+0|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index abb25ab3e..17e203c03 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -2,7 +2,7 @@ from __future__ import print_function, division, absolute_import -import sys, os, subprocess +import sys, os, subprocess, hashlib, tempfile, shutil def cmd(command): global process @@ -28,6 +28,7 @@ process = subprocess.Popen ([hb_shape, '--batch'], stderr=sys.stdout) fails = 0 +skips = 0 if not len (args): args = ['-'] @@ -46,8 +47,24 @@ for filename in args: for line in f: fontfile, options, unicodes, glyphs_expected = line.split (":") - cwd = os.path.dirname(filename) - fontfile = os.path.normpath (os.path.join (cwd, fontfile)) + if fontfile.startswith ('/') or fontfile.startswith ('"/'): + fontfile, expected_hash = fontfile.split('@') + + try: + with open (fontfile, 'rb') as ff: + actual_hash = hashlib.sha1 (ff.read()).hexdigest ().strip () + if actual_hash != expected_hash: + print ('different versions of the font is found, expected %s hash was %s but got %s, skip' % + (fontfile, expected_hash, actual_hash)) + skips = skips + 1 + continue + except: + print ('%s is not found, skip.' % fontfile) + skips = skips + 1 + continue + else: + cwd = os.path.dirname(filename) + fontfile = os.path.normpath (os.path.join (cwd, fontfile)) extra_options = ["--shaper=ot"] glyphs_expected = glyphs_expected.strip() @@ -63,6 +80,12 @@ for filename in args: print ("%s %s %s %s --unicodes %s" % (hb_shape, fontfile, ' '.join(extra_options), options, unicodes)) + # hack to support fonts with space on run-tests.py, after several other tries... + if ' ' in fontfile: + new_fontfile = os.path.join (tempfile.gettempdir (), 'tmpfile') + shutil.copyfile(fontfile, new_fontfile) + fontfile = new_fontfile + glyphs1 = cmd ([hb_shape, "--font-funcs=ft", fontfile] + extra_options + ["--unicodes", unicodes] + (options.split (' ') if options else [])) @@ -85,11 +108,12 @@ for filename in args: print ("Expected: " + glyphs_expected) # file=sys.stderr fails = fails + 1 -if fails != 0: +if fails != 0 or skips != 0: if not reference: - print (str (fails) + " tests failed.") # file=sys.stderr - sys.exit (1) - + print ("%d tests are failed and %d tests are skipped." % (fails, skips)) # file=sys.stderr + if fails != 0: + sys.exit (1) + sys.exit (77) else: if not reference: print ("All tests passed.") From 3d2b98ef14af29acd74f01647bef60cd410825fb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 10:45:44 -0500 Subject: [PATCH 047/158] Minor --- src/hb.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index be8b2148f..bc322a814 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -446,11 +446,11 @@ typedef uint64_t hb_vector_size_impl_t; * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (1U << (unsigned)(x))) -#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (1U << (unsigned)(x)) : 0) +#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) +#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) -#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (1ULL << (unsigned)(x))) -#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (1ULL << (unsigned)(x)) : 0) +#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) +#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) /* Size signifying variable-sized array */ From 748962264a9f098b32b9cb3fe4d18c786907a184 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 11:10:17 -0500 Subject: [PATCH 048/158] [aat] Disable mark advance zeroing if kern table has state-machines Geeza Pro for example, relies on that for fancy mark positioning. Fixes https://github.com/harfbuzz/harfbuzz/issues/1405 --- src/hb-aat-layout-kerx-table.hh | 15 +++++++++++++++ src/hb-ot-kern-table.hh | 9 +++++++++ src/hb-ot-layout.cc | 6 ++++++ src/hb-ot-layout.hh | 3 +++ src/hb-ot-shape.cc | 4 +++- 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index bb88d9d15..74fecbb11 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -843,6 +843,21 @@ struct KerxTable /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ inline const T* thiz (void) const { return static_cast (this); } + inline bool has_state_machine (void) const + { + typedef typename T::SubTable SubTable; + + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; + for (unsigned int i = 0; i < count; i++) + { + if (st->get_type () == 1) + return true; + st = &StructAfter (*st); + } + return false; + } + inline bool has_cross_stream (void) const { typedef typename T::SubTable SubTable; diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index b2d571404..b57ebaea8 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -274,6 +274,15 @@ struct kern inline bool has_data (void) const { return u.version32; } inline unsigned int get_type (void) const { return u.major; } + inline bool has_state_machine (void) const + { + switch (get_type ()) { + case 0: return u.ot.has_state_machine (); + case 1: return u.aat.has_state_machine (); + default:return false; + } + } + inline bool has_cross_stream (void) const { switch (get_type ()) { diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 092633c5d..9488fe82c 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -65,6 +65,12 @@ hb_ot_layout_has_kerning (hb_face_t *face) return face->table.kern->has_data (); } +bool +hb_ot_layout_has_machine_kerning (hb_face_t *face) +{ + return face->table.kern->has_state_machine (); +} + bool hb_ot_layout_has_cross_kerning (hb_face_t *face) { diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh index db85508d2..a00b940b2 100644 --- a/src/hb-ot-layout.hh +++ b/src/hb-ot-layout.hh @@ -48,6 +48,9 @@ struct hb_ot_shape_plan_t; HB_INTERNAL bool hb_ot_layout_has_kerning (hb_face_t *face); +HB_INTERNAL bool +hb_ot_layout_has_machine_kerning (hb_face_t *face); + HB_INTERNAL bool hb_ot_layout_has_cross_kerning (hb_face_t *face); diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 8d844807c..ef9743578 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -146,7 +146,9 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.apply_kern = true; } - plan.zero_marks = script_zero_marks && !plan.apply_kerx; + plan.zero_marks = script_zero_marks && + !plan.apply_kerx && + (!plan.apply_kern || !hb_ot_layout_has_machine_kerning (face)); plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && From c9cc96c0cfbbb87b9292e413d500a454182be9f4 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 23 Nov 2018 19:58:56 +0330 Subject: [PATCH 049/158] [aat] Update expectation --- test/shaping/data/in-house/tests/macos-10.12.tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/shaping/data/in-house/tests/macos-10.12.tests b/test/shaping/data/in-house/tests/macos-10.12.tests index 770a70ee1..6841ef93f 100644 --- a/test/shaping/data/in-house/tests/macos-10.12.tests +++ b/test/shaping/data/in-house/tests/macos-10.12.tests @@ -3,8 +3,8 @@ /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] /System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] /Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+0|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+0|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+0|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+0|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+0|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+0|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064F:[u064f.damma=0@250,-250+0|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] /System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] From 018ba46e4d003a5dd0f6d2d899226129c4ef0c60 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Fri, 23 Nov 2018 13:21:22 -0500 Subject: [PATCH 050/158] Don't canonicalize '@' to '-' in language tags Fixes #1406. --- src/hb-common.cc | 2 +- test/api/test-ot-tag.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index 28b0c2b82..b7f9ad68b 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -204,7 +204,7 @@ static const char canon_map[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0, - '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-', 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 diff --git a/test/api/test-ot-tag.c b/test/api/test-ot-tag.c index c0329bffc..82a57dc0b 100644 --- a/test/api/test-ot-tag.c +++ b/test/api/test-ot-tag.c @@ -449,6 +449,9 @@ test_ot_tag_language (void) /* A UN M.49 region code, not an extended language subtag */ test_tag_from_language ("ARA", "ar-001"); + + /* An invalid tag */ + test_tag_from_language ("TRK", "tr@foo=bar"); } static void From 9552f4ef0da0b7e1fb28cb2738b865888e7941d9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 15:24:17 -0500 Subject: [PATCH 051/158] [kern] Don't enforce length of last subtable --- src/hb-aat-layout-kerx-table.hh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 74fecbb11..c60f29a68 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -936,7 +936,11 @@ struct KerxTable if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (*st); + /* See comment in sanitize() for conditional here. */ + if (i < count - 1) + c->sanitizer.set_object (*st); + else + c->sanitizer.reset_object (); ret |= st->dispatch (c); @@ -968,7 +972,18 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - c->set_object (*st); + /* OpenType kern table has 2-byte subtable lengths. That's limiting. + * MS implementation also only supports one subtable, of format 0, + * anyway. Certain versions of some fonts, like Calibry, contain + * kern subtable that exceeds 64kb. Looks like, the subtable length + * is simply ignored. Which makes sense. It's only needed if you + * have multiple subtables. To handle such fonts, we just ignore + * the length for the last subtable. */ + if (i < count - 1) + c->set_object (*st); + else + c->reset_object (); + if (unlikely (!st->sanitize (c))) return_trace (false); st = &StructAfter (*st); From c514f65181390ab98b0f738632f71cda31e46b68 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 16:04:56 -0500 Subject: [PATCH 052/158] [arrays] Add as_array() to ArrayOf<> --- src/hb-open-type.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index f4a9a5e87..17bc9c5b4 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -479,6 +479,9 @@ struct ArrayOf inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } + inline hb_array_t as_array (void) { return hb_array_t (arrayZ, len); } + inline hb_array_t as_array (void) const { return hb_array_t (arrayZ, len); } + inline bool serialize (hb_serialize_context_t *c, unsigned int items_len) { From 04f7e5536924e7f277d72b8cb9d878239877c331 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 16:07:43 -0500 Subject: [PATCH 053/158] [arrays] Add as_array() to hb_vector_t<> --- src/hb-vector.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 7056a5b54..c1f680ed8 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -89,6 +89,9 @@ struct hb_vector_t return arrayZ()[i]; } + inline hb_array_t as_array (void) { return hb_array_t (arrayZ(), len); } + inline hb_array_t as_array (void) const { return hb_array_t (arrayZ(), len); } + template inline operator T * (void) { return arrayZ(); } template inline operator const T * (void) const { return arrayZ(); } From e2ffb33a534a427c760dae53d0469eeced4343ba Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 16:24:28 -0500 Subject: [PATCH 054/158] Remove lsearch for small TableDirectorys --- src/hb-open-file.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 2ef6d775f..cd5f9dbc9 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -111,9 +111,7 @@ typedef struct OffsetTable { Tag t; t.set (tag); - /* Linear-search for small tables to work around fonts with unsorted - * table list. */ - int i = tables.len < 64 ? tables.lsearch (t) : tables.bsearch (t); + int i = tables.bsearch (t); if (table_index) *table_index = i == -1 ? (unsigned) Index::NOT_FOUND_INDEX : (unsigned) i; return i != -1; From ec83b2228e0bbb6df7e7b94dad49db32b041af4a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 19:58:49 -0500 Subject: [PATCH 055/158] Add null bytes for CmapSubtableLongGroup --- src/hb-ot-cmap-table.hh | 1 + src/hb-static.cc | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 4297550fd..70373ee8b 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -417,6 +417,7 @@ struct CmapSubtableLongGroup public: DEFINE_SIZE_STATIC (12); }; +DECLARE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup); template struct CmapSubtableTrimmed diff --git a/src/hb-static.cc b/src/hb-static.cc index 73d9528e6..3ea640246 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -27,10 +27,11 @@ #include "hb.hh" #include "hb-open-type.hh" -#include "hb-ot-layout-common.hh" #include "hb-aat-layout-common.hh" +#include "hb-ot-layout-common.hh" #include "hb-face.hh" +#include "hb-ot-cmap-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" @@ -42,6 +43,7 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_ DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; +DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; /* Hand-coded because Lookup is a template. Sad. */ const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; From f99abcc37990a478189dda691d1fdac7b9d51386 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:22:21 -0500 Subject: [PATCH 056/158] Add template-function convenience macros --- src/hb-atomic.hh | 2 +- src/hb-blob.hh | 4 ++-- src/hb-common.cc | 2 +- src/hb-ft.cc | 2 +- src/hb-null.hh | 11 ++++++----- src/hb.hh | 3 +++ 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 64ed257bd..265de1267 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -282,7 +282,7 @@ struct hb_atomic_int_t template struct hb_atomic_ptr_t { - typedef typename hb_remove_pointer

::value T; + typedef typename hb_remove_pointer (P) T; inline void init (T* v_ = nullptr) { set_relaxed (v_); } inline void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } diff --git a/src/hb-blob.hh b/src/hb-blob.hh index 4f9d8f040..bf2132bda 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -60,7 +60,7 @@ struct hb_blob_t template inline const Type* as (void) const { - return length < hb_null_size::value ? &Null(Type) : reinterpret_cast (data); + return length < hb_null_size (Type) ? &Null(Type) : reinterpret_cast (data); } inline hb_bytes_t as_bytes (void) const { @@ -86,7 +86,7 @@ struct hb_blob_t template struct hb_blob_ptr_t { - typedef typename hb_remove_pointer

::value T; + typedef typename hb_remove_pointer (P) T; inline hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {} inline hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; } diff --git a/src/hb-common.cc b/src/hb-common.cc index b7f9ad68b..c3cffccb1 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -784,7 +784,7 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv) static void free_static_C_locale (void); #endif -static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t::value, +static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t { static inline HB_LOCALE_T create (void) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index fff0e285a..633e0ecd2 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -748,7 +748,7 @@ hb_ft_font_create_referenced (FT_Face ft_face) static void free_static_ft_library (void); #endif -static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t::value, +static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t { static inline FT_Library create (void) diff --git a/src/hb-null.hh b/src/hb-null.hh index 58151d72b..c0cefc9a8 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -56,6 +56,7 @@ struct _hb_null_size > template struct hb_null_size { enum { value = _hb_null_size >::value }; }; +#define hb_null_size(T) hb_null_size::value extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; @@ -63,10 +64,10 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_ /* Generic nul-content Null objects. */ template static inline Type const & Null (void) { - static_assert (hb_null_size::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); return *reinterpret_cast (_hb_NullPool); } -#define Null(Type) Null::value>::value>() +#define Null(Type) Null () /* Specializations for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ @@ -104,12 +105,12 @@ extern HB_INTERNAL /* CRAP pool: Common Region for Access Protection. */ template static inline Type& Crap (void) { - static_assert (hb_null_size::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); Type *obj = reinterpret_cast (_hb_CrapPool); memcpy (obj, &Null(Type), sizeof (*obj)); return *obj; } -#define Crap(Type) Crap::value>::value>() +#define Crap(Type) Crap () template struct CrapOrNull { @@ -129,7 +130,7 @@ struct CrapOrNull { template struct hb_nonnull_ptr_t { - typedef typename hb_remove_pointer

::value T; + typedef typename hb_remove_pointer (P) T; inline hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {} inline T * operator = (T *v_) { return v = v_; } diff --git a/src/hb.hh b/src/hb.hh index bc322a814..c771d1fb9 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -508,10 +508,13 @@ _hb_memalign(void **memptr, size_t alignment, size_t size) /* Some really basic things everyone wants. */ template struct hb_remove_const { typedef T value; }; template struct hb_remove_const { typedef T value; }; +#define hb_remove_const(T) hb_remove_const::value template struct hb_remove_reference { typedef T value; }; template struct hb_remove_reference { typedef T value; }; +#define hb_remove_reference(T) hb_remove_reference::value template struct hb_remove_pointer { typedef T value; }; template struct hb_remove_pointer { typedef T value; }; +#define hb_remove_pointer(T) hb_remove_pointer::value /* Headers we include for everyone. Keep sorted. They express dependency amongst From 39b9d63b014380d421cc9b94a49dd411c7a5aabf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:25:40 -0500 Subject: [PATCH 057/158] Add hb_static_size(T) --- src/hb-null.hh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/hb-null.hh b/src/hb-null.hh index c0cefc9a8..1583d5b90 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -44,6 +44,7 @@ /* The hard way... * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol */ + template struct _hb_bool_type {}; template @@ -58,6 +59,24 @@ struct hb_null_size { enum { value = _hb_null_size >::value }; }; #define hb_null_size(T) hb_null_size::value +/* This doesn't belong here, but since is copy/paste from above, put it here. */ + +template +struct _hb_static_size +{ enum { value = sizeof (T) }; }; +template +struct _hb_static_size > +{ enum { value = T::static_size }; }; + +template +struct hb_static_size +{ enum { value = _hb_static_size >::value }; }; +#define hb_static_size(T) hb_static_size::value + + +/* + * Null() + */ extern HB_INTERNAL hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; From ba38378fd4374f3d44bdc9aa0de902401b60b13d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:27:57 -0500 Subject: [PATCH 058/158] [aat] Minor --- src/hb-aat-layout-common.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 7340996e5..2c09a796c 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -436,8 +436,10 @@ struct Entry * which ensures that data has a simple sanitize(). To be determined * if I need to remove that as well. * - * XXX Because we are a template, our DEFINE_SIZE_STATIC assertion - * wouldn't be checked. */ + * HOWEVER! Because we are a template, our DEFINE_SIZE_STATIC + * assertion wouldn't be checked, hence the line below. */ + static_assert (T::static_size, ""); + return_trace (c->check_struct (this)); } From 690d9eb83d3421b397b0cb824cd768d6d73cbf12 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:29:22 -0500 Subject: [PATCH 059/158] [vector] Rename --- src/hb-vector.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index c1f680ed8..926f00544 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -31,13 +31,13 @@ #include "hb.hh" -template +template struct hb_vector_t { typedef Type ItemType; enum { item_size = sizeof (Type) }; - HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, StaticSize); + HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, PreallocedCount); inline hb_vector_t (void) { init (); } inline ~hb_vector_t (void) { fini (); } @@ -45,7 +45,7 @@ struct hb_vector_t private: unsigned int allocated; /* == 0 means allocation failed. */ Type *arrayZ_; - Type static_array[StaticSize]; + Type static_array[PreallocedCount]; public: void init (void) From bb2a2065080a3099eb0dc82d1df0891ad2601316 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:31:40 -0500 Subject: [PATCH 060/158] Assert that item-type of arrays have static size --- src/hb-dsalgs.hh | 2 ++ src/hb-open-type.hh | 4 ++++ src/hb-vector.hh | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index da8aad013..c133a532d 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -562,6 +562,8 @@ struct hb_bytes_t template struct hb_array_t { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + inline hb_array_t (void) : arrayZ (nullptr), len (0) {} inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {} diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 17bc9c5b4..1c7b738be 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -345,6 +345,8 @@ static inline Type& operator + (Base &base, OffsetTo template struct UnsizedArrayOf { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + enum { item_size = Type::static_size }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); @@ -449,6 +451,8 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf template struct ArrayOf { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + enum { item_size = Type::static_size }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 926f00544..c1d7f946a 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -34,6 +34,8 @@ template struct hb_vector_t { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + typedef Type ItemType; enum { item_size = sizeof (Type) }; From fd94e729cb50f2b6bd83b80cbf400e10ac633a1c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:45:55 -0500 Subject: [PATCH 061/158] Whitespace --- src/hb-ot-layout-common.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 46c2f182d..1d0ec0839 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1265,10 +1265,10 @@ struct ClassDefFormat1 } protected: - HBUINT16 classFormat; /* Format identifier--format = 1 */ - GlyphID startGlyph; /* First GlyphID of the classValueArray */ + HBUINT16 classFormat; /* Format identifier--format = 1 */ + GlyphID startGlyph; /* First GlyphID of the classValueArray */ ArrayOf - classValue; /* Array of Class Values--one per GlyphID */ + classValue; /* Array of Class Values--one per GlyphID */ public: DEFINE_SIZE_ARRAY (6, classValue); }; From 5cd9546ba73d9f8c8b7b8db0960d657c50b70f64 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:38:36 -0500 Subject: [PATCH 062/158] Minor --- src/hb-ot-layout-common.hh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 1d0ec0839..d7c317843 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1194,10 +1194,7 @@ struct ClassDefFormat1 private: inline unsigned int get_class (hb_codepoint_t glyph_id) const { - unsigned int i = (unsigned int) (glyph_id - startGlyph); - if (unlikely (i < classValue.len)) - return classValue[i]; - return 0; + return classValue[(unsigned int) (glyph_id - startGlyph)]; } inline bool sanitize (hb_sanitize_context_t *c) const From 30cb45b3eaacda15cc45435815cae3fd50e87557 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:35:31 -0500 Subject: [PATCH 063/158] Change ArrayOf.bsearch() return semantics Towards consolidating all array bsearch/... --- src/hb-aat-layout-kerx-table.hh | 16 +++---------- src/hb-open-file.hh | 12 ++++++---- src/hb-open-type.hh | 42 ++++++++++++++++++++++++++------- src/hb-ot-cmap-table.hh | 30 ++++++++++------------- src/hb-ot-color-svg-table.hh | 3 +-- src/hb-ot-layout-common.hh | 29 +++++++++-------------- src/hb-ot-vorg-table.hh | 9 ++++--- src/hb-vector.hh | 14 +++++++---- 8 files changed, 81 insertions(+), 74 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index c60f29a68..521c4c728 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -49,7 +49,7 @@ kerxTupleKern (int value, const void *base, hb_aat_apply_context_t *c) { - if (likely (!tupleCount)) return value; + if (likely (!tupleCount || !c)) return value; unsigned int offset = value; const FWORD *pv = &StructAtOffset (base, offset); @@ -93,21 +93,11 @@ struct KernPair template struct KerxSubTableFormat0 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - hb_glyph_pair_t pair = {left, right}; - int i = pairs.bsearch (pair); - if (i == -1) return 0; - return pairs[i].get_kerning (); - } - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - hb_aat_apply_context_t *c) const + hb_aat_apply_context_t *c = nullptr) const { hb_glyph_pair_t pair = {left, right}; - int i = pairs.bsearch (pair); - if (i == -1) return 0; - int v = pairs[i].get_kerning (); + int v = pairs.bsearch (pair).get_kerning (); return kerxTupleKern (v, header.tuple_count (), this, c); } diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index cd5f9dbc9..d3ecc606d 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -111,10 +111,14 @@ typedef struct OffsetTable { Tag t; t.set (tag); - int i = tables.bsearch (t); - if (table_index) - *table_index = i == -1 ? (unsigned) Index::NOT_FOUND_INDEX : (unsigned) i; - return i != -1; + unsigned int i; + if (tables.bfind (t, &i)) + { + if (table_index) *table_index = i; + return true; + } + if (table_index) *table_index = (unsigned) Index::NOT_FOUND_INDEX; + return false; } inline const TableRecord& get_table_by_tag (hb_tag_t tag) const { diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 1c7b738be..f255ea12a 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -740,21 +740,45 @@ struct ArrayOfM1 template struct SortedArrayOf : ArrayOf { - template - inline int bsearch (const SearchType &x) const + template + inline Type &bsearch (const T &x) + { + unsigned int i; + return bfind (x, &i) ? this->arrayZ[i] : Crap(Type); + } + template + inline const Type &bsearch (const T &x) const + { + unsigned int i; + return bfind (x, &i) ? this->arrayZ[i] : Null(Type); + } + template + inline bool bfind (const T &x, unsigned int *i = nullptr) const { - /* Hand-coded bsearch here since this is in the hot inner loop. */ - const Type *arr = this->arrayZ; int min = 0, max = (int) this->len - 1; + const Type *array = this->arrayZ; while (min <= max) { int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = arr[mid].cmp (x); - if (c < 0) max = mid - 1; - else if (c > 0) min = mid + 1; - else return mid; + int c = array[mid].cmp (x); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + { + if (i) + *i = mid; + return true; + } } - return -1; + if (i) + { + if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) + max++; + *i = max; + } + return false; } }; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 70373ee8b..cdc610be3 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -468,10 +468,7 @@ struct CmapSubtableLongSegmented inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { - int i = groups.bsearch (codepoint); - if (i == -1) - return false; - hb_codepoint_t gid = T::group_get_glyph (groups[i], codepoint); + hb_codepoint_t gid = T::group_get_glyph (groups.bsearch (codepoint), codepoint); if (!gid) return false; *glyph = gid; @@ -518,7 +515,8 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented { static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, hb_codepoint_t u) - { return group.glyphID + (u - group.startCharCode); } + { return likely (group.startCharCode <= group.endCharCode) ? + group.glyphID + (u - group.startCharCode) : 0; } bool serialize (hb_serialize_context_t *c, @@ -674,16 +672,12 @@ struct VariationSelectorRecord hb_codepoint_t *glyph, const void *base) const { - int i; - const DefaultUVS &defaults = base+defaultUVS; - i = defaults.bsearch (codepoint); - if (i != -1) + if ((base+defaultUVS).bfind (codepoint)) return GLYPH_VARIANT_USE_DEFAULT; - const NonDefaultUVS &nonDefaults = base+nonDefaultUVS; - i = nonDefaults.bsearch (codepoint); - if (i != -1 && nonDefaults[i].glyphID) + const UVSMapping &nonDefault = (base+nonDefaultUVS).bsearch (codepoint); + if (nonDefault.glyphID) { - *glyph = nonDefaults[i].glyphID; + *glyph = nonDefault.glyphID; return GLYPH_VARIANT_FOUND; } return GLYPH_VARIANT_NOT_FOUND; @@ -723,7 +717,7 @@ struct CmapSubtableFormat14 hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { - return record[record.bsearch (variation_selector)].get_glyph (codepoint, glyph, this); + return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this); } inline void collect_variation_selectors (hb_set_t *out) const @@ -735,7 +729,7 @@ struct CmapSubtableFormat14 inline void collect_variation_unicodes (hb_codepoint_t variation_selector, hb_set_t *out) const { - record[record.bsearch (variation_selector)].collect_unicodes (out, this); + record.bsearch (variation_selector).collect_unicodes (out, this); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1157,11 +1151,11 @@ struct cmap key.platformID.set (platform_id); key.encodingID.set (encoding_id); - int result = encodingRecord.bsearch (key); - if (result == -1 || !encodingRecord[result].subtable) + const EncodingRecord &result = encodingRecord.bsearch (key); + if (!result.subtable) return nullptr; - return &(this+encodingRecord[result].subtable); + return &(this+result.subtable); } public: diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index bad8ef549..ad3551035 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,8 +103,7 @@ struct SVG inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const { - const SortedArrayOf &docs = this+svgDocEntries; - return docs[docs.bsearch (glyph_id)]; + return (this+svgDocEntries).bsearch (glyph_id); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index d7c317843..6c6bcf580 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -128,15 +128,12 @@ struct RecordArrayOf : SortedArrayOf > } inline bool find_index (hb_tag_t tag, unsigned int *index) const { - /* If we want to allow non-sorted data, we can lsearch(). */ - int i = this->/*lsearch*/bsearch (tag); - if (i != -1) { - if (index) *index = i; - return true; - } else { + if (!this->bfind (tag, index)) + { if (index) *index = Index::NOT_FOUND_INDEX; return false; } + return true; } }; @@ -823,8 +820,9 @@ struct CoverageFormat1 private: inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { - int i = glyphArray.bsearch (glyph_id); - static_assert ((((unsigned int) -1) == NOT_COVERED), ""); + unsigned int i; + if (!glyphArray.bfind (glyph_id, &i)) + return NOT_COVERED; return i; } @@ -896,12 +894,10 @@ struct CoverageFormat2 private: inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { - int i = rangeRecord.bsearch (glyph_id); - if (i != -1) { - const RangeRecord &range = rangeRecord[i]; - return (unsigned int) range.value + (glyph_id - range.start); - } - return NOT_COVERED; + const RangeRecord &range = rangeRecord.bsearch (glyph_id); + return likely (range.start <= range.end) ? + (unsigned int) range.value + (glyph_id - range.start) : + NOT_COVERED; } inline bool serialize (hb_serialize_context_t *c, @@ -1277,10 +1273,7 @@ struct ClassDefFormat2 private: inline unsigned int get_class (hb_codepoint_t glyph_id) const { - int i = rangeRecord.bsearch (glyph_id); - if (unlikely (i != -1)) - return rangeRecord[i].value; - return 0; + return rangeRecord.bsearch (glyph_id).value; } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh index 98af00e14..a0480cbcb 100644 --- a/src/hb-ot-vorg-table.hh +++ b/src/hb-ot-vorg-table.hh @@ -63,11 +63,10 @@ struct VORG inline int get_y_origin (hb_codepoint_t glyph) const { - int i = vertYOrigins.bsearch (glyph); - if (i != -1) - return vertYOrigins[i].vertOriginY; - - return defaultVertOriginY; + unsigned int i; + if (!vertYOrigins.bfind (glyph, &i)) + return defaultVertOriginY; + return vertYOrigins[i].vertOriginY; } inline bool _subset (const hb_subset_plan_t *plan HB_UNUSED, diff --git a/src/hb-vector.hh b/src/hb-vector.hh index c1d7f946a..b30511d8e 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -260,7 +260,7 @@ struct hb_vector_t return bfind (x, &i) ? &arrayZ()[i] : nullptr; } template - inline bool bfind (const T &x, unsigned int *i) const + inline bool bfind (const T &x, unsigned int *i = nullptr) const { int min = 0, max = (int) this->len - 1; const Type *array = this->arrayZ(); @@ -274,13 +274,17 @@ struct hb_vector_t min = mid + 1; else { - *i = mid; + if (i) + *i = mid; return true; } } - if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0)) - max++; - *i = max; + if (i) + { + if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0)) + max++; + *i = max; + } return false; } }; From 53ac46e974cf0ee8720b40ef394714eb97ff53b9 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Mon, 12 Nov 2018 12:17:06 -0600 Subject: [PATCH 064/158] Usermanual: expand clusters chapter. --- docs/usermanual-clusters.xml | 747 ++++++++++++++++++++++------------- 1 file changed, 475 insertions(+), 272 deletions(-) diff --git a/docs/usermanual-clusters.xml b/docs/usermanual-clusters.xml index 7b2c7adc7..f7db0f596 100644 --- a/docs/usermanual-clusters.xml +++ b/docs/usermanual-clusters.xml @@ -5,306 +5,509 @@ ]> - Clusters - - In shaping text, a cluster is a sequence of - code points that needs to be treated as a single, indivisible unit. - - - When you add text to a HB buffer, each character is associated with - a cluster value. This is an arbitrary number as - far as HB is concerned. - - - Most clients will use UTF-8, UTF-16, or UTF-32 indices, but the - actual number does not matter. Moreover, it is not required for the - cluster values to be monotonically increasing, but pretty much all - of HB's tests are performed on monotonically increasing cluster - numbers. Nevertheless, there is no such assumption in the code - itself. With that in mind, let's examine what happens with cluster - values during shaping under each cluster-level. - - - HarfBuzz provides three levels of clustering - support. Level 0 is the default behavior and reproduces the behavior - of the old HarfBuzz library. Level 1 tweaks this behavior slightly - to produce better results, so level 1 clustering is recommended for - code that is not required to implement backward compatibility with - the old HarfBuzz. - - - Level 2 differs significantly in how it treats cluster values. - Levels 0 and 1 both process ligatures and glyph decomposition by - merging clusters; level 2 does not. - - - The conceptual model for what the cluster values mean, in levels 0 - and 1, is this: - - - - - the sequence of cluster values will always remain monotone - - - - - each value represents a single cluster - - - - - each cluster contains one or more glyphs and one or more - characters - - - - - Assuming that initial cluster numbers were monotonically increasing - and distinct, then all adjacent glyphs having the same cluster - number belong to the same cluster, and all characters belong to the - cluster that has the highest number not larger than their initial - cluster number. This will become clearer with an example. - - - - A clustering example for levels 0 and 1 - - Let's say we start with the following character sequence and cluster - values: - - - A,B,C,D,E - 0,1,2,3,4 - - - We then map the characters to glyphs. For simplicity, let's assume - that each character maps to the corresponding, identical-looking - glyph: - - - A,B,C,D,E - 0,1,2,3,4 - - - Now if, for example, B and C - ligate, then the clusters to which they belong "merge". - This merged cluster takes for its cluster number the minimum of all - the cluster numbers of the clusters that went in. In this case, we - get: - - - A,BC,D,E - 0,1 ,3,4 - - - Now let's assume that the BC glyph decomposes - into three components, and D also decomposes into - two. The components each inherit the cluster value of their parent: - - - A,BC0,BC1,BC2,D0,D1,E - 0,1 ,1 ,1 ,3 ,3 ,4 - - - Now if BC2 and D0 ligate, then - their clusters (numbers 1 and 3) merge into - min(1,3) = 1: - - - A,BC0,BC1,BC2D0,D1,E - 0,1 ,1 ,1 ,1 ,4 - - - At this point, cluster 1 means: the character sequence - BCD is represented by glyphs - BC0,BC1,BC2D0,D1 and cannot be broken down any - further. - - - - Reordering in levels 0 and 1 - - Another common operation in the more complex shapers is when things - reorder. In those cases, to maintain monotone clusters, HB merges - the clusters of everything in the reordering sequence. For example, - let's again start with the character sequence: - - - A,B,C,D,E - 0,1,2,3,4 - - - If D is reordered before B, - then the B, C, and - D clusters merge, and we get: - - - A,D,B,C,E - 0,1,1,1,4 - - - This is clearly not ideal, but it is the only sensible way to - maintain monotone indices and retain the true relationship between - glyphs and characters. - - - - The distinction between levels 0 and 1 - - So, the above is pretty much what cluster levels 0 and 1 do. The - only difference between the two is this: in level 0, at the very - beginning of the shaping process, we also merge clusters between - base characters and all Unicode marks (combining or not) following - them. E.g.: - - - A,acute,B - 0,1 ,2 - - - will become: - - - A,acute,B - 0,0 ,2 - - - This is the default behavior. We do it because Windows did it and - old HarfBuzz did it, so this remained the default. But this behavior - makes it impossible to color diacritic marks differently from their - base characters. That's why in level 1 we do not perform this - initial merging step. - - - For clients, level 0 is more convenient if they rely on HarfBuzz - clusters for cursor positioning. But that's wrong anyway: cursor - positions should be determined based on Unicode grapheme boundaries, - NOT shaping clusters. As such, level 1 clusters are preferred. - - - One last note about levels 0 and 1. We currently don't allow a - MultipleSubst lookup to replace a glyph with zero - glyphs (i.e., to delete a glyph). But in some other situations, - glyphs can be deleted. In those cases, if the glyph being deleted is - the last glyph of its cluster, we make sure to merge the cluster - with a neighboring cluster. - - - This is, primarily, to make sure that the starting cluster of the - text always has the cluster index pointing to the start of the text - for the run; more than one client currently relies on this - guarantee. - - - Incidentally, Apple's CoreText does something else to maintain the - same promise: it inserts a glyph with id 65535 at the beginning of - the glyph string if the glyph corresponding to the first character - in the run was deleted. HarfBuzz might do something similar in the - future. - - - - Level 2 - - Level 2 is a different beast from levels 0 and 1. It is simple to - describe, but hard to make sense of. It simply doesn't do any - cluster merging whatsoever. When things ligate or otherwise multiple - glyphs turn into one, the cluster value of the first glyph is - retained. - - - Here are a few examples of why processing cluster values produced at - this level might be tricky: - - - Ligatures with combining marks +

+ Clusters - Imagine capital letters are bases and lower case letters are - combining marks. With an input sequence like this: + In text shaping, a cluster is a sequence of + characters that needs to be treated as a single, indivisible + unit. + + + During the shaping process, some shaping operations may + merge adjacent characters (for example, when two code points form + a ligature and are replaced by a single glyph) or split one + character into several (for example, when performing the Unicode + canonical decomposition of a code point). + + + HarfBuzz tracks clusters independently from how these + shaping operations alter the individual glyphs that comprise the + output HarfBuzz returns in a buffer. Consequently, + a client program using HarfBuzz can utilize the cluster + information to implement features such as: + + + + + Correctly positioning the cursor between two characters that + have combined into a single glyph by forming a ligature. + + + + + Correctly highlighting a text selection that includes some, + but not all, of the characters comprising a ligature. + + + + + Applying text attributes (such as color or underlining) to + part, but not all, of a composed base-and-mark combination. + + + + + Generating output document formats (such as PDF) with + embedded text that can be fully extracted. + + + + + Performing line-breaking, justification, and other + line-level or paragraph-level operations that must be done + after shaping is complete, but which require character-level + properties. + + + + + When you add text to a HarfBuzz buffer, each code point is assigned + a cluster value. + + + This cluster value is an arbitrary number; HarfBuzz uses it only + to distinguish between clusters. Many client programs will use + the index of each code point in the input text stream as the + cluster value, as a matter of convenience; the actual value does + not matter. + + + Client programs can choose how HarfBuzz handles clusters during + shaping by setting the + cluster_level of the + buffer. HarfBuzz offers three levels of + clustering support for this property: + + + + Level 0 is the default and + reproduces the behavior of the old HarfBuzz library. + + + The distinguishing feature of level 0 behavior is that, at + the beginning of processing the buffer, all code points that + are categorized as marks, + modifier symbols, or + Emoji extended pictographic modifiers, + as well as the Zero Width Joiner and + Zero Width Non-Joiner code points, are + assigned the cluster value of the closest preceding code + point from diferent category. + + + In essence, whenever a base character is followed by a mark + character or a sequence of mark characters, those marks are + reassigned to the same initial cluster value as the base + character. This reassignment is referred to as + "merging" the affected clusters. This behavior is based on + the Grapheme Cluster Boundary specification in Unicode + Technical Report 29. + + + Client programs can specify level 0 behavior for a buffer by + setting its cluster_level to + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. + + + + + Level 1 tweaks the old behavior + slightly to produce better results. Therefore, level 1 + clustering is recommended for code that is not required to + implement backward compatibility with the old HarfBuzz. + + + Level 1 differs from level 0 by not merging the + clusters of marks and other modifier code points with the + preceding "base" code point's cluster. By preserving the + cluster values of these marks and modifier code points, + script shaping can perform additional operations that might + lead to improved results (for example, reordering a sequence + of marks). + + + Client programs can specify level 1 behavior for a buffer by + setting its cluster_level to + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS. + + + + + Level 2 differs significantly in how it + treats cluster values. In level 2, HarfBuzz never merges + clusters. + + + This difference can be seen most clearly when HarfBuzz processes + ligature substitutions and glyph decompositions. In level 0 + and level 1, ligatures and glyph decomposition both involve + merging clusters; in level 2, neither of these operations + triggers a merge. + + + Client programs can specify level 2 behavior for a buffer by + setting its cluster_level to + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS. + + + + + It is not required that the cluster values + in a buffer be monotonically increasing. However, if the initial + cluster values in a buffer are monotonic and the buffer is + configured to use clustering level 0 or 1, then HarfBuzz + guarantees that the final cluster values in the shaped buffer + will also be monotonic. No such guarantee is made for cluster + level 2. + + + In levels 0 and 1, HarfBuzz implements the following conceptual model for + cluster values: + + + + + The sequence of cluster values will always remain monotonic. + + + + + Each cluster value represents a single cluster. + + + + + Each cluster contains one or more glyphs and one or more + characters. + + + + + In practice, this model offers several benefits. Assuming that + the initial cluster values were monotonically increasing + and distinct before shaping began, then, in the final output: + + + + + All adjacent glyphs having the same final cluster + value belong to the same cluster. + + + + + Each character belongs to the cluster that has the highest + cluster value not larger than its + initial cluster value. + + + + +
+
+ A clustering example for levels 0 and 1 + + The guarantees and benefits of level 0 and level 1 can be seen + with some examples. First, let us examine what happens with cluster + values when shaping involves cluster merging with ligatures and + decomposition. + + + Let's say we start with the following character sequence (top row) and + initial cluster values (bottom row): - A,a,B,b,C,c - 0,1,2,3,4,5 - + A,B,C,D,E + 0,1,2,3,4 + - if A,B,C ligate, then here are the cluster - values one would get under the various levels: - - - level 0: + During shaping, HarfBuzz maps these characters to glyphs from + the font. For simplicity, let's assume that each character maps + to the corresponding, identical-looking glyph: - ABC,a,b,c - 0 ,0,0,0 - + A,B,C,D,E + 0,1,2,3,4 + - level 1: + Now if, for example, B and C + form a ligature, then the clusters to which they belong + "merge". This merged cluster takes for its cluster + value the minimum of all the cluster values of the clusters that + went in to the ligature. In this case, we get: - ABC,a,b,c - 0 ,0,0,5 - + A,BC,D,E + 0,1 ,3,4 + - level 2: + because 1 is the minimum of the set {1,2}, which were the + cluster values of B and + C. + + + Next, let us say that the BC ligature glyph + decomposes into three components, and D also + decomposes into two components. These components each inherit the + cluster value of their parent: - ABC,a,b,c - 0 ,1,3,5 - + A,BC0,BC1,BC2,D0,D1,E + 0,1 ,1 ,1 ,3 ,3 ,4 + - Making sense of the last example is the hardest for a client, - because there is nothing in the cluster values to suggest that - B and C ligated with - A. - - - - Reordering - - Another tricky case is when things reorder. Under level 2: + Next, if BC2 and D0 form a + ligature, then their clusters (cluster values 1 and 3) merge into + min(1,3) = 1: - A,B,C,D,E - 0,1,2,3,4 - + A,BC0,BC1,BC2D0,D1,E + 0,1 ,1 ,1 ,1 ,4 + - Now imagine D moves before - B: + At this point, cluster 1 means: the character sequence + BCD is represented by glyphs + BC0,BC1,BC2D0,D1 and cannot be broken down any + further. + +
+
+ Reordering in levels 0 and 1 + + Another common operation in the more complex shapers is glyph + reordering. In order to maintain a monotonic cluster sequence + when glyph reordering takes place, HarfBuzz merges the clusters + of everything in the reordering sequence. + + + For example, let us again start with the character sequence (top + row) and initial cluster values (bottom row): - A,D,B,C,E - 0,3,1,2,4 - + A,B,C,D,E + 0,1,2,3,4 + - Now, if D ligates with B, we + If D is reordered before B, + then HarfBuzz merges the B, + C, and D clusters, and we get: - A,DB,C,E - 0,3 ,2,4 - + A,D,B,C,E + 0,1,1,1,4 + - In a different scenario, A and - B could have ligated - before D reordered; that - would have resulted in: + This is clearly not ideal, but it is the only sensible way to + maintain a monotonic sequence of cluster values and retain the + true relationship between glyphs and characters. + +
+
+ The distinction between levels 0 and 1 + + The preceding examples demonstrate the main effects of using + cluster levels 0 and 1. The only difference between the two + levels is this: in level 0, at the very beginning of the shaping + process, HarfBuzz also merges clusters between any base character + and all Unicode marks (combining or not) that follow it. + + + For example, let us start with the following character sequence + (top row) and accompanying initial cluster values (bottom row): - AB,D,C,E - 0 ,3,2,4 - + A,acute,B + 0,1 ,2 + - There's no way to differentiate between these two scenarios based - on the cluster numbers alone. + The acute is a Unicode mark. If HarfBuzz is + using cluster level 0 on this sequence, then the + A and acute clusters will + merge, and the result will become: + + + A,acute,B + 0,0 ,2 + + + This initial cluster merging is the default behavior of the + Windows shaping engine, and the old HarfBuzz codebase copied + that behavior to maintain compatibility. Consequently, it has + remained the default behavior in the new HarfBuzz codebase. - Another problem happens with ligatures under level 2 if the - direction of the text is forced to opposite of its natural - direction (e.g. left-to-right Arabic). But that's too much of a - corner case to worry about. + But this initial cluster-merging behavior makes it impossible to + color diacritic marks differently from their base + characters. That is why, in level 1, HarfBuzz does not perform + the initial merging step. - - + + For client programs that rely on HarfBuzz cluster values to + perform cursor positioning, level 0 is more convenient. But + relying on cluster boundaries for cursor positioning is wrong: cursor + positions should be determined based on Unicode grapheme + boundaries, not on shaping-cluster boundaries. As such, level 1 + clusters are preferred. + + + One last note about levels 0 and 1. HarfBuzz currently does not allow a + MultipleSubst lookup to replace a glyph with zero + glyphs (in other words, to delete a glyph). But, in some other situations, + glyphs can be deleted. In those cases, if the glyph being deleted is + the last glyph of its cluster, HarfBuzz makes sure to merge the cluster + with a neighboring cluster. + + + This is done primarily to make sure that the starting cluster of the + text always has the cluster index pointing to the start of the text + for the run; more than one client currently relies on this + guarantee. + + + Incidentally, Apple's CoreText does something else to maintain the + same promise: it inserts a glyph with id 65535 at the beginning of + the glyph string if the glyph corresponding to the first character + in the run was deleted. HarfBuzz might do something similar in the + future. + +
+
+ Level 2 + + HarfBuzz's level 2 cluster behavior uses a significantly + different model than that of level 0 and level 1. + + + The level 2 behavior is easy to describe, but it may be + difficult to understand in practical terms. In brief, level 2 + performs no merging of clusters whatsoever. + + + When glyphs form a ligature (or when some other feature + substitutes multiple glyphs with one glyph), the cluster value + of the first glyph is retained as the cluster value for the + ligature. However, no subsequent clusters — including + marks and modifiers — are affected. + + + Level 2 cluster behavior is less complex than level 0 or level + 1, but there are a few cases in which processing cluster values + produced at level 2 may be tricky. + +
+ Ligatures with combining marks in level 2 + + The first example of how HarfBuzz's level 2 cluster behavior + can be tricky is when the text to be shaped includes combining + marks attached to ligatures. + + + Let us start with an input sequence with the following + characters (top row) and initial cluster values (bottom row): + + + A,acute,B,breve,C,circumflex + 0,1 ,2,3 ,4,5 + + + If the sequence A,B,C forms a ligature, + then these are the cluster values HarfBuzz will return under + the various cluster levels: + + + Level 0: + + + ABC,acute,breve,circumflex + 0 ,0 ,0 ,0 + + + Level 1: + + + ABC,acute,breve,circumflex + 0 ,0 ,0 ,5 + + + Level 2: + + + ABC,acute,breve,circumflex + 0 ,1 ,3 ,5 + + + Making sense of the level 2 result is the hardest for a client + program, because there is nothing in the cluster values that + indicates that B and C + formed a ligature with A. + + + In contrast, the "merged" cluster values of the mark glyphs + that are seen in the level 0 and level 1 output are evidence + that a ligature substitution took place. + +
+
+ Reordering in level 2 + + Another example of how HarfBuzz's level 2 cluster behavior + can be tricky is when glyphs reorder. Consider an input sequence + with the following characters (top row) and initial cluster + values (bottom row): + + + A,B,C,D,E + 0,1,2,3,4 + + + Now imagine D moves before + B in a reordering operation. The cluster + values will then be: + + + A,D,B,C,E + 0,3,1,2,4 + + + Next, if D forms a ligature with + B, the output is: + + + A,DB,C,E + 0,3 ,2,4 + + + However, in a different scenario, in which the shaping rules + of the script instead caused A and + B to form a ligature + before the D reordered, the + result would be: + + + AB,D,C,E + 0 ,3,2,4 + + + There is no way for a client program to differentiate between + these two scenarios based on the cluster values + alone. Consequently, client programs that use level 2 might + need to undertake additional work in order to manage cursor + positioning, text attributes, or other desired features. + +
+
+ Other considerations in level 2 + + There may be other problems encountered with ligatures under + level 2, such as if the direction of the text is forced to + opposite of its natural direction (for example, left-to-right + Arabic). But, generally speaking, these other scenarios are + minor corner cases that are too obscure for most client + programs to need to worry about. + +
+
From 939220e57da613e090d247aa1af2396c28370af4 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Thu, 15 Nov 2018 15:47:03 -0600 Subject: [PATCH 065/158] Usermanual: clusters chapter, minor updates. --- docs/usermanual-clusters.xml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/usermanual-clusters.xml b/docs/usermanual-clusters.xml index f7db0f596..c59818fc4 100644 --- a/docs/usermanual-clusters.xml +++ b/docs/usermanual-clusters.xml @@ -30,20 +30,21 @@ - Correctly positioning the cursor between two characters that - have combined into a single glyph by forming a ligature. + Correctly positioning the cursor within a shaped text run, + even when characters have formed ligatures, composed or + decomposed, reordered, or undergone other shaping operations. Correctly highlighting a text selection that includes some, - but not all, of the characters comprising a ligature. + but not all, of the characters in a word. Applying text attributes (such as color or underlining) to - part, but not all, of a composed base-and-mark combination. + part, but not all, of a word. @@ -52,6 +53,12 @@ embedded text that can be fully extracted. + + + Determining the mapping between input characters and output + glyphs, such as which glyphs are ligatures. + + Performing line-breaking, justification, and other @@ -69,7 +76,7 @@ This cluster value is an arbitrary number; HarfBuzz uses it only to distinguish between clusters. Many client programs will use the index of each code point in the input text stream as the - cluster value, as a matter of convenience; the actual value does + cluster value, for the sake of convenience; the actual value does not matter. @@ -122,10 +129,10 @@ Level 1 differs from level 0 by not merging the clusters of marks and other modifier code points with the preceding "base" code point's cluster. By preserving the - cluster values of these marks and modifier code points, - script shaping can perform additional operations that might - lead to improved results (for example, reordering a sequence - of marks). + separate cluster values of these marks and modifier code + points, script shapers can perform additional operations + that might lead to improved results (for example, reordering + a sequence of marks). Client programs can specify level 1 behavior for a buffer by From 5fdf7b724eb3cb5ac60cd7f90d3250877ad7ca06 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Thu, 15 Nov 2018 17:40:21 -0600 Subject: [PATCH 066/158] Usermanual: clusters chapter; add brief grapheme definition and clarify monotonous cluster handling. --- docs/usermanual-clusters.xml | 56 +++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/docs/usermanual-clusters.xml b/docs/usermanual-clusters.xml index c59818fc4..f48e89c20 100644 --- a/docs/usermanual-clusters.xml +++ b/docs/usermanual-clusters.xml @@ -14,15 +14,29 @@ unit. - During the shaping process, some shaping operations may - merge adjacent characters (for example, when two code points form - a ligature and are replaced by a single glyph) or split one - character into several (for example, when performing the Unicode - canonical decomposition of a code point). + A cluster is distinct from a grapheme, + which is the smallest unit of a writing system or script, + because clusters are only relevant for script shaping and the + layout of glyphs. + + + For example, a grapheme may be a letter, a number, a logogram, + or a symbol. When two letters form a ligature, however, they + combine into a single glyph. They are therefore part of the same + cluster and are treated as a unit — even though the two + original, underlying letters are separate graphemes. + + + During the shaping process, there are several shaping operations + that may merge adjacent characters (for example, when two code + points form a ligature or a conjunct form and are replaced by a + single glyph) or split one character into several (for example, + when decomposing a code point through the + ccmp feature). HarfBuzz tracks clusters independently from how these - shaping operations alter the individual glyphs that comprise the + shaping operations affect the individual glyphs that comprise the output HarfBuzz returns in a buffer. Consequently, a client program using HarfBuzz can utilize the cluster information to implement features such as: @@ -69,15 +83,15 @@ - When you add text to a HarfBuzz buffer, each code point is assigned - a cluster value. + When you add text to a HarfBuzz buffer, each code point must be + assigned a cluster value. This cluster value is an arbitrary number; HarfBuzz uses it only to distinguish between clusters. Many client programs will use the index of each code point in the input text stream as the - cluster value, for the sake of convenience; the actual value does - not matter. + cluster value. This is for the sake of convenience; the actual + value does not matter. Client programs can choose how HarfBuzz handles clusters during @@ -100,7 +114,7 @@ as well as the Zero Width Joiner and Zero Width Non-Joiner code points, are assigned the cluster value of the closest preceding code - point from diferent category. + point from different category. In essence, whenever a base character is followed by a mark @@ -160,23 +174,31 @@ + + As mentioned earlier, client programs using HarfBuzz often + assign initial cluster values in a buffer by reusing the indices + of the code points in the input text. This gives a sequence of + cluster values that is monotonically increasing (for example, + 0,1,2,3,4,5). + It is not required that the cluster values in a buffer be monotonically increasing. However, if the initial cluster values in a buffer are monotonic and the buffer is - configured to use clustering level 0 or 1, then HarfBuzz + configured to use cluster level 0 or 1, then HarfBuzz guarantees that the final cluster values in the shaped buffer will also be monotonic. No such guarantee is made for cluster level 2. - In levels 0 and 1, HarfBuzz implements the following conceptual model for - cluster values: + In levels 0 and 1, HarfBuzz implements the following conceptual + model for cluster values: - The sequence of cluster values will always remain monotonic. + If the sequence of input cluster values is monotonic, the + sequence of cluster values will remain monotonic. @@ -231,7 +253,7 @@ During shaping, HarfBuzz maps these characters to glyphs from - the font. For simplicity, let's assume that each character maps + the font. For simplicity, let us assume that each character maps to the corresponding, identical-looking glyph: @@ -297,7 +319,7 @@ 0,1,2,3,4 - If D is reordered before B, + If D is reordered to before B, then HarfBuzz merges the B, C, and D clusters, and we get: From 22e1857b01c71714245ddca05cb3fa0127bf7da2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:53:19 -0500 Subject: [PATCH 067/158] [arrays] Change argument type of cmp called by hb_vector_t.bsearch() Towards consolidating all array bsearch/... --- src/hb-aat-map.hh | 4 ++-- src/hb-ot-map.hh | 4 ++-- src/hb-set.hh | 2 +- src/hb-vector.hh | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 07454b2c1..7d85c7c38 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -77,9 +77,9 @@ struct hb_aat_map_builder_t (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); } - int cmp (const short unsigned int *ty) const + int cmp (unsigned int ty) const { - return (type != *ty) ? (type < *ty ? -1 : 1) : 0; + return (type != ty) ? (type < ty ? -1 : 1) : 0; } }; diff --git a/src/hb-ot-map.hh b/src/hb-ot-map.hh index 8e1f5aa8c..0a5a4fbcb 100644 --- a/src/hb-ot-map.hh +++ b/src/hb-ot-map.hh @@ -57,8 +57,8 @@ struct hb_ot_map_t unsigned int auto_zwj : 1; unsigned int random : 1; - inline int cmp (const hb_tag_t *tag_) const - { return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; } + inline int cmp (const hb_tag_t tag_) const + { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; } }; struct lookup_map_t { diff --git a/src/hb-set.hh b/src/hb-set.hh index cc061a7c8..a464131d4 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -45,7 +45,7 @@ struct hb_set_t struct page_map_t { - inline int cmp (const page_map_t *o) const { return (int) o->major - (int) major; } + inline int cmp (const page_map_t &o) const { return (int) o.major - (int) major; } uint32_t major; uint32_t index; diff --git a/src/hb-vector.hh b/src/hb-vector.hh index b30511d8e..436b92bbc 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -267,7 +267,7 @@ struct hb_vector_t while (min <= max) { int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = array[mid].cmp (&x); + int c = array[mid].cmp (x); if (c < 0) max = mid - 1; else if (c > 0) @@ -281,7 +281,7 @@ struct hb_vector_t } if (i) { - if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0)) + if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) max++; *i = max; } From 3e26c8d2b10fc08642c25c7f13aef68b0b1008f6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 00:58:44 -0500 Subject: [PATCH 068/158] [arrays] Update ArrayOf.lsearch() Currently unused apparently --- src/hb-open-type.hh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index f255ea12a..4e0c033fa 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -545,14 +545,23 @@ struct ArrayOf return_trace (true); } - template - inline int lsearch (const SearchType &x) const + template + inline Type &lsearch (const T &x) { unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (!this->arrayZ[i].cmp (x)) - return i; - return -1; + return this->arrayZ[i]; + return Crap (T); + } + template + inline const Type &lsearch (const T &x) const + { + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->arrayZ[i].cmp (x)) + return this->arrayZ[i]; + return Null (T); } inline void qsort (void) From 96cf0889804b7d72a96274b25641bb18f7dd2e1e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:07:15 -0500 Subject: [PATCH 069/158] [arrays] More --- src/hb-face.cc | 6 +++--- src/hb-vector.hh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-face.cc b/src/hb-face.cc index e23842fb1..5b33784f4 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -588,10 +588,10 @@ struct hb_face_builder_data_t { struct table_entry_t { - inline int cmp (const hb_tag_t *t) const + inline int cmp (hb_tag_t t) const { - if (*t < tag) return -1; - if (*t > tag) return -1; + if (t < tag) return -1; + if (t > tag) return -1; return 0; } diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 436b92bbc..e17f8897d 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -233,7 +233,7 @@ struct hb_vector_t { Type *array = arrayZ(); for (unsigned int i = 0; i < len; i++) - if (0 == array[i].cmp (&x)) + if (0 == array[i].cmp (x)) return &array[i]; return nullptr; } @@ -242,7 +242,7 @@ struct hb_vector_t { const Type *array = arrayZ(); for (unsigned int i = 0; i < len; i++) - if (0 == array[i].cmp (&x)) + if (0 == array[i].cmp (x)) return &array[i]; return nullptr; } From 830856ba6b9454bf507e00416f9d45e9975fb7dc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:09:28 -0500 Subject: [PATCH 070/158] [arrays] Port hb_vector_t.lsearch() to hb_array_t's --- src/hb-dsalgs.hh | 26 +++++++++++++++++++++++--- src/hb-vector.hh | 16 ++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index c133a532d..1d5bb3520 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -575,9 +575,24 @@ struct hb_array_t inline unsigned int get_size (void) const { return len * sizeof (Type); } - template - inline bool sanitize (hb_sanitize_context_t *c) const - { return c->check_array (arrayZ, len); } + template + inline Type *lsearch (const T &x, Type *not_found = nullptr) + { + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->arrayZ[i].cmp (x)) + return &this->arrayZ[i]; + return not_found; + } + template + inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const + { + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->arrayZ[i].cmp (x)) + return &this->arrayZ[i]; + return not_found; + } template inline operator T * (void) const { return arrayZ; } @@ -601,6 +616,11 @@ struct hb_array_t inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } + template + inline bool sanitize (hb_sanitize_context_t *c) const + { return c->check_array (arrayZ, len); } + + public: Type *arrayZ; unsigned int len; }; diff --git a/src/hb-vector.hh b/src/hb-vector.hh index e17f8897d..d1fb65df8 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -229,22 +229,14 @@ struct hb_vector_t } template - inline Type *lsearch (const T &x) + inline Type *lsearch (const T &x, Type *not_found = nullptr) { - Type *array = arrayZ(); - for (unsigned int i = 0; i < len; i++) - if (0 == array[i].cmp (x)) - return &array[i]; - return nullptr; + return as_array ().lsearch (x, not_found); } template - inline const Type *lsearch (const T &x) const + inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const { - const Type *array = arrayZ(); - for (unsigned int i = 0; i < len; i++) - if (0 == array[i].cmp (x)) - return &array[i]; - return nullptr; + return as_array ().lsearch (x, not_found); } template From 268eca24921e85eda98f4f0cce05d40c7235ba62 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:11:12 -0500 Subject: [PATCH 071/158] [arrays] Port (unused) ArrayOf.lsearch() to hb_array_t's --- src/hb-open-type.hh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 4e0c033fa..7fa38b1ca 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -548,20 +548,12 @@ struct ArrayOf template inline Type &lsearch (const T &x) { - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (!this->arrayZ[i].cmp (x)) - return this->arrayZ[i]; - return Crap (T); + return *as_array ().lsearch (x, &Crap (T)); } template inline const Type &lsearch (const T &x) const { - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (!this->arrayZ[i].cmp (x)) - return this->arrayZ[i]; - return Null (T); + return *as_array ().lsearch (x, &Null (T)); } inline void qsort (void) From e604306f2829804e9016966c1378166253b19d29 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:24:48 -0500 Subject: [PATCH 072/158] [arrays] Port hb_vector_t.bsearch/bfind to (new) hb_sorted_array_t's --- src/hb-dsalgs.hh | 63 ++++++++++++++++++++++++++++++++++++++++++--- src/hb-open-type.hh | 12 ++++++--- src/hb-vector.hh | 57 ++++++++++++++++------------------------ 3 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 1d5bb3520..a7592828a 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -564,7 +564,6 @@ struct hb_array_t { static_assert ((bool) (unsigned) hb_static_size (Type), ""); - inline hb_array_t (void) : arrayZ (nullptr), len (0) {} inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {} inline Type& operator [] (unsigned int i) const @@ -576,7 +575,8 @@ struct hb_array_t inline unsigned int get_size (void) const { return len * sizeof (Type); } template - inline Type *lsearch (const T &x, Type *not_found = nullptr) + inline Type *lsearch (const T &x, + Type *not_found = nullptr) { unsigned int count = len; for (unsigned int i = 0; i < count; i++) @@ -585,7 +585,8 @@ struct hb_array_t return not_found; } template - inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const + inline const Type *lsearch (const T &x, + const Type *not_found = nullptr) const { unsigned int count = len; for (unsigned int i = 0; i < count; i++) @@ -625,7 +626,61 @@ struct hb_array_t unsigned int len; }; template -inline hb_array_t hb_array (T *array, unsigned int len) { return hb_array_t (array, len); } +inline hb_array_t hb_array (T *array, unsigned int len) +{ return hb_array_t (array, len); } + +template +struct hb_sorted_array_t : hb_array_t +{ + inline hb_sorted_array_t (Type *array_, unsigned int len_) : hb_array_t (array_, len_) {} + + template + inline Type *bsearch (const T &x, + Type *not_found = nullptr) + { + unsigned int i; + return bfind (x, &i) ? &this->arrayZ[i] : not_found; + } + template + inline const Type *bsearch (const T &x, + const Type *not_found = nullptr) const + { + unsigned int i; + return bfind (x, &i) ? &this->arrayZ[i] : not_found; + } + template + inline bool bfind (const T &x, + unsigned int *i = nullptr) const + { + int min = 0, max = (int) this->len - 1; + const Type *array = this->arrayZ; + while (min <= max) + { + int mid = ((unsigned int) min + (unsigned int) max) / 2; + int c = array[mid].cmp (x); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + { + if (i) + *i = mid; + return true; + } + } + if (i) + { + if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) + max++; + *i = max; + } + return false; + } +}; +template +inline hb_sorted_array_t hb_sorted_array (T *array, unsigned int len) +{ return hb_sorted_array_t (array, len); } struct HbOpOr diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 7fa38b1ca..e384a7ad5 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -370,8 +370,10 @@ struct UnsizedArrayOf inline unsigned int get_size (unsigned int len) const { return len * Type::static_size; } - inline hb_array_t as_array (unsigned int len) { return hb_array_t (arrayZ, len); } - inline hb_array_t as_array (unsigned int len) const { return hb_array_t (arrayZ, len); } + inline hb_array_t as_array (unsigned int len) + { return hb_array (arrayZ, len); } + inline hb_array_t as_array (unsigned int len) const + { return hb_array (arrayZ, len); } inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { @@ -483,8 +485,10 @@ struct ArrayOf inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } - inline hb_array_t as_array (void) { return hb_array_t (arrayZ, len); } - inline hb_array_t as_array (void) const { return hb_array_t (arrayZ, len); } + inline hb_array_t as_array (void) + { return hb_array (arrayZ, len); } + inline hb_array_t as_array (void) const + { return hb_array (arrayZ, len); } inline bool serialize (hb_serialize_context_t *c, unsigned int items_len) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index d1fb65df8..14967a410 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -91,8 +91,15 @@ struct hb_vector_t return arrayZ()[i]; } - inline hb_array_t as_array (void) { return hb_array_t (arrayZ(), len); } - inline hb_array_t as_array (void) const { return hb_array_t (arrayZ(), len); } + inline hb_array_t as_array (void) + { return hb_array (arrayZ(), len); } + inline hb_array_t as_array (void) const + { return hb_array (arrayZ(), len); } + + inline hb_sorted_array_t as_sorted_array (void) + { return hb_sorted_array (arrayZ(), len); } + inline hb_sorted_array_t as_sorted_array (void) const + { return hb_sorted_array (arrayZ(), len); } template inline operator T * (void) { return arrayZ(); } template inline operator const T * (void) const { return arrayZ(); } @@ -229,55 +236,35 @@ struct hb_vector_t } template - inline Type *lsearch (const T &x, Type *not_found = nullptr) + inline Type *lsearch (const T &x, + Type *not_found = nullptr) { return as_array ().lsearch (x, not_found); } template - inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const + inline const Type *lsearch (const T &x, + const Type *not_found = nullptr) const { return as_array ().lsearch (x, not_found); } template - inline Type *bsearch (const T &x) + inline Type *bsearch (const T &x, + Type *not_found = nullptr) { - unsigned int i; - return bfind (x, &i) ? &arrayZ()[i] : nullptr; + return as_sorted_array ().bsearch (x, not_found); } template - inline const Type *bsearch (const T &x) const + inline const Type *bsearch (const T &x, + const Type *not_found = nullptr) const { - unsigned int i; - return bfind (x, &i) ? &arrayZ()[i] : nullptr; + return as_sorted_array ().bsearch (x, not_found); } template - inline bool bfind (const T &x, unsigned int *i = nullptr) const + inline bool bfind (const T &x, + unsigned int *i = nullptr) const { - int min = 0, max = (int) this->len - 1; - const Type *array = this->arrayZ(); - while (min <= max) - { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = array[mid].cmp (x); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - { - if (i) - *i = mid; - return true; - } - } - if (i) - { - if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) - max++; - *i = max; - } - return false; + return as_sorted_array ().bfind (x, i); } }; From e700392f5cbf366f1e03dc7e7b1a2eb6c3027b92 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:31:00 -0500 Subject: [PATCH 073/158] [arrays] Port SortedArrayOf.bsearch/bfind to hb_sorted_array_t's --- src/hb-dsalgs.hh | 9 +++----- src/hb-open-type.hh | 50 +++++++++------------------------------------ src/hb-vector.hh | 35 +++++++++---------------------- 3 files changed, 23 insertions(+), 71 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index a7592828a..e66f2b4ca 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -635,22 +635,19 @@ struct hb_sorted_array_t : hb_array_t inline hb_sorted_array_t (Type *array_, unsigned int len_) : hb_array_t (array_, len_) {} template - inline Type *bsearch (const T &x, - Type *not_found = nullptr) + inline Type *bsearch (const T &x, Type *not_found = nullptr) { unsigned int i; return bfind (x, &i) ? &this->arrayZ[i] : not_found; } template - inline const Type *bsearch (const T &x, - const Type *not_found = nullptr) const + inline const Type *bsearch (const T &x, const Type *not_found = nullptr) const { unsigned int i; return bfind (x, &i) ? &this->arrayZ[i] : not_found; } template - inline bool bfind (const T &x, - unsigned int *i = nullptr) const + inline bool bfind (const T &x, unsigned int *i = nullptr) const { int min = 0, max = (int) this->len - 1; const Type *array = this->arrayZ; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index e384a7ad5..0ea884314 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -551,14 +551,10 @@ struct ArrayOf template inline Type &lsearch (const T &x) - { - return *as_array ().lsearch (x, &Crap (T)); - } + { return *as_array ().lsearch (x, &Crap (T)); } template inline const Type &lsearch (const T &x) const - { - return *as_array ().lsearch (x, &Null (T)); - } + { return *as_array ().lsearch (x, &Null (T)); } inline void qsort (void) { @@ -745,46 +741,20 @@ struct ArrayOfM1 template struct SortedArrayOf : ArrayOf { + inline hb_sorted_array_t as_array (void) + { return hb_sorted_array (this->arrayZ, this->len); } + inline hb_sorted_array_t as_array (void) const + { return hb_sorted_array (this->arrayZ, this->len); } + template inline Type &bsearch (const T &x) - { - unsigned int i; - return bfind (x, &i) ? this->arrayZ[i] : Crap(Type); - } + { return *as_array ().bsearch (x, &Crap (Type)); } template inline const Type &bsearch (const T &x) const - { - unsigned int i; - return bfind (x, &i) ? this->arrayZ[i] : Null(Type); - } + { return *as_array ().bsearch (x, &Null (Type)); } template inline bool bfind (const T &x, unsigned int *i = nullptr) const - { - int min = 0, max = (int) this->len - 1; - const Type *array = this->arrayZ; - while (min <= max) - { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = array[mid].cmp (x); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - { - if (i) - *i = mid; - return true; - } - } - if (i) - { - if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) - max++; - *i = max; - } - return false; - } + { return as_array ().bfind (x, i); } }; /* diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 14967a410..085523f84 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -236,36 +236,21 @@ struct hb_vector_t } template - inline Type *lsearch (const T &x, - Type *not_found = nullptr) - { - return as_array ().lsearch (x, not_found); - } + inline Type *lsearch (const T &x, Type *not_found = nullptr) + { return as_array ().lsearch (x, not_found); } template - inline const Type *lsearch (const T &x, - const Type *not_found = nullptr) const - { - return as_array ().lsearch (x, not_found); - } + inline const Type *lsearch (const T &x, const Type *not_found = nullptr) const + { return as_array ().lsearch (x, not_found); } template - inline Type *bsearch (const T &x, - Type *not_found = nullptr) - { - return as_sorted_array ().bsearch (x, not_found); - } + inline Type *bsearch (const T &x, Type *not_found = nullptr) + { return as_sorted_array ().bsearch (x, not_found); } template - inline const Type *bsearch (const T &x, - const Type *not_found = nullptr) const - { - return as_sorted_array ().bsearch (x, not_found); - } + inline const Type *bsearch (const T &x, const Type *not_found = nullptr) const + { return as_sorted_array ().bsearch (x, not_found); } template - inline bool bfind (const T &x, - unsigned int *i = nullptr) const - { - return as_sorted_array ().bfind (x, i); - } + inline bool bfind (const T &x, unsigned int *i = nullptr) const + { return as_sorted_array ().bfind (x, i); } }; From 7c1600dcd9813ca560ecccc5c54877a5750caf4e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:37:11 -0500 Subject: [PATCH 074/158] [arrays] Add (unused) SortedUnsizedArrayOf<> --- src/hb-open-type.hh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 0ea884314..eaefc3bc6 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -449,6 +449,27 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf } }; +/* An array with sorted elements. Supports binary searching. */ +template +struct SortedUnsizedArrayOf : UnsizedArrayOf +{ + inline hb_sorted_array_t as_array (unsigned int len) + { return hb_sorted_array (this->arrayZ, len); } + inline hb_sorted_array_t as_array (unsigned int len) const + { return hb_sorted_array (this->arrayZ, len); } + + template + inline Type &bsearch (unsigned int len, const T &x) + { return *as_array (len).bsearch (x, &Crap (Type)); } + template + inline const Type &bsearch (unsigned int len, const T &x) const + { return *as_array (len).bsearch (x, &Null (Type)); } + template + inline bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr) const + { return as_array (len).bfind (x, i); } +}; + + /* An array with a number of elements. */ template struct ArrayOf From e3face8e791d677f94154e8a7f3d787d0d69a02f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:42:17 -0500 Subject: [PATCH 075/158] [arrays] Remove one flavor of hb_vector_t.qsort() --- src/hb-vector.hh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 085523f84..a5fa4142b 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -225,13 +225,9 @@ struct hb_vector_t ::qsort (arrayZ(), len, sizeof (Type), cmp); } - inline void qsort (void) - { - ::qsort (arrayZ(), len, sizeof (Type), Type::cmp); - } - - inline void qsort (unsigned int start, unsigned int end) + inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) { + end = MIN (end, len); ::qsort (arrayZ() + start, end - start, sizeof (Type), Type::cmp); } From 61de55bf496c1edb120e4d096140eb1125552bbe Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:45:58 -0500 Subject: [PATCH 076/158] [arrays] Port hb_vector_t.qsort() to hb_array_t's --- src/hb-dsalgs.hh | 16 +++++++++++++--- src/hb-vector.hh | 10 ++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index e66f2b4ca..ef030732a 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -572,6 +572,10 @@ struct hb_array_t return arrayZ[i]; } + template inline operator T * (void) const { return arrayZ; } + + inline Type * operator & (void) const { return arrayZ; } + inline unsigned int get_size (void) const { return len * sizeof (Type); } template @@ -595,9 +599,15 @@ struct hb_array_t return not_found; } - template inline operator T * (void) const { return arrayZ; } - - inline Type * operator & (void) const { return arrayZ; } + inline void qsort (int (*cmp)(const void*, const void*)) + { + ::qsort (arrayZ, len, sizeof (Type), cmp); + } + inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + { + end = MIN (end, len); + ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp); + } inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const { diff --git a/src/hb-vector.hh b/src/hb-vector.hh index a5fa4142b..a8c98d221 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -221,15 +221,9 @@ struct hb_vector_t } inline void qsort (int (*cmp)(const void*, const void*)) - { - ::qsort (arrayZ(), len, sizeof (Type), cmp); - } - + { as_array ().qsort (cmp); } inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) - { - end = MIN (end, len); - ::qsort (arrayZ() + start, end - start, sizeof (Type), Type::cmp); - } + { as_array ().qsort (start, end); } template inline Type *lsearch (const T &x, Type *not_found = nullptr) From ad5c871d801b481f95dd32c8b65ecc70def597be Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:47:49 -0500 Subject: [PATCH 077/158] [arrays] Add copy-constructor to hb_array_t and hb_sorted_array_t --- src/hb-dsalgs.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index ef030732a..876060721 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -564,6 +564,7 @@ struct hb_array_t { static_assert ((bool) (unsigned) hb_static_size (Type), ""); + inline hb_array_t (const hb_array_t &o) : arrayZ (o.arrayZ), len (o.len) {} inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {} inline Type& operator [] (unsigned int i) const @@ -642,6 +643,7 @@ inline hb_array_t hb_array (T *array, unsigned int len) template struct hb_sorted_array_t : hb_array_t { + inline hb_sorted_array_t (const hb_array_t &o) : hb_array_t (o) {} inline hb_sorted_array_t (Type *array_, unsigned int len_) : hb_array_t (array_, len_) {} template From 073d837aa2394d29dda72679802d583c559c3c5b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:48:48 -0500 Subject: [PATCH 078/158] [arrays] Port ArrayOf.qsort() to hb_array_t's --- src/hb-open-type.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index eaefc3bc6..4704861d4 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -578,9 +578,7 @@ struct ArrayOf { return *as_array ().lsearch (x, &Null (T)); } inline void qsort (void) - { - ::qsort (arrayZ, len, sizeof (Type), Type::cmp); - } + { as_array ().qsort (); } inline bool sanitize_shallow (hb_sanitize_context_t *c) const { From 70d80c90fe2f4eca66bec3e1d313bbf7e4d0ab65 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 01:59:50 -0500 Subject: [PATCH 079/158] [arrays] Port ArrayOf.qsort() and hb_vector_t.qsort() to hb_array_t --- src/hb-dsalgs.hh | 14 ++++++++++++-- src/hb-open-type.hh | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 876060721..cc1a1d425 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -559,6 +559,9 @@ struct hb_bytes_t unsigned int len; }; +template +struct hb_sorted_array_t; + template struct hb_array_t { @@ -600,13 +603,20 @@ struct hb_array_t return not_found; } - inline void qsort (int (*cmp)(const void*, const void*)) + inline hb_sorted_array_t qsort (int (*cmp)(const void*, const void*)) { ::qsort (arrayZ, len, sizeof (Type), cmp); + return hb_sorted_array_t (*this); } - inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + inline hb_sorted_array_t qsort (void) + { + ::qsort (arrayZ, len, sizeof (Type), Type::cmp); + return hb_sorted_array_t (*this); + } + inline void qsort (unsigned int start, unsigned int end) { end = MIN (end, len); + assert (start <= end); ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp); } diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 4704861d4..c7154c424 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -375,6 +375,16 @@ struct UnsizedArrayOf inline hb_array_t as_array (unsigned int len) const { return hb_array (arrayZ, len); } + template + inline Type &lsearch (unsigned int len, const T &x) + { return *as_array (len).lsearch (x, &Crap (T)); } + template + inline const Type &lsearch (unsigned int len, const T &x) const + { return *as_array (len).lsearch (x, &Null (T)); } + + inline void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array (len).qsort (start, end); } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); @@ -577,8 +587,8 @@ struct ArrayOf inline const Type &lsearch (const T &x) const { return *as_array ().lsearch (x, &Null (T)); } - inline void qsort (void) - { as_array ().qsort (); } + inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array ().qsort (start, end); } inline bool sanitize_shallow (hb_sanitize_context_t *c) const { From 8dcc1913a1670ede7b124f7b5b775d7ab8791386 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 09:47:45 -0500 Subject: [PATCH 080/158] [kerx/morx] Make sure object length is sanitized before accessing it --- src/hb-aat-layout-kerx-table.hh | 5 +++++ src/hb-aat-layout-morx-table.hh | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 521c4c728..2d5489324 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -962,6 +962,11 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { + if (unlikely (!st->u.header.sanitize (c))) + { + c->reset_object (); + return_trace (false); + } /* OpenType kern table has 2-byte subtable lengths. That's limiting. * MS implementation also only supports one subtable, of format 0, * anyway. Certain versions of some fonts, like Calibry, contain diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 7a39eea8d..5b44a4cfa 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1061,6 +1061,11 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { + if (unlikely (!c->check_struct (subtable))) + { + c->reset_object (); + return_trace (false); + } c->set_object (*subtable); if (!subtable->sanitize (c)) return_trace (false); From 1204a247a5d9a4da39675d3da85d4fd3268a5b66 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 09:49:21 -0500 Subject: [PATCH 081/158] [fuzzing] Add tests for previous commit Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11526 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11522 --- ...ase-minimized-hb-shape-fuzzer-5634620935110656 | Bin 0 -> 41 bytes ...ase-minimized-hb-shape-fuzzer-5716208469409792 | Bin 0 -> 243 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634620935110656 create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5716208469409792 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634620935110656 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5634620935110656 new file mode 100644 index 0000000000000000000000000000000000000000..39f9c3ce90af50468479cb3fddaddebb2b946791 GIT binary patch literal 41 jcmZQzWME)mQ~-ki3fZYec_0>0L=njU4`M5TBta|yo=XUE literal 0 HcmV?d00001 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5716208469409792 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5716208469409792 new file mode 100644 index 0000000000000000000000000000000000000000..00915d68a3d73319186de3f2b316cb1f34e57a6d GIT binary patch literal 243 rcmZQzWME+6Q$Pp*(FG{r|Njp)EjzU+4`dF|#`hGMM~PMj1_cEG-7zAI literal 0 HcmV?d00001 From d77a098b735cf14aa601feab5bdb9f4e474c794f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:06:13 -0500 Subject: [PATCH 082/158] [arrays] Improve bfind() interface Much more useful now. :) --- src/hb-dsalgs.hh | 29 +++++++++++++++++++++++++---- src/hb-open-file.hh | 9 +-------- src/hb-open-type.hh | 12 ++++++++---- src/hb-ot-layout-common.hh | 10 ++-------- src/hb-set.hh | 6 +++--- src/hb-vector.hh | 6 ++++-- 6 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index cc1a1d425..1680bf914 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -650,6 +650,13 @@ template inline hb_array_t hb_array (T *array, unsigned int len) { return hb_array_t (array, len); } +enum hb_bfind_not_found_t +{ + HB_BFIND_NOT_FOUND_DONT_STORE, + HB_BFIND_NOT_FOUND_STORE, + HB_BFIND_NOT_FOUND_STORE_CLOSEST, +}; + template struct hb_sorted_array_t : hb_array_t { @@ -669,7 +676,9 @@ struct hb_sorted_array_t : hb_array_t return bfind (x, &i) ? &this->arrayZ[i] : not_found; } template - inline bool bfind (const T &x, unsigned int *i = nullptr) const + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const { int min = 0, max = (int) this->len - 1; const Type *array = this->arrayZ; @@ -690,9 +699,21 @@ struct hb_sorted_array_t : hb_array_t } if (i) { - if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) - max++; - *i = max; + switch (not_found) + { + case HB_BFIND_NOT_FOUND_DONT_STORE: + break; + + case HB_BFIND_NOT_FOUND_STORE: + *i = to_store; + break; + + case HB_BFIND_NOT_FOUND_STORE_CLOSEST: + if (max < 0 || (max < (int) this->len && array[max].cmp (x) > 0)) + max++; + *i = max; + break; + } } return false; } diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index d3ecc606d..af68892ab 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -111,14 +111,7 @@ typedef struct OffsetTable { Tag t; t.set (tag); - unsigned int i; - if (tables.bfind (t, &i)) - { - if (table_index) *table_index = i; - return true; - } - if (table_index) *table_index = (unsigned) Index::NOT_FOUND_INDEX; - return false; + return tables.bfind (t, table_index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); } inline const TableRecord& get_table_by_tag (hb_tag_t tag) const { diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index c7154c424..1c810e712 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -475,8 +475,10 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf inline const Type &bsearch (unsigned int len, const T &x) const { return *as_array (len).bsearch (x, &Null (Type)); } template - inline bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr) const - { return as_array (len).bfind (x, i); } + inline bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array (len).bfind (x, i, not_found, to_store); } }; @@ -782,8 +784,10 @@ struct SortedArrayOf : ArrayOf inline const Type &bsearch (const T &x) const { return *as_array ().bsearch (x, &Null (Type)); } template - inline bool bfind (const T &x, unsigned int *i = nullptr) const - { return as_array ().bfind (x, i); } + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array ().bfind (x, i, not_found, to_store); } }; /* diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 6c6bcf580..b5af73af6 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -128,12 +128,7 @@ struct RecordArrayOf : SortedArrayOf > } inline bool find_index (hb_tag_t tag, unsigned int *index) const { - if (!this->bfind (tag, index)) - { - if (index) *index = Index::NOT_FOUND_INDEX; - return false; - } - return true; + return this->bfind (tag, index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); } }; @@ -821,8 +816,7 @@ struct CoverageFormat1 inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { unsigned int i; - if (!glyphArray.bfind (glyph_id, &i)) - return NOT_COVERED; + glyphArray.bfind (glyph_id, &i, HB_BFIND_NOT_FOUND_STORE, NOT_COVERED); return i; } diff --git a/src/hb-set.hh b/src/hb-set.hh index a464131d4..8b7a0f3d0 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -544,7 +544,7 @@ struct hb_set_t page_map_t map = {get_major (*codepoint), 0}; unsigned int i; - page_map.bfind (map, &i); + page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST); if (i < page_map.len && page_map[i].major == map.major) { if (pages[page_map[i].index].next (codepoint)) @@ -575,7 +575,7 @@ struct hb_set_t page_map_t map = {get_major (*codepoint), 0}; unsigned int i; - page_map.bfind (map, &i); + page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST); if (i < page_map.len && page_map[i].major == map.major) { if (pages[page_map[i].index].previous (codepoint)) @@ -670,7 +670,7 @@ struct hb_set_t { page_map_t map = {get_major (g), pages.len}; unsigned int i; - if (!page_map.bfind (map, &i)) + if (!page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST)) { if (!resize (pages.len + 1)) return nullptr; diff --git a/src/hb-vector.hh b/src/hb-vector.hh index a8c98d221..787512f92 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -239,8 +239,10 @@ struct hb_vector_t inline const Type *bsearch (const T &x, const Type *not_found = nullptr) const { return as_sorted_array ().bsearch (x, not_found); } template - inline bool bfind (const T &x, unsigned int *i = nullptr) const - { return as_sorted_array ().bfind (x, i); } + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_sorted_array ().bfind (x, i, not_found, to_store); } }; From 918b1ee54d43eb493c9226bff7677ed8ec07934b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:09:17 -0500 Subject: [PATCH 083/158] [arrays] Add not_found to reference bsearch as well --- src/hb-open-type.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 1c810e712..2e3db31df 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -469,11 +469,11 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf { return hb_sorted_array (this->arrayZ, len); } template - inline Type &bsearch (unsigned int len, const T &x) - { return *as_array (len).bsearch (x, &Crap (Type)); } + inline Type &bsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) + { return *as_array (len).bsearch (x, ¬_found); } template - inline const Type &bsearch (unsigned int len, const T &x) const - { return *as_array (len).bsearch (x, &Null (Type)); } + inline const Type &bsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const + { return *as_array (len).bsearch (x, ¬_found); } template inline bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr, hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, @@ -778,11 +778,11 @@ struct SortedArrayOf : ArrayOf { return hb_sorted_array (this->arrayZ, this->len); } template - inline Type &bsearch (const T &x) - { return *as_array ().bsearch (x, &Crap (Type)); } + inline Type &bsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().bsearch (x, ¬_found); } template - inline const Type &bsearch (const T &x) const - { return *as_array ().bsearch (x, &Null (Type)); } + inline const Type &bsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().bsearch (x, ¬_found); } template inline bool bfind (const T &x, unsigned int *i = nullptr, hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, From 4a3b20738fca3231e5d9a36adba333b5bce05f4a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:17:59 -0500 Subject: [PATCH 084/158] [trak] Coment --- src/hb-aat-layout-trak-table.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index 91c0f4562..5474d1d11 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -133,7 +133,6 @@ struct TrackData if (!sizes) return 0.; if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes); - /* TODO bfind() */ hb_array_t size_table ((base+sizeTable).arrayZ, sizes); unsigned int size_index; for (size_index = 0; size_index < sizes - 1; size_index++) From ae96c98dfaef3a789227ffecd40b92518dface8a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:25:10 -0500 Subject: [PATCH 085/158] [color] Use SortedUnsizedArrayOf<> --- src/hb-ot-color-colr-table.hh | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index fa40223b7..84c343325 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -66,13 +66,6 @@ struct BaseGlyphRecord inline int cmp (hb_codepoint_t g) const { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } - static int cmp (const void *pa, const void *pb) - { - const hb_codepoint_t *a = (const hb_codepoint_t *) pa; - const BaseGlyphRecord *b = (const BaseGlyphRecord *) pb; - return b->cmp (*a); - } - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -103,12 +96,7 @@ struct COLR unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const { - const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph, - &(this+baseGlyphsZ), - numBaseGlyphs, - sizeof (BaseGlyphRecord), - BaseGlyphRecord::cmp); - const BaseGlyphRecord &record = rec ? *rec : Null (BaseGlyphRecord); + const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph); hb_array_t all_layers ((this+layersZ).arrayZ, numLayers); hb_array_t glyph_layers = all_layers.sub_array (record.firstLayerIdx, @@ -137,7 +125,7 @@ struct COLR protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ - LOffsetTo, false> + LOffsetTo, false> baseGlyphsZ; /* Offset to Base Glyph records. */ LOffsetTo, false> layersZ; /* Offset to Layer Records. */ From 24887d1115ee41cfad70577eb243382f6c23ab6e Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 24 Nov 2018 20:07:24 +0330 Subject: [PATCH 086/158] Add Adobe AOTS tests (#1395) Annotated OpenType Specification or aots, https://github.com/adobe-type-tools/aots provides a set of tests for OpenType specification, this change add those tests in addition to modified version of their HarfBuzz test runner for generating harfbuzz project specific tests. --- configure.ac | 1 + test/shaping/CMakeLists.txt | 13 +- test/shaping/data/Makefile.am | 1 + test/shaping/data/aots/COPYING | 13 + test/shaping/data/aots/Makefile.am | 37 ++ test/shaping/data/aots/Makefile.sources | 126 +++++++ .../data/aots/fonts/classdef1_font3.otf | Bin 0 -> 6060 bytes .../data/aots/fonts/classdef1_font4.otf | Bin 0 -> 5984 bytes .../data/aots/fonts/classdef2_font1.otf | Bin 0 -> 6004 bytes .../data/aots/fonts/classdef2_font2.otf | Bin 0 -> 6016 bytes .../data/aots/fonts/classdef2_font3.otf | Bin 0 -> 6052 bytes .../data/aots/fonts/classdef2_font4.otf | Bin 0 -> 5984 bytes test/shaping/data/aots/fonts/cmap0_font1.otf | Bin 0 -> 5196 bytes test/shaping/data/aots/fonts/cmap10_font1.otf | Bin 0 -> 4968 bytes test/shaping/data/aots/fonts/cmap10_font2.otf | Bin 0 -> 4960 bytes test/shaping/data/aots/fonts/cmap12_font1.otf | Bin 0 -> 4980 bytes test/shaping/data/aots/fonts/cmap14_font1.otf | Bin 0 -> 5028 bytes test/shaping/data/aots/fonts/cmap2_font1.otf | Bin 0 -> 6000 bytes test/shaping/data/aots/fonts/cmap4_font1.otf | Bin 0 -> 4964 bytes test/shaping/data/aots/fonts/cmap4_font2.otf | Bin 0 -> 4956 bytes test/shaping/data/aots/fonts/cmap4_font3.otf | Bin 0 -> 4956 bytes test/shaping/data/aots/fonts/cmap4_font4.otf | Bin 0 -> 4972 bytes test/shaping/data/aots/fonts/cmap6_font1.otf | Bin 0 -> 4948 bytes test/shaping/data/aots/fonts/cmap6_font2.otf | Bin 0 -> 4944 bytes test/shaping/data/aots/fonts/cmap8_font1.otf | Bin 0 -> 13224 bytes .../aots/fonts/cmap_composition_font1.otf | Bin 0 -> 5096 bytes .../fonts/cmap_subtableselection_font1.otf | Bin 0 -> 6412 bytes .../fonts/cmap_subtableselection_font2.otf | Bin 0 -> 6140 bytes .../fonts/cmap_subtableselection_font3.otf | Bin 0 -> 5872 bytes .../fonts/cmap_subtableselection_font4.otf | Bin 0 -> 5600 bytes .../fonts/cmap_subtableselection_font5.otf | Bin 0 -> 5332 bytes .../data/aots/fonts/gpos1_1_lookupflag_f1.otf | Bin 0 -> 5208 bytes .../data/aots/fonts/gpos1_1_simple_f1.otf | Bin 0 -> 5136 bytes .../data/aots/fonts/gpos1_1_simple_f2.otf | Bin 0 -> 5136 bytes .../data/aots/fonts/gpos1_1_simple_f3.otf | Bin 0 -> 5136 bytes .../data/aots/fonts/gpos1_1_simple_f4.otf | Bin 0 -> 5136 bytes .../shaping/data/aots/fonts/gpos1_2_font1.otf | Bin 0 -> 5108 bytes .../shaping/data/aots/fonts/gpos1_2_font2.otf | Bin 0 -> 5148 bytes .../shaping/data/aots/fonts/gpos2_1_font6.otf | Bin 0 -> 5120 bytes .../shaping/data/aots/fonts/gpos2_1_font7.otf | Bin 0 -> 5132 bytes .../data/aots/fonts/gpos2_1_lookupflag_f1.otf | Bin 0 -> 5220 bytes .../data/aots/fonts/gpos2_1_lookupflag_f2.otf | Bin 0 -> 5220 bytes .../data/aots/fonts/gpos2_1_next_glyph_f1.otf | Bin 0 -> 5180 bytes .../data/aots/fonts/gpos2_1_next_glyph_f2.otf | Bin 0 -> 5176 bytes .../data/aots/fonts/gpos2_1_simple_f1.otf | Bin 0 -> 5148 bytes .../shaping/data/aots/fonts/gpos2_2_font1.otf | Bin 0 -> 5148 bytes .../shaping/data/aots/fonts/gpos2_2_font2.otf | Bin 0 -> 5188 bytes .../shaping/data/aots/fonts/gpos2_2_font3.otf | Bin 0 -> 5188 bytes .../shaping/data/aots/fonts/gpos2_2_font4.otf | Bin 0 -> 5148 bytes .../shaping/data/aots/fonts/gpos2_2_font5.otf | Bin 0 -> 5140 bytes test/shaping/data/aots/fonts/gpos3_font1.otf | Bin 0 -> 5120 bytes test/shaping/data/aots/fonts/gpos3_font2.otf | Bin 0 -> 5160 bytes test/shaping/data/aots/fonts/gpos3_font3.otf | Bin 0 -> 5164 bytes .../data/aots/fonts/gpos4_lookupflag_f1.otf | Bin 0 -> 5256 bytes .../data/aots/fonts/gpos4_lookupflag_f2.otf | Bin 0 -> 5240 bytes .../aots/fonts/gpos4_multiple_anchors_1.otf | Bin 0 -> 5352 bytes .../data/aots/fonts/gpos4_simple_1.otf | Bin 0 -> 5200 bytes test/shaping/data/aots/fonts/gpos5_font1.otf | Bin 0 -> 5284 bytes test/shaping/data/aots/fonts/gpos6_font1.otf | Bin 0 -> 5176 bytes .../shaping/data/aots/fonts/gpos7_1_font1.otf | Bin 0 -> 5160 bytes test/shaping/data/aots/fonts/gpos9_font1.otf | Bin 0 -> 5096 bytes test/shaping/data/aots/fonts/gpos9_font2.otf | Bin 0 -> 5124 bytes .../aots/fonts/gpos_chaining1_boundary_f1.otf | Bin 0 -> 5496 bytes .../aots/fonts/gpos_chaining1_boundary_f2.otf | Bin 0 -> 5500 bytes .../aots/fonts/gpos_chaining1_boundary_f3.otf | Bin 0 -> 5496 bytes .../aots/fonts/gpos_chaining1_boundary_f4.otf | Bin 0 -> 5496 bytes .../fonts/gpos_chaining1_lookupflag_f1.otf | Bin 0 -> 5520 bytes .../gpos_chaining1_multiple_subrules_f1.otf | Bin 0 -> 5592 bytes .../gpos_chaining1_multiple_subrules_f2.otf | Bin 0 -> 5592 bytes .../fonts/gpos_chaining1_next_glyph_f1.otf | Bin 0 -> 5540 bytes .../aots/fonts/gpos_chaining1_simple_f1.otf | Bin 0 -> 5488 bytes .../aots/fonts/gpos_chaining1_simple_f2.otf | Bin 0 -> 5488 bytes .../fonts/gpos_chaining1_successive_f1.otf | Bin 0 -> 5524 bytes .../aots/fonts/gpos_chaining2_boundary_f1.otf | Bin 0 -> 5704 bytes .../aots/fonts/gpos_chaining2_boundary_f2.otf | Bin 0 -> 5708 bytes .../aots/fonts/gpos_chaining2_boundary_f3.otf | Bin 0 -> 5704 bytes .../aots/fonts/gpos_chaining2_boundary_f4.otf | Bin 0 -> 5704 bytes .../fonts/gpos_chaining2_lookupflag_f1.otf | Bin 0 -> 5728 bytes .../gpos_chaining2_multiple_subrules_f1.otf | Bin 0 -> 5800 bytes .../gpos_chaining2_multiple_subrules_f2.otf | Bin 0 -> 5800 bytes .../fonts/gpos_chaining2_next_glyph_f1.otf | Bin 0 -> 5744 bytes .../aots/fonts/gpos_chaining2_simple_f1.otf | Bin 0 -> 5696 bytes .../aots/fonts/gpos_chaining2_simple_f2.otf | Bin 0 -> 5696 bytes .../fonts/gpos_chaining2_successive_f1.otf | Bin 0 -> 5732 bytes .../aots/fonts/gpos_chaining3_boundary_f1.otf | Bin 0 -> 5504 bytes .../aots/fonts/gpos_chaining3_boundary_f2.otf | Bin 0 -> 5508 bytes .../aots/fonts/gpos_chaining3_boundary_f3.otf | Bin 0 -> 5500 bytes .../aots/fonts/gpos_chaining3_boundary_f4.otf | Bin 0 -> 5500 bytes .../fonts/gpos_chaining3_lookupflag_f1.otf | Bin 0 -> 5548 bytes .../fonts/gpos_chaining3_next_glyph_f1.otf | Bin 0 -> 5524 bytes .../aots/fonts/gpos_chaining3_simple_f1.otf | Bin 0 -> 5496 bytes .../aots/fonts/gpos_chaining3_simple_f2.otf | Bin 0 -> 5516 bytes .../fonts/gpos_chaining3_successive_f1.otf | Bin 0 -> 5544 bytes .../aots/fonts/gpos_context1_boundary_f1.otf | Bin 0 -> 5480 bytes .../aots/fonts/gpos_context1_boundary_f2.otf | Bin 0 -> 5480 bytes .../aots/fonts/gpos_context1_expansion_f1.otf | Bin 0 -> 5492 bytes .../fonts/gpos_context1_lookupflag_f1.otf | Bin 0 -> 5508 bytes .../fonts/gpos_context1_lookupflag_f2.otf | Bin 0 -> 5500 bytes .../gpos_context1_multiple_subrules_f1.otf | Bin 0 -> 5568 bytes .../gpos_context1_multiple_subrules_f2.otf | Bin 0 -> 5568 bytes .../fonts/gpos_context1_next_glyph_f1.otf | Bin 0 -> 5500 bytes .../aots/fonts/gpos_context1_simple_f1.otf | Bin 0 -> 5476 bytes .../aots/fonts/gpos_context1_simple_f2.otf | Bin 0 -> 5468 bytes .../fonts/gpos_context1_successive_f1.otf | Bin 0 -> 5508 bytes .../aots/fonts/gpos_context2_boundary_f1.otf | Bin 0 -> 5492 bytes .../aots/fonts/gpos_context2_boundary_f2.otf | Bin 0 -> 5496 bytes .../aots/fonts/gpos_context2_classes_f1.otf | Bin 0 -> 5540 bytes .../aots/fonts/gpos_context2_classes_f2.otf | Bin 0 -> 5564 bytes .../aots/fonts/gpos_context2_expansion_f1.otf | Bin 0 -> 5524 bytes .../fonts/gpos_context2_lookupflag_f1.otf | Bin 0 -> 5540 bytes .../fonts/gpos_context2_lookupflag_f2.otf | Bin 0 -> 5532 bytes .../gpos_context2_multiple_subrules_f1.otf | Bin 0 -> 5600 bytes .../gpos_context2_multiple_subrules_f2.otf | Bin 0 -> 5600 bytes .../fonts/gpos_context2_next_glyph_f1.otf | Bin 0 -> 5512 bytes .../aots/fonts/gpos_context2_simple_f1.otf | Bin 0 -> 5508 bytes .../aots/fonts/gpos_context2_simple_f2.otf | Bin 0 -> 5484 bytes .../fonts/gpos_context2_successive_f1.otf | Bin 0 -> 5544 bytes .../aots/fonts/gpos_context3_boundary_f1.otf | Bin 0 -> 5476 bytes .../aots/fonts/gpos_context3_boundary_f2.otf | Bin 0 -> 5472 bytes .../fonts/gpos_context3_lookupflag_f1.otf | Bin 0 -> 5512 bytes .../fonts/gpos_context3_lookupflag_f2.otf | Bin 0 -> 5504 bytes .../fonts/gpos_context3_next_glyph_f1.otf | Bin 0 -> 5496 bytes .../aots/fonts/gpos_context3_simple_f1.otf | Bin 0 -> 5480 bytes .../fonts/gpos_context3_successive_f1.otf | Bin 0 -> 5516 bytes .../data/aots/fonts/gsub1_1_lookupflag_f1.otf | Bin 0 -> 5208 bytes .../data/aots/fonts/gsub1_1_modulo_f1.otf | Bin 0 -> 5216 bytes .../data/aots/fonts/gsub1_1_simple_f1.otf | Bin 0 -> 5136 bytes .../data/aots/fonts/gsub1_2_lookupflag_f1.otf | Bin 0 -> 5212 bytes .../data/aots/fonts/gsub1_2_simple_f1.otf | Bin 0 -> 5140 bytes .../data/aots/fonts/gsub2_1_lookupflag_f1.otf | Bin 0 -> 5224 bytes .../fonts/gsub2_1_multiple_sequences_f1.otf | Bin 0 -> 5248 bytes .../data/aots/fonts/gsub2_1_simple_f1.otf | Bin 0 -> 5144 bytes .../data/aots/fonts/gsub3_1_lookupflag_f1.otf | Bin 0 -> 5224 bytes .../data/aots/fonts/gsub3_1_multiple_f1.otf | Bin 0 -> 5168 bytes .../data/aots/fonts/gsub3_1_simple_f1.otf | Bin 0 -> 5144 bytes .../data/aots/fonts/gsub4_1_lookupflag_f1.otf | Bin 0 -> 5220 bytes .../fonts/gsub4_1_multiple_ligatures_f1.otf | Bin 0 -> 5252 bytes .../fonts/gsub4_1_multiple_ligatures_f2.otf | Bin 0 -> 5252 bytes .../fonts/gsub4_1_multiple_ligsets_f1.otf | Bin 0 -> 5240 bytes .../data/aots/fonts/gsub4_1_simple_f1.otf | Bin 0 -> 5148 bytes test/shaping/data/aots/fonts/gsub7_font1.otf | Bin 0 -> 5096 bytes test/shaping/data/aots/fonts/gsub7_font2.otf | Bin 0 -> 5116 bytes .../aots/fonts/gsub_chaining1_boundary_f1.otf | Bin 0 -> 5516 bytes .../aots/fonts/gsub_chaining1_boundary_f2.otf | Bin 0 -> 5520 bytes .../aots/fonts/gsub_chaining1_boundary_f3.otf | Bin 0 -> 5520 bytes .../aots/fonts/gsub_chaining1_boundary_f4.otf | Bin 0 -> 5520 bytes .../fonts/gsub_chaining1_lookupflag_f1.otf | Bin 0 -> 5544 bytes .../gsub_chaining1_multiple_subrules_f1.otf | Bin 0 -> 5616 bytes .../gsub_chaining1_multiple_subrules_f2.otf | Bin 0 -> 5616 bytes .../fonts/gsub_chaining1_next_glyph_f1.otf | Bin 0 -> 5560 bytes .../aots/fonts/gsub_chaining1_simple_f1.otf | Bin 0 -> 5508 bytes .../aots/fonts/gsub_chaining1_simple_f2.otf | Bin 0 -> 5512 bytes .../fonts/gsub_chaining1_successive_f1.otf | Bin 0 -> 5544 bytes .../aots/fonts/gsub_chaining2_boundary_f1.otf | Bin 0 -> 5724 bytes .../aots/fonts/gsub_chaining2_boundary_f2.otf | Bin 0 -> 5728 bytes .../aots/fonts/gsub_chaining2_boundary_f3.otf | Bin 0 -> 5728 bytes .../aots/fonts/gsub_chaining2_boundary_f4.otf | Bin 0 -> 5728 bytes .../fonts/gsub_chaining2_lookupflag_f1.otf | Bin 0 -> 5752 bytes .../gsub_chaining2_multiple_subrules_f1.otf | Bin 0 -> 5824 bytes .../gsub_chaining2_multiple_subrules_f2.otf | Bin 0 -> 5824 bytes .../fonts/gsub_chaining2_next_glyph_f1.otf | Bin 0 -> 5764 bytes .../aots/fonts/gsub_chaining2_simple_f1.otf | Bin 0 -> 5716 bytes .../aots/fonts/gsub_chaining2_simple_f2.otf | Bin 0 -> 5720 bytes .../fonts/gsub_chaining2_successive_f1.otf | Bin 0 -> 5752 bytes .../aots/fonts/gsub_chaining3_boundary_f1.otf | Bin 0 -> 5528 bytes .../aots/fonts/gsub_chaining3_boundary_f2.otf | Bin 0 -> 5532 bytes .../aots/fonts/gsub_chaining3_boundary_f3.otf | Bin 0 -> 5524 bytes .../aots/fonts/gsub_chaining3_boundary_f4.otf | Bin 0 -> 5524 bytes .../fonts/gsub_chaining3_lookupflag_f1.otf | Bin 0 -> 5572 bytes .../fonts/gsub_chaining3_next_glyph_f1.otf | Bin 0 -> 5548 bytes .../aots/fonts/gsub_chaining3_simple_f1.otf | Bin 0 -> 5520 bytes .../aots/fonts/gsub_chaining3_simple_f2.otf | Bin 0 -> 5540 bytes .../fonts/gsub_chaining3_successive_f1.otf | Bin 0 -> 5568 bytes .../aots/fonts/gsub_context1_boundary_f1.otf | Bin 0 -> 5500 bytes .../aots/fonts/gsub_context1_boundary_f2.otf | Bin 0 -> 5504 bytes .../aots/fonts/gsub_context1_expansion_f1.otf | Bin 0 -> 5516 bytes .../fonts/gsub_context1_lookupflag_f1.otf | Bin 0 -> 5532 bytes .../fonts/gsub_context1_lookupflag_f2.otf | Bin 0 -> 5524 bytes .../gsub_context1_multiple_subrules_f1.otf | Bin 0 -> 5592 bytes .../gsub_context1_multiple_subrules_f2.otf | Bin 0 -> 5592 bytes .../fonts/gsub_context1_next_glyph_f1.otf | Bin 0 -> 5520 bytes .../aots/fonts/gsub_context1_simple_f1.otf | Bin 0 -> 5500 bytes .../aots/fonts/gsub_context1_simple_f2.otf | Bin 0 -> 5492 bytes .../fonts/gsub_context1_successive_f1.otf | Bin 0 -> 5528 bytes .../aots/fonts/gsub_context2_boundary_f1.otf | Bin 0 -> 5516 bytes .../aots/fonts/gsub_context2_boundary_f2.otf | Bin 0 -> 5516 bytes .../aots/fonts/gsub_context2_classes_f1.otf | Bin 0 -> 5564 bytes .../aots/fonts/gsub_context2_classes_f2.otf | Bin 0 -> 5584 bytes .../aots/fonts/gsub_context2_expansion_f1.otf | Bin 0 -> 5544 bytes .../fonts/gsub_context2_lookupflag_f1.otf | Bin 0 -> 5560 bytes .../fonts/gsub_context2_lookupflag_f2.otf | Bin 0 -> 5552 bytes .../gsub_context2_multiple_subrules_f1.otf | Bin 0 -> 5620 bytes .../gsub_context2_multiple_subrules_f2.otf | Bin 0 -> 5620 bytes .../fonts/gsub_context2_next_glyph_f1.otf | Bin 0 -> 5536 bytes .../aots/fonts/gsub_context2_simple_f1.otf | Bin 0 -> 5528 bytes .../aots/fonts/gsub_context2_simple_f2.otf | Bin 0 -> 5504 bytes .../fonts/gsub_context2_successive_f1.otf | Bin 0 -> 5568 bytes .../aots/fonts/gsub_context3_boundary_f1.otf | Bin 0 -> 5500 bytes .../aots/fonts/gsub_context3_boundary_f2.otf | Bin 0 -> 5496 bytes .../fonts/gsub_context3_lookupflag_f1.otf | Bin 0 -> 5536 bytes .../fonts/gsub_context3_lookupflag_f2.otf | Bin 0 -> 5528 bytes .../fonts/gsub_context3_next_glyph_f1.otf | Bin 0 -> 5520 bytes .../aots/fonts/gsub_context3_simple_f1.otf | Bin 0 -> 5504 bytes .../fonts/gsub_context3_successive_f1.otf | Bin 0 -> 5540 bytes .../fonts/lookupflag_ignore_attach_f1.otf | Bin 0 -> 5416 bytes .../aots/fonts/lookupflag_ignore_base_f1.otf | Bin 0 -> 5256 bytes .../lookupflag_ignore_combination_f1.otf | Bin 0 -> 5408 bytes .../fonts/lookupflag_ignore_ligatures_f1.otf | Bin 0 -> 5320 bytes .../aots/fonts/lookupflag_ignore_marks_f1.otf | Bin 0 -> 5288 bytes test/shaping/data/aots/hb-aots-tester.cpp | 343 ++++++++++++++++++ test/shaping/data/aots/tests/classdef1.tests | 1 + .../data/aots/tests/classdef1_empty.tests | 1 + .../data/aots/tests/classdef1_multiple.tests | 1 + .../data/aots/tests/classdef1_single.tests | 1 + test/shaping/data/aots/tests/classdef2.tests | 1 + .../data/aots/tests/classdef2_empty.tests | 1 + .../data/aots/tests/classdef2_multiple.tests | 1 + .../data/aots/tests/classdef2_single.tests | 1 + .../data/aots/tests/gpos1_1_lookupflag.tests | 1 + .../data/aots/tests/gpos1_1_simple.tests | 4 + test/shaping/data/aots/tests/gpos1_2.tests | 1 + .../data/aots/tests/gpos1_2_lookupflag.tests | 1 + test/shaping/data/aots/tests/gpos2_1.tests | 2 + .../data/aots/tests/gpos2_1_lookupflag.tests | 2 + .../data/aots/tests/gpos2_1_next_glyph.tests | 2 + .../data/aots/tests/gpos2_1_simple.tests | 2 + test/shaping/data/aots/tests/gpos2_2.tests | 5 + test/shaping/data/aots/tests/gpos3.tests | 11 + .../data/aots/tests/gpos3_lookupflag.tests | 2 + .../data/aots/tests/gpos4_lookupflag.tests | 2 + .../aots/tests/gpos4_multiple_anchors.tests | 1 + .../data/aots/tests/gpos4_simple.tests | 5 + test/shaping/data/aots/tests/gpos5.tests | 2 + test/shaping/data/aots/tests/gpos6.tests | 3 + test/shaping/data/aots/tests/gpos7_1.tests | 2 + test/shaping/data/aots/tests/gpos9.tests | 2 + .../aots/tests/gpos_chaining1_boundary.tests | 4 + .../tests/gpos_chaining1_lookupflag.tests | 1 + .../gpos_chaining1_multiple_subrules.tests | 2 + .../tests/gpos_chaining1_next_glyph.tests | 1 + .../aots/tests/gpos_chaining1_simple.tests | 11 + .../tests/gpos_chaining1_successive.tests | 1 + .../aots/tests/gpos_chaining2_boundary.tests | 4 + .../tests/gpos_chaining2_lookupflag.tests | 1 + .../gpos_chaining2_multiple_subrules.tests | 2 + .../tests/gpos_chaining2_next_glyph.tests | 1 + .../aots/tests/gpos_chaining2_simple.tests | 11 + .../tests/gpos_chaining2_successive.tests | 1 + .../aots/tests/gpos_chaining3_boundary.tests | 4 + .../tests/gpos_chaining3_lookupflag.tests | 1 + .../tests/gpos_chaining3_next_glyph.tests | 1 + .../aots/tests/gpos_chaining3_simple.tests | 11 + .../tests/gpos_chaining3_successive.tests | 1 + .../aots/tests/gpos_context1_boundary.tests | 2 + .../aots/tests/gpos_context1_expansion.tests | 1 + .../aots/tests/gpos_context1_lookupflag.tests | 2 + .../gpos_context1_multiple_subrules.tests | 2 + .../aots/tests/gpos_context1_next_glyph.tests | 1 + .../aots/tests/gpos_context1_simple.tests | 3 + .../aots/tests/gpos_context1_successive.tests | 1 + .../aots/tests/gpos_context2_boundary.tests | 2 + .../aots/tests/gpos_context2_classes.tests | 2 + .../aots/tests/gpos_context2_expansion.tests | 1 + .../aots/tests/gpos_context2_lookupflag.tests | 2 + .../gpos_context2_multiple_subrules.tests | 2 + .../aots/tests/gpos_context2_next_glyph.tests | 1 + .../aots/tests/gpos_context2_simple.tests | 3 + .../aots/tests/gpos_context2_successive.tests | 1 + .../aots/tests/gpos_context3_boundary.tests | 2 + .../aots/tests/gpos_context3_lookupflag.tests | 2 + .../aots/tests/gpos_context3_next_glyph.tests | 1 + .../aots/tests/gpos_context3_simple.tests | 2 + .../aots/tests/gpos_context3_successive.tests | 1 + .../data/aots/tests/gsub1_1_lookupflag.tests | 1 + .../data/aots/tests/gsub1_1_modulo.tests | 1 + .../data/aots/tests/gsub1_1_simple.tests | 1 + .../data/aots/tests/gsub1_2_lookupflag.tests | 1 + .../data/aots/tests/gsub1_2_simple.tests | 1 + .../data/aots/tests/gsub2_1_lookupflag.tests | 1 + .../tests/gsub2_1_multiple_sequences.tests | 1 + .../data/aots/tests/gsub2_1_simple.tests | 2 + .../data/aots/tests/gsub3_1_lookupflag.tests | 1 + .../data/aots/tests/gsub3_1_multiple.tests | 1 + .../data/aots/tests/gsub3_1_simple.tests | 1 + .../data/aots/tests/gsub4_1_lookupflag.tests | 1 + .../tests/gsub4_1_multiple_ligatures.tests | 2 + .../aots/tests/gsub4_1_multiple_ligsets.tests | 1 + .../data/aots/tests/gsub4_1_simple.tests | 1 + test/shaping/data/aots/tests/gsub7.tests | 2 + .../aots/tests/gsub_chaining1_boundary.tests | 4 + .../tests/gsub_chaining1_lookupflag.tests | 1 + .../gsub_chaining1_multiple_subrules.tests | 2 + .../tests/gsub_chaining1_next_glyph.tests | 1 + .../aots/tests/gsub_chaining1_simple.tests | 11 + .../tests/gsub_chaining1_successive.tests | 1 + .../aots/tests/gsub_chaining2_boundary.tests | 4 + .../tests/gsub_chaining2_lookupflag.tests | 1 + .../gsub_chaining2_multiple_subrules.tests | 2 + .../tests/gsub_chaining2_next_glyph.tests | 1 + .../aots/tests/gsub_chaining2_simple.tests | 11 + .../tests/gsub_chaining2_successive.tests | 1 + .../aots/tests/gsub_chaining3_boundary.tests | 4 + .../tests/gsub_chaining3_lookupflag.tests | 1 + .../tests/gsub_chaining3_next_glyph.tests | 1 + .../aots/tests/gsub_chaining3_simple.tests | 11 + .../tests/gsub_chaining3_successive.tests | 1 + .../aots/tests/gsub_context1_boundary.tests | 2 + .../aots/tests/gsub_context1_expansion.tests | 1 + .../aots/tests/gsub_context1_lookupflag.tests | 2 + .../gsub_context1_multiple_subrules.tests | 2 + .../aots/tests/gsub_context1_next_glyph.tests | 1 + .../aots/tests/gsub_context1_simple.tests | 3 + .../aots/tests/gsub_context1_successive.tests | 1 + .../aots/tests/gsub_context2_boundary.tests | 2 + .../aots/tests/gsub_context2_classes.tests | 2 + .../aots/tests/gsub_context2_expansion.tests | 1 + .../aots/tests/gsub_context2_lookupflag.tests | 2 + .../gsub_context2_multiple_subrules.tests | 2 + .../aots/tests/gsub_context2_next_glyph.tests | 1 + .../aots/tests/gsub_context2_simple.tests | 3 + .../aots/tests/gsub_context2_successive.tests | 1 + .../aots/tests/gsub_context3_boundary.tests | 2 + .../aots/tests/gsub_context3_lookupflag.tests | 2 + .../aots/tests/gsub_context3_next_glyph.tests | 1 + .../aots/tests/gsub_context3_simple.tests | 2 + .../aots/tests/gsub_context3_successive.tests | 1 + .../aots/tests/lookupflag_ignore_attach.tests | 5 + .../aots/tests/lookupflag_ignore_base.tests | 2 + .../tests/lookupflag_ignore_combination.tests | 3 + .../tests/lookupflag_ignore_ligatures.tests | 3 + .../aots/tests/lookupflag_ignore_marks.tests | 1 + test/shaping/run-tests.py | 9 +- 332 files changed, 815 insertions(+), 3 deletions(-) create mode 100644 test/shaping/data/aots/COPYING create mode 100644 test/shaping/data/aots/Makefile.am create mode 100644 test/shaping/data/aots/Makefile.sources create mode 100644 test/shaping/data/aots/fonts/classdef1_font3.otf create mode 100644 test/shaping/data/aots/fonts/classdef1_font4.otf create mode 100644 test/shaping/data/aots/fonts/classdef2_font1.otf create mode 100644 test/shaping/data/aots/fonts/classdef2_font2.otf create mode 100644 test/shaping/data/aots/fonts/classdef2_font3.otf create mode 100644 test/shaping/data/aots/fonts/classdef2_font4.otf create mode 100644 test/shaping/data/aots/fonts/cmap0_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap10_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap10_font2.otf create mode 100644 test/shaping/data/aots/fonts/cmap12_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap14_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap2_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap4_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap4_font2.otf create mode 100644 test/shaping/data/aots/fonts/cmap4_font3.otf create mode 100644 test/shaping/data/aots/fonts/cmap4_font4.otf create mode 100644 test/shaping/data/aots/fonts/cmap6_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap6_font2.otf create mode 100644 test/shaping/data/aots/fonts/cmap8_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap_composition_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap_subtableselection_font1.otf create mode 100644 test/shaping/data/aots/fonts/cmap_subtableselection_font2.otf create mode 100644 test/shaping/data/aots/fonts/cmap_subtableselection_font3.otf create mode 100644 test/shaping/data/aots/fonts/cmap_subtableselection_font4.otf create mode 100644 test/shaping/data/aots/fonts/cmap_subtableselection_font5.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_1_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_1_simple_f3.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_1_simple_f4.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_2_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos1_2_font2.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_font6.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_font7.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_next_glyph_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_2_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_2_font2.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_2_font3.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_2_font4.otf create mode 100644 test/shaping/data/aots/fonts/gpos2_2_font5.otf create mode 100644 test/shaping/data/aots/fonts/gpos3_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos3_font2.otf create mode 100644 test/shaping/data/aots/fonts/gpos3_font3.otf create mode 100644 test/shaping/data/aots/fonts/gpos4_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos4_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos4_multiple_anchors_1.otf create mode 100644 test/shaping/data/aots/fonts/gpos4_simple_1.otf create mode 100644 test/shaping/data/aots/fonts/gpos5_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos6_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos7_1_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos9_font1.otf create mode 100644 test/shaping/data/aots/fonts/gpos9_font2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_boundary_f3.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_boundary_f4.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining1_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_boundary_f3.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_boundary_f4.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining2_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_boundary_f3.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_boundary_f4.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_chaining3_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_expansion_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context1_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_classes_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_classes_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_expansion_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context2_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gpos_context3_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub1_1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub1_1_modulo_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub1_1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub1_2_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub1_2_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub2_1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub2_1_multiple_sequences_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub2_1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub3_1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub3_1_multiple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub3_1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub4_1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub4_1_multiple_ligsets_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub4_1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub7_font1.otf create mode 100644 test/shaping/data/aots/fonts/gsub7_font2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_boundary_f3.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_boundary_f4.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining1_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_boundary_f3.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_boundary_f4.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining2_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_boundary_f3.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_boundary_f4.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_chaining3_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_expansion_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context1_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_classes_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_classes_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_expansion_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_multiple_subrules_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_simple_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context2_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_boundary_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_boundary_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_lookupflag_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_lookupflag_f2.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_next_glyph_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_simple_f1.otf create mode 100644 test/shaping/data/aots/fonts/gsub_context3_successive_f1.otf create mode 100644 test/shaping/data/aots/fonts/lookupflag_ignore_attach_f1.otf create mode 100644 test/shaping/data/aots/fonts/lookupflag_ignore_base_f1.otf create mode 100644 test/shaping/data/aots/fonts/lookupflag_ignore_combination_f1.otf create mode 100644 test/shaping/data/aots/fonts/lookupflag_ignore_ligatures_f1.otf create mode 100644 test/shaping/data/aots/fonts/lookupflag_ignore_marks_f1.otf create mode 100644 test/shaping/data/aots/hb-aots-tester.cpp create mode 100644 test/shaping/data/aots/tests/classdef1.tests create mode 100644 test/shaping/data/aots/tests/classdef1_empty.tests create mode 100644 test/shaping/data/aots/tests/classdef1_multiple.tests create mode 100644 test/shaping/data/aots/tests/classdef1_single.tests create mode 100644 test/shaping/data/aots/tests/classdef2.tests create mode 100644 test/shaping/data/aots/tests/classdef2_empty.tests create mode 100644 test/shaping/data/aots/tests/classdef2_multiple.tests create mode 100644 test/shaping/data/aots/tests/classdef2_single.tests create mode 100644 test/shaping/data/aots/tests/gpos1_1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos1_1_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos1_2.tests create mode 100644 test/shaping/data/aots/tests/gpos1_2_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos2_1.tests create mode 100644 test/shaping/data/aots/tests/gpos2_1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos2_1_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos2_1_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos2_2.tests create mode 100644 test/shaping/data/aots/tests/gpos3.tests create mode 100644 test/shaping/data/aots/tests/gpos3_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos4_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos4_multiple_anchors.tests create mode 100644 test/shaping/data/aots/tests/gpos4_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos5.tests create mode 100644 test/shaping/data/aots/tests/gpos6.tests create mode 100644 test/shaping/data/aots/tests/gpos7_1.tests create mode 100644 test/shaping/data/aots/tests/gpos9.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining1_boundary.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining1_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining1_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining1_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining1_successive.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining2_boundary.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining2_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining2_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining2_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining2_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining2_successive.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining3_boundary.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining3_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining3_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining3_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos_chaining3_successive.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_boundary.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_expansion.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos_context1_successive.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_boundary.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_classes.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_expansion.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos_context2_successive.tests create mode 100644 test/shaping/data/aots/tests/gpos_context3_boundary.tests create mode 100644 test/shaping/data/aots/tests/gpos_context3_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gpos_context3_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gpos_context3_simple.tests create mode 100644 test/shaping/data/aots/tests/gpos_context3_successive.tests create mode 100644 test/shaping/data/aots/tests/gsub1_1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub1_1_modulo.tests create mode 100644 test/shaping/data/aots/tests/gsub1_1_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub1_2_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub1_2_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub2_1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub2_1_multiple_sequences.tests create mode 100644 test/shaping/data/aots/tests/gsub2_1_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub3_1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub3_1_multiple.tests create mode 100644 test/shaping/data/aots/tests/gsub3_1_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub4_1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub4_1_multiple_ligatures.tests create mode 100644 test/shaping/data/aots/tests/gsub4_1_multiple_ligsets.tests create mode 100644 test/shaping/data/aots/tests/gsub4_1_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub7.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining1_boundary.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining1_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining1_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining1_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining1_successive.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining2_boundary.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining2_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining2_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining2_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining2_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining2_successive.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining3_boundary.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining3_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining3_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining3_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub_chaining3_successive.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_boundary.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_expansion.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub_context1_successive.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_boundary.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_classes.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_expansion.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_multiple_subrules.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub_context2_successive.tests create mode 100644 test/shaping/data/aots/tests/gsub_context3_boundary.tests create mode 100644 test/shaping/data/aots/tests/gsub_context3_lookupflag.tests create mode 100644 test/shaping/data/aots/tests/gsub_context3_next_glyph.tests create mode 100644 test/shaping/data/aots/tests/gsub_context3_simple.tests create mode 100644 test/shaping/data/aots/tests/gsub_context3_successive.tests create mode 100644 test/shaping/data/aots/tests/lookupflag_ignore_attach.tests create mode 100644 test/shaping/data/aots/tests/lookupflag_ignore_base.tests create mode 100644 test/shaping/data/aots/tests/lookupflag_ignore_combination.tests create mode 100644 test/shaping/data/aots/tests/lookupflag_ignore_ligatures.tests create mode 100644 test/shaping/data/aots/tests/lookupflag_ignore_marks.tests diff --git a/configure.ac b/configure.ac index 95ab48f80..e9db42a78 100644 --- a/configure.ac +++ b/configure.ac @@ -508,6 +508,7 @@ test/api/Makefile test/fuzzing/Makefile test/shaping/Makefile test/shaping/data/Makefile +test/shaping/data/aots/Makefile test/shaping/data/in-house/Makefile test/shaping/data/text-rendering-tests/Makefile test/subset/Makefile diff --git a/test/shaping/CMakeLists.txt b/test/shaping/CMakeLists.txt index 25f14177e..8e33edeec 100644 --- a/test/shaping/CMakeLists.txt +++ b/test/shaping/CMakeLists.txt @@ -5,7 +5,16 @@ if (HB_BUILD_UTILS) add_test (NAME ${test} COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/in-house/${test}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - set_property(TEST ${test} PROPERTY SKIP_RETURN_CODE 77) + set_property (TEST ${test} PROPERTY SKIP_RETURN_CODE 77) + endforeach () + + file (READ "${CMAKE_CURRENT_SOURCE_DIR}/data/aots/Makefile.sources" INHOUSE) + extract_make_variable (TESTS ${INHOUSE}) + foreach (test IN ITEMS ${TESTS}) + add_test (NAME ${test} + COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/aots/${test}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + set_property (TEST ${test} PROPERTY SKIP_RETURN_CODE 77) endforeach () file (READ "${CMAKE_CURRENT_SOURCE_DIR}/data/text-rendering-tests/Makefile.sources" TEXTRENDERING) @@ -14,6 +23,6 @@ if (HB_BUILD_UTILS) add_test (NAME ${test} COMMAND "${PYTHON_EXECUTABLE}" run-tests.py $ "data/text-rendering-tests/${test}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - set_property(TEST ${test} PROPERTY SKIP_RETURN_CODE 77) + set_property (TEST ${test} PROPERTY SKIP_RETURN_CODE 77) endforeach () endif () diff --git a/test/shaping/data/Makefile.am b/test/shaping/data/Makefile.am index 4f2c11366..2b908b3c3 100644 --- a/test/shaping/data/Makefile.am +++ b/test/shaping/data/Makefile.am @@ -3,6 +3,7 @@ NULL = SUBDIRS = \ in-house \ + aots \ text-rendering-tests \ $(NULL) diff --git a/test/shaping/data/aots/COPYING b/test/shaping/data/aots/COPYING new file mode 100644 index 000000000..d000f23b2 --- /dev/null +++ b/test/shaping/data/aots/COPYING @@ -0,0 +1,13 @@ +Copyright 2000-2016 Adobe Systems Incorporated. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use these files except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/test/shaping/data/aots/Makefile.am b/test/shaping/data/aots/Makefile.am new file mode 100644 index 000000000..3b1faee5f --- /dev/null +++ b/test/shaping/data/aots/Makefile.am @@ -0,0 +1,37 @@ +# Process this file with automake to produce Makefile.in + +NULL = + +# Convenience targets: +lib: + @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src lib + +EXTRA_DIST = \ + COPYING \ + fonts \ + $(TESTS) \ + $(NULL) + +TEST_EXTENSIONS = .tests +TESTS_LOG_COMPILER = $(srcdir)/../../run-tests.py $(top_builddir)/util/hb-shape$(EXEEXT) + +init-aots: + git clone https://github.com/adobe-type-tools/aots $(srcdir)/aots + make -C$(srcdir)/aots + make -C$(srcdir)/aots/harfbuzz + touch $(srcdir)/init-aots + +update-tests: init-aots lib + cp $(srcdir)/hb-aots-tester.cpp $(srcdir)/aots/harfbuzz/hb-aots-tester.cpp + $(CXX) -Wno-narrowing $(srcdir)/aots/harfbuzz/hb-aots-tester.cpp \ + -I$(top_srcdir)/src/ -o $(srcdir)/aots/harfbuzz/aots \ + -L$(top_builddir)/src/.libs -lharfbuzz + rm -rf $(srcdir)/tests/ + mkdir $(srcdir)/tests/ + export LD_LIBRARY_PATH=$(realpath $(top_builddir)/src/.libs); cd $(srcdir)/aots/harfbuzz; ./aots + +.PHONY: update-tests + +include Makefile.sources + +-include $(top_srcdir)/git.mk diff --git a/test/shaping/data/aots/Makefile.sources b/test/shaping/data/aots/Makefile.sources new file mode 100644 index 000000000..8340bb6cf --- /dev/null +++ b/test/shaping/data/aots/Makefile.sources @@ -0,0 +1,126 @@ +TESTS = \ + tests/classdef1_single.tests \ + tests/classdef1.tests \ + tests/classdef2_empty.tests \ + tests/classdef2_single.tests \ + tests/classdef2.tests \ + tests/gpos1_1_lookupflag.tests \ + tests/gpos1_1_simple.tests \ + tests/gpos1_2_lookupflag.tests \ + tests/gpos1_2.tests \ + tests/gpos2_1_lookupflag.tests \ + tests/gpos2_1_next_glyph.tests \ + tests/gpos2_1_simple.tests \ + tests/gpos2_1.tests \ + tests/gpos2_2.tests \ + tests/gpos4_lookupflag.tests \ + tests/gpos7_1.tests \ + tests/gpos9.tests \ + tests/gpos_chaining1_boundary.tests \ + tests/gpos_chaining1_lookupflag.tests \ + tests/gpos_chaining1_multiple_subrules.tests \ + tests/gpos_chaining1_next_glyph.tests \ + tests/gpos_chaining1_simple.tests \ + tests/gpos_chaining1_successive.tests \ + tests/gpos_chaining2_boundary.tests \ + tests/gpos_chaining2_lookupflag.tests \ + tests/gpos_chaining2_multiple_subrules.tests \ + tests/gpos_chaining2_next_glyph.tests \ + tests/gpos_chaining2_simple.tests \ + tests/gpos_chaining2_successive.tests \ + tests/gpos_chaining3_boundary.tests \ + tests/gpos_chaining3_lookupflag.tests \ + tests/gpos_chaining3_next_glyph.tests \ + tests/gpos_chaining3_simple.tests \ + tests/gpos_chaining3_successive.tests \ + tests/gpos_context1_boundary.tests \ + tests/gpos_context1_expansion.tests \ + tests/gpos_context1_lookupflag.tests \ + tests/gpos_context1_multiple_subrules.tests \ + tests/gpos_context1_next_glyph.tests \ + tests/gpos_context1_simple.tests \ + tests/gpos_context1_successive.tests \ + tests/gpos_context2_boundary.tests \ + tests/gpos_context2_classes.tests \ + tests/gpos_context2_expansion.tests \ + tests/gpos_context2_lookupflag.tests \ + tests/gpos_context2_multiple_subrules.tests \ + tests/gpos_context2_next_glyph.tests \ + tests/gpos_context2_simple.tests \ + tests/gpos_context2_successive.tests \ + tests/gpos_context3_boundary.tests \ + tests/gpos_context3_lookupflag.tests \ + tests/gpos_context3_next_glyph.tests \ + tests/gpos_context3_simple.tests \ + tests/gpos_context3_successive.tests \ + tests/gsub1_1_lookupflag.tests \ + tests/gsub1_1_modulo.tests \ + tests/gsub1_1_simple.tests \ + tests/gsub1_2_lookupflag.tests \ + tests/gsub1_2_simple.tests \ + tests/gsub2_1_lookupflag.tests \ + tests/gsub2_1_multiple_sequences.tests \ + tests/gsub2_1_simple.tests \ + tests/gsub3_1_lookupflag.tests \ + tests/gsub3_1_multiple.tests \ + tests/gsub4_1_lookupflag.tests \ + tests/gsub4_1_multiple_ligatures.tests \ + tests/gsub4_1_multiple_ligsets.tests \ + tests/gsub4_1_simple.tests \ + tests/gsub7.tests \ + tests/gsub_chaining1_boundary.tests \ + tests/gsub_chaining1_lookupflag.tests \ + tests/gsub_chaining1_multiple_subrules.tests \ + tests/gsub_chaining1_next_glyph.tests \ + tests/gsub_chaining1_simple.tests \ + tests/gsub_chaining1_successive.tests \ + tests/gsub_chaining2_boundary.tests \ + tests/gsub_chaining2_lookupflag.tests \ + tests/gsub_chaining2_multiple_subrules.tests \ + tests/gsub_chaining2_next_glyph.tests \ + tests/gsub_chaining2_simple.tests \ + tests/gsub_chaining2_successive.tests \ + tests/gsub_chaining3_boundary.tests \ + tests/gsub_chaining3_lookupflag.tests \ + tests/gsub_chaining3_next_glyph.tests \ + tests/gsub_chaining3_simple.tests \ + tests/gsub_chaining3_successive.tests \ + tests/gsub_context1_boundary.tests \ + tests/gsub_context1_expansion.tests \ + tests/gsub_context1_lookupflag.tests \ + tests/gsub_context1_multiple_subrules.tests \ + tests/gsub_context1_next_glyph.tests \ + tests/gsub_context1_simple.tests \ + tests/gsub_context1_successive.tests \ + tests/gsub_context2_boundary.tests \ + tests/gsub_context2_classes.tests \ + tests/gsub_context2_expansion.tests \ + tests/gsub_context2_lookupflag.tests \ + tests/gsub_context2_multiple_subrules.tests \ + tests/gsub_context2_next_glyph.tests \ + tests/gsub_context2_simple.tests \ + tests/gsub_context2_successive.tests \ + tests/gsub_context3_boundary.tests \ + tests/gsub_context3_lookupflag.tests \ + tests/gsub_context3_next_glyph.tests \ + tests/gsub_context3_simple.tests \ + tests/gsub_context3_successive.tests \ + tests/lookupflag_ignore_base.tests \ + tests/lookupflag_ignore_combination.tests \ + tests/lookupflag_ignore_ligatures.tests \ + tests/lookupflag_ignore_marks.tests \ + $(NULL) + +DISABLED_TESTS = \ + tests/classdef1_empty.tests \ + tests/classdef1_multiple.tests \ + tests/classdef2_multiple.tests \ + tests/gpos3_lookupflag.tests \ + tests/gpos3.tests \ + tests/gpos4_multiple_anchors.tests \ + tests/gpos4_simple.tests \ + tests/gpos5.tests \ + tests/gpos6.tests \ + tests/gsub3_1_simple.tests \ + tests/lookupflag_ignore_attach.tests \ + $(NULL) diff --git a/test/shaping/data/aots/fonts/classdef1_font3.otf b/test/shaping/data/aots/fonts/classdef1_font3.otf new file mode 100644 index 0000000000000000000000000000000000000000..2a0f9cc8fbea43ddb902429d72bf85354cac6ec7 GIT binary patch literal 6060 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 I_5VHo2jRzv^Z)<= literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/classdef2_font1.otf b/test/shaping/data/aots/fonts/classdef2_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..2e2faafee002ca24442bd596e54c42e896b83b6b GIT binary patch literal 6004 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/classdef2_font3.otf b/test/shaping/data/aots/fonts/classdef2_font3.otf new file mode 100644 index 0000000000000000000000000000000000000000..14c91193811e714c3399b4b1b1b4fcc441d40e39 GIT binary patch literal 6052 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/classdef2_font4.otf b/test/shaping/data/aots/fonts/classdef2_font4.otf new file mode 100644 index 0000000000000000000000000000000000000000..c75c883a08621852a00d9ed51b1e127484197be1 GIT binary patch literal 5984 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap10_font1.otf b/test/shaping/data/aots/fonts/cmap10_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..023e9456153819e6bc4146e8121e870b7d0ab689 GIT binary patch literal 4968 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 Q;KO4g9_+>6t^RZRKeQ7bTmS$7 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap12_font1.otf b/test/shaping/data/aots/fonts/cmap12_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..2d74b3a90f20e75cbaad0b03a7cef1e27ca9695d GIT binary patch literal 4980 zcmds*iFXuLy1=UwNGgkfOM^o+WM2fd_XXKE5oB0HSQKco-0UHHI!R~gC0$ir)k`{i zlZ`YeN!UYVc>#eaAgByDDsLS0d7RNV58qK#s$<2&`)(4?yfg3k54@`LyLE3>{i?g} z{l3~ZY~8wn2qJ0;e`3ap)vF_-w=s1DK^!2688I8Syd=xHl{5_XcVOM#lw93@VuSu! zf_O3l+KP-cU24X?brNWAg|;dKR)`J3524LMJ0>HyxO{2xf>vmsfcE>jy7K)*>PDzO zRRu*ro-Q}-iS!sFw9U}Iy+6OG_;D8@BZ#N*@ghXTlqrO03RFdS_tcWyT>U@WYkkuR zUyaCD>*uTW_dPpBcrw&KJeVLK+ia7I&_J8*xuB8f$n>et6U4Efo`BN7XgV&-o`jOv z1Vy0VQ$+f2zu^xnrviaM5D)@90Za#;1fB-O0CWKn2808VKnxHMya3Dxpi2ljpaQhO zLSPB799RXc0oDP31U3Qqbd!Odz#G6`AO%PVGJzZ*A1DM$fO4P`s0Q$G;qJ2n48Q?S zzzsA5Z2$}>(FGg?4gqfg{lGEcBrpiP4V(vtfp>tbzfe1P~3t`HQlV z1WAz$$&msnkqW7i25FHLR!WgnhNN;NRUoMnNmWRyMp6xuYLQHWWZ=k|-l1q?WisW!eIg%@oT#4i=Bv&K32FbNZAwdc$Qpk`3eo=uGN~BOBg&HX| zNTEea2~tXtQiharq=Y}DL`oG>s*zHIlv<>cAe9uUWJo1PDg{!(|5YKC8mTl$rA2B9 zQcICqhSYMTRv@(!so`|gNUcF?Ez(GkMv62tq>&?y0%?>;qe2=uTMg1^kye7VQlyn3 ztsH3;NUKCz71FAa7CJ+_B7eWWFcW1IMqM#v-*S;Vr`{C#N=Tl7W6X}LuaujZxX z7w*q5)D@?tz8JAACnsVv-n}Sdb6QbaVJWPfNG?JoqV^G~zokO}3>!{?82}D@7#?B{ zfWtizcoD#1t^pPSIJ{p0UITDgZv%D#dx10{3&3Gq4CnzIz9xVIaM(5gEdUPJ9^f#5 z!}J7j2EgHY2^axzSbhlH1#me275ECkVfX;}0l?uWKnTHNJnVvD38_3DZhwF!r0;l` zCBPEWRs>fbks5$>6)gi+1M7f|KoYPM*aM^jkd~r6pa_6;6d3>`0BI;<0T%%2C-MN@ z0HmF$4>%4$x{1yK7Xe5!(RJVh0MbkJDeyS}X(jqQ@LvF=ljvtjuq1d|L~tZ7qHqz7 zix^zQ;vx28*$i(!$ur7;;<2i zjW}$?Vb*SBw`~G8;RIR#6}`E60uR}9gX!0RxiJ@^@>+$_6G3By<=CscfD)9f&aRV z{O7iy{@^b|`a?s%bcQ|wH^65AF*b< z*-$!km+jmj!{=D|EQZgnJ*Kmn(@Fl`uZgf{v~NKCUeEPYH|_VF_7}2uEfIo*?yW{) zA)V8l>&$W1IqRG1hpXOo53{$}5A3(t6AiXA8O>xQEfD4i2i;-n;0}2BNWSIDZ9eEO zKWz;kB}h_|4Z8}qm!}v!+XvkwKRPxb4*ACSnYh)}+R)~>?BQQy8yB$ER5fKV?iOYk zbS9FfStg7Q%&l^!9J5}lzhOPU_x@6W5N2!3mR7|5U1umUne|Pj9L>=z-Bj01HE|@z zF>IK}+z#`AVZdi`ZyqA47x3sbreZc3?1g+!zlg_JNc(+I|cvG;xajm3~8}YR_h#^!4oM|jLj1_ zwz=9GTRpueE*|K)aC7*^@Qt^kSi#RKh!jR)R`rf9(ibk|i$exSXNp;Amb?R=y|e)b>wo?{W8?pLYM- zZPI((cA@!9=iR+Sy0hy)66A$T4wVhPebw^8_iaDaKV&9`Q4qoJI|ZVGWLTSxon1Jv zyPzYD^v(TMDGu>Pk0yu_m)?|N66R%Z5uQ&MW@iX9uLvvnNF6VEgAe0f>-g!Z_p+%4 zZ3RwbD5^tM`TBx_&hOvnXYv6ZWWTe|)Ia%Cq~H<8#Fs|+#5-pMzXA1PAxW4zka#5T zq2rrIa~spvNcv)hOX86K_B|56-*%(wCQbGnWVxO>MOo!(C21-laj}qCE-Z7T4_RA| zcJkUk^Rf5&sG}p^>sOC=_Zp65)1>9~ou*x3E4el8t12dg&!_tJB^c#1qZ+ZiB`V&m zWQyww8cP~W-NmhCE|c5bSg)(fDJb2XqZt&!zs~d;dn*sKf8#9me>z8AJ5|q5HN8vs zR`(ctOkMi+Dv!Cr=rG#tPMBRoUzC1D{ms%<;WkipjkWG-maG{g#1I3FooTVQGL5D~ z`qng8es9d)`9i2Cx_vnx@t6C313mPahE8jz{XhfR&u4>7&!dJ3PC*$u42h!EC|(`MeL7R5~8eq^l8MQ@Xo5 zJ)Q&ZwT`ux_0}w7Qi|c#;zj3^x>8!pcbq6cS8=xDY-L~V(UyMhN0*J?Y`sA;$LnFH z4_bSvgRK`Ux;ig9J=RvEyS>?Vu*^fQP>Z=tM}{+lDz{cz%;hB|Wu>JC)?lk*x4oPB zUdI>C?)C#s9o-Gxo*rtj{$%-S1If@3@wCBSWwe%(eA3tj==+_cGsLWkHF75F8;qf1 z{T@NRKu9PT7EcUi!?pHzJFZ@_UTVAS=t$~H@^0%)AMUI^O=|eHY5b;aKACJ_-K;yD z^Om<%P!*isU@s&GgpK0XS3GMvU)9y8)ah97owx4vd`$8^V_U@`@A!TYmv1qaQ5z`9 zVX0kWUro8H*N_xzW$Ezx%BJ#O`i6_2%U!+P-RCa*KP&-bKGd zpD_=a-zND4epvjW{?wxFo40Lvxn@ZX$=Dbsj5P<+Hil)wiz;0ief6I-UuYhFQ}5C{ zD>$7)XW7ftpJUE7opbgyb~bdA4UCI&hF|P>v;C@p6jXvm>?n8Y9pxk&Ky^`_G+Zs@ zW3wPEUiOWOcOObU3t_SA@T+5CCxsd3g}M8W@PP`_>TIB0VgK&D-Ffec3EM|g zNoTAi-<~bzr_N0k@-=Z;`(Df2Y9#G}W`5O9e#IcaoOA}>a9w9E?IHOkW4FX1mwdm7 zyHw5vRymzaA!{;esT5W;l!P~D4qA^e+>(3(Zeh=qDAt}7>AIN(cw-EnWv^o2je%LhC?{pc+Z^JCji!G!H1JvLPzW;r0^wa4}3z&C-UHpQ%Y=xcTfbMPjX;u n;qUJCd-gW43yC859D|Q1g?C@c?;gW{{G5o#2k^J7|2zE;bD$zv literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap14_font1.otf b/test/shaping/data/aots/fonts/cmap14_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..a8e941d8f9c7c21bb0508163a72947fb8acab58a GIT binary patch literal 5028 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 YEg8J!O8<=?IB_h*gMIj$)&HLU2lZ$qR{#J2 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap4_font4.otf b/test/shaping/data/aots/fonts/cmap4_font4.otf new file mode 100644 index 0000000000000000000000000000000000000000..450508e3b4a1a69b56083a83dd5d8a63c315e63f GIT binary patch literal 4972 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap6_font1.otf b/test/shaping/data/aots/fonts/cmap6_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..10b64a782b799c299e99edfc1048d5e594ad3169 GIT binary patch literal 4948 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap_composition_font1.otf b/test/shaping/data/aots/fonts/cmap_composition_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c79071739931fd3dbddb10e756809e25648d97f8 GIT binary patch literal 5096 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 N@o+!>e)fN-{{_K^KRW;b literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font1.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..8929f8ab238d765e5c42db8c8ece32eb89f247b9 GIT binary patch literal 6412 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 CcRxD- literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font2.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font2.otf new file mode 100644 index 0000000000000000000000000000000000000000..26110921f7f1ac42739adca4b0ad6973de56a865 GIT binary patch literal 6140 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font3.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font3.otf new file mode 100644 index 0000000000000000000000000000000000000000..9f39331557ccdb2c533c171140c21cfb52b0e1e5 GIT binary patch literal 5872 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 DHUvFA literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/cmap_subtableselection_font5.otf b/test/shaping/data/aots/fonts/cmap_subtableselection_font5.otf new file mode 100644 index 0000000000000000000000000000000000000000..8b614adeb6af16a928739e993e64c54e287d6737 GIT binary patch literal 5332 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f1.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c5f888822d8a92620d1c78fd8df435533d236a9d GIT binary patch literal 5136 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 H|1SRn)tov+ literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f2.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..905d0a398186941bfd2824689c5af9c331f5978b GIT binary patch literal 5136 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 MNBi)1wg0>P4~V-uL;wH) literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos1_1_simple_f4.otf b/test/shaping/data/aots/fonts/gpos1_1_simple_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..448bc8b83af8d3f98a20c224fc1586ab39852f70 GIT binary patch literal 5136 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_1_font6.otf b/test/shaping/data/aots/fonts/gpos2_1_font6.otf new file mode 100644 index 0000000000000000000000000000000000000000..cd4ea94c6e53f52176e5b1097cc4528985da82f0 GIT binary patch literal 5120 zcmds*iFXuLzJRL|NGb^e3XL;FLuXF}w72wv?3)NOtRXB4G+A!;ed{EhrI&P7b@i6c z-dRaNNx~i?%L@oZ0YPQJQJ7I=JdXJ0;X8^-b*w1wcLSa|Gw;m%176knZryvUzFSrI z{%&`}OnNkiQOfTi0!RNtSsn zewZMhj)C&-#4K$t5lrrYG7aVRsma=;)Z1$$P`(9aWhzvN^nniu;+d&Xj!4ZaEL~hU zuNle;D8HYjEzKp8)%B#Io2yYeXt@iO&`+9#jL3nzSZ%80PJ+fM#Y$o|zt$# zffoR{9Rj+9kON9U1Iz~&0ZV}uz$#!3@CRT6uo*}IwgYbfyMaU?1xN!jfgB(oC<01> za-b5x!)F3401MavC*TGeffk?*=mhox`+&EAe&7&r6c_~F22KORz&pT2;6309a1Hnf zxB>hLz{C9);12Lt;49!B@OR)_;5*<4;2|&yi~)~e7<~ZfUlN9!guW#w1JJMJbl_QF zCIDkXih*zd?w`y+5+p@3Bu5Gqhm=T#)JTJ*P$@-H8IsD8RDq;%NUB6q6_TovRD)y^ zBm+l=WO5`^AXyxeDUnQtWNIYSAh`s|rAQ7<%8^`wkUx1zrSjn5%&W01oe0fY$&V)>{C0T8xKtGHlZU9L9x!4#44S z1ZV(TZ5deqfhrmq$hvVnKmjDjK`@r`A4nF}x2sYzk z7YJLJ%H!eod)UJC9S^e@*uu0W;mJd)0GO`i5@02;23QZo1KWXJKoS7clFSAQ0GN)X z9xwnf4M`4g0WkeY56}g`v?Kd~!vIV-@)U3ufN4fv20j2_dXb+3p8+tf$ghF_0$@6k zKS=^5fs@67p*RV{NjOd-a1x1=D4ay&BnBt3fs;c6#W(>Y6dR$~2*pMyHbSuxij7cg zgkmEM8)4W8!$uf3!mtsBjWBG4VIvG1Vb}=AMmRRYu@R1qaBPHQBODvy*a*i)I5r}% z5rK^eY(!uq0vi$7h`>e!HX^VQfsIIPL}DWn8kMl3dBu@Q@nSZu^%BfobvvRAP5^2?hq^a_o= ze*EFyv5UPodsp}R|LZ>LANvCO1Mdd)PnvYsIq50*0h|tq;IT?_k)=9hdE1uPeH6xP)`~8$kDl?CA)Kk zdFI76!qhGymyg*+RUbKCcP!ZDwmTfNu3tLVXM4cC?HsZUnZDe{XUR_%G-q=;bycj< zVm6gC<#eTy;wNtt-Cx-!uodFUIog*6-+=^A)`jv@8Q-#e|KC4qu5V{r9UNzawS{SB z8o|(y38El=*=VeY6Ea*v2BZ${dAn_pen5Z7^g#F7f1bI0_RgAb7aq27w9R5`tMk;i zHr=|M@o@fe$!WpgAW5Wh3))i-*HPX%W4E9Oz8duxEuFjIr4=t^>`Y2xHrdLZrWVtu zN&F1Y_YKT0W*58raSw7QZLm@1@`eaG zqM*Ui86pn4gPm!znVhvDtt*#@UEXLF6-Oixrwd6UGzMuwG3FPc**E^i*~mx{aN>)(VfQ&fqZE?M_%-LthksN&n5gTtL zY)(o?e1lvj;|)fYeJpZjB>n|7P)%(hHNrY(!&H;p-AJf@6J5pDDA=uL153-)FR z?$73Yu&CT|pP^j!_?gnx)#359xmP<@o7Y;>4e^QkR|^-Mj_*utF5Pyd^i+*EdgSAIXkLxLxfrw}H_6mcgnBwEd z&OqO9ADt@VjGVz{w7kLU%hv7^RP%(GQeolap{%>q`fmHh3zl;&=N;|wo$Nq#&4zcx?HkHw3Hl5y{PYnp`Ma{2xR&~6ptxc@aa=ka+y3zeH z#dnWw76rZI{a#eM$xuSCqb2*Lc8Pr@?W$Zw(VT^2LTbw!N_&_qE`GM{;`y$w-uBks zOAls$GyBlq<{r=f?vF0yKTJ5Q>&SB#Hm&bloEopA@(fHtqn?3{MTREvz}RMb`RM*nRl2IrXkbY6d%J6i$2sHTd;NGmUS;zEvlkeE6WCRCV$4t za%@OJxhu7=_LIgljl*y1Tsmi&P3zE_ceAyp*i#LsoZa;ubzM{)>!O_@XWQRwy{M-I zrC=60N}W1KDaHBGopc8SPYe0jvk(?9dq+h(_a&W#u-LKx)v@5C!qn5k?A!yqzk;$j z>ljz?pPkn`j$iZaZ|vUN+52YRKw4F0b+w^duP-g!P;5@CNj0V#iaptl`tD_XP&yC9|*e^&zAVqZ?t z{zjXLGufGzs-_Z_qG>Bj&#JaqXjAog2QVRYh279t{ly}F`_&6~zu_bH@{|9-D{A)V zcj&s;ej)@{C~7FyY_^(%_b_z)2@A!yW{CKSvy+4zbyWJE*RnSoD7(LjU$LEEHpnlf zoc>o_m)Uc>D1On{HBrzx@6V!6rE{J|&Lq&tl0ccug=KX`A&qH+mIEyH!~G+!2Tz{d zVsq&00@+$W!j9NSY<;$VTi>wltaJFu@7p$Zd+k=new)5sew+HHi>IvjbR8xA4Yq#P zZnd-a+E#O2xg)ekc##gxqRPzXs_L06ZKXMy@@^jc8Tx6|N96RgXX?@{S(Xg0iq%qc z{f*U}-fgf6q!T}Q$tOR|Kbapg4?k^%Gqv@#R}CU&S^3iD4Y$rMfxnsPK zA!ybYcAA~#4`k0m|Rc@$31=*A~Usx*-*moM#Q5>a0I*z z1&okR_%mP<`6Kxw@iQSC-x83A9PAGC^Yxn;e059y Sk9K^=?~Q)u=S-Ktyn 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..600378243f7e08d2b9d1ddd182c5899d19e2c0f1 GIT binary patch literal 5220 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos2_1_lookupflag_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..9d0a273c0318bf44b520656a0e230b4efa84e440 GIT binary patch literal 5220 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 W_#$M+@3*}tt_=aX0$;-aclaOkCPF;` literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f2.otf b/test/shaping/data/aots/fonts/gpos2_1_next_glyph_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..3d8c37ae724e82e0cc025a6dc2b2a7868f803916 GIT binary patch literal 5176 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 SZ?^--#)g2I0&l_pcljR)vq3xn literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_1_simple_f1.otf b/test/shaping/data/aots/fonts/gpos2_1_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c947776aa88d97f9307d19278739369f8dc34ec6 GIT binary patch literal 5148 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_2_font1.otf b/test/shaping/data/aots/fonts/gpos2_2_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..dde370a0e3df8417c0fcda6c31bef8acb12d9dc2 GIT binary patch literal 5148 zcmds*iFXuLzJRL|NGb^eij6Y_LuXF}wD$$sHxXo5Ls%4OvfS(;``TH0Nmo@@Z|Uq! zHqxLZVGohz1q7mipfcbn%s9w+oY6NA-%&)WW5vV!-4NfLH}A~*176kn?pF2PuB!XH z)m61_^X7F#Fi}JJ6XInnSBfLIu(bq1^b^F?sMpr7+jKwg+q+P{32pi7HoYRtx{)wM z5YH}$`tGD`-CiP;+yQkj)Yqq_=#ta!u8~0f5!6*_&>+$WKO~6f=0H6vExWLEapAlc zsIQ0mhuON)y+krDPMZlyK#nduW%A|daHvN?{m$Opg2E@AgbeDVP#2TLgb4&W0g5Ev zJ-H}5yX+tJ)xIf&ubTAL`1xx5eZQF?JUhuhESR94SgqsPq(G~6X3+3VDs|$E1aaii zGm!chOu=c%vyc)SAPMw)j!6CWH~gV-A`l1!0U^LMz!czFU>YC-eglL8VE`OHfe$|x zcnO#bz$GE%fC|t8^MOUcQeXwJ3RnaD4%h%}1`>hoz+1p>APGnX(t#`>7sv;SfKs3W zr~>ftnE(sG0ye-2xPd0171#%K0{ejjz&k)6a0ECG3;^!}XMrK$J>W9%0dNht0ek}7 z0{#Hp0saKs1O5Vh4SWOq9rzCT9{3S>42%GHIG?~U`T=l#NeX~#OHKyhx{}WWF90(D z7!y(qL;`UBWG0dzDUu;MQXnN#AvMw_Ph7|CN z3ZzgXg$gOuNTERrEmBI5Qi_x^q?98i9FP(zRY<8uN)1wKkxGJ8Qlye0l^m%QNCn5M zLMk;8O!fgVb82ksyr}X=F$vM;ZmvD3L~mG;p>W zq|qX+1Zky6D??g2(khTviL@%DRU<824DGVqy=D37D6LQ&mlQ9SNhC7ylH}YyDdJ6K z1%)Zu1>)Cpl5+F+=H}}PQ<7g6FUiUhZ^XM7h&QGbq~sSvt8i46aE&)~oYk>7Y0Hz}) z(~#r<7XZ_b^Z;D|Ogpj{I10dYBhLWm0hngwRp284rWg4+@C5+Viu@b!9{@}z@+V2K zBzUqoI25!i^pMg%q@un~cc2y8@PBLW+d*oeeNBsLE}%P()aA+!v z@LLRAfq%w@fSVvDB*H%-%$11{(*Y3Y0T7dcFlQ<7DTs9n+9@L+Ju+9cWOuGG&%C%+ znA#=m<>PiyHOEfYp9poi?GDGRn^#Ws+8%Q6ItML-rmwc~+49o`Eje6neKl*em`xQ- z1zlyN_{rNu4_5XHY^Atrj_y^#zdzBFeW~J1=65XL_xDd)8rqpQ2gli9ZDm@RCNT7) zf+&PvHWDx5giM!^38_PO(QX@H`7AS^!Sb0kM|4(GD#hRZB_8&S^!1BA=)QX5y8W)x z{!-?SMM99!wb>xdXR?~IomtLWXI*36Q04pXA?^nEk^KgDtloMmt%(X}1i~bCFzv>6 z+ddB;&NpAW$p_u$C$Hio1W8h&en;Nc(j>iS>wuf$M@IWaA>a7!h+14N^{tMJ9{vrk zVIEgSSJ8UIPGPEEXQUX0V?&w1>`G_S5zCdjYnHRS?=2PxVTQJ3ae2(&bowHrsjRWs z#@HB+X{>Fc8*P-$#&V$^QyZ-P`hNWp)5Eea{{7tD^Y_+#xA3Tiqiq)3zIsnXTl1Z( znUCk6l$;d;4U!~kZ$W$N(R#`^XY>wSfv-mbMN8){cxA;)nLCq{nN79|r>WKSc``rU z^Ft%Ei`m8QetHGD(>7Qsm&?jIXAQW`7j-nn&@2<`;6rKtx7+z?jGcz#GrNoq1526B zw8b)uVevu<<)d>%4Xv)$h89oHvGe=7&s`t7HgxTs2u|>`2&BRwyim2Rlk$ZLxuTGP zk?A51E(bfqWHUMI!rE3YkGQ(?);2!l$~l2*D6tpNMODJ{ThoL|<`i~qUEblG?u=Yd z#)++;SwFDdbAI0SZ#OCLQR}&;QysT=59&^@{X~%GFFH^%`0i!%N8h*pQ1_61I*bAd zzwZ=?a*E}wR&GXq|IWPj6v{XI7o{k~7da9qLblY#G@~#lbCd95sxTu>n0`rE#)s>8 z$y1VN`Tsn2*18 zO7QDfFBB4liT&}1avnOqX)v|2tqqhfTDTwz`A^?t(TA!gnN#&0mJa*Ada94#Dzfb` z?8r#XPFGzw4%A%!l%M(gLO1O;*PCrwjx1X?#cvvQ!gx#>nIhWe+2Kue2@CdT3hpoF ze6*;-@qnRR4fvkY)z#tg>~pVntTwN;WEc{X^sg5#IGfO!)Ka?bSm~Ma)8(ftdTS0h z_t}1QS^15YYZQC54pwHrrH9_%a=yH?L%bEeUymI||} zw5X`0xLD8Wt(DxC_tQUU|I*pjwy&|htG>(AO%K!^FFmQJSOy}V(c3ExmST!e7(EBq ze*4H&5ohEKHlyV&R$sn$m!O^}#FYvQpAKdHmA3cWFJH1;XuarYPv}hWZs|xJ>Zm$N zY53JC{Dw?Ek*eq1oIA|sEp0BR%WY+Pdp^}KtQWPs=2_M8x~?v%R>yg7y>qMkQ;P2% z-7E@u&-a6*{8oogC;yUbPQEVt<#I`eL}?hJdT@r<*(p`*Tws%KraGwgi(+ijQil%NvK zB1fsS%uz~l0dyzb!NA=@KKcTL#jCy%(arS*t^_PCE19fS3F*@4p;Uh31)5mCs;z6TX7+q;MG}U~$h~Iww(*1AwsQvup-|>ptgZUk0 z-D^J+LMs)u6l*qH&7pf3I^mRs;@dJs{KVPGLartzW6v8on+=pb(8RCU&MzC_mr~Ba zYp$#8gKNco@P3w` zOuS#u(;Wn|P#_uwKSxD(eqC(^GF!Kwv{1ekzxY8o&{k1M$k?;YPGUWL(}2$fgdaTB zkOT#}0&+iiAs0i6TmO4`qIt3pT1a@ApEkA+NjwKDIkrMxm{L#(Jv@C%BC~XbIZ(q- zO~jKYun%7Rf`&;ad?=ViJ|Z6xKNGUCoPaWvU~_PQf55~LKfhm}wZ$F@N-))O3gB(?JFt|{|>f|nt9n)~PF$>X45DivD&p^v8vIKLhzIftAB zWoY>y3-pAy{C`;SdBKZb^4R$Wz^54)feAry#`vxGY1xmM47I0ae<;O`mnT4Z>3De} zjMbatWoih5_&q^Pjas#Q#Y!TAmYlvU|a zAvOd*g7Ow9N2TW!l`bxt-wfqaD8HAZE8Rz=Y=G>v<&XsA>T*&i4@E~o`Bf<2-IrHb z^rVB35yW(;BP1eX!URGz0kR@|cuH|jj{YCzHNGi?uS(>r_VZQy`+hS)czTk5STI38 zvDwBqlLBqFSwTay$h3*i5yY_{pMuoCa0*WMKMg6d5t2Z^XNa_4&*2Z16M;Y=2nYe5 z0;T{@1JG5382Akk3WNdS0KVK<;CWyk09``J0TrMH766NYrN9bcHLw==9k3C=-IWCF z0A2_70LefakOAQC&jSj8VgPq%IZz4U;WPtQfB`tb3AlkqpanPpbN~l|L%^FrFK`Sv z3G@SR0q221;BDY4@Gfuzz{C9^a2xm|a2NOtxDWgn@D=bi@HgOF;5*<4;4v@^i~vty z82td~Ul9pF--;#!(66HDz_Y+i0LDZl0U`moe^C~aq68#Ea-={?q(W+>L0Xgml?f<8 zh7#l`L4gvKC_#l1)F?rN60}GrMKW+?NG3-z1(GR|Ooe1>B-0?77RjYZo`B@gq#Vf= zNUlV36_TrwT!Z9Vq>v&-0#eA30?w#F3MEpgkV1_V8l=!7r4%U>kWz+}a-@U{QX-`a zDb+}+K}s!BNs%f6sbokcM=AwU!S$+;N{v(+q|zd_6sZ%CT87keq*frc5~<;K)JUyC zYAw=8ktP9YWJn`N8U@lQkw%3yaJL$y(ITxBX%moEhO}~|RUoYrX;nz8Mq20$?XtXm z`hpCUUL=W2j+e-!Qki5)O5Wa7$!2|FQEE=1#YDhEk?sR6}FiG4&x#~58&`M0Th74whm|laJY5>hXEX>Cx9~m4$n)#5P-w-1Ke!HX^VQfsF`kL|`KV8xh!uz(xc%BC!#P zjYw=nVj~h8k=TgDMkF>Ou@Q-lC~QPwBMKW)*oeYL6gHx;5rvH?Y(!xr8XM8rh{i@V zHlnc+jg4q*L}Mcw8`0Q^!A1-=Vz3c|jTmgiU?T<_G1!Q~MhrG$u@Q@nSZu^%BNiL6 z*oehOEH+}X5sQsDY{X$B4jXaUh{Hx4HsY`mhmAOF#9<>I8}ZnP$3{Fh;;|8rjd*Ot zVr!6zZsNvJ1HeDv@<@sd4x!hFl(8ewXuu#b=1O;(>cU3V(f<+eK3as)u{T zzU3US4w%2(&gaO_7B=Uyd39Bc$!al|)8$m9iR3457e8FtBQO<`%DK9i1pmGyPtKL{ zb6MXqeDB{rY_4ykTOBOR!P-JM(~V#lMg(yPzic>O%nDg9Aq!H6?y{ZhXZUOjpULo9 z)yH%;a~jFt`z0QZjP&)1-|f17>Zbjk)Bb$c&P76y(7DAZETFR+bDY`E8fR@o?O??_ z?m_kz`@a1ad!o*ECcTjirv<_+anNn1Htv9j59gb%e8dOc;U}-=BLr!3l3{25w$fyS zXIsCULdCbPbwgrhl{r5kD*sRoYZIED@Nm|J1(GxQmbnIGvt z|L+U;F5X}J?aRllEX7&519hJI)~37HvmP%vEj=#;8l}nPzQVS&<8`EO?#Nx}fv<)G z#Y^Wcd~wC|S-VnF=*?WY)7)bIG=-nx`M!bPP48y*jP)RUmV=daxooU+cE8(lSx1pH z#n7P+K9u5ryMv!b+bOs{i_7FNGNi>qS*^2a1}~&gHZoUS-{NYiZ}xPbxOkxJ!p*@O zgE!ucUPaM)eJVVSvcQ7-}oY`3$*1B?e#PwabxAU3TE(m1( zetRKRTq#W7mM%=Pq%!Mj^N;3sW#)M@Pi_0e_AYnd`Dy3xKO()yZ5JBPwBOk?pgX(n zLqT4!=+ORwx2{^=|E}fx+DFXTFbX0#zf&N}NQSl9*qH@=yYkyoN#C4bl;RLy;Ougf$A_b2yBEB@l$KO69`1Pq@77~Steep+fA346RH@7e?^`tLaxFinw zyYI31y_OplH)*o#Aj@^lF3c=VElyPl@h=PUrNR#9h?9-(_-} z>uYrt+4&`#vNioe*jE`|V|V#s_Ai{J_7CUCYo}`YiKchx?#eD>m#IVFTH!I*868Hu z-3hB};ER$kslQk{%G?I3roP%;$&ytggcxFgu`^B9W~SbBNZ*|5%Il8WGf$Z0iELfU zOFp~b)7M3xscW~k+Yi){z5F&Yx6`;YGc6}Wb<@;eef490)*p)8l-p8g;j$gsTn@=^ z9&y5WOc|ac-tO7yO>zkf4`vDO&*#3ssNC_8CSCRTnbO(W?(rOOuW_ugtg~hs6O#?E z6fHcT*pb{^y8T4yxw5lmXUlu4k2dvkKe%lCChHB7IbI7ZebCxX9c;c>*3o{^>9IB& z-K~wbgZn+?GPRh?aHKoasZwjX#avokyuYNxz#427?ACWO-fjEB+1Yxap{=v7)6+%u z*PbjrZ6FyMBAzzbD~#3>l207D0DZq>c&eB+u}02heVs9st=lcA=L>PA!pmbrS$D1V zowlo2te09YJK7RE61`j7(+1lsPm>ycO)9@Ji%%l!SU2kq7u?p-(A$Sp=WV=qMpn* z(uIu%8Wx5k`-LOoKXb>M?x0UnJ7f!9TeWusz0~3!uy@dJ(`U>B=C?>bjvo|%pg*;6 z+orASU#ePEMKU&q31!WJw2fhzu)=azdQa^qjTagR-_X1C&N5Et&{_5{wda^~4dn7BBgR#k&rroQ1I1 zdH9u)(38T{^TM2cNBBSmX?51ouFyX@KWaaH%X7G~>tKiXjr_ihs>JOdG^pYQs42wfP@I4f}>)HCy zTw!**@LZc9A?ZL@64PQ|PEvs;&di$abW2s!euktd8$->mwpuB3^=JpsVN`|P*jW9= zB7VosD-XWmqYmHRN@&c$+u>S`H6EgJ0IqFD0FUH(b}5OS?&a(a0@v$R*#;;trK_zEw^qQOKG^TFQlG zb;V(g8U5BH4Ee*u6Rt<&Pi~1N{53(;T0g`L*@w6uu9xc>>@T0!H}B(d+GYGBk?mK z8{HC+haBt<4)70{7~<#m>pR$}gp(!9m#!cd6HABrith_P08>WqF980s zff1Mx1b2+ThR5=L#AGOq<^3TSH=dsW`K9Cei7-~LjpqZPejkB=JfaZ(@7g^|8kBP3 z+gL_yB2r;*G5qbLgTH+K{c-<(&sJ!m0NTzNZ8HJB)TRGVJN~2hMnL?-7x4dG{udiz BIz|8h literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_2_font3.otf b/test/shaping/data/aots/fonts/gpos2_2_font3.otf new file mode 100644 index 0000000000000000000000000000000000000000..b5306764d14cb73a6fe4608af8598ab6cc0d2dfe GIT binary patch literal 5188 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_2_font4.otf b/test/shaping/data/aots/fonts/gpos2_2_font4.otf new file mode 100644 index 0000000000000000000000000000000000000000..b549e0239817bf90da6bb27b18f38b78408134ac GIT binary patch literal 5148 zcmds*iFedSo`5AAY}qD2jwUmhnD%W4NcwUg1j0=SgyA&iNPxyi`M$5V-9GwoOKSDy z_T4^lLxOE?<8Z7YfWr|;!ayd0oeW{~GLy_K*_RN4?8tfSuZ)>_JNst;fR)}?sw(NL zma2ZGmb7m3=5<6MQBC*~;$_CH3UKQ6U6k0H`cG)bT9X>3m|_3>hjlZdR3Nr zJ${HFo?Q;*-HBP+Tq2m<0c9_g*QX|HlTz=jkwEz&l$EJaA<_pvAc*JYLOCKetFUx& z;rwPOuZQwSS=!QEA_-@op9P6uwl*ty>ZQn+p&S9_+qpRfg^xQ48I;GMEGCIblL&GW zWJ!E@Qc+fx?jPmVBh!eHDsrUSXQbM9C#oub36)-%DN}2o; zK^%Jc45YpV({NhyETqH+Nc?@CBT}CJhA&i32K<2lAP9H{m02f#((5^xo` z4txsS1pWZr2L1@#1^xs02KW~E8}L2w1Mm~@2p9$Ma6X1%^Z}rMNeY0zC8q+=ujC8B zi@;0(#)K3D;Q(AenSmroieyNR6etcUkqW7i21%h(ilj0ml_RMFN#l@IiKHqdRU@ee z$s|Yyjtt4Qp=HAfz)wG ztwd_LS~XH@kVb+uQlya~jT~tdNE3%NN~BRC4RnTPSx&AlKMkc8ienOE#WIORCSH=1 zvnN@+Nmo#qoK+xxGdnRSKQ|{|TbP{mig-z8rg$ShygEH*$hNr-E0Eayc4>23S;T{XT0^l%L0}BBh-fsYJ0XVF;0C2Y$59egqrUN*P3jrN~ z!`BGV01n$apb5a?+70XnaF`weP5?MO&jG^#4$Dt~TL2EnKLK9@I1KLtKLR-X1PCG6 zjE7wyY+)*ohud#q3)6Qz%wk{*)0Tug52*rRx{^zPmB1QcJrECU2X+BT08C3V8z=x^ zI+A+80KhaPIlu+L^dmh$7XZ_a>;(=3Fx|*gz*zvM8F>Zx7=Y?ANf=JTaT0-(NSs9BBpN3%IEf9M8X73Z2^gW+2*pMyHbSuxij7cg zgkmEU8)4W8!$uf3!mtsBjWBG4VIvG1Vb}=6MmRRYu@R1qaBPHQBODvy*a*i)I5xtu z5rK^eY(!uq0vi$7h`>e!HX^VQfsF`kL}DWn8kMl3dBu@Q@nSZu^%BNiL^-qA>}VDa+Hn=g2U zMz0@#*gJO7d&|4p>;KRDsDJDW=nK3T)Hh|yJ?E5X;1BQxKm@l{V#D*qbCd970BQi3 zTjUJjAVK&n1}?)t_i5a)gnlm0MgDex(XbqeY!BOf_BPqbur zjxgW6xJH=XCFJrkyQu0T$Lo#-yWDn%WA=^9$9ioKxc8ldmO<0k+xRT`$%5u=E~l=F zHCoK3a;BWFG*bN3ZKC@tdj+;aTsc?!n&8`?;K{mBek$X8mhb!9r_J^4Osj+AY_PU4 z%}gU0`Y}Ni#4j6-6>&m_OUQuKp*?T64X}KsnNMf=jOs&Lt0{%z@BA7IM~08|i!OCv zId;u{$7z2#W5*&PK{6_%K0|n4sU0x3x4;@7X%wrufmZeo@f3BezA(uI9QH z$9WI`7FR!?tE4MwyzGx3n+a_v>i>D_l13xqIJQ?j@$>MvS- zkzLN21!EwoH!QUWBq;d<|Qx4ZrBXh@YLl1m2>MvS4Z{e#eUe4H=l*DYZl{-x> zrZ1BC8J-^-m|e^+cK4GWppXB=<3kb_rf^A$0CplgYaVIwoYm! zM92{Z4UEnZanK#?Oq0#ztPN>hxjgL3&YRo#^vh=is=mZtKo?aCFKkT}rkIo2wY7N% zv%AxCJn6@_er~;FyX*X->)&or-ow^2jVC&8?H<&gT>GgY&tJ5!Wbplq=8u19`LXr^ z`(zje5`Nz)5M>n0S*_g6{QjMJ?a9>0oL}QaK_lU#F(PD3X-G8+b2ByxFQo`GQ-v89 zgk^lFmY2N42lK8q{IsMy8T9;?JSWl@)S!wSU0z%@cx8zv^`%UYOh;dm#IPu3)@mpjYJCPL_z;G@<{Yi%hif&4As4tvvtod zNH0w;N>&Q7uM4rI!V*Wyprz?x2e0`9A9pUa`A9ikN!XgLz&;+Zrl;P+_tK9 zMcG8~jVOP86-N2Qs9Gd%3X3+yv4u5x^+ol??!x90m(gviuhmv$<`r+uR1XLt-=ujB zJ>~nkKikZ;zduD?K32<5Hh#$TRCXJ>jh(vI3XiGI;4s+jPFP)oUlo5%|JmGG=GN0S z_0{f5j;b0XL=Xe4oo%u-v-QS(y5?k8PEW+{dBPM=cwt04V6I{Z= zy%~c0%efyfDtFvxC|5ncr*w67csySHVXzca zeEirM==<%X(?y(-GuVulcUXPd+FgQbz7SI?y#8b;>n^u`*naVXFxPczp!4^{Dx;$$D7*P#2PKzF=h!Zu@9Ofl zw|Xx>nDgD7LwlQhJo~#py^#MX;jFGB&t2HGzISnIypGB>z??7*n%<}Q7=B3fiSF3KtsA$jd#!3w6~$UvHkdQ{ zGgg*kLkh}WslBzIH=b!6dROPtIm>KXht|BCtv$t_YB=TWuJ5SpqUu-|?F>2F{%-3< zJtZgwv&d2E)HzBi&X4Y-I~cfI$j4rUuy}1`RJ3zn(n$!59sA!L3qC4LKP}A3J;3`b zD2ua>aRvXo^G3(<>z@6M-FrK|@8;pC(!veJ=CqnrW2&LplijHAUd9Kt z^G6@vr#jkutv&9eMMq#gs@r!m-AjEoHYy7GWaPfcUC-4AXA84CgqPX{F~#`164(~| za*Fmh+Dx3u&a_lDm9P{|TUmN`wZ%f4s>eHk385?OhQ{iz7V+D!UAXrhAF-F8`a51x zvp>H>*S+?0A-FbowUvVN=UDCujk z^|5xVowe7tn(N9Pp*_MYbZ8b;W;Rz<&tz#U&C%4z=CNO(pGJK|PCt95F3pl<$>6G3 zEj7>ISk39(2Ae=S@r{?9_+$Rr{D^tS0AiMvFKu34!wzzTwn55vqGNzN z#`{=)Ht{|^PYw{sLV;)yd>rN7`L#9W$ZXwy+(M14_|*r(fwqc*g2ta^b`tC1n+AL? zAbjAdh9oH1Dq!maFXUoKaqZui$8C?>poS!#gB2h1G)Io-$in1;LTKU1Qxch}EzE`z zerh5fKZYal;uA1TI^jdX6!IbYkobj=jc*CaLk@Na`uX}z4)XDN`m8lB;bh73r7MWV z#1dkCz%UfA;Pl=i@-ehb1PnuI39NYWA$-SwO9ESXYaw1Bri|Cm8c!$A4f2TqzHTvW z@zvw&NyM!Y(CGL+NXA=&GY_A%;_F@07W@n^L+~{B&&%US0mD=Z)cQgjPZn^Vo+mk% zoC|rV`5z0kg!lY^Sn+kii(bJ+Y@;|sLv%3kV6!}cdcFHq(CVf-hmawMj{#Z7QyEoEqvPf*T?g literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos2_2_font5.otf b/test/shaping/data/aots/fonts/gpos2_2_font5.otf new file mode 100644 index 0000000000000000000000000000000000000000..64c40bba952a4dbe36c4b0fd18ff43369efa908e GIT binary patch literal 5140 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 BI7a{g literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos3_font3.otf b/test/shaping/data/aots/fonts/gpos3_font3.otf new file mode 100644 index 0000000000000000000000000000000000000000..7522660d9f3cd19bab83aedcfc524ffd3d3750ab GIT binary patch literal 5164 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 E2R>^#MF0Q* literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos4_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos4_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..b141116af150b28f7ee6566515e8a4c3cf06eb6f GIT binary patch literal 5256 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 T?=!u}`+|6K5dXjXztjH!WiCfJ literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos4_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos4_lookupflag_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..84e48437c7cf066fe975dd53550f344debc262f9 GIT binary patch literal 5240 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 P-WSA^1NeX4|DFC9dtXL5 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos4_multiple_anchors_1.otf b/test/shaping/data/aots/fonts/gpos4_multiple_anchors_1.otf new file mode 100644 index 0000000000000000000000000000000000000000..025f69b3188611c61eb280c7bbee28a555dd0b4a GIT binary patch literal 5352 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos4_simple_1.otf b/test/shaping/data/aots/fonts/gpos4_simple_1.otf new file mode 100644 index 0000000000000000000000000000000000000000..da54a1fd11d892b858b43361e934a964d5919ae9 GIT binary patch literal 5200 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

;X~$7?xx%PzboW$ZJ4kz(A zNeG%85fqLSFe0!KfsF`kL|`KV8xh!uz(xc%BC!#PjYw=nVj~h8k=TgDMkF>Ou@Q-l zC~QPwBMKW)*oeYL6gHx;5rvH?Y(!xr8XM8rh{i@VHlnc+jg4q*L}Mcw8`0Q^!A1-= zVz3c|jTmgiU?T<_G1!Q~MhrG$u@Q@nSZu^%BNiL6*oehOEH+}X5sQsDY{X$B4jXaU zh{Hx4HsY`mhmAOF#9<>I8}ZnP$3{Fh;;|8rjd*OtV&7%odcEu(-%AV9ND?T=3FkXu8K8U%%*atoUSxd{Nx>?hpT!7wj#W8uJ$Ftw=c<) zbG7_@*0(I*`?n98>)V)C2gli9Zeg04MlkfFf+(0@K9V5fge;ek1*t=O#cu0o`D`}dK8txOl({KY0xwDTtGk^tbWJn1-50y1_=-Y%CY*F}1?nr|;7r zH$BpQ_ScK|F5O@E?V=MFj<#8B2kSibtxcca$a=isjQD~OU=Sx$`wQFBPSjDub4Ndg z9{6%3K(uV$!WUOQpS3$Bh1p^&cbZyEpQP|JJ>NGldzd}!-tivf&e>q5TrMl;oZas> zU(wPOL$ge%gAb+o-|pn6Gj>YF{?CodiB zx_E2w=HSgYB00gwB9L-}@J!{74r(||$P)$kkIWQt&>ie7lg;F;4QpMsBJ#%WJ3IKy z>lX#8{(!xZF0K@2Y)=#5wfK@oIE?1~aR!l>x-5T9`8tl-n9S|lV2lll^l=00+KU2ke(Tk5Id z7~!%g_`il9i{5RyS#gV@x(;!+uGxi|rK!cKN+Ds9kWeZtb)*egnvS*enm_U}_xZ?U zL*5(LPIPwbk7hBH`PH4qU7;&%Yg$*9O$6Vt@|PFkDxV!ui)2laaV7;@RFhv{TwmfY zYChmHx=r=9+KTM_lFixbej)7346mWP{0R3Ko4NK6=c((bYxzmWx0&wBE<=~GL)Tj2 zG1VCy2D{w}vuoh-J|EKo@}BBrO}(}sTvmRw8%yqwzo6hY5UyS*?O>{ zt+TGv(?$2!o+>?~r&tCep3&PY43-j#PaM4neZO;Ls)#dk2Ak3H8mli`zeiBb7vf8W zMdO#U?t1InZP%_^F1K89v?X>VdbhQw4YpUFq161^RDM$ypG4JhZq6NM^OiQ1(PcKB z-d;fU2^&Stt37MlU)I(p*JwHKoj2}ueMIqHqgzG6Zw-GhD&1l@KyRSMMZp7JQ`o3yU}9;iUpOlIv+YFFUG#BkhjhWKtM_eWmYLlH_73JP=B#PJ^d`l} z^Mj)Ib*C3@-@I+ZOI3@jDAvldp`0mzv9cT+R#@&z@2UN`@nYlP>pGXtS!UBZwC25R z?RoZm!+B>{eS2LeRmZw$XV|5-*ITdYDM2ZiMUGOZ&QVHn{&WZ3&cNM5Hu?;N#Y@8@ zqTPp6&Ouo0I`Z;p=qX|91!2zqqkMpzvN-D)SLlB@KWsm9+jFF`>rjXH_58k!s>eEj z38O3QhQ{j87xO!BU48HkAAN|Q{5xJ=bEKeM*R}p*A+$nXL$PMF)f~Eyp%c$qD84mI z#7~-&BIK!KGxxocyVXG115EtNo&55Cei`KqxaqpVUfx6Ti$`yZf-evMEb34?=UZe< z5{)cLl(}43URNB}n9*-J%2Gc(Jn4Egapw*k`d;}x>YGlUvVN^=KhWD?>t*d$J8Q3PHP@9pBD#ea=!hJu%xtczp2gBu znxm=Vt)o9fKaKc^oc{J~U4|vclEqcAT54W^v6|Dn4K{&v;u|kH@nHVR{Fr(CNh|E> zU{70BKVp`bFKb>=!wzr*wgJj^w!NP_&HGq>GVwm$;~NNMkw7#EK92IPg4&vLWVY@+ zW1)su{^A4SKwCw@!DH_-A@DAPCm+HOKGUZ`-P17pz~}mO!k3r2W${_s9=8+hqAc9gRrN5Zd!|GPz>z#-BJ#~wod zNd8FtOi0I;1mqzHryu0+>pv;j$LH5~ys?A8$I!>4U}O6F5>L za0p6EVaAisL{Euf313UlbK`yc?AY3gbA@~|fR8^MmblkQAQ`ttK%-;pAc5L3E>~VI z-7{suPw){2Z;}5xJ$W2BM5RHkFSIc}f%ofil5@$qkjE|k^8_v7HUA%Gd|L2~~gvJ@7A$vLk+FN=-kbMzk2ulcy0!@~ieNV{NS$auVRabB6 z>`gWjP?E5R$T9(e$Rel=I4YxqjK@*O!FLpu>R9pcz8m71^XAR_2VT|reRc1x`c>Dh z`fhbqt>3(PJrPLM5Z;7j*~*on5nI?=f*}4#5K|*pEnl&cc%9e`<@?YkUKPK7)8DRq zD-gsq3hJrrH@zs!x|uKx^*pHWPRiEi5y9jRsNaHmd|HY&IqmLR2|+v^3Uy@~G>CKo z523yl>XB*LMWu_2=C?q-66)_}YfJNpbUV*UT$I0<4!_G z5Ho%U^-z-V@gYbbD3W;d zpT+X5|H!jc>ZIog;>b@=LG&)1g5%z45Qz;C{JfqfQh)mmZ)ltZ_yPVvAn+701(*g* z2SflqykH;%2m>O47~pwe9ss9=kON9U11ta*0ZV}u0Pg-;;19qC04@QM2y6#l2X+HV zKq`<9WC6KA0Z%dLm1K>9BXW$dyQ{W!(H{eU)Yv5bpJK%fZN8k}K3XB1d;WBywaDGV& zfOAVu2H?DsGk|A+SpZxUG8Bjap#Nkhk{~IPAvsc@IHW`>q(&Mfg+?io%8*o!qzWXB zLsBJ@s*qHTq#7iXAQ?C^B$FeV0?Fc#Oo?PFBvT`q2FWEzE=6+Kr5wo>NFImeN+eey zxf;neNFhNADN@Lg0)A0}6mdwQL<$vBsF6a0;v^_eisED_PLAT>fZ|Y`62+-doEpVx zkWzw_Qlyk2r5q_0ND0TQL`oG>s*zHIR1&0;B9#oOJTjZ_+>mLRnh zsbxqlM`{I9$04;6siC)Oq}Cvf1Zkv5BSRWF(kPH74r!D~qe2=u8JcCed1VFZD6J?| zoD>@>lSpKtOOkWieFSkHjl#={H=#s3g(2aQW!qAN=g((Fk z(D-C<5hO|PA(DR^4!&^N@DP{^;IxO!L(B$ny2k=9065Lnz(N40_bT930H^g90PYs! z>6`+~3;?Hb5l{x;^fdr9fYY`fXa;b)b^`|ioTkTsQvgoS3&03~)AD`b4uI3~ufP`o zPQwSl4**U-0a6GS<7pQFOBl-I>GpeA!tfnWGchb-*phJPAyohjS8@rk5?Bkw0|~%( zU>A@Kz_289fIyKHw+-!;L%xoCjc-k=KCt02p56 z$G~R*3@h?0;GX~tC-P@WfFxjYXh0Ya;W$L#5Q#$+4$(No;2_2!HehmCKqwAigkd8L z8)4W8!$uf3!mtsBjWBG4Vf9HX^YRiH%5XL}DWn8<&XA`UGBZpyQbIg-`7$9TIb&%a6hm=DCoW;=qdOEoB@d7wn}W6 zPCV^{2Ln(Gz}O;Z0*490YcX&Y{uy5eTm<2h2>*mIRwhAC`$C@kLQeX@n5Dp{AlE5q zrwn}5=seMq-MPYi)8blTYL}45i+52q$4=It2zI(`cKhsGS5Nd=A98OwhRj38FSha7 z^3#PaIb3diHES@Nj1^1;U1gy7$=gH^R`v;OWoXr0?Ms69K%zVQQpK6f?^wS7+YeeA z+L<;x$5~-+Wm=dfFmz*rD3D(^8Y|+2Os9|u(XPE{vktO+mWj_``OKOlT8lB2;_v<% z3tL8b21Hl7ubsGIyX&w$pSfd^;4gG-)(Z=mtfp*7mZR2D*H|}P`HpLtyUD$0yU87^ zx136AqQV$~FoxQhc0;>$pPLWkn=jqs{qOLTSM%Y5Bq>q1BY$gYlFq$#&_(g1V*{eV zuRWiLTAVHQt@ev<{#CAFK37Fo(K`K3VX97RpcsZ@gBic=QTxUyk~Tmd;!F;)>@p zcP1w@o2(TMW2^DwWPYamhel=>vy0vRw525T;V$Upn1A{Xs4)tjtY_AF~Q#cvvO!1b6i zIz_b2y`wkLDJ!y~eMAmeBnj?)aHCLF7rNza2OG2hnC&Q?GT2=StpRqoXt zuW0L%YPDSN?Kf|Ce@OA&W1B^RZ+m_am2T4SrPtGvgHoHswvu*Mt)^(s%rPN#6^*4m z%ylO}$9nl=w$gE^xgV_`Wqq_D!7)>rpY)48VMH_Du4j&iHkt~Kpu>&~!e8qYYo8#?N{ zsCw2(J3`L4ztMJCM+r*7B(j$}%Iu{S=Sz3e9SqzpYbX$H7;| zf{zPR&kA$$4)J~p%Iv6ToWXx_-0C=a(|xe1dw*x|8~Fq2)m1e$`Wl_Cv}i+#DZMt$ zkftwj=QQcMm+^t^{PCY2P#x`kmLAvf;$tu$FFSBLqnG+{Y*ZBZzUP6+)xb3b=LoYq zgy-6YP>S($CbF%zK+8zKGv` zvO5`rrgwG?YISxmuu7&_sUnc~|rMf{{W$wIC=I%ChP zIh*yA&CkfM*v>B-kq)ZjUvijnX zru0GcA(r~_!7=BU=7Jx?|e$RdGg6uj&e-34{E706`Se$q^NR{ZJ(=|EdV zfq~=CGC}YxgC{S-2VT>sLEFnf(#F<3U zcsofX!%H)MKJtZljra;8-W!h739=}qun4RtPf%o*wkQW`_=$>m{1~>tlb8Pp>41+2 zLF7;5PsA^TYHYik_>unzl?tuiu#YDbIKLeyIhULZWoY>y6YL4E`TsEEe!)v% z@_7Gz;j<0olaD|27@nRd%3j1|s6A=-hEn82*$2w=C(4uHTE$P4eW5*>KtvwA5f{RT zqFwN@Czr^9cVj8Bkw}3x#qilj3!i-c^EUsvbqkmUu)p;2eM#XBUGjhU-s62C9`D27 I+y3|T-#KA7NB{r; literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos7_1_font1.otf b/test/shaping/data/aots/fonts/gpos7_1_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..ced8907e90f9f8f3cb316a802a31a0417f3f6a65 GIT binary patch literal 5160 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos9_font1.otf b/test/shaping/data/aots/fonts/gpos9_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..e99c25a04898254347767ad136d08fec412def8c GIT binary patch literal 5096 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 U$^YT|k6#P%ct8G^_P?k92JhW7O8@`> literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..44c4117a0d317c607a696480f23f61f6966f86a3 GIT binary patch literal 5496 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..431b08fed7732e3fd60555e2a6b5c1336d9ad097 GIT binary patch literal 5500 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f3.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f3.otf new file mode 100644 index 0000000000000000000000000000000000000000..1bac49ab9b5d764028dc703857c196ba8ec4fe10 GIT binary patch literal 5496 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f4.otf b/test/shaping/data/aots/fonts/gpos_chaining1_boundary_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..3d377829c090147b03a75049cab0083586a3671d GIT binary patch literal 5496 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 j%_iJ64y2q8|P} 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Ⓢ@ zToU~klX-WwrMO{_Q*a6np`o&oZ*X!>r|1arSz3|$&Hd&>mYc<&|JRwTXRkf;?c;}S z4&G^V?yvRLw>EutDf8B&$5p50z$#TTx2vEn?QktOvS92pjKEi;fy$*1KKAg62Qs&& zqzLPrr5;O*<1Jo5(XtZ$fjPT)l$#4UyJ(!HCd zy9F1I`?Gqh-BluIwemLGJVB%zCzp&ZP}aA2Tk4yA-AB&u?>h6&(B+}aFNZs1g-vF) zRq{RMn>x6WxpJ;Dcwlt4(t+U+=UAK;PtDxcmCM5~ZT)bQwDaN_nXBLHD&TjQ%d;&U~5ujX{^%=PU&w(%4DTh42qPdk720oQZbex~t6`$yXcO(&mwU)JO=dU5aI zYZt8Ve%JDS%}sG)8f6yO_sC2MCpzqQ$DI8Bt$A&!+{pZ&6O_Rt5u>q6;!JBuua*~N zu9NRiljo$%v(L-Rq%f1DdO-@2yw6B8Qm$t53tRF$#9UBG%5sbI^4h<9TbeBev~hi& z-s--|OL4MK9#fthmf}7WF^a&Ef6uD7&^E%n?;lzdJZ{I`)?%C}oC zm%Sr!T?ZV_u6YGJi&A%|>g2e`<+vhwi92o3*7Rz-Wc-5^bxjI?b-3r!g~OfQ=2tQW z&ief3>MbG5olmx|D4BG=5#7%ZW0p^h8kCx*@EA*iSXh}?zq@`sam&=3X z9sFX?m;9ft9VK;UzOufeuH3=x8)KC40nsHk*_y@r>KBWfQ@y#}k=q}Xr}-jUmr9|3 zyw=;_C7h^jx3#Dgafv2{y_8Dl8*MX9-pnb zs;;%seqgVUTc%e!Gu-K(biT+|YPA&Y-o1Cv9<#%2FLP{oGvlqcFFc*C`y1LiYdd{i z{6NjoqT^;x6yWiK*;Q6$+rvqTV`nh-n@49V9o3F1XSMAG(OmM}Hd((=jxCZOpP0(p zi>+_AT{v$$*YbwDEwLl9XG441P<#1t&LBOVDy_+slDJw&ouh89v!|%3gfDRxn_c-_ zzr0%6{Dkkx_NPoW$(1HY&xbF6*!3|db&ai82ERV?y|QRs)n0xTuR0j-Qn^<0-ts3o z-eGeHb8AW)in@i%UTMDb!W*5PJ#DQ$7jMr0X8xfA&E39(UGJaIzm;^hxIM3~uxWMg z;`GE~F0V=`XfzAhM4lUvUs3+adAR8#@=0ok`qAf~*s)qzYONb|bqKEuCoF@O*ElIw z8dAPjeC)A}Yd5TVWZ$BFoM;!t5QimDu!|0HZb7Lxy|?C*#xspWFBN->Jta<)+hpA? z)|?VgHJtKv)wkDna!5i`)o)6lOU-2Dm>^jiV^HN@a#=i23 zimD2;xu|f>9&1KrdUbl$9$!wQxoepe+$J6U@dnr4)@$#sJG%P_($V4-3TU^UIKCs$paadeJ%f6<)BFFP~k)Ky#v+Z%Nt@p}fBhRN@_;n`x01H){q?npLoK? zNv)YmY0CT*IoA-qbH}qe>#I0dpha4-Sz0zAE#*9cm%W$7bK5v+(byGb@VSw{D?4=?QRU6=&G8ZJCaJqKSJju)4xwuB&p&tcN~$*~u64Pu5$) ztxsEVrTx8a`v!=xtaNGf@=9^gG3XrRoG01`9LFSu?I(+*=$<%1W(#GeK~}g+yYg!) zONrIK`M8Z6S@E+1?!eoX!NKF-GSl!aLpKF8i&>4tV)d~Gb}bUitV3e4#9j}Zh@`-} zWCLsxl7iWYq+m87DX{$B%=lr&vIX{eBtI<1Ux3|;Z_?06lu z%JCfS8Eu1d*LV$!wpp|=3znXx_{Vkr@8k3u6MEVPRRzH+(E`1LdvRAG%ze!L3|p95 zP&j$l=u?)dFb5_2&B)xo4HfQW>M-j;AE&WDvOh9^XVl|+26^OgI4Hm`U`nt;@ymB6 zm5y&qmM>kwEM}H4tEUd5;u5vj7qPd|E;Dr)r6ovoQ(&y=l~mYc#fJNwnBV*8L2MI! znfO71UqnnO>inT%K{9QPL8FuB{o`zB&gs8xoAKyRSP0@v_TRVLx26trX{hxZA4z%` zSNY{W*#+zZ4=#OCTASN#G@`7KeMtBD;YQ|i%CUI0cv*O zHy5o>9oMDdf8bi=$#|U!$9|nQf1Oq~;Lh@KpBd<74*K*Ey!O{=*>8LCT=s*+@i9!X6^X1Qeox;xg)}ym8Ryan$F-cNCRMtay0en}nHn=AHBY@XuHGd~V%a zRi9f`w|=*}Z>`y|VGR?&R5IR-a>eS^!C@Q4Du!YH#4xkNA78m@wO@qaB9yiAQk`&dK=ZBxR@0uThnvu3;E9 zes^v`;jK-#NoO z$e-bE*=$p*8Gbg~{OKd}xwL8bG0fqg??CQdFpK7U??le5Mds&q7n64T9NySC4fuiS zAOPF}W`R4w-9Q2U00Kb}2m#?B3fvDK0O%4%4Ya@jXm>0D%K^HVc>+8Q{s`6r+P#Tj z3wR#v0LdT?WPmJ?3-ZApPz=gI1)z_Uc9#{1zyVyK9yEbgupe}S1Kj~GPnZX10R6DfKS0+!8P#j;4APA_zrvzegHp#n_vu#gIjovUI6{e zasYkH&IIUJb`H1)%ma8PY%mA|xPLa2C`l|)5jD|}IHDywq9+Cti;b})Rz+gfBvwOW z<4CNQ#Og?_p2Ql6N=a03R79mFDh*M^5tWvxbVQ{mDg#j~i8_|3(WIKFHAEdp)LNp} z5w)JE4Md|PnpmPy5e?3$A(}X%(Grc0X!Jy5AaP0(7fa$)Bu-7@a6xe-PD|o+Bu-D_ z3`DCW+E}7h5v`hNHAIW+)e^0aX!S&EAUY+{#S)#0=+s1~A-XuC!|mvZPET|OqE`}q zEYYioUQP5GqK_kbEz#p{^+azV1|>1X5`&5u)Wo16hB#u-5`&Hy&>4mmxw}j9Ge~-2 zaCCA^uu7>^1usj<-I*G^zNDZqHM=1A$(-ce{N1_vNrkB?4+byG$_idb4=)H_ms*gT zUxba5gNtEVekYT1dpP*wvC$zg8_=-F<6#y68tyURK|sS?4;}?HydMY802G19c~~95aAlW))!=Cm4-&u@upOiT z3`;f#6aWlI)(A`h!;rNDH^A^?J)jF<*s*=!2*7Y-PlK}n!;HNI-T@e1>?hzefMLac z4gM2gII+Jd{gwVRgZ)Ej7D}@)nuXIWf@YC4i=tUH&0_p#hWH253`PhwLZ}f!jSy;t zP$PsIA=C(=MkqBxsS!$zP-=uyBa|AU)Ci?UC^bT<5k`$LYJ^cEj2dCo2%|%7BZ3+c)QF%) zBsC(b5lM|mYD7{ak{XfJh@?g&H6p1IMU5zGL{TG(8d21UqDB-oqNou?jVNkFQzM!h z(bR~hMl>~|sS!<$Xlg`LBbpj9)QF)*3^ih?5krj_YQ#_@h8i){h@nP)?^r~yZ0(g+ zww&*kn|ghvBfaAndOz%as@Lyd_i_K+H@)Bgi-7(aGrn-mxC1|cbASS`Rc7to%w0Zo zFn}t6vBk~>hZx3dDY%GV#>YTC!}uiPmk?uR8e-ZPaqf$l^uw6t;B$y|4%@kEDPrsa z#j+i_@?y)6SB**CxI0bPS48mPOhnN|}|1lWgWRPP+PA42}#N z9Zr$kXMn4JP>!A*(6dmF22()il-&m%mXzY`sTZA_}>1i>x_3Vzw;uH?hki#3<6ukN_ERA%IP zhP_KmBfm~E?x{AHG!{7ohhP^PtD5*m2j_5z_CSxh4QaqQU_5NTQS#Y;oVj}T+SA`Z zcEoDu9ahKwI!{Ae^QV_GZ$5HD`Ks(^QYLe|3)<6;)N!MW#y>?5d^P5$SpLAH53RaC zb6ZM^u-;MTGPjyPNs;Dyery!B3){sVlRaoZtyw$ou5b46nrQ?ef4Xy6hh89oH(X;!z&%8Z+dHC{6p?2BJ zDzh4sd{4#ZPHr?v&Q$~qj?Gor(H-JEv%~DF32IxtGW6264>n7?E}oIOhP}=Leouuw zXH&X7!;&gKTa$Mvr+ZhfXV>vfAKTt^TyuTW^{4l_-Xpd%O(#1(+%c4N>e=^Xb^ekU z_71&r!Sc=ztv}Y>5GNm_%;NkmnJMK&yUk{wmp`yAuRWC;UHDs^B49LZELuSvX^rXC z@}kW3@_lLYymWc)d3l8tk|ZggmjWgC)6%SztC{@b);t$67F3b)+>*S!jvwBV=1RWp zT)(TYx_|0aoa~Xu73W5zm=8|MUIV(v`W4cusid`=PYU!yk_ zZ?#@7e_Pr|wDB$}x}0F~#z-+O#2S^PvvO@E0lKniP6yr1#Q=BV9el zmoo*<^4yl{t$`~YPqeKnoeI8D?Qaj^DW4qEE7Z-QQRXdun3a*w&rRBLiN zT}bYs&x^j~|8D6ltvB*j4VCp3c5dG|qd*LZPO;hAA~saNP|}j>&g}``@qj$T6V|p| z3jXW0zJYGxWL<}~!@0kX>z6hu99vCWcco=#Xy2|Lti14%H2=?q^?bdh&f>_b&2nUO z()w{1p2w`QS&Ge`t-XnE`OyQJa{XtE-dR#sdtKn%4fLJT)z#tg?5}^S_9@G=)?KEA zWaE>CkG`7FncPym`DpR!(o?0U%K9n~HTOGya@(YJ*2|oDqy|YiVC~@#w45#N>^ST4 zSX)f>ZB4cVdp+C=ox+h(o9;^Ii>+lAbMc-%dy9&UcB8G_zVVHWH`_mVb+zqpZ11Y; z@^tfqHOGoi7&%cu#0y4exyf3@NeSa;(Dz%$W-IK~c9Wyp`n+f?eRjL7TP#Nx%a2Vy z%DRhfZ?s=HZ#~!gdTo0`XF~7BjBTnib-=GM1ZS+S)@p{u!ezI#&~f4QuCCtpw%&_37Jj?%@PU>d&%y5Z&gb7uJX_L{S6|p1 z-?ub9p@hpb2?b3?0gK3UgYwIYzd4RHe@H$~?NmMT+~Ygrh2@s|A!n!XnsCxQWPXK{ zqNQQQyCugT-L!7wnuqr-*~f`CQ4F-3{REq67lR7Q-06KaA2*$88h)|FUE(TrB-JKa zc8E2n#nX+aUEK{GbzNMY=;mEPXWL(FyI|yGt!z=$7Q0Gni#fY5-^q6fcw4B)??G5R zJUXV>_Cm@jgvHi_PmTv3lV`swFWmjI9C<;9d|$g9%n5$(M6uPmlH>iV9cH`PDYWiu-YarEZxi_il~yZn zuAJxqA&4(`nwlyRptPKG`CWEj63=btq$T556anW(e^qp9 zU5l-1A(1E6M9xwsuc+G-)RZx3eOcswx_;DsW9rQvYzcWzX4@J@#1ZF+qtDUr=o@yN zbq!DbzHJt_)NB%*SNW@DSGjMyB+m9tNypy)Mn}Ksv^hm*O`D~ztTv=aevl8z=1MJ= zeU-p1Q`Zgj)=ujr>SFNMq3nN^Zu&9-LR_lZf|1Af(&c4NKCA+s*};$^3Pn18X{ z6mEXfhBNK&Yu`6WgcW7WTUJ(yL-rxZ5a&4AF=#(7d0BrkOI|&b2gq!p%rwegwPoG; zHC1KAV%u`U%8jo2%?shc+Y|u-6aQsq;J*xAyqGymJQ9o9$6Dm;kXU9t5{oJJ2IL7y zUYM6`M4pJ`#cV?IVm2drVfwv=@y3j0EAr=%yfGPn9{DyTZ)Q7^59TsEkS8JeFguZa zFi}rNPXAMV%v@sp@d2TUDZ&}znHdZwy4b@34cecFz4)jxv2F5S7|p3W2YcsYeGk@j zp{=nfE3k!@>AlfbD0fY4VbMAZXAW`}$5HS9+CSOi?KY_84_AQ}?!o7bdvR@n%zWlP zhAm7jD4e=(Tv=99VGe5anweX-V9~{E`Uva7ea>KiW`AaWWmFSu24$46+uzsQcUpj# z*X=ua`Qf3(wKYaw%OEmvt3404IGt);l^s;jVGUtXAY{1-*~kK9>yUK1(^b_= zy3^U4Y$T#4ku^k+2?#_1#bwk{dE=nZ` zR()!@_jjxN)~faES200MCF9E|mn>f%8nHpFVi@N43^P6Qsin)72Sf$T#rBt|Do_Vq_XKvX339^cku29l766zI%#q zNFc-Ave_n9Qvz(Z2PY3d$fZwuh+z)>bQf~p!f7<$dpB}s4YB~Adzkb)*YHK|ucprQS{s=w;e*)LQe}b>UH{fsJJMcaD5!?i$U<}+sH~IjyFUtY6 zEjtyUUD+AnJ}?WQPuNfp0r3267EzLTq9SUdAqhlFbVN@KBp#LVBwj`0)g)d+;uA=` zmc;8wyq?4xh)PLRa8yL4CMpe4B@mUCsB}c7Cn^I`D~URusBua)QEP}gfvB}ats`nZ zQ5%RxNi^|9qaqqyQA0EdM584d9nt8C#y}F3Bq5$8s7QjEB;bY;NP?Cm=tzQ|Bp8TR zNwo1qt0G!8(Q1em_p2pZ9ntEE)Yd@>k8YzwU^<{-kM3b+0~+pe;88%sTo0ZEG`ybzbhOj3-T?5n7!T(( ztakz$#zmk6(D1DWJfLA)2bus4*Di1n&@ep$P5>I7XTdO_Vfh~T2+(l+Gx!S7FuV?a z05tq$gb-HaVHb!shVpp0J%BZa?|7KSVvS+T;?2YA0ER2O2rLIH!D^5QHiK;-6<}Dh zxu6hWII>1y0vLv@9k>C8AL|930K<;$1&0BK8+!_z0T^cNCGal5@M1p&p92gl_OIaY z0KSsADdoEjP!Mze65MbIpgW>GYYrdbTlVrdo^I5jLVlx8r(s1ZhuFlvNRBa9kh z)Ci+S7&XGF5l)S8YJ^iGoEqWO2&YCkHNvS8PK^j^L{KAw8WGfpphg5WBB&8TjRm2I2YAI^;5yhhI zdGb8V!YX-sr@Tvw-NscOIbL@x*zIxF*3SOm;;~-G4f|`ZLF=ITt4&gl`eb2qu05}A zpIB|Rn9GDRzM`6wrfyPPU*0Q=<)IaGlOLCT`;)vm=gUrIeJ4tNe|x{VzD;PYwc8y? zEkd)<2*WrgD}tmYqj3tmoaL6Ykk=-kb2bi979p_b-^Wm&53*^ai=X#U;gpl2sQn;*4NiuH9-&mYt^llvRaMI{lzar?HkBi)0P7v&3un>?_?n*giy;yVE`ug^33uQ*0W!Ss0 zH2SZ}#@*HCl7>AF!6Dd%hN?!s!NEBkqCMDaZbj-h_8SkGZ7` z-eGm@uk+ToHhp#}>*f>3m9NVICS?k@tFSHoa2+=?ckDB?z}KSzip7sS`Pj0Dv$m$D z3hNwYE^~|d(^P4u_lE{yo3KsXe!B(jCml$f+ikPEW)FBQ=aP9&;6)+0Rtn~&2R2Lh z3QivPXK`28nnccG;jPx$f=CxmE*+bzsBdw%)Hi#(kDS@xb^4v5%R`r64!6rbR+-h9 zp5&Y-FTw?qwRyqC!c#?Ru?RIaqr-3 z7cB37-||Dv4e@q2$}Fz$l9^IYwA*axaDKSpjU-fp>E z{*J(P9k4sPW*6=(PTQTPmE-2iamDhY+Vnwd)2r>0;g3?(H7Wen;hswu4tI7NU&#_U z%k!J7w*)VBJl(pibRzghw7))vUOq9ZSE!r9W6TL+QB{8Z?)p8RqUOEsYLB_TCb>L2 zf6v-%{eT?ub!LyLyX>I-FAhu1A5L)>kJU(%s^1j4E4oZw)g2|RMK1Jc5dGoqd*LZPO-__EY?@QSkj#4&g+ic{)jxq8_~L03jNcy z-u^D(L|wbJ-MPPx>ytJr99v9VcBbcKYTv0IsJ!s8^xz+gJiNzJXK`fLW;=2?Y2BC$ z{V{EHnqrf8OHYzpe)2$;?D>4|y9>%{uM3>Jp1xB$JKMe9{hk%ID=g1hcbXDYjL#H3 z`FdhUN^|k1BgLmmPnMo6>#cmXsn7AF+a|5GUgpHZHAun%Yd3$O`Alg?`x%$l+HCT) zHrfvC^>Rye3P)ybhAV?Fww77U#k+U!-LuDNH`>bW8{W)(tL+O{XY2lkw$8dvZx=sM zbF}!lkrM?(ykK;eo2+{{DRJyH+J5usbcMazZgNyxUl5I@&ux=+^W@lKdH(ILth?Cy zX4{4H*0U|=YTFV!5_>kZrw_GP9Ov}XiZp3WmXyTR**$hoh@+>tsgy5ulo*`_T)(_p z(fpM6>Go%mYf`F`?L8m9{9)I}oYXb8UJ>-h$PbF*b*8=iDqeXo-l=ph=iL=gbG+SZ z7eZ>v8j8Dx%Wi3o8ND^1G@fo8da1-+;wp6{*Ct!Gi#4aj zQw^tFUG?pCom`#h=3OCY+FokCVB}=2Y*Ew}yGm+{IlDjK!M6)|Td2qGLs&dMGOF16 zV(LkR#g>E5j0GQ+r@t=G+4YJPpy8~pI>8f4a`KxAoe(Jx6yRK{{IU;>n#o+{a_1ilFyK zt}8tC_WIyld3L+}P@5de2?6dTvBkNR;{&Q4X1m!bwCrozD{?$<6ZzSdRx59=9B%+2 zgfDlR8Y{n8AZ>o<{FmQKkq4xyzmqgo2MgLux}N()4ldVJaiYayvjp!D_{0-dPHN3k zNR#HI%6awi zi6_=1&Qc~XsoNdWm^om5MdW_Ge#Cua;>{gu342~irvJ*edKU;1JH$QE~ zmG<|x?HeG%lCs6kORK~|`=DcxbDU@&upg6rtUsG2pYGcS$ZV0!G{`=+WnBd|Rb|9t z+kD*0jV$}s2jRfm6hT4b|7E7&zYJY`m>JA!Bo?!eHOSW@vCKLo7E|o?$P>`9by+0E_!fN*YEbSOuVHZ} z7RC(Z^eAfmU;A&L@6I`>6$n>>Gu($y7Y|?_7tB1!JjAd?X@x}-_lWz-PABiTQ<5jjtJOV+*?j{eAr>1^M{g`CmCM(QMJu#mkt5%pzv> z@A#`nLLcrA|$%_pl#{3lvrbihC998pAXWVSZ+Vf?GGaOB*cWG&JPv~ zQs~(joOI&2e;z&Xk2AyDrakd9CVu$m`tQrFo0EsRbkzEew>wJ;meuh4MFF(|5ehm|Oelcgp|0{5OdyULgPg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining1_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..3293ad8c28a40e73aa0a42256ce7d8a4628bd7a8 GIT binary patch literal 5488 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining1_successive_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining1_successive_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..4c8666321025cc932179924f4562a45722fc08d6 GIT binary patch literal 5524 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 x4&Ry-==NZk9G~$qWNz=L`>+4~_%CoFX%+wg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..456fc9b64ab8eb8888c71e0125f7ac4abe6d5d58 GIT binary patch literal 5708 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f3.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f3.otf new file mode 100644 index 0000000000000000000000000000000000000000..768492a893a1906d1d8f899289149656df79ec86 GIT binary patch literal 5704 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f4.otf b/test/shaping/data/aots/fonts/gpos_chaining2_boundary_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..2670da652467451551ff572405b311c8a0c87c36 GIT binary patch literal 5704 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..e8cce567e62459b46bf82846104a68ec26491769 GIT binary patch literal 5728 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 CK5P;I literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..f182c7f3cb9350d0bb4871a5ebbe494bced6e497 GIT binary patch literal 5800 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining2_multiple_subrules_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..d24896a13013b0cbabd4330895a7f77361376676 GIT binary patch literal 5800 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 Y6NeQZ)o)ZkA8%hUxA)QY-T%J*7r#+?1poj5 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_next_glyph_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..f6bbda472d078aea489fb3b87f1c0ba9e4864be6 GIT binary patch literal 5744 zcmds*d2|$2zQ?ONAt{mws5B};$i4__r@PY&F6_7uYY2-1O_rOGjckyuL(=I^cU3Rx zPG@hjk%*c^)(}A^pb!NVmr+OMje|aqGx~h^j-pb@R6M-zP2$Wu^Uita9nX3Hy!xHb zukO8dzjbfj`@7YBYt6=uYnWiBit%F4hM5)h*veI_1ET{MA^io) zY>%y7v*Fv#H-2Q8+cOx39a^*DL1p%pq+y1+GYr>vrsNp*Frn-=#a zjx4)&PhMfstxiVCFmq_7FqZN6XIOuFjaE-B&dDkLNB+stnat>ZcC<=1TIDx-x4(3I zh~NAmhP!3APn|*n?e=-oN9J+q)9z)M!#~{y?^igJ`hB;HZT+14(b@10m6v63C6%UxP@ty0gNw; z@L(~v>9`ZqD~-cB~hbAHBl!LwT7s*M6DxgJxNrM!~~M4B#A1Lhz=!^L=8#Ql0+Rz z)Dw+@XcCAtxM3+c(8luC~>WEHH^a`R+AbKUytB77r^oc~TA$l#*V=(k9^7fP#WRi@c zu(*`?Fr`AF3|p3(w<|4dLup}AT25iu6S*mQ1$*)e3`J?F4}>kt&JJ5os~3i?Pb*9- z*o(r+#l^6!Z5NaJ>v9Odw9zFn3(&B~^e_tm4flBP0H9&61CIb2-j9K&0S)U-0B?(l za8AQ{H=to$1WEx7-x^>8G;HfZGoazx4GsYsrbod^K*RGK7y&da-vu868jgPkUjiD2 z*TD~fhM$BG!f7Jxf^f!Co(Q*laK`eT2(vhxv20nqc~~vLa%Go+)!-?x79@eKUY}KNrY?rMSnA@aiw~L+9u!6$6ya16P8H!)5l$81 zR1r=U;ZzY$6%kYsK@|~H5kVCZR1rZH5mXUD6%kYsK^2iy5lI!1R1rxPkyH^$6_HdC zNfnV)5lIzMR1rlLQB)B{6;V_XMHNw05k(bIR1rlL(Nqyl712}?O%>5p5lt1*R1r-T z(Nqyl6){v1LlrSp5knO*R1rfJF;o#l6){v1Llv=95la=ZR1r%Ru~ZRD6|qziOBJzH z5la(G%M-_2Y5l0nqR1rrN@l+8{74cLNPZjZ05lFj_ z|F`e8G_><=bqd|#FY%}uIXWPJv-{HVw_R7=uKTjKEs>^6T^mi(!+dsAjyv03?XGRC9j!y3v^x*@#Bj0s{QKhc55*aeixH9{CE2(we{)HS(YJZf z%ZX#-1M=XnM?aOfcv|XP>t6SXPdgeGJ1T9JHlt~~G|OnH;dtI5gz|wo74DS7){C{5 zt*`F9wp3!Ix%z!e%VPd&Fc#OCOB?q(c_;7S8>^dajZV(#6da*Ga~o{HIAA<%zES$w zzn!^y_S#e5J$l6IusN;H1NFX!w&qVSW!-%EgyK~x(4 zP`>>BM;=^tU)J{2RDOfA+-+_(f08QB@%_-q@8EX`J10lbamoqfJRZBly+ zc$>h7)`_7u@t&>XoxID2{#iUVbtZwcSZr470$!j8CzXvak~g$^S{qt?Jx9+T=sxrI z@a5slFGe^dnN?!dCh4xqEuGxxd?`;JJUBK-?!a&ebIne(yLNut>Xi|fwtuii+MQ9lT-yup5Hh0$_2|i-?#oydqbFeVdU;?{gOF&0*nioDYN z{EqM666c5k?OeaRucm*hDNgc90z_kzORC27TJ8Y%u!DZWHnR+m0xZGO2!)c;Y8z9vSz zJkopV!jY~X<4ajQXL)vO&9=~$&d1wUl}!cTsOFakG0P{%baGX5M65YcD5}nHC~ny6 zEo#~4sqvZ{Y7G_H`Fq!A>jtIyUuE{1ddd$u{^GRM{^2xt@p!E`t>z8Br?T7BUDH|G zR^c<(o9aw1mmB68`h4$~w!c_9%e+Qgbwic6(!uQ?XXJl^6iPu6!>J6s3qxqfl8+_}xPZFhQ3rsnOM!Kw=%iSzzYzF&{I>X3Dqtw)G}^q(=^BN#4&Ey|bje?mEwT8t6NvtETqGv$mMLZB6!r`+VFAt=ySem*LK^l~~Iy=91##eS7yB9Y%YFW78X%Z?=E# z?rJ;G*xps&vio(ok_i$I?{(bDo=1a@yRrCU6z>4)jPZn?|f%( zNpqR4%vox56>tO6T6xQ3zQ;SBFw~}08yvkKy!b))N1WI_zEK|h+UO7Rk`1PPwly}z zp#+!0wc6&Xe4Mj6tPXyDZFyr!4}aMsE_7aay{oIYy{-4+jfLMVJbbXF$9Jgvz4HY( zlh2lR*n*Y+*VNGj#>O?+XKk;fs}xIyV9`JbIfnm;5Tr*$eHe)h3lYx(6C?~tpL ze~mwB9x}heiE-kv{N2*yk8EDQY0X3Xm+a>RyC8%*%z?aJa0v4Y%RL!=wI4T~X&Qc^ z)Kls%a~kRlmYqWFY2kF^X?J%+M|~GpFL-S3`Dfc-XuDwKB#mT|*OjqNzuB!mdxsmnheukUv87JdxaR>E*|^oI@i(OXYcVID?SQ4 zR{H#@-M!pL<74vRcSoRk%z|Ri7^rx4wP;i*LlJgW`4HJoWpwMc7)qnRi{aT`j-LebXg!_ODAj_VqV9`vsTXCAezaEcNAe z;XTp=w(uOT%wpMJHCM3NZ4MhZx^et(7^g9r+#TS`F3q&&ShF1a1p{|~U`>_7=ruVd z)=gi$?9>nQ&z76~%}?6U(t*DA{ey&GQNFxoWwkKm7;+AA&XXO3j^m=t`m@h8{9zHnSGSV)wBQem#t3 zHo#bHu{Xje!DQH%Y=TdQ$(YSB8M6f@!}fbCTn$hfehLf9KYt z+VZKY_!xo|{pUuZp0+s~cbJ?8j?ArFP|-s+eS~%6qfZF?6Z;eMH%2*eW{^e-mxBWQ0;UDa zWWSF7gowIjE0?cgmNLtjwbMtCy+r*NOW0euGc$bzxn(eV$PhcUEd|clfug6A@j8!Q z#4-6alOKHOtcIb?A1W54(7Q3X=~TVH*Y1eu8s9PV;h(Xw#Xs|ZK5pHdKEkD=)Nf)e z>1DL?Yd_gV>>{LTyZ`mTo#>VS4@MsgoA%U+#|yw`Hq3zkbUZQrQZbp9F*A^xO#30V zdMfRYbmdff8s=(fDjk6Gw;00g!554|ya`g647>v}ncN8ozFO`;It`!ZijX2$>7}Tf zfpj{PfcH=u%8F5Hz(>5_dY9j-+l1B&(CbX}Jr})s0I~R6@8vf!rp&Da^gHc;KmHSP CyKNEx literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining2_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..1805a034bb298b4b2b045ee0af6f4d40f4685826 GIT binary patch literal 5696 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 uX~-)^N-{R-3rEGv?NQy6^hmkN*N!NM;!T literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining2_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining2_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..1df12f5285c75ab5feca7ce5398b566a161f6642 GIT binary patch literal 5696 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 vG31QvG2a literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..48be5dda3392737e7df10ed078a9efd4ee31e27a GIT binary patch literal 5508 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f4.otf b/test/shaping/data/aots/fonts/gpos_chaining3_boundary_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..8030ac0eb455272fcd0bf321f6deacc1816fa818 GIT binary patch literal 5500 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..7864ce02e82dd1a83bfdbb1aa875b04fee8e8fed GIT binary patch literal 5548 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 LNWXFZ@8iD!9ExQb literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_next_glyph_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..20a7966c5fc4539af76c34d5d8dbbd2436b8f238 GIT binary patch literal 5524 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_chaining3_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_chaining3_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..2c633280ebcc71c37543f5504c76bb4f490da266 GIT binary patch literal 5496 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 L?x){3|M&DiIOJs+ literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context1_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..22bb3eacda800510dafc003d53d8d9aaf10ec58b GIT binary patch literal 5480 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context1_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..7e4c0e198a79eb69acd091122d8828bd4a42662f GIT binary patch literal 5480 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context1_expansion_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_expansion_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..f7c60f68b94ad5d386f412ba531077afcbf3d218 GIT binary patch literal 5492 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_context1_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..e9b03ae13c06a38295779d199504671fd3859b97 GIT binary patch literal 5508 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 r2BMXpiLNb}jboVTo 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 ouIP7O<4}t=_ObW4EH*gYufJ3`2U>m8TRae}}Rr z3l(x>$aRLfI|1dGth|!4B_#{mP<|TaxAF{SyP5Pg$jhGA=V z7ZjJ=>}HeyFlsAX#wFO z40qFRzrC9lY`5Pxb?iPabISb;bLhuAU;~P0P`md|SY|Cuu1%40Kf(;-QYyr=K z9Uu*4f^3ir3P2Gk1!bTTR0BGlW?%&ZZ~`~*f)>yY_JeM406Y&~1cTrZI0}ZrE8tZy z3SI-}!JFU`xD4I{AAmoBPr+ZnRq!9+EATb=2ly6z2YvuIzyz2CH!+PefbnHHfU#w# z1B@#>3)}&GKnN9Ns@{rsYy~YNz#xc zElJXmBt20oh!PqlQL2biO_a$*sUb=&QR;|NPgDw`N+K$BsUj*hQ6&?VhN!eer6Vdm zQ7ec#iKvxCjWeo=I+>_7M6D%i9Z~B^vVtThkz^%FR*_^}P%=r@kYp`M){$gA(I|)} ziD;BWqaqqL(cpSDM584d9nt8CRzb8$M5`oP7164RHkoK~J6fXE5v`u+6hxOqbV{OA z5uKXol8H`3bhuj`(dmg^LG(#PuOxaE(W{9*ndmh{uO)g6hJJa$?((8+l2sCskd_#s zR49}YOVbN>W<;znFD}W*D~@;~Kdqo>cR`V%BqRNyh^4u?5$ovT#S!Z=iZhD#pz>C5 zF)VA_$)x`p4ndeU8Uix`b$d(?GZ#>IPXrGE>gGD|D4_2B7@*Nk-FhRy)57o08QAXv z)Qu7GOgW(LTL)}_x@{w91=L-8!9hUX^awZssC%9TV}QElyWm4W-SMyBOF-T58u%Vi z_mkj4*!kTq1bc+C-`(!T9^vbEvjprBwk)1JtQH_#*`;6=cnYimDPRlO4$=X_lFbLj z0O80Qfe9cCSqJa{gdghzJpf_H4uHb|;l`c%@EJf@v402u1rSc` zPl^yl$n=PiNNS>}iKZronpkS$sEMa0fttjS>5(B3)IbqQ6_HdCNfnV)5lI!1R1rxP zkyH^y6;V_XMHNw05k(bIR1rlLQB)B{6;V_XO%>5p5lt1*R1r-T(Nqyl712}?O%>5p z5knO*R1rfJF;o#l6){v1LlrSp5knO*R1r%Ru~ZRD6|qziOBJzH5la=ZR1r%Ru~ZR9 z6>(G%M-_2Y5l0nqR1rrNaa0jU6>(G%PZjZ05lmi{2|aR21_{tx?~><|9;Htt_-QwKx72pya@?F;v`JMaRW1>|_FGHdT< z?h2&A0BQkZi=7Q#W*FHLZ~CB37orr-R_s z6A#Ll?kJEJSeDdEGkc`nV#0Q==E(8JV__bztD#};`xlN4IIlZiagSI>%wKL6^He8` z+wvU+jr)W;tHoT&SK6xUIC1)B`L$I8l28>T$%6fl(P%R5(jD(7249Q?<7ZB3ng zM}x!RL~7^T_!cOPlaf4CTt1N~cSt!NDF?Q}@Vd)6EQq-lahD+G)EqL{&6%8d<(EVp z89hEEf3x@EvA11U+^z?5wl0>YN^RbB zKathKMe-73j%eUJ>pGqLePX28dhUI3>WAX=$Hgc~k(O%QTDYk!&FI@S?B&FX$su{@ z*W;hc+dOTJ?G3N{#HSri3mnz9YMartO`2&m)NwrT5W@K2yefCvA?t@%fXVVg$aL2$nB<@X?1? zK9I95J)K|gtaO{(&7Y);vwhz;^V|9D!j4-b=s4*_;yfO^!##J{YkA#Z<9M6Ehc$>{ zHu2sq;@!NF<>KaS}XR+9<*15buH%_XUoG))`_p~>)`TCBW+24Em?a@o4mtKr= zNHVL$s!h^8)tkGy@o=d?9y&ZRTkgPc2y@I%v%5aLW7UeNi`zcfEbh8+TH>1ax{7V3 z)zYj@S<*C1hVV>%;mi5Gy9#`}j&1tb{-*P)`;(qOywCL?wx4b}(e>eu5yQ!6-jh^C zi=W>+^2&M3JKwc`Uw>V=HH{LB^SdRcf)gBeyJJq#(6++P3~qehFUj)I@#u*JIdNt- zXVppbbJk1uXG(Ljq}k`BQ6a6*y|X%|T;(v+dZm-4SSeBESj7uuV+@mT4sJoKOA zH{@@%U#fbW=Xwt~oV|04ca>$7W@x0uMN(p!w6q~}#M=6Dm#F`f7<*NWdU>q>;`zfp zea4q^c+T?dmb$HBE1ZvatgN{0eB+v59>y%6n9#{ptx@sjWTB+Cu&K0ZkGG_4ucyvy zZmKs_bo|X}ssH0C?!vKpaZ24Ad|!31skg4XyrarzZZtKR zTrM|~XXNueU)ug=>8|h^ZM97`-f9Q8Z<3M22LzYUYHbsm>Ygue%kUKR#q4-cn&yk{ zSSCjN*A3U4|46*=k0oB4*V1Tl<~HOy z^Eh$+q#N@wV`7GUvu|sEsz-YCK#t`7Z2mioD;uuyoTrICQ+j&3e7^nOCmWu$JY(Hu zN=Y+5QS#`kDcxypWt)$bovJulak6rt=H=Ew=MNscxXyZs6AsrS@dvDZwgYWvD!RMQ zxP8_(leeSAeqgVUTdtKmvm3J9S++83rNvxUTDo`79;3r(uX1dBBm2$H&)q#8`j^`BTCKs+|G|qN^nS#Ny^|Z{p|6d9FE3kf+G|^FQyffkDO{^; zp6bUro5Skh!|N-X%li0B9&w)Y{OdhE{hb~C7p~9yX5OI#ZGFCjz3-hXx{-ROysOY# z(z<3~NmfcZS7_pkTZ}w5!Nv_sFUkMvJly&r`8cCnx$xP?cCO)|4B#6YPQz<}e5IcEKTp7gu_+2I@a2 zN0Srs(09kL$-PaErm%czZkKd_rxd~Q!Jbs1-L-tt#Vv22`{Elh=72c;_oBM?U{P0j?=v4uVO8o{POw<)mav_? zE#-uj6FYL`;*@#mQh_dR*UqQ&H<&nAuvuKWMO;2CF5}$6mpm7Rv)egw@#JNB=-Kg~ z<=q8%PW_)t*8}793##V&UvD1*l|phS${H%vc6jfNNkD3G)uCE z%HE>-+Dc-vZ#iz|##jC#gFD#l^3YKKx6Cwr%g{~6%wpCcu~>bqgw;A<3A{NHQ$Hw=e-%v22BX7AXLW@#kQ-Aq6nokpi)n*#T=n3S@R7 z1!AF|21~!G#+VT%1V0eWOggiIS;S29|43jN4y`eO!#QR$L9i^=Q&bV)&*2*k8;dl{ zUrX5645nI+6pX3f+wR9vL?i^c3s^vg^gLun}z-DLhzpg&ClaFzHOgnOmieSS-? z>=tSMeIOHoeV~5~WlS3FjX|gWHke5z(10- z8E5(RI@$T`eB|kQ|L2CDXv_bHL~jd=+I0Wz1>rXo{4j7T?sx@iZsldnbd+x81CU#H zJ0FOA%kBIW%+;T7=YvrHPlhnNvBED#q@-b=kClD~epZz*NvO%gud7_-vvEu=>bK*# zQbbUZzdpmS%EXcD&_?`q2DJSaJ^mJbY{XR+;Tp63_mzZyABx}P+5-G@z}(zV|9k%L G?Y{xNLvIfN literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_multiple_subrules_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..ed9a387640dce4dfb497d4d67cfdc998a5626238 GIT binary patch literal 5568 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context1_simple_f2.otf b/test/shaping/data/aots/fonts/gpos_context1_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..b4fddb33bebfa6821cd67bcd41b70bb5c607317a GIT binary patch literal 5468 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..3fce49709ceac13a3124b48957e00f68b5146768 GIT binary patch literal 5492 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..5b4e012335179620a56fde051ec1b8d224f0b6e8 GIT binary patch literal 5496 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_classes_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_classes_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..585b511c46d0c874e839cbd772c9f8b2abc090cb GIT binary patch literal 5540 zcmds*d2|$2zQ?ONAt{mws5B~3$i4__r@PY&Dm%CjYY2-1A2G8%ZQ`$#zCLY8GZBc9Yv**sd#wb+krE4=AHA-@!wa!^ZC`S zd+U2|)ve#Jx^JyozkU@H%v3XejAGf!m0^(^gc^one$Oy7qMlm5Vr5`-;Cz(7LY?)g z)vMNh|LK1mVVJu!8HNp6weB%x&gG;LhPkI0?b}mxQ+6?->=qnxpm6=;yy0~~jD~_vi{9bNK=`JR1HHtHzhYQF{$xXli%44{m znd>p0Vpo1q@vSaK$uM#g+QV4J-=AUqQDo`qX(hS2W&b#Sc5FH`wwE2NmW@^Wjot4r z-5ugLCy3#0*=)CWA%QmAgHuNz1#)md2nBOMIH0#53myiK089y^0vezPPk=>WDOdrX2G4=tfi(cP z&m@D*;3cpfq=F2P1#&<>C*5)IK39nq5nR3?xFB}q_` z1T{%WBncXlpd|@9lAtF_1yMqyBuW)gs);g@C^bZ>B}yGp>WNB0R0%|dE>%ROCaOfD z(h!xFsB}c7Cu#*zClIxgs4=3Ns1u1=L)2QL))BRyBq~T^0!dVoL={QI1tpS14N26J zL>)=g6ODps5{O1gG%BJ|6Ai9cLo`~V(GiWFXca`8K(tDtRS~V4XcLJRx1%Lm9ntEE zPC;}DM5iP=7161QE|KUoM2EZ85uKjs6-1vv^h%;v5xtt|6Nz3!^jf0FWayXW?25)cjXtR6sM;>8nz@SCu}V}y(nyL zdQp1eZd6Vt7sImF9ZcGtbO^v>qbV>0(6GnjVderF?(yJJK*L-Io&+?!p8_fQD-iH~?sv9tOt&4bL-R6wt8z09*ky9RCcy z1~d$>gC7A6KM5g(oiFTyutzHU!tDX@5u=fG-^1U7?h zAPpcb**s7LkdCYY7y;6dwF5Um`mtWn4Ul$hKR5)CZtO{L8X(Qs3*dc#^kP2)UjU>P z`&aN^0O`d3q6kt1O$!SOr!IoJNa~`fi>5Ayx>)MssEZGp79JEv9TeeI5l$81R1r=U z;ZzY$72#A7P8AVU5kVCZR1rZH5mXUD6%kYsK@|~H5kVD^R1rxPkyH^$6_HdCNfnV) z5lI!1R1rxPQB)B{6;V_XMHNw05k(bIR1rlLQB)B{712}?O%>5p5lt1*R1r-T(Nqyl z712}?O%*Xz5knO*R1rfJF;o#l6){v1LlrSp5knQRR1r%Ru~ZRD6|qziOBJzH5la=Z zR1r%Raa0jU6>(G%M-_2Y5l0nqR1rrNaa0jU74cLNPZjZ05l5ytqc1(Jk!~d1sh9K4c?7I z9!?ye7?cNpJNCJ})!o|AR{yqFeBR!;z+PpovKowAr5T2lT8`)KLMR`YTj@$YXgObZ z(emc@Yl|gDnyufnxIE^sDTb0-Q(4n)2k+qRd{a%cwaLLb9D+U6YifrL8U_sqO*hKE z_|H>UPhWfP`-O)rcB{kU*w^4~Y;XDeLiWukjw#-h0*#7PZdXx9#-RpoZ2rXOn1OG` z1LaE}dGfIp4`**pOXJr$DqN;E(`RYoEbos^{5F1@uzhj{?I#>C&h56@U2}&#=C@O< z9B&o)(0Vb{Dn77Tyq9-caeZcYZM{+8%x0^_GM5+V#!2N9^W}|g?zYBOZ|~vL`+81Y z8o4-f@zn^sB(q4Y+9=&uwW*66nrW9gM7hb3=-#BM}|A)38>uv~>k5OVVzDr`tIl*qT*=H9HZY}6Y=f>v!nkWw* ziyV)W6GuiGCw~eMYp{UaZF+Ant<2t#jB_h_8C=}NeG?p~( z_7u17ao2iGjddxNIR(4d=IDl`Ip1XU8G9=Z*#F`%*Ztuncm8OdIHmR-zPGB!*i+k8 z)?Vo~H5luSPNxgz9{zIo*Vez7yUINVYfWRdr^?RlonYjM0l_J>SXza~+Ly~()7|;K zQQIGpLcEdfOU1B1UF#q0;g2_TS~{Kk8n^**qujB@xMgQXZkFa!?NIf(Ps9iRQ0%dK z%nfEoPJNCemlM}bxbQrtk589x@^0x%c1ut0&z3x2%zuATMg4W2b2rj=N_Tgs*SpX2 zZ2hz57c4uCNvVcsil2NlsVlX$bkpI|ljSGMPgL|*zuq$7_{nV(*IF)e!l61Czu(ep z-QRk;ysPuH%WG*hdfJ<9`}cUcWm>r-t3K0}X)U!>m`$Z6C3|-7HrNfeO8bU)vfl0Z z($(F*uc@QEq1)SI9jZH0dd$EHJR+VqI4g~o-JF;-aSC(4d3=W4UTZfxYAr7bhVmD- zN!kTcT&c8h@=-RNZ-1xb+*!++wzum$lDd-mHgsl;bXFbXbmFt=;+kwRnQO3n?4CJ} zzS5R*Yq_J$;4I_@rPcD*r@T*hK9f?HT9ab$`}oz5dp_aBo{9DH;J3zpl$WkE?y;`2 zDh?z#70#7bch%FJ)o!u#bLuLZN_+W>ZgHOD+}qvVeI4z6=WopWZr;KDt-am@Js+Me zyqSEuth2yV+_JiVab{8(S779enhiWQ!O9IuugU-HIMi~5e45^+eB#BYcC6-?nmxnL zF8(e4xM|q*1}DaeBk~W*jy}0@?S@s4?_IQ)6KsMIYBvS)Ho-2;DXMU1_Sb#de5!fm zl`?mktK5-NpJLuF)SVPgHl1|!GY8)98E;DScD*JBsyU0Rfp>@go9m;_W0$=L zntS$l^}SLsn64-3Cgtm5cJ6pSZ@rOo2Aaebo5f{A;!@5Pc+q`9IJ1ot z7foE22cH@HySz)|T3}J}$yQ=X=FAn+vWAj5%~?a1*97jT>xbPpZoj$1%;7IeYF zQ6JtbJ!%cl<;uyx|#}NwrxIU;l@_{DnmF}ZSvq?-+!49{FkAdjG4)-hOt3LogZI=^fLv=|+2?W3kLVz8V(e z(|%~5v{xC<`M=s}FO%)G52_0C^*)Qa4_EO3t|1g-Kg6)b=|#mDXYwxCoRs1`9MOAY zZry?kS2A^!bzvSt*q_;-nZGki-=0AkB{T;G_ytS}mdWn?7o}3)wq*Iz70hC03A1|Y zC@L;c|J5S)7W!qTj^bzujBa;kO@Z0Lst(sV83PacTIrQdlIq+0Ghx{KLq%sSmG;J< zQ(qh0owGZgm(FgR{=_d>EaKnpzizi~P95bkQ0wQLN!pB2?p!B3pPi2~9rvF%^h8_! zKN!6&EQHg1w-+3yc?zCY=k0O;>W?yn z*@dqHMaZsH?DOz-ARXCLjPHQ7CI^{T1WWgwk-;P&r_-S+@wF8GX7z6!Z39Lt#MoKB ZYfHd455;dD)6X|&%&mR&+vfk?{s(m~VI2Sf literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_classes_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_classes_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..411d58e6da6620847ab1dab80747d9a785880aab GIT binary patch literal 5564 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_expansion_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_expansion_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..4b2d36ae7f945a0a0a57cf4021a3dc1484d34ce7 GIT binary patch literal 5524 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 CEnyx2 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..1c0c48086127525304af510aa2bc6a1bd2eba757 GIT binary patch literal 5540 zcmds*X?PS>y2qyUK1(_Pg| zy3^U4Y$T#4VGj|+fI<{dTt*$083(;yXY|g+`zR`vSn=WhPZICkXYO;q_;Knyzqigg zRsVCU&UxSJK4;Cwjcb@dri$@l6w6nw3XRw#R5J|oD#Of*e0;^qRsK=_3y}W;b=Jq% zuG#SKPv1yqm^(92zPV<@!^-TdiNg$Y*Rv?^Ovy>!!vwS2P==man~|2BnsMzZ1;gAO zgt8_B6>>wsO_W!l9GQ_*RI;RKVGGK%y|;3bOZG6SYmuF;hVjcy&PfY?GyZ3kA7vPJ z^`5-KqT8K}l40Z~Tn}X#UtfmxMV6(vrxxerl>VdqK?%Cb$#a4dmc=AQ*&zFc1l1zyshxfFWU2Km+suug5F~%fL#o8axGl57vQ=APH;* z&w-sF1z;+eOpp!oKmjNQC7>Ks0y>>^xGX>b4&VYF&;(k+0niB!g6F}DpdTCo$H5?Y z8N339!E4|mcoSR!SHXMW1Mo-iDflzE4*m^%1-=G<2j7D4zz^US7z5+rHl|SqFup7Y zFt+RrfN^DKgL}YSfH`49K?K12vspwz;)#-|h?*o24bc)E(UW*o#*=s@iC2+$HHl9k z@fs4ZCGk2EuO~_cQ9`36N)=J6i86sGHAJZ;N*z(^iAq6K@kE6tRYavGssy6a5S5mw zbVQ{mY6Vfp6Sb14(W9EE6Np+v)LNp}5w)HqC`dv)Nl=mm6-mGYC6ELSNzjr69ZAp= zje=<6iAG5@Dxy&n4W3s+G+Lt35sjW`6+|0Pv`V5?5v`hN6NnbCqa|7$(dvm#L3Hs% zrzAQR(W!|pf#@_uhqu)cou23wL?2J|N}^X0y_)C~h+aeVTB65b=$Gg1DJ{q(8AYM7 zDRH4ng+dv+G&OHmTIhz-!lJaC!q6vjQ}PP-gGbUnSjFm!!dVOqgn zR89sL!?M<0OzN-U;D>3WAutP2x5xA_^8j`CIPeglZmt850qWk5gQo#?>rDV(iwSp5 z!+AHLZd?RP0d?ORUp?T1?%E9w0qUm5z$rl8^E?;<)Ggly9|G!*e*s?t>V`MK z_kg;e1Q)_-!tDZZMkr6X+r2m=d?(y27H5Pli!TqW1qfGmDOd%b0&77c*a~)lRDiH# zb3q|MII;#{1PDXc4%`6Y$9h2*K-jT;;3z=2v1hP=rxM7*&K(MHp3tQAHS4 zgi%EpRfJPTI8}sGML1Q2Q$;vcgi}R0RfJPTI8{VYMFdquP(=h)L{LQpRYXul1XV;( zMFdquQbi3QbiHRm4z53{}KXMGRHM zQbjCP#8O2pRm4(7ELFr(MJ!dsQbjCP#8E{YRm4$6996_oMI2ScQAHe8#8E{YRTT7& zMfFOSUU5asg%*{r~wI_m6AS`vblR><}36kV7JFvS2yqdODFmqH|;OGhAcy-FSm#} zs?&unx%RyJ{X&h!Y%1r=t(7&LIAe?a#;QI^s0giGko<_`GmzxXxln#4>svwW|NDC_ z4efkeo!#z0YUNw_CMXQ!k~~mcJ{BjpOIdCy3$`x#b*E!c5VOtVZb8hdI+AQNrE}u7 zU*d3Q#OQ$h&F;%5-gaJdIUmT{wpf}jb!{|CkMh|~Ij(G1wX3$VcDUjV&#?Wf{T=63 z`>}f4sf;ErjF%WwXdT~P)9yIn6~n~l3-625KNM%I7Q-b)N|Iq){^pVtgLm_whZD!f z2jqcYkA5m|aktdB*1hf(pSCwFv{zaytp?+EX_g_mhU0m=5X}4MRJc-(ST5CGvAnYL z`Vxte=IZw?DU1GFvZ1)fRNA=L!8>?6-&oybZFF!BhhPu(n%a;C3627(j`#aUeh0rp*f}|Z_R|g|&h56@UGoM#=GT+09B&o) z;5sqbD&D(QyqkAg@qA`?O`TET%x0^_GLIMN!AWJ~3*-&0?$(ADZ_lxF2fEL`J$z;O z%8TK4NoJ8)wNbjKa!V&S8Y1P%0|&?E$n6*oVXnzxa@B^kty&R&dHV-j#NC(9N?gM} zXQ8#YQkuOvLkcpd3D4B#AI|OGo#)+sV)MtgHyzhqpLD(YKG%EHcDCtM$A>$Il21SL zo}?;R{QSP5moJ*%`L6Z*+MB}UG)gS`cS%ecC)jN^``m(o?fLC#-01vY66ArS5o57( z;z)1IsF4i@thbex}Oqfre4dkE^N(r5kp}$smLqM&+qu| zEpd+M*Ut63`fB>8y5c0SG%i0sBF24iN|Fs|7fFfIw1K#na&Ojs-C$}JS{u00DCxXB z@V`cH$=_v=bsw}ly5|+{E=em+(@1fPq_`4kXkbj@4}|%ch)fRP)QjnB`MrI=QMjJjRqD6jkRp6gTYk6t(Pg z*LX|~waFFP`Fq!A>jtHeuQGd$J>`e&e|4B^|8R!8bfQ+AR`UkmQ`v3ouIVgotMHoY zjdez+(}m<7`h4$~*1wuN%RB~abwib>($4K4XXNk!!6`IbT7-t0=Sy4C+<85bJ0FyS zyb*27#Lz!q?;GgmPt|u=I-CdUxqfl8+_BBLZFhQ3rsnOM!K#ZNiTC}X$Yb@G>&=er zx@<=dCvF&bVLoP#&6IEPZtG2QOOGAQl02U+cxQ2W-3^{|H_&fNS67GEd%*K#-IL~L zEW3?~DTXJC9(yIRGo__u%dwI(Wv9zdm-kg2Zti#d;I@hDEmt_$F2j{!EwPlFO(n&}`}XcN*bTM{`=&QC-)#Tf)zx;O zvAwIl%iC=otUX?G(!dEkJf1f=D~y)CoR~O%7GuA4Y?jdc#EYAssvS)Tk+J#bV ziL_{PD(f$`z0rR0g5`Yc>vipkor%4hI?{(bDo=7c@yRrCU6z={)!RLGPl%(pq`Aym z<|s8d3%CJkt-R%N@9K^xl510{lkL49y!b))N1WI_zEK|d+UWQ4k`2av)-_hep?Igl zxytIUT+LbS7CRqOTi#gG!(VZW^Boso@9OGpZ|l8ubN)B;j~s02@gC}a??S_SLkxjUn;_T#3rO~Wsgx=USU zj^w&z^G>1mjBuv$jH|n$qrQu)7u;4?$hr0x+AbP6Nh6u%btSISx)RRrXYI6h@c3G& z#_xe!JTf{a-~N2+X}HCqAMEUX zA%7rqe`QsbvC3d5DO$JJoLQYwlVRNJ&22JtFBb#b#p6HT;5yp-Y(1Xi#mA72mp*@b zcQ5zR_?SHK-O(FzPlLT7I9Hn2A>H3Dg>t;VJ4tADuHdZxH4c;Ahs0o*0(Qw@r@XHP@M65QC)qgprf?=nUAI53UxInn9VkG z@Gjn(c*??wZCP@0+Wb^0PZzy=*VDNhjhxfpB(B^lE*}(^aW4NW?#sgY9h|s${Hi?g z{OHf}PK|4!Ma3ssi6x0MmrKj*i$j_+2Q4oN+z&U7xo=K=xkJri&q{1t!-z2A9C7qH z`W=14j&rWzso%FP!q(c&yz`p%TKP5Zn=X;FeO=nIufNgJFF0*Z!CBj8t}m|(>yaL^ zhUIW&X7m24xq{VZwOhH-jpILKoW^8wm!C7cG}Dq}$+GVklDP-{YpU!9kI^BqF8bkR zr+%1!GT-8FebR=W4)nF}A0+(p@?|Y6s)Zr@kYk8*oaz{~pAco1pG=~xXYvM#Es~f< zNmf_hT~J$HPRzEgCoSCQ%3ow~2dhmU7&!4?CJ6s!=pkcfGi#AptUlJku18{-4M;4O z*c)LJkz`nxY=TWfk};c+WXu*M8J6E$86T`zw!uD&IKoefZU(SvzJv`V$s~ z_*eVS$L(9wN4Rv<(%G3j(95sS$u3|QAW!@K-v?TvSN;_eeJw0_Qzu@}4_j220pIC( zV-0F1^D<@zN|SjXy2q=MkQ7M-R2oO3kbM!m-$ zbf>d7*+@i9!X6^X1Qeox;xg)}%sA-vI-}Q%_fb?TvEsx1p9G$nXYT#v$Eo-Ey>*uQ zpHp?}J=J~As`cwvF+offNou|ce680HTQGb8eeWy@CtLWTgEVVW+4CVs&x;mvM(nNGt6D8$@le~)wVYeVZi2Uk|wB*!`D^DvK=59aa zwHYW-7z3{(|0wd2897BIi;5PsAio{?w{nt8b}^}|k(`M>8UNhmoV1V&@xLOkVHkGh zuDrsco1Kh`VH6dp4`mrYKZd1Ev-I-R-8ng>|HwZzI-MEa%Z^t0j8^%M{?1RnGuU@d zAj93X*>0VJ18lbYrjFdlrBAt^VGjLt2fT0Lbn5rq3D2y73-Gy%Nx$8PFAArC05BB< zfjhu-a3{DMD8TPP2$%!HKqQC(4}b>&hJ;ZAEieE&91Fn`upF!ePlMlsHGmFp64(r$ z2irjkNC%l98{~lkup5+sa!?8A>ofx^5P<`@fCn^zRrdU%*xHAK)wSHTV{M2fhbCf*W8AjDwqajXnV5%W?o? z%T5CrS9T`22h0X|Cu}H)0C;{jizrDvQ4uxKkOZP7I-(~A5|6@o60aihY7(y@@d+ee zOX77TUQgl;M5QDuXjDX{CMpe4B@mUCsB}c7Cn^I`D~URusL`aFs5L~LK-5~I))BRy zs0~D;B${}lQ4tM#)DTSq(P)WAM>Kk(F^~i$Nr)#2Dw3ck3AmvIlAt9CI+CC#2?nB7 z5^X%us)$xiv>Kwt{c4F;N3?pPH4vSW=;Db^MRaPS(-2(((cy7)M5iY@1JNsqKAz}R zM6V`#4bdkMy_V?lw0fd95QCB!;)y{;3~FM~5JLhnXo*2b3>XZ<(!5=z1(_tHC^R-D zE>xvdszMj1=IuxeT~}IIl$KK%`ebfOUcs)sg5;vK)Q3VBXJ?15rI#0mu1zaUD=0?c z1hHnkv0S()F&Vl_$dOUYs#~C&DZiXG~ibUmjKmFkRWjUf!>Yg$0IE2SpfFgi%EpRfJJR7*&K( zMHp3tQAIdagi}R0RfJPTI8}sGML1Q2Q$;vcgi}QXRYXul1XV;(MFdquP(=h)L{LQp zRYXulBvnLGMI=>3QbiHRm4z5 zELFr(MJ!dsQbjCP#8O2pRm4(7ELFr(MI2ScQAHe8#8E{YRm4$6996_oMI2ScQAI)T zSX8fU?Uk0boa>dFdi|xtz2oP5KkR*~H{f6ExPR15?GOASs6ROP3s>+R_yL>=6!@$% zYwl+5@}rXhR0GT{b{06uFg}aG1^hBT4m=FwmxNzJ%#|sKX@A7IKVmWfbC!diL#%Ts z=W3*=u?H24x97w*cu@JY%Sywmr{R_wX9M|oyxQ47l<}Wu% zIqH*zExGo*`n_U})nYCe%K6F~PMWq!acxDPELMb8&QE?s_8my_=A0`(mGzw{^?&k+9^s|Rfm#o=5$WF z@@pKfj2InIyxD#6*xSx4F6RSTTNcVw<*xN6`B5ReDaV!Vs&>^j)(%&^;Tg7Hw!h=N zY(G+OJCV`Eg$Xia4y_Z~YuX+Ayi%CdeC~Z|>W9*_l~TB@Oi40s$=_I#V)Skt^l;MH z_<$nl>(NgYE$){3*1Ffd(lhpk1@=n5k~f;R$}^0~HJl*W#SkGNr^1zT$a)ei z&Rl)^yT=b(?YzV4*jMjuXlwrTV%CjEk1Jo515C;kZdYM@`r&$RbpH6K7=f?G0u)Og zeC*-n4`gjkO%>KT%3bDG^Czj&EbkAE!Zu->xP5X2?I#^D&h56@U2_LLme-ScPT)l$ zq)rOqrF%C^cMDD)_h)g})R{!iV&SdUxq?U!PA(gtuV`p>w>GqRdybsh*M0i!;Y-7p zUJAF%K3194nB;pZH+6EObL2cl(BRlCg&o5o&Ne&DuG%?mE0%>{-1@;LY3GI0GS{%j zS;+6MlxJ?tkb^C0;+xW5VO~+N&CtZJdpX)trJKc1m*S+8F=$>1+vm|YInpTc`T#hS|7uTf^S(^`bNQOU2QCFq#gCo5c z&mZpUF}|E7aF*vb*K7${=2+RbyzEx+jcR{=7;pK+m|mf74v#S>h(*=;4Z9nPJw+{h z+%+C^Lv32$%|L!TFa$^XsLS>`eF)eTjiN;|iAoKYYKM5ownZ4n!4UMOuzbLaI$Zhue? z_C~ZVkwX7+wQrzXI8onW?Qrg^=lZ3M3da`HmYwN2ncBB&2CL40B;EJNA`kDe)LR_c zb=i&_PFgqa!uyy$HeIpFyQMeDEkCwDOZI#=|DA>9b=L&W-9W!7U0oes?>^5{bx&EI zweB<}rWl_rdhFH2&XkstO-D*jm7Od*S>9K5u({vyquVB}wO-=H!?iGBzqNZ?=E#>T289 z*xps&2`3X`>%lM=^IW9&DN%~05D>?TKz^?A`)_UtxUw?K|9 zksqIYmGu|e-e^C6&U&`>^}6=N&cxmg9qGdzmB%@~^i-O(CQC}<>g^u8XO5${q`8bQ zbCepL1>AtVTG8@^cV)+u$+aof$@bn4UizT>BTnibU#|#yZS)64$vV>>eig4g5bsnv zSMcu2l^k!k+J!l_<&7mh!X>vf&vE|suCCtpw%!ZZ=Y2Ep(EgSl?}6_3&K2B9I#b$_ z?r_4Z+!H%i3rj4XA!n!XnsCBA zWPXK{Vx?ilyQRk-+qibasz>%N+{=kJQ4F!00|c9B7v~g~yEFP~KW;kRH2h+zyVObtml(apQ&oN0ft?YxnbwX#J~SK=zIE8*<^d?()_;A^2C zzXxIQ$mp12>kFwT5f)nxJUJe6RG#swJa5;_Qhzq9wn z{DI89l~q-yDx-m?G%i(Q67%gS{anSDxD;-`_5WazcPRNo;j4H`HGrQOedEQeHRsyWeOu~|ZP z2z=rRD<`#ODWoa$Qsq2-^v)g6d<2usVCv@EL@hwMX+AdLzdYOBkM#kTpll^b3Ds}I6~w<&^xCjQF=v#~S#xFqT;dW3j|u z51$D0!MbDvd=kuu*$DGtHo<(b{NBv?V#Trr{yCU07UR#uZ-x0X+hBfJ%WQ{FhWRl& zV18Jrr@+(yR39@JnLunHG%>~KVKozsjRX!g9NN}0p}1;tEk*x<`JqJ?<&&PCXTn&l zvlJ+u1*0|WMA_uCO}4}`ccGNF5DaEb)KituL>ay2|F56a+-`&R6bP*XE!>0cjC--R z3t{eK?q}Gdw8A3X@#H)Gc1NWI3~lSc3dX-bBmH)Dh$s!{{+NE_5Ts7x#$` zB0McU?wj!R-X=+zIQuc7IQv0GM>K`D#-P!OI=I_cAN*ygY1{Nif5u`E|7QR7xOrph z2$zmh--)rL)#&B+eX{e}`AE}#|M@^mwC3Nz=wo4_n>z7${@9vA{P|7A6Khd2nf76( zAvc-!MQYitv>(!Cx6)Jau8!PF`=fk>AOTz|SVh?9+lGy;JXjVs zwRT~%D;u+lpfnwIYjG7pIV~&rjcxq4o;RT90^D!r#NEbYmqYm*`}ds~OXlW2x~KVn GkN*Y3qhuQZ literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..05b6b73cb252c64f04efdbf844e10396b09faada GIT binary patch literal 5600 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 XVsAw8t32EEJAt{mpYDtP@8iD!^dfN% literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gpos_context2_multiple_subrules_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..f79712cc46ec193b40e84bb218c97672a7afd126 GIT binary patch literal 5600 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context2_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_context2_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..9aaec44ff09ec0ebb84e8af8c54bf9b27fd2d4e4 GIT binary patch literal 5508 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 T#{T^#$CA0ZpYCt|@8iD!(spAT literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context3_boundary_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..f8949d475c7c9c6bda290a13c1da5937f88b7ad0 GIT binary patch literal 5476 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context3_boundary_f2.otf b/test/shaping/data/aots/fonts/gpos_context3_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..ceb7452a8e6045a7815137f4c2dd7f74e2c00b31 GIT binary patch literal 5472 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 iePcbYSd2F2_*y2q>zq^d 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 vl!($apTFC3Z9vzp;J4@v&rXAE5h}|NHoFrSfAN literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f2.otf b/test/shaping/data/aots/fonts/gpos_context3_lookupflag_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..bcf4d17ecdeddb4d41d4a640342894c601ab5bf5 GIT binary patch literal 5504 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_next_glyph_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..6f9d9197ff2435063eafcddbcf863d0b0e1532f3 GIT binary patch literal 5496 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gpos_context3_simple_f1.otf b/test/shaping/data/aots/fonts/gpos_context3_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..470c2ed3e9100e53b3b0d3cb3eec965b1cfa6bc0 GIT binary patch literal 5480 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub1_1_modulo_f1.otf b/test/shaping/data/aots/fonts/gsub1_1_modulo_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..7ba237920ce894666b1deb361e80066ba417a52d GIT binary patch literal 5216 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 GPX7zU&O$u^ literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub1_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub1_1_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c21fcd3f0220cac15289dbc58e93936b5309a162 GIT binary patch literal 5136 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub1_2_simple_f1.otf b/test/shaping/data/aots/fonts/gsub1_2_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..d3851b3327bcb23196372a2031a88f4cd8bd5599 GIT binary patch literal 5140 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 M$NTWVwf{T)Hz6cBMF0Q* literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub2_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub2_1_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..8330ad4cffc86ce636d4dfcad8b32a6af665c0c9 GIT binary patch literal 5224 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub2_1_multiple_sequences_f1.otf b/test/shaping/data/aots/fonts/gsub2_1_multiple_sequences_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c912937e6a808696cb82050e44806024d572a4b0 GIT binary patch literal 5248 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�=bt~OR145dXIN-P;Q>85mJi8r^=(4D}CwDZS* zyiaws_u6_q$BU1_d|ZFvbf%B`cx+S@^1;Y`k*A)k56u;3cL>k53u1~1bSJSbj%5@b zXtJ9*vx8}=YTCzAG;L$)+0|AnZLS_~049vCa2Ok_zgWa?zkcc7H+PKuDHiOJmaYVKwu6T z6?n~kmA$Zw;unqG5QSVA`B~Jda?Q8OnIsxnlPF8MkWg0~)|fG1J;YK!+&|`iFmdM= zTf$!x$kzH{cGxj&@3r^Ydxz}jT|*Pkw{7h9+O3S^4t=Nm4)skJPuafKckJtHu=lYJ zn}c=Kwp!}So#8#g3v_r6Rc5hNRnKB+8_m(w$mX%1p`AwkM6Liwwm!p}W6k2KSRFMl z&{WMCJVv`fy6}ycoOm$*WO>Lu{InI0)YjWxHGr6e@}W zPiEe)=kW#tStJk*f}gXzyP&qF99eAJPg<#w<-hnrIM6mxNXYoR%u+%D|1{ut0pSO4 zH6%d+Ga)}6YW*Ph45TyQ3x2hK*v4mJ3Gz`V7IK8)s zd<1(Yf`*~A1ZF(>5&q-HlE4zaOyCTsjMqOqo=%(_ZDLsBE5uikjQ2*sPRG|l zGQKA`^T|h}R_>a%;3xRtfj72)pB_C78m7{q)*trqcmn6w^Cahzb0H5k|7U_d;WhsW zGrlhPm`fSIz5w|B0zEJ(2(EZO)I84n5mTY`IPVX+RTKG1kT*``CqrNTaUvf8^*0Gb z6vB_0J@D^p7a;|5pp*^Yxf#S>Sf)ZvA*A_Gn@Z$DkETL-7yRCl5*s0p#<$kN@15Vi npWkk7fioz8^T~j3^ISNi7vT5RZ{M5$c-s<>+VFq8|3CdN4j)Z1 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub2_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub2_1_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..584a7f555392e7c35f29ddac046b6dc00f316d82 GIT binary patch literal 5144 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 OdnX?5#oyQd@AALwcQ{4> literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub3_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub3_1_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..4ccf55f4a8cac6761cf8d552cb3a08fa17b582e9 GIT binary patch literal 5224 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 AJOBUy literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub3_1_multiple_f1.otf b/test/shaping/data/aots/fonts/gsub3_1_multiple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..075f1962d97f09bd9ef9a823d8073ea72a3ac2ef GIT binary patch literal 5168 zcmds*d2|$2zJRL|NGb^eDvb`&(Ag6K?R`P^O#~U%5C{r1S#I`_jii%wmR{0T)zw=% zduJs9B?)_oEE5oj0)onbqcY3a`JrPV)6aIvF`Kndo$gOM*K@bB3F+J*)%?Zoywf!R#$~U2H>-x?GmIDgI%>1og;fo5-dF+HB7SjXX!CO@5vrj{Nup zr2d7|a9Z*tq{K!@0{xyM(th2CKQvAT0)ZeP1b70N20RJi;}!wW0--<{5Dr8EvA_$! zJOC~UAqP}|7FYl*29^OUfz`lT;P=2rU<;54Bmr*#yMbgN4afkpfjpo9Cv#6>`{Rf zN~BOBg&HX|NTEea2~tXtQiharq=W-fBBcr`)kvv9N-a`JkV=YFGNh6tl>({YcvVQH zMk)6Xks^%@Y2-+wKpG{|sE`KER)aKJ zq?I786lrBhD@R%d(khWwg|upA| z%_$VWnwy+gus5$jSCpFaqIhX`ws;d>y->U~inz-Zi~}|GA9%*Rr7g;CmtcQ>NT=O?d(yfHMFQ+*XN=PZLi~!h->*0bp#AGl9bd z;kN|10#C+8fQKL^CBl;s#>!-f=>UlH0Eo#z7_$`k6vR3O?Uad+9-Svzx;sypZ&^|! zOz#r*@^QPU>SHJCPK3HW4ySYW%_}GR><_rNT|?F(^OxKC9QoXl{wnAJvSNF2uKal9nxm128>syxZ|K~@|_3ccnljH0#w=m62BN&D; zK@`F-AB`7rLY7;|g4C(I=&%p6e71$pWcjS>BRZQojpFb85)W%e`UXVrbzePk-Eqg| zcp+=YVj)QA+F}$IFxibcu54G0tG1zbxZ+*UFn5Fdz;S~+R%bhv-bjTr0$~ zKcB0lD`|sqr!d{1Gf@n~v7t<0PK7J^i1kYCHS5{kcb5o+FiTsqq%7v|IzzF^tZ&$7 zXY35eG}JWG4R*?IXSq{_fgu7ag^7wB2fNtMk^kHhp$A z>*0cvlCwgfQIbsUEo@IaT1WZjj(rAK;H%L<(Xx39Ut0M>*3Og^X0yHAWo|Kln!?ZY ze&4|CVs^2+A74T4v>j&3?Y42Q*@GU-MIB8sG|PlK`B0kwT@wE^> zp4j$@?LGTl*QZ^7xJmUMwVi7`)p2|GknZ%lj|6$a;sYf^Z(p{2@LkLIwGY_G-6)W- zf0sa%Q7mV(akB~rcILOIQocFAC`BQ@$k8|vvZpnqn}oSpn}z4ogjwmr%uB*@K3vC3 z-rz%d_ga2h%AG8FeoMX!847DqMV>xCzvH|2`I&q`JJs*%GxbmGiW0oSnCQX?AAjqV z;5VRNBqRuv2jUOqK5%|rZ*E~*>M38ea6uIEKfZ^e_gk)2TxY26{hYmfc41~|YH_Mc zh+ibcmkLXrX+zeg!yUZ#Pki)UKH~65@72pkyLt?VvKY$pdXi~J=nDJl)|F)w!RJ%` z@)Gp&sZotc-V_mQRC2o_)TwklJ$j;xlDO)orgngCKYwRgM$odJ{)ezNIZrl+#o*lp_6w^n$~bw;Pr;c&t19{OV6m-OE(on;;aT~lA}spP1t zF+v0}z&h9_YcpGKI-qY(b?5a&?Vcx0@kX{Tbkt$^kD7r(vt>?Wgy}igQLP|-AC~WW9Q)7 zCyh=QaVE}aH(B3c4Q1} zVYxfKulAG1bB)7q>fL%*nO*19S$4CvXV^0hXI$O&9d%t)9qXoDVdvZ5Y`tut1eIVB zIZIu7XDP)6(4BM#19uDg*fS6oFZ)JCI}fCshOpRi@YS)<SI$1eaAMprnDjn!W)=98{py7vtqwV$8*dtOm6HZwvzBNn4Po9$^+7#Yi~<&HTzFe)%B3jB*8D zb6;gI?4tO^V>d)07kod9I#sUuRymVMBWogMDHoR46^Auu3|bGd)DQQMxgSj2xy6?7 z*9Ee*euN!yjM)3^{r0|L`+3*!#Pe-Cn^e1vaonNrl;5Gg>EbEd*ZPi<{swzL>##Xk zM{TR6uG|^kBfLn5=TK!9OI7tOmbTFxP5HKr{S4P>)KBCJaAfNYdwAwBC~ZxxlqGzM#Q5>uoj;Df<{Oe z{0x{v{z(2v{7lHka{|gxg2llB{sEIi{QQ1>pBk5NvUJ6=mBbQaDX}4F1gckYdT%lL z2)0ZFjX-TF%y{yHqs9A@Kn`CfaD-EEGx6MbI&o}JP6qI~i6Nf^7Cwt)yfp$gI=&2& z@h!pDo}H$eyldKmpWuTB-q`+gdh{@8gi3=}f7r(337lV#lblP=g)%;-f1hAWc**~V z8J`w>%%zN?aLs%4OvfS(;dpb#H=_OrNUA?8V zH`z#ol7u}(mI(+%0YPQJQJHa&=W#}79=@ZfRL6>k_uYVJ=FI!U|6kSl-MY7`ezn~D zebv>qcGIS{L?}^91QOznyCM~&J@Q+1MzX9uBTf6ZESIJq6#wa{Ldk)}({xV>5eZM?rK16GI(q4x=58U^i`jNIb#MaA=4 zp*;uM@8{~u_YkS;pgPSDMNpnDH*H!-f{h@af+peLlV4Q)u#1pE8*dkr#Dob1IRUC9 z5R_Vyo2&mzP12v1H5j0h#Dhc?^e#iU@HZDz>GOe%fivjlPY z$0wi+ESiGLvL~S=)2Zk4nzQvKnxHM zJO|7Lpi2ljpaQhOd|)B41XvEN1XcsD0qcQHKr*lmcmvo4qyXtaCXfT<1BE~dP!3cA z)c_toGhhW+zz(0egWiU>~p_cnjzU4g<%4LEvrR3@{A516%^$1FizsfscTj zz@LE6fWH8Dfd2x%0=@?R349BD2mAm$07ii^;2{iS008|X^|9GN|98Cq;e!xAgK~bRYRQlHAt;R8VS-!kw%6za->lpjS^{8NCS7P zK^iU6N|08Hv@)cXBdr2yl}M{XS~b!_XK0t^@6i`#qKsm3LQ0}oCXvX*i&OJ=r-?V} zi;B~7i^Q+wrQ{dx$uHCur=>nGUYwI7-hg*65^qQ=N-Hddm5-8(AW3>Rk@{;o1i`T3 z6qpL&u!rFxW&t?d6M^Re9OfEe0f58%W#Cl+hxKLvo)+WboCeD*0Eclgpa*dHngANW zVcP(-061KGfCB&y)1$yi0Eg#!U^jBng#- zP8Nqo;vxzc(YT1gMJz7ja1oD-1Y9JBPL2!};{uFGY(!!s5*v}&h{Q%DHX^YRiH#_1 zL}4Qe8&TMZ!bTJ}qOcK#jVNqHVIvwF(b$N_Ml?2}u@Q}pXlz7dBN`jg*oeVK3^ro0 z5rd5wY{XzA1{*Qhh`~k-He#_6i;Y-p#9|{B8?o4k#YQYPVzCj6jW}$?VIvM3aoC8% zMjSTcun~uiIBdjWBOV*^*oenQJT~I75s!^{Y{X+D9vku4NWew{HWILrfQetPq6y8@+i6YvB0G$4Y7idZOWYxZC4!I%nOue7w(opL^RiWF0bpxs}hApDJq2Spe$?97!L&O$&JJ@M)54X zdihAc<>C!Kp%a;+1uyttp4_;BUX;KTkU%ryp8QGpIym* zF#m+)j1X*;q)>Z`I?|6cQ2se%pFt0NH5x2hGIzlX%b&~Mk($bEv{$;!ZRSr?`RU&8 zo0y%ZE_k}%3`6d z)>#aTCrYRonaAUrKSIbCg$<5Q z7je)X>M@D9j%{njk{<^rj4xFeiJX@NBv;BSV;eQCP}H>UhZ; zd^qo3%}+_aolVbcD{vu0Q5~wv*B2CYe)m2P`H1g|hAIzPfE-aIJ; z45(icl7xu^i3juUJHKu;x3O)Fls{HDFADn~{{zwcZC9(VF;ve!&fYVtD62fJBuynG zz9b};3yYoUL)MleC!=Q>d=Vq%B3USy@rF?3}tzJn`wLaGW*K*^aUHdoIOq9CN{VOc|Xb+UnizOLhwj_GJs6&*yxw zu+n*tq1=u5nbO_e>GkgQta7fhtg&VplTr+?6fZcF)Rod&zV&GN>55Yorz-nu54H5$ ze{kFQ4c4m^d!!y_W}mf}-q(7rqO0?q%WG{ldfJ<9`^vo3QnkpQ>CA9t(B;-ji@Cg{ zq^z{mz!_{++~#*P-|P6o)!n|gsiV80+uK7A)*mZBVW3zBBAzigs*KiBiccCl3w^(B zbgGCmaYnnz`UY#LShG`5&l3{Lg_j-;Wy9t6cRMa!w4QIf;Ot21O7d;)Odsy7K0#^t zRcZYCY(AN4;5?is!tN_?sh}(DdV`~o8W7frT3`0A?0iL6pHiped^g{^+4C{Q_l#{4 zg}vkdUR1u(SVpgMNVddzq_lezyJ6h3;-&N4xLx{n_8l zKD@8B*L$Gnql<+PlF#Wo3p~Xw>-rXDBR`m6m&%PsUtT9<78 z>o4zK$1JgUh8$hYJIqP*koj$jPvD0|AL@@U*s@{s+81jU)=;dCWy3jhFk@pmHlnD~ zozYkSN%Ps};Wzbey{p2mbLuR+*!t7#>88`Jp2p6GZmNNG)2@hf9dEW@GEjm_u!x-H zF1@py;)3Wdx|4yYg?#K82#Xi}qoN)AQ%^xyY(MbISokqv>KS47o`Za_g0i|A7vyWlozirwPe<1m@K77Ij^5a6urDXg!nL>Ak&6IRN<{FeX-2ihhI3mboznMcflZyNBqfCz-Q8j_%Z zspHE);%WHjG9Bt9F^wRL(~62=>!UXyGDlaO2QBkK~WU z&xCAzNkAQHusJj+Flb^}K)|o>QR5OW7B5?}oLEFGCf0?FK=TSN?=B=C!jXxP5oj%j z8BYOlmH1o|Si(ONxWY+zH8FF%e0*(CPXX{fiD5YbED}h;M35_{l-O&YY)VciC(A=oE}(81@M-`@YX_t*?aEF3>mK9L7!cpk3xw=J9* OFg@Ihzpwq@>3;z|UN}Yo literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub4_1_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..08ec01a7282705ad844fd60e6c32a62170abf8bb GIT binary patch literal 5220 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..90da33160c6dacb45a6ca41de7721cc623a581ae GIT binary patch literal 5252 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f2.otf b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligatures_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..4383ba93822e5fc5c9fae06ac3cdae7d5154aa93 GIT binary patch literal 5252 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub4_1_multiple_ligsets_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_multiple_ligsets_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..cea1b1aee12c30626da984e5aa59aa3d8f37292b GIT binary patch literal 5240 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub4_1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub4_1_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..50c713a85280369f470f5c83b99c110fdb23986f GIT binary patch literal 5148 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub7_font2.otf b/test/shaping/data/aots/fonts/gsub7_font2.otf new file mode 100644 index 0000000000000000000000000000000000000000..c98bafb51d4992a07f16935687896b85e148c0f7 GIT binary patch literal 5116 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 JAKJf9{|h8zE>Hjf literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..444d93174a1bd745633bf6f73c97244e0cbbd94f GIT binary patch literal 5516 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 BVjKVf literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..2268647d75fdaa8064c65ca49509b61a658a826c GIT binary patch literal 5520 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f3.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f3.otf new file mode 100644 index 0000000000000000000000000000000000000000..a5929474902ea64b7e6cb1ca6ef3f7736cb3828a GIT binary patch literal 5520 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 A9smFU literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f4.otf b/test/shaping/data/aots/fonts/gsub_chaining1_boundary_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..f3f6b8c28e52ee07dfdeb242abfed23ef19199ba GIT binary patch literal 5520 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 LpZ?$c-`jrykL_j| literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..741362c8ce3ea36282e5f944705f23e36354d361 GIT binary patch literal 5616 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 b_l_Kl^g(#-@6)r-_*yWx_S5gA|NHnKrcHAU literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining1_multiple_subrules_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..67801f210648822d3c44a7da04919e31d648f445 GIT binary patch literal 5616 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 Z*_hKq@Y>&|XYaAKU~cWF-%0=P@pteda|{3g literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_next_glyph_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..655000aad2d2a85a9dddfde0f76fc0b9f860d93f GIT binary patch literal 5560 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 S+LrIcoHDl$(*4f=ef$^O-)0y9 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c7709656a61ff07cedf46c3c0260824f7b570917 GIT binary patch literal 5508 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 BU>^Vg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining1_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining1_successive_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..ad472ece265bb5e6be2dfcb575606a980e95f203 GIT binary patch literal 5544 zcmds*X?PS>zK5%lkQ505E{#esWM2few{&+<_RV!<3t>^9$#N31k(F#6vUI1bs+V+U zPnv8bq9&0wM34z6L;=NR)KR(Ppx1Fm?_9i(qEd+!AMWoYVdg$_?t>OS@CrcKW>0Zaws%_vu{SrZ(#S*&Cj=JyOUJACb`)oc7B{1&48CARTvH^#5{ zj{l1{!`zvQ`uERnd_fx!G`9;g}7qy_Cg!F|ZV@0IR{{;3@DsupVpz=musRcpmHm zi68}}feerhazOzo0;QlF(8p;8Rv-cgaDjTz1X{rX&)---3tR?Q!294s@JH|&_!GDW{vCV`z5#y+-+}MJkKiU41LNQp9-|jP|FQ@d7JbXk z1n5`x9&j(13-Cot9l_XY0V$~#8Lt=43u_RVUV)Z1}Kw{&FPDyks zqEi!{hUm0JhwIf5ou23nL>EW&N}^X0y_)DXM6V_KSfa=6=!xDy^l`+XBnA~RsEI*C z3|eA{B?cWa;BF1X5J%#aBu+)*)Fe(r;e5(N+?KEubKr^7>+6@i?8m33VNkGH%92fyKEZ+kk0UC~f244XhhS$Ll zfQFxp5W;FA?EJCDP@V|4`?1FGod~mNtTAj^ym?qXz;I=kgEinOunxq7ZD1!z0vMKT z7RUn_j;sk(0SrUd4%`64kM)2qfMLh>fg=FJjXe#{0t_?u5_lJ2c(I>?&jE%N`#12P z0KS?RCzpBd~QLbFhsh0!dWW)U=tq*)ZrqG=Z6KQqKXm}W3Ss1ZVq5Nd=_BZL|u z)Ci$Q2sJ{f5lW3vYJ^fFlp3Mb2&G0SHA1NoN{ujTgi#}m8e!B3qed7t!l)5OjWBA2 zQ6roh;nWDHMmROXsS!?%aB758Bb*xH)QF%)1T`Y45kZXzYD7>Yf*KLjh@eIUH6p1I zNsUNqL{cM?8j;k9q(&q)BB>EcjVNkFQ6q{PQPhZ{Mie!os1ZetC~8DeBbpk~)QF}= zG&Q2B5lxL~YD7~bni|p6h@nOdHDag{LyZ_}#84xK8Zp#}p+*cfa(l-jdSz>`w5sKN zuiVt@D;?<_ztH z1Q=WF9PkRmcr61L@yoab)H94v0)7cGR;D4QeG%urh)F+;Sq?sjSm&^vtCk|h9#Smd zl`Su_EUT1fcgcID=$%}}(GzvY1Kst`+S>UaTs+?AxM6?QHDnz!f3;Q0)SSv|$+BnH z?H8-97IUdk%9mGj(#)-j>udUCu`IZJq481KdmzD+dA{^?`gfw#|M&M>8rp@nTD#qW z)GD+HO)yO3vLZlQIToX^%js@89eJ(s4X0yJlrk*R9#KlKIBc|;Q#k4BuQ50>Y;-{J zR`;dj?>MizoDZgNUn)&Slc`Ny zh#)iO;98-*y4`WWBZWxK=Rc69ef zi@T++we}5<^t8QUk-eNR=S@{RmrUBDo^Nr%q|KrTnv)7*bZpjg= zop)Fr2kJZxZOxxuO27Ho3FT|DUzIYE+nd*(a-@zMT{!+3df@9ZKgEiN7C*B3!So$T zNy0`)smt7I{xnINHclf z-GY)Y%r)$D=J5sP@;zHp z6YVyeeQxf+j-2*nZgjz~v5J7vu(4EzOa9+qr&M zUv>XfQ=IIP#}(&Bq?iv+%3cHdC33txZ6N05tQ)o8G?-h()&_1gLO!Pm_^;8Minm)Y zm%Sr!-3RTC?)iCpijoVGb#lxSIi^TnUYjyxZGNRgiug|E69FMoHE}06xQQfbP;3=ORGbl98p;6{oF~2gWp`f9#KEGw3ySm=oP-861 z$SK^AVHlKyzE10{>M1>B|Et4N^M}*i#p5;7wCXp7p7QRh?&{9swla^ouBx`m>2x8v zhrTHMivO#nv!vd{S2k4Cm)p7h8lan@% zyYM__jm=VQ^=$7=aLbDirpxu8FMM}tY3+4^b2rd;N>^8h$8(_m$=W9^&sg_V#V4Ac z$Y1e2Jsj0HCR%OB@> zyVWiP)s!|C^$3^U(gMeYH@dod+uM3C-dOPMg2M+}dOU}^-#?#wGvRD;M^1fy^SZue zsqw{JPL+_?WD>B5JU1x6toXCzNb^VJljKhIW6!PKy-rwRsULE73a<+%%|qr_IVoBi zR=ihyeDRhIo1cAj|I+=OXcNUiyV*~$iFPq4uhgB|SMy2JnWo_vi`~Vp5{I$YXxSy! zoEA?vo_2LNbkucmb)uVh1)XhwvF(D1lXbF1QCs9Ht}Wv1zI-R&A>eJH8NU}{@#yH7 zV#fn`^zgT zswzyTqWtxRmbA*$>eQ-2Pgawud!-c6E*<;nI@i(OXX~jyR&W&QSn&&|_VjWekB=z= z-W$EHsBf@01ZK(eJLCu2(c&Q%=mSM4y{%}$|pfAc<(<9VCN&#$mrd2_`? z2M9rYnX{^?;)|uyws+2d`K=UwP@4HWNn3d+x1+fGnNQ@vGHoR%S}Zn8;BJABKWXKp zwseIwZ9$TpZHU~n`{}GrRh-k$EUn%qtsInAa4x^g?n~miot(6E{E8yr+~_ZgPMvF! zRU;(u#G1faO68Sx1wl<|gVvWt?#Js#-8ZJ*+`*QR=VZ36VMH8pjyU=p{f@q2$643# z)bHC?aa+w6!FiRxT6&fHwoBq{-xPQ3>u+@Qi%y$Ubk?+4>Pl-vdgO=skW8+`V%c9Y zSLAKHo##e3jsJpv8uL=Pe4QD^Y1T|@x_!TB?uCSZxs~j@xqAy-{>WBGf%T3|t zr)_BIKwta*K_aXyUD2|tQXH}mIfgjL$&Nw$amma2vsv=$nLI#d^JS({_Np!I&aJ5| zB^KMZ6IO0?^{-wC2i~R#2$=XUGXwu+=;FoP!>mJMG5c7Ld;=28Y(!!)#omNG9?1*y zlFi5yki3{JNM6iVBriR$p;hl zMC9~8)#sRz_~QdY2WB=qm}SfihR&c^h69mPYkK7UI9|cbVeUowKD5gsc}*P2;tnQD z)R_%9w7i&Eg3kx^CH9L#DEXts$!oa}*EJWP zHRdr7Fl>HuUOrl($Kr}JjQLrp(f^Ljty|cJzMek9x^S;E*q_*+m|qz6#F{}FCG7V1 z_4b_>;N^Au|0Y!@mgTEftVZ7~XVy(0!G=pT|8gmN3+H8~kD#_3i7sBabJ~&;Ys}nm zos-Xb9^Hv$@=hi{l+ddT#x@^Vv@a9s*%+L3>bQR#-TasHOLxwC>}N~}@sIXjms>Zd zk8mm2>Wy1r literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..845c2560acd6b913c49591947273cdb07aadfdb6 GIT binary patch literal 5724 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 JF8klN{{mXRY7_tf literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f3.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f3.otf new file mode 100644 index 0000000000000000000000000000000000000000..28679c86763584d87ad82b63697ddd90edb16459 GIT binary patch literal 5728 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 J`?CN2_)mhtX%+wg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f4.otf b/test/shaping/data/aots/fonts/gsub_chaining2_boundary_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..14746c6e834b6a923622a6b417cd3ebb87bc4476 GIT binary patch literal 5728 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%0A~Ot zKC8^?yP3Ou>0|&E0CS6-30`3s#bR&~zl;k(EyMUG;g=9|WfEfA4{`2?nDob-<)G&f z>m2gADk*a0A?1>7x$->A;tF|shrCmY*~*n4IbL%t$W!Zdxn{qA@mP=Jru|j-fOWw9 z#YQPxb27gv$DUiWPpq<9%q2nzUslCQQ#UGatn87+(vY&b#z$qJz9et<`I1wa--uH0 zU*Bu0YZY2tcDn=CEHnuXP?$z#WuUZdBvxscGd*%9yvz8y)6p+VSr%!BC}ox(GTO{( zoOJc)Slk&t+^2lA^U|@mombt?2QxP>k|)a@>ni2>LRLezJIh_+uCA{hEPbPP(0;}K zj`NEBNR918dIJ|K$c#C}CA3zxI`(^|P^t0!`_kkOrKyigVX`VY$+UUbhQef%cSCx_3I5ro?&L$(i`AE{ zr?*{OEHm;f!`{WkQGYR-c2}8;>i0MVhhP`#D;oHE2j_5z_8_mh1=eTkGaWMDEc)y} z&s;rw?Wu1T9=6(fht;va##`6Y`01t0Tl0^rPRst4s$_0werwv{8g6**=%?s`FGu{9 zOCMVB$chIux1^*9YaJzSbF=xA6ltdSyLw@(uvOeP-h=j&4jAY0*zE4v{k4|YjXWpt zq7dYgf_Uk^P14A}gxqjQyY&7S7ECU4h~v->;Gyghh% z@bXJxc3EMS+4xHNp0bVY+;Fg*s|@TPnW?m+JH%OLhuK{n+_G|c*rhEWY?O9fJR@^; zd!70G?lO7ChIDy~B~^T;de9JC1Gm*!HI5n){QE-@eavAGV!oIMMduwgKbG zXWo-Fd5d1yJMiiS%RApTe^-4|93MuR#q-@VQ_P8Wo6SBeuW!q))>LkI&d&+Tz~S(b z7$tF})u&gSVyWGT-UqMQ9i+1g5 z`}QqqrsUVk^}2hidM6&m$zFL>d2UFG{osVG=+iBf6Xi*Lu`lP`bbVE4ZWf#CxZz0o zoHFpghHoj~YQ9|hw!n2Busb?u=kF*?-JPnHV;9P?h4K}pBT|AHH~4><^-{zVprYnx;?c8 zO?y36wdT5NV`^@h+@)>+wE)n3$6 z>NVF?x+<1YfXGbU3qPpo!d9cC=mmqQ*5+0iFH*k6g8!Ka=Rk7 zJtR-@hPN!0LjHKIr>|2uQPXB^bMCL*bc|l#UEnx;vdOw3b-Rg}Zm}-LuDJH`z+<>)*(Dv-NX# zN6Y^D){dGEZztbheYEhni4z4xykK&cR$BLPQsU?t^!=uh=}LQ*z0y%-eO@#bKeJWV z&68sa<%Q!zS#z=Fjn)h2t>>CwceN(ACw8xIOB-w}JI?8)CsU=>nNkv0W3RQ>20OY7 z8;kj3N0G^y$MwmplueI$A8&iYSe;y9w0D2-(g&R%aZ=~#I%VK%!`~?j*H-T3pXF5t z2(b3)7(tYvfoUi8`I?&YRJ=po)`Mg_6 zXN%f))fP0a>RFtgSj6qB6!IHP0uGVq`sJ6Ee{vjd{E&Q{+OD4e++*8U2}>=t1I~8g zHQ|JL!2BvF#Ylt7cZ-fK*sx~(vybjuw2u>Qq8Ma1`wKSFE(Yh9c+z{SKW;eFF!*AT zr^sFGFuIJEZDRE)@l^dOcV}H&O$S#adU$v6+13|ZE|@r3D_fMVLU)m?khA;o?R=Yn zuZ3px9)!iC!z0QqFQlAASZqG{#Awh_dHQL2&d!%5|9H;ot`R&ze{jFwcKnL>U_SMKrVG?+S(I0MbZLK}FuG*u!kHC%= zy>N0zH}}!#h%)fq;Ty`@I(uDEjy$_fexOwj;RJtAlGyBA&hh?L4zu0t6q@%n?iD$n zw~74ha;ud$mydOT5X_f4D;vr`UnFgM`~3BI>ysTz-a6?AF^<|O!{>Bl{&518}h$ZwnnQf^X5{H~a zjvhy^qi4`@);&1!`?gWsRJ}oPUgfWrT;;y*kT}~{MQwX~>m9wK)8-VN)h(8q5?5%K z{4gJy%@tcL`^smDyp6Z>-0-^5pU_Vu3Z>i6nN^fw&9-LR_lZXCA^)m!yQ#L)A+v7! z;bkX&n18g~5^jCcf+y|oY2DXPgk>d5o0eCI1NH&O0OvT-)^9&1DXc%5B}Lcx4KiCG zGxf5JegPqTeY05gd#WuIf`V|6iwp(`ks;ZXN5^A^@MIb+)fV~zbkxTXJe zj{=(xeyD2(>Y9o3J%Ij?`z1$#oO{P|Xg~PlK5EJ_n+e5ClvBHR%N zmMF)be(%^56=QAY(9-FEL%%Ly7GiURzKs(7NJ}VpO`LsEKK{nz<>USNzm<>o2-W*B zG4KIneL&xR{OLi={mcUlTacPxfTz&9FmhSOf*hpiKV#4(9`vdy} z^An>UJ2SY(6^aA=eEcQ_Dipu`pB@uYw`BR!70hC03A1YQ5R#XuzrKjQjhdOsLr5)w z(L;fEr_WO1jFl-`Iv&UO(?T5M?=rp-MB5pHJYT3-kW6c1Q0c^df4|%Hv)H+H+Wa4} z;Ke`oe?4yBnmoj%A=d|Wj30Q)FYRRKvU71wpZm`TYN93o4n|)Ki}{qX*Ym^n8%Dr) zGTs;~{fTP@GZm@vd>>q`o4EGHb<4!{B#hPdiEBUP|G*F?9~*Pq@r6ic((!G`z)YtQ z>}GCdvQd_WU5^ZAC(fzJ8NWMkEI$>gt=Q^|!`CVm3VN>*TYbMyoxe^k>(R12v@-+y aH#unO!-(2nr)HnAv0!fRr~AJD^Z0KD0ek}h literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining2_multiple_subrules_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..ae0298fd26aa08b015b268b43f76ba2b91c059e4 GIT binary patch literal 5824 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_next_glyph_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..878666f5c10c0c10096ecbed969cf53307d3660e GIT binary patch literal 5764 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 Q_hg?kw+_&~+y8$22X$R;5C8xG literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..e8609309d582d0b0299beed0ae35e130a2106441 GIT binary patch literal 5716 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 I{qNg<0)yda7ytkO literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining2_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining2_successive_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..90f9f731c468d396ef8d40137620f814e040c7d6 GIT binary patch literal 5752 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 MZtkc1wg3D0Z&fgC5&!@I literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..1aea8bee2c011008e43a630a11e48940ddad1b60 GIT binary patch literal 5528 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 I`M;0<0(h%p9RL6T literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f4.otf b/test/shaping/data/aots/fonts/gsub_chaining3_boundary_f4.otf new file mode 100644 index 0000000000000000000000000000000000000000..e81d00ed5e8138bdbd5018b309dda1e24b436af9 GIT binary patch literal 5524 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 FzW{z?VjTbg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..47c1007c067134eac205dda5dcaff6a53107f35a GIT binary patch literal 5572 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 NGPe)XInMvR{1+Z5Wf}kg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..5982eb512c190d6f631b823dc2b874d088e6e6e0 GIT binary patch literal 5520 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 LkABDeztjH$`ruz6 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_chaining3_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..359b12602f129701256659e10319a31777389269 GIT binary patch literal 5540 zcmds*d2|$2zQ?ONAt@3BR2r3N$i4__r@PY&%D%XdY#|U72w84IHnIR&=#X@}(^b_= zy3^U4Y$T#4ku^k+2`EGX#bwk{d86p_IHPYKzN4sAV#UMz-UMgfnfLzj-&gm1epPj= zKDFHX-Ri#e%=-1uFu_a}}&6LZ!pa5Sq#GlJ+tm1b?)V)VTQS*1lzZz<)!XqLfFk%{|M`=voccCv#va;VwgLl zu&&EOh0+vs9qZ3xJt`}&q;yHif)=b-Vg0SV)Y6?y`f4oBdI}*RKQ%Ao?z0bmj`j68 zpK518amme2M$Irv3$}-`jK4p_`eTu$yQlBU%Pafm`V*rwn9+UgXq95L%5U^;fBE)l zexX4OchhdaHJcV_x8FN;s7L})6AjUlM4}^lVjxD6fXW1tpe6|#lAt9C zi6lWs67(d&KoX2Zts-hTYNFNB+)<; zjYOv+x&)$A6PBzhImClI}w=ru&ICHh37$L;8e-azz5Vo(u7 z0x_tGK|>5$Vn`$g9Wmf;4a8t1Mint85TlwHHN>bT#zbP&5u=_M(HO?%1v|@%vPo7+ zSX^3sm|CS$hb>Jn*q#x#uB^BuBd<8@@%*%cqMZdrsU;cd4~8wx%?(>icP|cGn^Bxm zv>TO^or_^vemj%?TXzV+W20SQCZK7L$HUA8G~MIDgMg;F0W1VGy&na%chj`q0Pwb$ zNaqa9cL18kC7=w@^sNCrplMqVngLDMZg3FLG(7@N0Ggg>!3dyf`7Zbn&~*G9dntn1;2(yW_3&I>-c_Q8J!5rOpBF*A3N4I71=3(^!-IZMmR)HtMYLEm{z*dkB z&@I_~Pz=x=Srae=bVJqwJOJH~^?@#cZpZe4!vNilJq6AHbTjrMcn6?+v7dm?0J;_X zH}IbT-HH8K6{HH99u^c%Lj(JSdC?7~#|ir$#t6!l@BX zjc{s&QzM)j5!8sFMg%n?s1ZSp2x>%7BZ3+c)QF%)BsC(b5lM|mYD7{ak{XfJh@?g& zH6p1IMU5zGL{TG(8d21UqDB-oqNou?jVNkFQzM!h(bR~hMl>~|sS!<$Xlg`LBbpj9 z)QF)*3^ih?5krj_YQ#_@h8i){h@nO-HDaj|OO04+#8M-c8nM)frA90@VyO{FjW}w= zQ6r8Tany*TMjSQbs1ZkvIBLXGBc2-Z)QG1>JT>B}5l@YHYQ$3`o*G5HW6`~`tyfyn za;{fy>J5+%_l}?M{jm3m-oSs|#{F~K)c&9^gZrmV`_et_Hv9n20!qAAnKgGZclguJ z0IC7{7CRff%rJ^2-~xUb7XdHB_$T9+5Pf9|aykHc9)O$-M4#p0bI5fL^<0e9zuSfptl>JhMyQDaCE&s*W75KNjNgy6WoYzJK9ZpYyuo759*B$nw=DDNl2Slf}JZmGe^{mi-2jeR=09PUU5&gm2#AwEkR%7AIWbjWhO?6dzkedWy6C%;>C z*yiA!Hs}6&Uqf5-rx$Z>JaSz1svKxmrExop+cOW>bEEUeKSc|CJr<~3_Q1l2R^Fep zB|TkO=d5sBS}mWXOS64HGzwdVt>U)H7Id6+qHrFM-Qk`)=(WC{%5wrQ3L$k;2ru1} zBHbytcwC>=Q&VRaIjfbo+2#r&ojAFCe7>@w)zjM0;_EqbW`FnTw}&qcUwSdZAuDV$ zt2N7aRc`9!MnmNSW$@tGY^4LuA^oxkEDkS&F_YMZ7%Hd-43?t{&4% zIRa;WHl=2B$O`9UZ7a)fCEuv-*N5K1;p1&g^oz zQ9MIm?EZ@XtF^P-YvQXLs=SpBZr?bgL=K29vDwxlHq<;{){@~V=!x3)fIQ6?*|tmy z`^(k7fo|bMeTS{XwZES0mo_S$o6VbdWaee--mV#}I{%S$@1IJ%yw_T9b>`OPI`cSb z-MAaiW5(DF7!aEI(P%SM_ppzw<|rU0Q3q#EFM%QG^4w9{xbfnext#Gj5-) z#q4csvLD#vv%l1Hmy3<(fh%RA9R1jN!{b?mBFu#{-7*fXWqjbM^xKyrHyr=Rp zj(6A`LTGJ8V`-0Y$s^5ko`1cotGB(a_rmpg-_AR9pryxmu=~ApMK_Yqlyww(OPW{r zEy+qM;|k3}ag#~FB=X##{F3r>=i%lL$;TO;>PMb^bo**ynbkYw>J(lRPFRL4uW(YF zG^~8L?AXGMYd1Xe@V>?SIMFVOAr4ERU>6-?XmN!ntFQLsrqfNsFO+%8+~v;Hx>V~n zvG$aBs_~S&yP>1Li>ntsygT$v`wMO7O`NQgt;)JmcUfI2=Lq0C`3?bZ3(fdlNQ;L@ z$CO*1Pd|yY*nIHu@sOkP%va@kJ71ClwVcgeFL*-!&HaAI@you0P2C4NdtWFV$lh03 zRb{R+nMzC6?6ziCXVqkxcl+|2Ox??+;CAWgPuIAP_C9-$_vo%8C`ZelKe?lq`)GVj z8T{_(HKn(~(GZd^&+U-!YnQ_~A<&a7wz^hud|-{!;;^`c)_u);M2_d}B0smvX5%eY z6Ad7Q@_Sw8rm8O%ODS)k`|?{U>VP!;50bX}U{Oa|_tPKCA$zseoM^S$ts&b5KIw#w zliG5W(v*4Wa)BXc$M&c4*PA(4pha4lA}t@3mT~UDOP-73*{z(kc>J<5`0VH}%1)ho zflVVM^Td|SSu5n_^}9lwvIlK1iQJFZj(D!$dUJ<8wJ-D{z}Ca?%OVjvwu_8v8TV$*)O{6F40xnX05NN3-6I1!vSW_SO&c&(<5l zjZfNeru}{G`v!@yykc3)ifVDlG2|TLoF_U49mgbv?PrUm=$YI>W=mwIQC8GdbQjfD zR}iZ`<+zO-UHPj5>A>5S!NC*%Wv1c344o9rEM_$di_ym##I-0avkryD5PLmh5{d%j zk`0K-C<KZm#l#gEyF;*YV+HpEmEe`Y(1KL+Y) zi1a_z4dz=W2p!YsgCi&0Y?)*_gDCmgz+#mI`rdnV%D z6Y;KzIC~<_nutnRlSgAQBAYzwLS_*@EKpa8Yv3koS>}#gbAOD=6wKr?==R_2|9d;V z1A0^zR~?5Kgw|BTz6+l_?!gs?;EL~K*piIm66{6y#a-v7mgHlN9-Fy&6LoY_OdVm} zXoqR+PwY?3FN}I(&R`i!*c=q#7ceDQq4@2;=!8VW(iO{AqMep9tEY}&^&*X5E@p4y z$jsCctSv>MlL9SC&!xf~qdHvaWDeX*H)5K+m&uPP^g6>(=MReoY4m6e4ti_9f9!qK zc#FL&(6m(J@5aVa3s3r|3jg-g@JJT z#O(#((-oe8|5V(u3N@3<3TFDm6QT9^-iX|stoO%q{;lOHcvc;^mIF|Kj3G=hK5A`8 z?@D8`(66$wFNNUS!d7g{X7ZSw_ym@LwM={+T#F?FBNzJ?{cijBo^1opRy1)H1-PaJ W^j_8PKBwPAn=v={({G#qd-`wdqG28Y literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_chaining3_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_chaining3_successive_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..ae39d9207b3ee4df3dbf45669943ffedc602555b GIT binary patch literal 5568 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 WJc!~q--D00O_|#V>AdIvUj7?$1!frl literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context1_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..0267cabfb4b68fcfd819f3251e4fdbb597edb824 GIT binary patch literal 5500 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 C>SY=L literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..52cd86161be825d038ca9cb04050141442895860 GIT binary patch literal 5592 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 Qz{D6ZH}=u}(Eok>54Z$z4gdfE literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f2.otf b/test/shaping/data/aots/fonts/gsub_context1_multiple_subrules_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..891356a083d5d1741e044aab938f001699021f0f GIT binary patch literal 5592 zcmds*d2|$2zQ?ONAt@3BR9Z)(A^Rezo$gLAsO;cAvW2iH5VG8aY-9nlbx1nh>8k1_ z-RbO2HWE>j$QmNZ1Qeox;xg)}I1V~KXY|cOkD^kE6%X%w6F4(x-uu(PrtbOt?pEJ> zt8V>nRo(ma+OSvPON4a<_`=rGwP9L%U1+O2hKzK3zYGXtVvq( zU(a7T!Z5dHBLCgfYaUSNTud5fnA_GPzcn>CWd{?&ZbJSz@+&jbQ_?aoJ)vTl+d1TQ znJ7@2g03RJ2>GbY+~Sf&#q(Q`PecCA+?0|XOxj8$XFFj{qCtFcXJt2?qQe%KivZBS2Tm#-M7Lrt6%~Zw=o$v`|v~I6c7lef?#k9 zm;r7Dw*w{k9S8xTARI)2Sa2`65767w039%bhrmLx1S|)Sf+xW5!78v8B!i9MS+EtP zf((!aazH*P1Uo?qCb`o!8I@j#=&(wMg_q5vTzp`W6Mql z7*}={xD(6BYI*WMv{QS1d^a82^x~1B?*ZnK}Qnw zB*8!uj6|&>YG~9%ts!bHQ700$j;QrSZ6InR(WrPmCB0vaHciwSp5N4y3QbiHRm4z53{}KXMGRHMQbjCP#8O2pRm4(7ELFr(MJ!dsQbjCP#8E{Y zRm4$6996_oMI2ScQAHe8#8E{YRm4+8JXOR~MLbo+Q$;*g#8X8)Rm4+8JXI9-jz#y% zwq9vj%b8xesW(76*gJl<_k-TYdjtQyj{9fb)c&9^g8QdU`@%i#7JL9_0VQ6m%&Oa& z+x+Qd0M!6- z9=lJucx%2q-@2$;p4lbukm9y*Rfmq&9|`ezU3GPH-aB`s&w17HvU|ujWchM~l&d*j z)RO1Ouiqoq*sPXvp`5R*;iTyslvh^t$znxV<-C*!Wxs)BU+$Um6WQO2QvW~RZE0v1 z+Ugt*Cqk>xA~Zo^8kd#9($cYbr9;m4$l0)UDX+PlgQApUm9~pgcGZCtyCs8@F8vyh zGb2X_ly7vOKk}CAlG}A}_NImMRJm)dS$;^!Y07oyxU1c@jkUuSuX~3b7aecAE;{ZT1GR;4DJHWjQdNj3S_4|+LiY-#Aj(k7%&Z(4p^?1e)iudFP*yl z#J39$+8n&o=GNkILqCZR?Ej}(jC4Z8ig&w7IEw32s(~C5jc;>?r_f;^jcp_;W>d9g^)Ta zgqQBxDBUi&cwC>=Q&VRaIjfbo+2#l$Jvg~+e4etQ)zjM0;_EqdYH#<+w}vkaUw9$H zAuDV$t2N7aR&MCzMnmO%W$@tG9ZCm=L!51KTHLjvZ7Y^VoZtNZ25I}blQP$^+f~Hx ztdwW1&y=TG)5WK13tr0W-k$HRnk= zxbV5%Loc7TzWsgc54Bgt$;T+O=-(|fWt`}++a0qD2R0Y9r*oroe@#>dk4BEgDTy5Cqtf{Dc^BMUMhvBNUCS05Xtj|G$ZX&Hb1|$z)eg=)ubZ7w4k8l`!}UK zq=0s=-`!W!f1@i-_Q~VQ(<4&+`^RL(fPR6TBu^QLe=+ZB-PaA4RQ7vdsBt+w!s-&Nr(2^#MHPV`B!Tra2Tt8o~W(&$tS@5`3GpUr!FVR_vZf%7!bcS=`RhtIdy`*_{s)~9US z%}J@I$BG|*C8;yDrDVgQk`rae%Z``#RlU^Q@BGnYmsZ;@aN@yQ1Yw`8hu_z7s;sl) zl-p-(F?-vZ?E7~6xTSifGpjDsoynKj%B_}?ojZ5$+GTQ>>=ll6uV=l{{<*uWZEs_H zSACbSn;)z_TyoUJi2^)cFu5wswq2Z*G=36ezj17)(oy3uJ8Nvuil(xsw#fSVa$JeL zVDeGcpKE)){p=ar>DJfk+LJnyde?Pi40lu>C&ofDVeKxcpctQXKzV!8DHis zHMt780ePje|m&&z* z_f$U0@eZ3q2(2w|Ea?$0c%-?`v#)h^^|rV5p1V5to4E(}weX$oM;!t5QimDu!{~cw5Z&Z*;o5f)5)gc=Sw}M?lNae zU5a(9SbIV|(Rjk$-Oy3r#np=*-W__X{rR@DCQjDLR%Km@yR@!^a|H06e20Lyg=YLt zxW$8`W6I6Xr5%S`Y})_Wc*tRS<}32t9WP3OTF&OK7d#=Ky5H+KdeOJPse4~%@ACx% zS$it0s?1d;Q%UivUDmAX%$iK|E?-`gse7pu+%6sd=?d4;-e>Re9^QEf;c)45$G7)# zAC8YHgWnmwqVzU68bb2qIUVvn?Q$3=1bULiR@X9)53F%o92S?*x~F-!$nm^gJu6Ub9nX-SoxF-uN*8 zY`rF2`?w7~?d@ydGf0G`0?Y4>j2~7kn_!p*57-Zp8kmSD>w%^*7c3fBj@XR3E^^!3Lp6dL?&aOXDuA z??RZnnR^(vIK8MCz0kIBXE`awdC1W}N9OuAObJ#fZvJmhh^Se-Y{_zF5wnY+Vq%==W{MxK z6PrXBPkP)vVd=F^k~$IlGhvARp<+QQZH+;r6Ll~*&+fWqpMA@WhknL_5P!7)eq6sc zb%e`6sUO;yJkZO{>tyG#^N^v$p6Wjpcf1TGlW7Gr z9l6Q0A5yDtr2Ua@x{;oOXZ7igbO6e~V+d1(jjL^#L8;gQ$iogmIySM2nFN&Nq9zCF zEM^Ddbd*ez`$UnM%fwQ7v1!GAwd~Sj8~R9~fq4)Z@!ntPG3}oQM2%)bWq6 zOImv4?_XYKm^(93zW(gGN7Ol2l7<-Ou2m>+Pt8r)#e}e1P<{#J)tTujX_;4_QlUJ8 zvMv)9N>k8HhPfMcOjKrWamnK1`OPS=NBQmCl#*Rc+G=F)34;m9OUX?Sc~$)Y%5eIyaU#+Xa===?}TO6zyvDpVlsa1!w;2HKp>b3 zg25eN2DlU44V2(_AOwVha1aGz!Gqu-KyP0IbifE61B<{?umaHGdK|>O>Bq5O` z=tzQ|Bp677k*HNf4UL+pHAJl?>O`W}5w)JE4Mc4u8Wqtb5DiYLAsQ{wBod8|X!Jy5 zAQ~gls)#m$Xw^iE9<@Z9NVGbl)f26OXpJOMMG_N8qM9UXNFpvMktFI!qMjrgNTQMG zR796RbZVm05S^CjaJ@RB(-WP6=!`_KBKicPR};O4=(R+jNc6ZJJ<%J8-bf58Vn`qc zH8E(2K}!sY#GoSv+^vBajKruS#sp$i6QhP0wZxc6j5=b}6C(!0xGaBHX<-)0EDnoH zjSo|+RO+xLY56b}*02h?rrKog+u+64{)>ZV7*NkHB692f@FE#Ctl0qTx_0bc^@hBv_X zfV!Uy7s77b?SimJD380_eb^&>$K5OrdxR~ECl9L!2v>FqSP7m2t3eXj47PzZfUsoq zKoLMVvL;{#2t(EZJOJUx`amZ@*s;Cf2tc^8r@>i(Fk>%)cLBnS{S3QbiHRm4z53{}KXMGRHMP(=(?#85>HRm4(7ELFr(MJ!dsQbjCP#8O2pRm4(7ELFr& zMI2ScQAHe8#8E{YRm4$6996_oMI2ScQ$;*g#8X8)Rm4+8JXOR~MLbo+Q$;*g6!wfp z_sF&$X?gSc9=Wk6KswShcA@8^o+o<(|Fw<#XWP`ipzFbX)23Z_PrCyzzuZ$iY%6!>%i{5$|Y8HkwWpy%N09O}7h zDSGrF<&y3B@_g&!DtTt7yi1DP##J6YQFlDV<8{^6&iUZt@m}Xm$E)r^+o0vkO;WDr zR8e!DBfoCHSZ%Xf%7t>iqMDPYZ&Kb^*(;0t!YbyaJSzM3C;M{Gm!Ho5R+Rew@qTlC zo6uV8a5#}#gl3@;3e%XZ43?IS#w#6iwnxr}txb8u(cReTvy$$2eY>&^0GLQZ3@JI7t+u4$+l+V`e+$Z^H-uIq~9 zXr29JW+N9a$c!bdR%okka~|+X;ZoE252UFdNz+$J5wa>Z*|eo#V@ayXw{gJBNuy)^ z%HXd@K2tV(n(JC>-|$IKJL=~8+0 zM^-$Ty)`XOSm!KvTUsoirb)AW-!}-`gl*#Xi4k<1aw2gakKN&(GvKwpk-~EVFA5>G zQV1{Iw^_PdaPhc4tEalwEOJ&WZ?nx2M7nWu+1NZ~eT%21zS-A(^z4DIGw%#t9=iNe zghN)?WL9gI@2%L>!HtB<`O4sd(OF6dhC`ffaa!Cpp{*;IM_k(a;U;P4#WONjzt>g7 z@2-&V*_bI$v!;vB)D*mu*R?a>xAXYMPwa0wuem?%{KE%a&k_5X#*^(IZ68cI_00RS zrf|^cFE5kAQzX^%Qi$YvN}7>&HJhK`Qs5@0qAId4zqFvB{kylN zSyDh7*XQo7?wjn2lYR1-^4zc#|KUkl(XU@9C&^R#<6q9ZS^IUprA2J1=SHICbIRcV z9J!@@yXEq}cLc8Mpu^cUr)XzM`tEd{9KTSGFOiqjW(?YzUTK$%f0ClFNfECM_guPg zq_f-fa<;%(pW9r$C1kmCRqKkfN#`5U{qhKA`Q)fUscDLcwIqtgRR#6C>-TtzoA-LE zy_Wi#lzlk`d)DR{2ISDMvU<$j<%b-9by{owc$&L-yhfT*{ie`e(Pi$c?kH{D=d;wA zYt1f~8_6^H#hx$uzgj!Wye7V?zS3La;P#I(O89{25}RzzVtw@srOoM{{O+jj56RPf zk*!Omus>hx?e7v!*0tN(T?gv8K53)Uxy8I?XGU(8?w#s^$_pP$_y4ij%X_VLR%cFa zjx(2&){VI_A2UX0C^z}G^dx)a1qZWb@8|R0T~uCsL*P91^qJDx+3xcl@IG1lr1crw zPIFSK>51Y6uO)S)HkWKVT5`JVRN1NW-pW^+`kX&_?9y7>WllU&gCrcZb@K z)>+r->*5D$j+LA+aiRc^7fh~wX4@W4N*X(ZvEMv8Q|YL7n4Q(O=S5T5GuveSd^xT} zUN|w8br)OTY`bvYcCO`(+P0*Qq@E4!8AI(ACpd%jWV*B_TT15Y9A1Yv)Y((gRK}M% zOHHmqu3uiQY<}Fgs{M(Sn$)TkN6&{Zec1IeCv}ajR|da6^1ZTTop~?+EU!A0;8M9( z@}7!S9Ph9>gwUGuhLUdKvPYWhyzoY6XHQ#e&&8W_znOdZU~{+cP}lqC3vVT#Ep0FG z7B{W#U7VRz$`zP}qDGT|P2{-&`DNu_oJX2IBA=vps2_Xo@g1v$rB?5tt3!BQIB6NQ zyvj*&(vb4K(&Gy@uHEqLqx%=_=R~_GhBz#Nf?afop+)7M%-)($8qYKiy;$lgb(c9) zYE!J+#hTON>4wwpuKM=6POeV$@b1vFZ7;T7FmbX@wkm5&+@-Z8oFjnm;M)Z}Ei_~I z!Yv*h8C7n5A?+00V#}c?#zKzCGhdVE?s{1Y)N(d=o!|-iH}?naC$9JoHFh2B=y|cA zKWl$QWu>{&WGX3Mv&WiMm06u>-s8(_G<7YLg4?8HKi=Tl+j{NY-ebFuA{{Gz;ndC^ z?&GmhW$=3=Hk>h$@zwuojab+TW{uEffi}SW@*`gw3KrPUiMrP&u!zRMPpZ#!RJPP zR(9yz^KBX-nJ2bn&RQ-ntJ@vgm^EN~S>%4Wany5j^2r@$4S!B%TkD6#Vb`#;*V*Un z9de#^4^6(`Hi?^SHVUq*{MGWS+&7&PXaBmieQ#fbvrlx{U81X|)mm3x8{REH%!lW4 zWmfC{%Gn}s=N&vZvVQDmjMJz>=?-w^lxEp-ZP||fVhZH;NbCZnQ8czp__uahgprpV)d~Gb}bUitV3e4#9j}Z zgrvZ_WCLt6l7iWYq+m87DX{$B%=lr&vIX`zBtI<1pNHLwe_eVc0u9I%;cup~%qir(*hn^NN z3-P;vwkmNvZK2#Xx%WrAV*Gp)?eskVcRRhViS_^{4!I!ot%Uks{KU8qE4mQoe&zv& zElw{g##!jGxR;!i;yje-w<2@)&WTT_R*4AlCe z_lXU?{Cb`2Ja!)PwBP@^;Y_sU|3jj;g~e^!`0WM2XE6i*Q*p;S)J)_R%yg6{@_xuI zpUnFsUpASag1I_6nGZnyFhiIk{HWT2h)KnYKMyPZbo{g`W)e`7H<{mtqjK;cU>B2# y+6=UkbM!c+L*SZYU4o!whrV2Go;Nb5nLPA?#Mv2T@;>nVyoCdF2Te!`$wV zx-JtNl%}BTs4qf2GBdZhWNGoj7Sxkbe=|3wWEYdR2E{wjCKHgClAC_l-yiUyu4NcD zc2|B;@y$*~%`nPmus@V#{QVi0o|>hHr|r(oE&XTx@zGh#=stF|N-6r-48) z9R!10z$|bpxE(0L??4Ec3&KDohynM3`vJOy(EuGV0@@u*z;dt(JPMuwzXxjp?cOA? z1w0FqK`O`qJ3$V}2ZdlaC;{c5641wK0X854CvXEVXacQZKj;Jpz;oaQ&<_rQqkuln zm%%Gw7`zJ3gEzn>a2dP{-UojIpMXDutKi?km*6Y#4fqy(2YvuIz!(?@H}M!10R78y z0Da5O1n5`x4saKk1Mp1PP!Iud|7O+3-ylp3PZ5={cp=!iy7 zGzOwE60M48|N5>zB1o+PMAf`%mEf)YrAjwI+wf`KF$ ziB3gy@kFO4It|fji4NDRBRW0N8HmnE^eUo{Cweu}YlvP;^a(_d+tCxff#{9IpdyBN zVo(!sb zv8i#PYL!YIx-2b!M|$Y`(xT$@+@jFO@>25)cjXtR6sM;>5V|ZUCv+V>yeM>CdQp1e z9&DT(Tnx+dJD9XzheH4!8yy0(0S$XR9%de(;T{Jb05r@E;9)?+`w{RYpkcicYz4_6 z9b^F-#>Jo%(D1DRJfLA)51IiD*KTkS&@ep$P5>I7XTb=dVfhaD0MKy!3-|)iFuVr7 z2Q>U-gb-E}VHboohVn$X-HkPd??jlzVvS+T;+Kcj0}NMo8CVUT0Bb-Z*aEhLG=O2r z=7A!B;mDeR8DJQ)4&VV8eyk640Sr5~4;%&f8HG|ggY7E80ZpqXJop)`XLMvX9Pgi#}m8e!B3 zqed7t!l)5Wjc{s&QzM)j;nWDHMmROXsS!?%aB4(QBZ3+c)QF%)1T`Y45kZXzYD7>Y zf*O(3h@?g&H6p1INsUNqL{cM?8j;k9q(&4qqNou?jVNkFQ6q{PQPhZ{Mie!os1Z$# zXlg`LBbpk~)QF}=G&Q2B5lxL~YQ#_@h8i){h@nOdHDag{LyZ_}#84xK8nM)frA90@ zVyO{JjaX{LQX`fcvDApAMjSQbs1ZkvIBLXEBaRwz)QF=-95v#oQP?{c)hpY2rIjt` zdgZ3x0O@e=`1#%sdLQo%{MUWlKle@V5BfZ~f5wc@-7{{%AK)E8iJw(w?d{BM{&X;a zYJjoD-U(h}7{yX>0soAPftO+YlkiW7u`&%Y9e_9wKuiW=%yRHK#5#xVT#XbpcE562 za=yIKy0luJ-6ijmVz+ZuM~>GY3-Neeb#?RJyKt<}dEN1{d&o9q`C_w_t2tTJlIO^; z-zV1Ctd?@2oUg3mq?wzQ*H-t*Vnt}>f|Q43zkwuQ?z!?)+24v%|2OZpG_(tCbq5|bzr^9lh|vM% z8{HR=z2&;%cHNh~b%{J(?%H6M7YR8{x$YcywY#>lcDUko@37;t<89Yv$B}ybiOeQ0 zOpqB%Xr0hr)9&2wlftCtbMHyhKagfVDuv6c)Fji^f=wlRQ5ImW$9 z%cB35V%l9}DQ(>26r6%XXsmAH8=aifDLO)YmNujT(}3xa<$CF-e?NWY%+)8pU3}Q) z;GH(-{(4_STk|Iuvu`Xqu6jidG^>Kf2fiE&R4%{&;RjdUm%S}5 zO<3VzLvss0xt?7by5f~-MvM+ zU2yTZKC7pu&Mb0PD{r&S6GXaja@qI-Wkai{wV}n=bL7na?$d7#UmCvjLbyX#*ko2~ zmhYTzl*UoKQy)yjbw)ZznSr<;rT*F>h5x=`qzGG9S zJj0qUK2=-rQeJmfzAx+8rjP7zIIp@t?)t-fT<>A~>82AMA0!W@oP6qCSyQ;=xxGU# zpSQmKUF-L?*Tu=lD6?qaEi+}D=&;)za|#Ex6||>wqw{}BPzH}ijKwO6GovxHMqZG; zUcNU&o|7rxc}`v-g{4TUXQdFy^Mo`j?MgPku(iNVOhwhCBEPhtpyRtYr8}j7cCO#u zSJOY$6es)Sapl<&DenCfvSL8LSWc9u4aB{ecfIbb21~2h+Q5xQ$!C?p|229;`DW{- zinj!=`+&pQJ+COMBzN19G%`bIG#y?3>SEcZmMtU!vKit)0dNEtz ztj}zz*&4Fa`Doj!vZ>%3)&24yp7Mz?gHqER9%D%mi>nJ7b~o(t7Psv6)OalowJ8-j z1$)-z7zX9JU+(NR_mm%W{MBi#{o^U_!m(OuTFvW1Pi42cyQZ_Wt-@!iH`ke6E;o{A z=(9av@PD;-mU&Hlbwic6(!uQ;XOxHm(Iqz9TEvE$=So}BJ^4M6$@j}Md=YKSrO-cL z?HlM8PSkhUI$ZnfxqfMr(z(^VH7g@`r|zwq!K(8gO85M+*vosZ^;Tz2U5+!Clh%*B z@jPaY%~EdmZS76+$PXXLmc5@Ycza2C-8F&pG|=CauC5NBZ@>5Py2q_g*|N-usiwz@ zAATjVGqt5;^O2HMWhcu{miJY?)ZFjlezgCGz6QM_GTN z?e+Ha=WJ(NU#n|R>`d(4*pV^ZQF)v*NROvWYqO;!uHNBwc;`BMOPb60GH0pDRmcs< zYm_aI_#W+eETuNJI>piZ{tNGSf5=JQ;~SL0ua17NELm^f%RkMl4#vAwuGPG!@==a= z*c`&#+VaMd9^sNln(sXST31(Zdt2{?>+`>!f9OCq7+ojNgT@cxZG? zx$U{MlL(8g2Ok>`IV#V7MV`OwMJZ6r+1&MlC*^s=heW0`V`GSF+`zoud z%vB~+N%7h})}7UvHJRo;zPu(=_X;VvT{`;XHLjz*&)(xby88&y(bDHmX7zF(j*lsW z-x%UkC@|5}PXAkF-}q^&+!*iqX3)JJkig|?a#tya4=WQV{fp0IIJ zTeeb~Ha|_yH$-RccrtH;nR5kNq*Ys_6@$`p&K-Ekb5T6Ios*V~UseX69sOC^sdF#1 zX@n%6*pfJFxxAu&_uQtPgSHn%?uTnfJlCgwxkIgC&&X_B!-zQI8gceH`<;Em&NJ@e zssFdl;+EP?g6j%@rThx_b(h51zbft6+u!Ky7hQIj=&EhA)|c0X^~ewKVYytH)w-{0 zj>y}22hWXe82=glG^S9x16(K1ra!#w)F1Ot)*Hf& zkK54F{=W8ogG5+SzPx2+wK(J$at?9M6CHz&W0J!5lSNYWOdcS!#WK?|-tRbx16;9*M;idjs-BBn9Rr z8<8g=DVR-23T88s0@Lp;j2~t!TaiD5G}Te{j{yg{Q*oYN@}`UvaBz0F{MWPfCSX4DgF24$46J1D>} zU|O(3@$0+hghaDtE0?cgmNLtjHPc5>y-4%Vm#{Z+W@h>bYRi!5qCg+fwp3VS)`lyc ze8%_ComeLCW%45lz0Oc<^M}QPRC+cBC!IR(A4i{v8v1_wtVKUzGKja?e_d|gm_EW~ zV5=X_F}a|XU$2v0z%D?Uw);O9oQdxF|B&cyVWOKhaeD#yG=(SNKOJ{WXZe$51v3-1 z$+90xi>Au{C}&NTr{P((OqBz$eSjfM5k6Y&!01WE>^~2)|8$IxVkRD2itu?Wm)V66 zTpBU&n)xB_}r@wisiZ*0$RqOX{n`{_5!|GoS-bfaA& literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context1_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_context1_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..d4a3fbfceb6c478b3b1f5b04a42dc22a10a7cb80 GIT binary patch literal 5492 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context1_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_context1_successive_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..ce2dce5d41fce799c36efecbd2ca35182fcf4213 GIT binary patch literal 5528 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 I@K28a0SI7V9smFU literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context2_classes_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_classes_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..85077601a36eabecddeba49f22541463bdb6bfc9 GIT binary patch literal 5564 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context2_classes_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_classes_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..ceb74b2cb4fccaf97996291ee054b6be9a9fcfcc GIT binary patch literal 5584 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context2_expansion_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_expansion_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..c12f0ac7a3eba9939ee62d1ab525ff80877b8a72 GIT binary patch literal 5544 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

%d0t6=e#iH3OLHXu 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 L0Xnbwf0zFTnVn=C literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context2_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_context2_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..16aae9d2e6baa2573e77d33c7e3dfcb04edef352 GIT binary patch literal 5528 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context2_simple_f2.otf b/test/shaping/data/aots/fonts/gsub_context2_simple_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..fc31262e6605eb836129a2ba9892fb790e225309 GIT binary patch literal 5504 zcmds*d2|$2zQ?ONAt@3BR2oO3kbM!2G8%c!IB#zCLY8GSSOj-pbD6%X%wLp<}&yz~C>-&gm1es!1n zR^7Vw`&HGw&u-Z8EECLBF@B6{#p>0e5gWy7hGG7|Ff$_`Te)g=U{v4&|#>aAUg{hCLk|4H|?H(Jk*V{fnnI# zUHL`Dw>lX$!zg#4J(Okq{TbFDS(YB2x;rrdpTRZo@8B!&HTXOD7JLVO05`!H7zelT7!?5H%fek) zj4eAIU|iW*;2tms;F++YAOhh2*=(XB@kC8DL`xEgj_8Sj7)d-T<4L@l#A`^rmc%EJ zcpZt?lXwG(HxjjqsG(64wT7s*M4dp?I-=GSwSlOOM57{_c%s26HAJH&ngpWJ5sjW` z3`AojS{2d86RnzPaYZfBCJ?QTX!S&EAX+0yP?3aqlAtCD8j^qxC6ELiNzju714%Fv zor>t;o#Hb@iJuzZ1j4SeYl@?}_jN;JP zl( z!S{f=p9~kmZo=(?utz9QxZAzhBYY>^EEao&EsHk~s|N^Ib{SX=o&sw?BG>}9gH(X9 zWb;4~Ksd4{UK;m7(w7eLstec&)axUr|e8GtZjFM@Xf!i)U`d&hDk7;Ok}4vpB9ba1sUngpBB>&hDx#<&iYlV0B8n=as3M9gqNpN@Dx#<& ziYlV1BAP0qsUn&xqNyU9Dx#?(nku5HBAO~=Td%aT_O$S9r^M?>(Xj@W|zE6irvmt9XVcqEX3n=)z!^=|H838=MBfJ?jhTd<;%@d zuI6M>OP(XYexF!lvs%i9a=x;LlcsN0USHiOixr`j3z8p^{RWbJx#!AHWq&J5{eOS2 zrJ-GDt8+M(xod-2UL@o+<+^j+)$ZEH+Tn^fy~B;xgO}lfyPYRQo&%G~A{ZN|zxD+m{Qj$zt3pSOcn0%WCy__^Q zKA;T#dh}Cei>IZ&weAg{^t7X4p`((oQ=t#GFtvR$aXWP5GL zwWTs6Ⓢ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 Z-faR_LKMHVeZTRsWNz-K>z@C6`)}~sW*Gng literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context3_boundary_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_boundary_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..01cd29dba670fa2950005975e4fe92c3406eef6c GIT binary patch literal 5500 zcmds*d2|$2zQ?ONAt@3BR2oNukbM!hMb#)s6IR}+R9=B`yJ?@G!t?q!15?I`!4ye=)pn4EU)NfpXJqO46r zh0+volVR@0F`4kRtb(Ft1&f+dUWf9VS;nHhOfub^H5Zv*wlOQ^-p^HQQ4VJqR=+nV zzukTA z>;g$36{LeqkOT5SAt(Z+pd8T0X$Dpx0tavb4`>7};2`J#hrn~-1<(hMfa72QybN9e zL*P|#5xfDefUDqL@ILqmdPTp2jH2o!5|Fa{@DzoBC$kGG$fA16D`pZJu#42RK}86HHp=b*fB-TLGDx!v?CTa~)#}RcrQEQ1>N7QF9MQxRjh1M1M58Af z1Bp|SxL6XWCUH1p9Epo3aat0mBXN2XXCUz^5+6(A)g)d+;&DOoBwkD6btGO-;tfQr zBHCD@RTHg-Xyb?$*Q+I39ntEE)bQNq#VRd1hwt2D*EG@P?H9l)QbY zoETgT%ksOKU-gb-HaVHbckhVpp0-HSDb?|7I+V~t_U;?2YA0ER2O9IOFPf^{GPYy&$%GQhB8 zvq3(f2FB+a5|7EQC5faxIt!8C&rLX8k=gis@d8X?pO zp+*QbLZ}f+jZkWYQX`Zaq0|VaMkqBxsS!$zP-=uxBa9kh)Ci+S7&XGE5k`$LYJ^cE zj2hw82&YCkHNvS8PK|JCgi|A&8sXFkr$z)dBB&8TjROtW*R(tE12_vP@mgip-_6|RO9um} z1Q=WFZ157pD3*as_+?xIJPhNTh+jgCl_`j6Kg78oV$vUDmV?hB);ZL3)l$Uh1Ip#Q za^yvpWtH;GPI<2sy_2grcCzk7klW*|t)2hgr4zl5oA#GogVsUwms_PQ&FTE+Y+Qs<;rwbx@sC~hRR;|4B4;R-*#TLAFH#SN^9go z1eq}h*9vXbZH|LpDMV_z@SZgF18MqWQmCv-N;GZH-BOff@@^UMaMI{lzcTRakx!M) z?&i9d+Sk0&Q}+5r_Hw?QH&yMBXPS)FoFLf6Ai+PY%$0P+da34$^_5-Mm&uGg$FP4{ zN#x&*row7-al<}`;1KLWLuDi1;NTn%(H`VAw<7hM`b|g7H;X^}kF(d#U4Qc1B}c7x z-eGkdtn=2lHhp?IEq;n=6>fv-mWl`9@t{Lt$AGj=2= z3mYA!E^~|dlVoYO_xlE6r?6ApHPM6i(+(ug?Y7xn^9MYZ*Ni+T@S+e@D+Te=z1yU_ z1t*W|v$(5kt3=LX;jPyBf=CxmE*V>>tZ#9*)Hi#(kDWW%b@r{HD??Xa2(`-!tIWn# z$@i3R?che{$vMivfzjDYJGw)hV|JKbHS=26tO~unb*K^c%w((T^2fGH1r`NtKYx0&pw}0^E zib}WSak5t)Q=T7|V%|R`EBbXyeq$t@~*0`>W<>pGOxL=snAS?c9MeMu`{@onn)j8P1H>`Dq6#U2Q zz5QLnsk(M+yYpZj*C%aJI<{AB-;_d&2(gO(#A0t zp2v*Q8Op8R?LCQZdGVnP+4I@Lx0jaI-ViuJK4DpF-BXp2WO}?{ z@hb@(NzFxDj}@IMIbCwPw724=ras3HZkx2hdW92@)*uOotlj*f=5r+-?dM!xYjc&S zwb6EHzn5F7Q##UX(_CqMk+sxfE-EbCzi*$(ZnBlxH@}|#M%(AE&enqsZJl+U-Y$Ni z=6KOb6DJCYc){c>tFrFnq=d1v==*J>GnMvgdzGWw`mAUwS-Vr#Es~>)unb=SkJe-R@;`)ks^+X zP|W343HgmC0gK3U1M-W?KRJ#zeLy}==}4y(2J-~@JQ4F%1{RNw77w6@dy3=}VK5jhQIP`q6yVzCYFxDC^yTqC^ z;+cjsuCDs_x=yZ6bn~ux=h~icy=dZOt!z=&7P*RRi#WR<-@&&Fcw1=3?m<{QJTj`> z@m%t0gvIv5kBNZh!iL@`{S8 z3X`d*VEsNzdSzO5TGc*pcB83lr4-mE9sltL*WT7^>-HQkJce|<__@=2dbkhAMwNl@ zjNDLq>h1MG+4B5$`Mx$em=pZniDHX$703HmJIr>oQ)oHRv|r?S-X`+%E38)DTru7O z!aTmrS=Cta`BG`yTNl3gMhZV9P5-SFS9v(Ey|`=b$8u0vTqP%3EH+EfZh=oYW#y#S z45c(>L9(2qkKD8Ssq9TvoYUVdt==ZB9FSIUF8?d;%i{T+oV0Z8sxt8W$j{0St!t50 zBP8;~n#fs7<&|}X^BU6!tS^e(4>yjvZ%)3sgDoM?$ZTu9KA!1bFQJu z-?y#ewwf)1^BRAx^cwd~r^MO5E^go7*WlmDYxI%MbD)SzL+5a-d?4 z$lG{3&y8#v`x*T-s!+Q8oSDVx)+}p={eWoX9`LWOu$w$p4w-e)7cV>c!~B!wmT>En zR-EZzZ`*+ZBCIT3(Y&fs9JCKQ206#6_5u3|Nn!oTEGfDtc97WunQ4#}wWVEoHI=2r zV%v7o%8ji4MS*bOZOXvF@&7W@@Lz^53T76w4vEF=V?FW>NG!7viNzFq6Y>Nk1?DB2 zktZT4m@P;OW-F2c)9-DJ4`wXekw1gvgUR@_$af(5FguZaF_+ne+=%4M>_+m%L_G;P z{ZI7? zFYY4KSdfhp{g=qxzKuG%D5egxF5JsB_DA+d=4VDdzGkqEEi?!C`S?u#Jx;> z6rtA{j5=RfEJ&h9V{p*P{r+d~;~x!}cFuU@CrtkE@AaRT+qb3;bE&AEcs8^dXZiIy z*@f&vY}51p?*&JqE&m@9y)8^^lgDq*51*p&1bnCBjxh_K+*UBtQJSdt!Pc_LZC`BX zO>R%Yv+9}L_Cx(?hA{c~NVOZIB?+_rY|Qpk@WHA8UkY}jHV19lII9syC`L^x6N^!r s0;>?8xoGXb@BjP8W}Gn(*O@+kg|YaOq540Z*Jr%%nA-<&-~VFyZ^E`<9{>OV literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context3_boundary_f2.otf b/test/shaping/data/aots/fonts/gsub_context3_boundary_f2.otf new file mode 100644 index 0000000000000000000000000000000000000000..6fa5f05a38705e9c889a75c1412377662fa7b579 GIT binary patch literal 5496 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_lookupflag_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..94371b4d1c86541c881214221bee3cce1cec7b9b GIT binary patch literal 5536 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 J>zV(1`!5(kWE%hg literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context3_next_glyph_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_next_glyph_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..93533b81c657aaa9b89396dd1bc56882f13a18bb GIT binary patch literal 5520 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 Dj_+d} literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context3_simple_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_simple_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..a1cd98c43b9a16155d185265e11b74690234a332 GIT binary patch literal 5504 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/gsub_context3_successive_f1.otf b/test/shaping/data/aots/fonts/gsub_context3_successive_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..d8b3d5ccb2f0e39e2548a96897bb37b4bd869840 GIT binary patch literal 5540 zcmds*d2|$2zQ?ONAt{mws5C0kkbM!Q7di4_m;dz1L)oq6Z|0e5u1c+hGBlsFtZ{bU%6_vf0X|M#J@nE_3;f! z%m4kg8#fu|&J3h)KD*%&W!BZCVTQTuIiz={Wb5}b!R$7qp=Z`+r0G*Lu05q-n7f0J z)?^??v+SKW@HzZEG=Bvf;6q~t!#bCUM6)dqO;X7emVN=wBTN4B+`#D47+A; zZb9MgPDaTvaudo!S;p6wVSN#0>Eo$I+1aK4NIy9`lNsI5j#kM=t9(Z9^_A`n@(BrG zxZ5_{)Gf&0X1jm-$o*XUv;x$w9qa~KAQ$9=B2WU#K_#HmNr%e<1mFNJ-~mmb6&wJa;2?Mbyaf8e5pWy~f>*$+ zU>LjxE`m3~6>t^22R;CQ1fPOGgX`emz*pdF@OSVn_zwI4ZhUSCV)YiC2^O1QM?y z@rfi}OX77zsUS*dltif_N;Od?5T%AF6NyqwlsckP5LG-;p-L4|sfj9qs5C^CNK{&) z(h;?SsN;!RNz{0wny3?qT0_){M6D%i9Z67-gm{vmBnc{#fCeRy1Pw_@BneuQpd%Uu z(Zmytl4w*!qb3@(S3@+3M584d9Z6J>#CVdZB#A1Ls3wUCBoW<7B#By*s3Teh(Z&<4 zl4w;#t0vk6qSX*BdaET`9nmR>E}rO=M5iJ;HPIyyordTVi4KFITamlBG=DeAC=88F zi3?RK6w1(Lskyt-LN}Ba6sBbtgg%jzlAFIbH(y_vmiln$vaGDo_4M(A(Di8rY5B#- zoLpQC%UX9aslP4hdrS{A4^VfH0}li0=31}_Q1^ZuJPoK@ZvyyQOt^Cz z?t1`r<3dmhsQcCcE1+&$51IjW*KTkKP&YjWP66tk=fMb|Zuu_w5Kwpg3-}UHH@pG9 z2h{x}xDaj=ZWn+%mhyzV-G@7t?}VGh;*Mp@;>*J(0xVZ{8CVUT0&77M*a~)lRDfm4 z=70i#<;WU<5nvgzcHjnBeykUC0W3SV4;%$pZtNLw4q%zFm%%##%ZvR4dLs5p5lt1*R1r-T(Nqyl712}?LlrSp5knO*R1rfJF;o#l6){v1LlrSp z5la=ZR1r%Ru~ZRD6|qziOBJzH5la=ZR1rrNaa0jU6>(G%M-_2Y5l0nqR1rrNaa57t zI~LU|S$f5lEf;#Frd~hsXz%#N-Vb}9?DhZWGVUK`)B6Ly2<#6E`oa}-2Yvu&135mc z%(}aoyL{6 ztM+5{wo@5RTo^AgrqDXRy{6r9z$=D{%@^Jmr++BUSR;l@ij-u-w!F@XXD?V*+SZJ@bR$2|l?b0lRzJ}v@yAaI#XIHpVj#w_$Ua`Eo z^ZHVWk>=|5EiH@wo8C}VV=8SdcJL0~&No&!SsNXk!y(v%y{0yV0mFddi0NkOXa8~b z+PUjbeY^Om#cp+290%&X4Q7f6eIA}n7@4a zLyI0+^S%K#k+Z@740*-YwC;wXEs|cmU+BDFHR~OUm$O2b+ij~&UdZf*WMH+r%__@ewW0Qaf01uv(L>R*q+y(#*NPZB|#oI8Zj0t zCyw;Sj2dY{<_773bZKseH0Oe}LJZT3is!{((fyP-Gxb`gbzy6six>*3NkwjHUS7v{ zZ;5k6zjm(Q)mPI$^(s#CO5^hLBVybKrzF`x;$kUDnl=#ka?Z`VuNzFQLTdvz8YP{V z2maUSE%{rmS1R7-x$c8@NB6vfJtb*HX&NbRu@qM#Evri(vNRv=5OsePqppkLhevuZ zUp(5?V|Y1}=giM-t=Sg5(y^v(RoRsDjcR^*1haf?uEF|Et4X`-d~!r4zN{w3;{gp2}`xcTHz$TZPwD zZ>%#qoh}6T(C5WpTK{V9Eb|zw)eTjiN;|iIoRPx^1gFq!X%QM~UMOuzbLaL%?tDlJ z@FnKKULph>2MyX=laFXa>q8~wms?DyESju3|3wINWA|Kg&wQNTyJ({ z)nz%dIdQ|d3-d8^Y^HpRcUy0=TUvB5Q}TSa;GHGqbvJm<-9W!7U0oes?*Y$~bx)d~ zvFtG>r5K(lT=Z&EXG%-SmSZJn%1)P^F7K;4+}!W@!EF=QTdr`z(OLxlpryxpu;pA? zXU930*V1D2v^Cid?(=dh66KEFbs4SezW~^S6ADC z#`doIE^oJWu=aS#NdqVF@Oa+ftT0-NIWcMcEXIE8*etod#%^@fSe_RQWzX!85*JFb zCDP)_sjR=$_D1`~3zqY(uh+FFbtd(0>PR2%s65GO#V6Cmb(vx^S8w;&Jt2+QWCy!1i$N1WI_zEK|d+UWQ4k`2av)@QAXL-9_9 zbG6l7xrVdaEp|Snw!E>Vhri+$=Q}RG-qqFH-qw5R=KOEwA3504<2}^<-i7>I$>&Nt z@;rsjYx|aFB$aY`M!ulQz~d6E+@SQb{4b89%^#AF(>j%pJ@@#owfu6kXUN&fzs8?3 z4Vhly#8`1y{%+}sMVr@ediK%%OZIbuO%Q_ZCV$>0*oBaSa(6~w?Z-`Ln}%O3b(gxz z9Qr!Fd8bf&MmW=W#?{@>QQyVY3vR0`;?>x)N7uT?uFRvvyiLczi8X z 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/lookupflag_ignore_combination_f1.otf b/test/shaping/data/aots/fonts/lookupflag_ignore_combination_f1.otf new file mode 100644 index 0000000000000000000000000000000000000000..b88359a8fcd75ddb1c5580ffaf0a713a20994d7d GIT binary patch literal 5408 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⪼}CEIp^jY^IGhV*|j1(v>!SQ_Yu) z`JFefJouK6I>=A?123;VoZnH_z5Y`nq*7i>u_lwn6ta(@6V8|^zAaP4Pnw%7yb z_Pw67RZrOhjQq--{PF>Q8RZDL;k?dX+C%Y+M{kLOFL{3vbt)YT%rYjCM&?AyR3R*{ zFA8l+A21(bsUIJna6X!Na)+71-w?>QhGBNtHf-&+_E~#}tQQ?a6Tfde*qwFT8QVSj zUd27?+b*86d{fp@(${G1V{H~2YpZKB)mPZVdxV$h@NBBwWU8*2#nKj=oVlb+r}9WZ8MzOnF!S>I30G zTSURZWA8GP;avtVK7>E~HGdA;o`*!j|CL$L76QqKm<`F7cma~{n6n7}qz6IC4-y4y z%#4Y(AMq^gHGQm363-B1VM;+E>@oi4L}qCVbD)Obq=+X^z`=`8;4tZcj|Y>eb^#;<$!*w%@@K{*M)*A)h9Kd?w32_KDsgN|*3Y^>MN^UJNb8~03I z_%r-Lf;YT>U!FV;9HvsC)fbL2zJT*vKgoIIJSaoU|61Tkc+3BXgs%(!{3VZFpFe!A zf!Og2ge#Uq%Xry`m;$x&vM-dDO_cqhTs%>p1ox_UqU;at7vY0WE~HHOn6n=~@?;TO z0ug)QQx76?pgo^Rfm$}S=EFV(P);Qz#AawkVBo#;f7cOy&sn#@S@WR}>Cmqn=*3Gg VZ+_2le8 Date: Sat, 24 Nov 2018 20:49:21 +0330 Subject: [PATCH 087/158] [test] Enable more of aots tests (#1408) The ones commented out in this change should've be passed :/ a closer look is needed. --- test/shaping/data/aots/Makefile.sources | 76 +++++++++---------- test/shaping/data/aots/hb-aots-tester.cpp | 1 + .../data/aots/tests/classdef1_empty.tests | 2 +- .../data/aots/tests/gsub3_1_simple.tests | 2 +- .../aots/tests/lookupflag_ignore_attach.tests | 10 +-- 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/test/shaping/data/aots/Makefile.sources b/test/shaping/data/aots/Makefile.sources index 8340bb6cf..93396824a 100644 --- a/test/shaping/data/aots/Makefile.sources +++ b/test/shaping/data/aots/Makefile.sources @@ -1,21 +1,12 @@ TESTS = \ + tests/classdef1_empty.tests \ + tests/classdef1_multiple.tests \ tests/classdef1_single.tests \ tests/classdef1.tests \ tests/classdef2_empty.tests \ + tests/classdef2_multiple.tests \ tests/classdef2_single.tests \ tests/classdef2.tests \ - tests/gpos1_1_lookupflag.tests \ - tests/gpos1_1_simple.tests \ - tests/gpos1_2_lookupflag.tests \ - tests/gpos1_2.tests \ - tests/gpos2_1_lookupflag.tests \ - tests/gpos2_1_next_glyph.tests \ - tests/gpos2_1_simple.tests \ - tests/gpos2_1.tests \ - tests/gpos2_2.tests \ - tests/gpos4_lookupflag.tests \ - tests/gpos7_1.tests \ - tests/gpos9.tests \ tests/gpos_chaining1_boundary.tests \ tests/gpos_chaining1_lookupflag.tests \ tests/gpos_chaining1_multiple_subrules.tests \ @@ -53,21 +44,24 @@ TESTS = \ tests/gpos_context3_next_glyph.tests \ tests/gpos_context3_simple.tests \ tests/gpos_context3_successive.tests \ - tests/gsub1_1_lookupflag.tests \ - tests/gsub1_1_modulo.tests \ - tests/gsub1_1_simple.tests \ - tests/gsub1_2_lookupflag.tests \ - tests/gsub1_2_simple.tests \ - tests/gsub2_1_lookupflag.tests \ - tests/gsub2_1_multiple_sequences.tests \ - tests/gsub2_1_simple.tests \ - tests/gsub3_1_lookupflag.tests \ - tests/gsub3_1_multiple.tests \ - tests/gsub4_1_lookupflag.tests \ - tests/gsub4_1_multiple_ligatures.tests \ - tests/gsub4_1_multiple_ligsets.tests \ - tests/gsub4_1_simple.tests \ - tests/gsub7.tests \ + tests/gpos1_1_lookupflag.tests \ + tests/gpos1_1_simple.tests \ + tests/gpos1_2_lookupflag.tests \ + tests/gpos1_2.tests \ + tests/gpos2_1_lookupflag.tests \ + tests/gpos2_1_next_glyph.tests \ + tests/gpos2_1_simple.tests \ + tests/gpos2_1.tests \ + tests/gpos2_2.tests \ + tests/gpos3_lookupflag.tests \ + tests/gpos3.tests \ + tests/gpos4_lookupflag.tests \ + tests/gpos4_multiple_anchors.tests \ + tests/gpos4_simple.tests \ + tests/gpos5.tests \ + tests/gpos6.tests \ + tests/gpos7_1.tests \ + tests/gpos9.tests \ tests/gsub_chaining1_boundary.tests \ tests/gsub_chaining1_lookupflag.tests \ tests/gsub_chaining1_multiple_subrules.tests \ @@ -105,6 +99,23 @@ TESTS = \ tests/gsub_context3_next_glyph.tests \ tests/gsub_context3_simple.tests \ tests/gsub_context3_successive.tests \ + tests/gsub1_1_lookupflag.tests \ + tests/gsub1_1_modulo.tests \ + tests/gsub1_1_simple.tests \ + tests/gsub1_2_lookupflag.tests \ + tests/gsub1_2_simple.tests \ + tests/gsub2_1_lookupflag.tests \ + tests/gsub2_1_multiple_sequences.tests \ + tests/gsub2_1_simple.tests \ + tests/gsub3_1_lookupflag.tests \ + tests/gsub3_1_multiple.tests \ + tests/gsub3_1_simple.tests \ + tests/gsub4_1_lookupflag.tests \ + tests/gsub4_1_multiple_ligatures.tests \ + tests/gsub4_1_multiple_ligsets.tests \ + tests/gsub4_1_simple.tests \ + tests/gsub7.tests \ + tests/lookupflag_ignore_attach.tests \ tests/lookupflag_ignore_base.tests \ tests/lookupflag_ignore_combination.tests \ tests/lookupflag_ignore_ligatures.tests \ @@ -112,15 +123,4 @@ TESTS = \ $(NULL) DISABLED_TESTS = \ - tests/classdef1_empty.tests \ - tests/classdef1_multiple.tests \ - tests/classdef2_multiple.tests \ - tests/gpos3_lookupflag.tests \ - tests/gpos3.tests \ - tests/gpos4_multiple_anchors.tests \ - tests/gpos4_simple.tests \ - tests/gpos5.tests \ - tests/gpos6.tests \ - tests/gsub3_1_simple.tests \ - tests/lookupflag_ignore_attach.tests \ $(NULL) diff --git a/test/shaping/data/aots/hb-aots-tester.cpp b/test/shaping/data/aots/hb-aots-tester.cpp index 81e30076e..bd46dec36 100644 --- a/test/shaping/data/aots/hb-aots-tester.cpp +++ b/test/shaping/data/aots/hb-aots-tester.cpp @@ -153,6 +153,7 @@ bool gsub_test(const char *testName, char test_name[255]; sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName); FILE *tests_file = fopen (test_name, "a+"); + if (!ok) fprintf (tests_file, "#"); fprintf (tests_file, "../fonts/%s:--features=\"", fontfileName + 9); for (unsigned int i = 0; i < gNbFeatures; i++) { diff --git a/test/shaping/data/aots/tests/classdef1_empty.tests b/test/shaping/data/aots/tests/classdef1_empty.tests index 71d87f1c3..76aaecc43 100644 --- a/test/shaping/data/aots/tests/classdef1_empty.tests +++ b/test/shaping/data/aots/tests/classdef1_empty.tests @@ -1 +1 @@ -../fonts/classdef1_font2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|25|21] +#../fonts/classdef1_font2.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0013,U+0014,U+0015:[17|23|24|25|21] diff --git a/test/shaping/data/aots/tests/gsub3_1_simple.tests b/test/shaping/data/aots/tests/gsub3_1_simple.tests index 5e65ba055..b8a28d15a 100644 --- a/test/shaping/data/aots/tests/gsub3_1_simple.tests +++ b/test/shaping/data/aots/tests/gsub3_1_simple.tests @@ -1 +1 @@ -../fonts/gsub3_1_simple_f1.otf:--features="-test[1],test[3],test[5]=2,test[7]=3,-test[9],test[11]" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011:[17|18|17|20|17|21|17|22|17|18|17|20|17] +#../fonts/gsub3_1_simple_f1.otf:--features="-test[1],test[3],test[5]=2,test[7]=3,-test[9],test[11]" --no-clusters --no-glyph-names --no-positions:U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011,U+0012,U+0011:[17|18|17|20|17|21|17|22|17|18|17|20|17] diff --git a/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests b/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests index 6534fc09f..55ae5385e 100644 --- a/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests +++ b/test/shaping/data/aots/tests/lookupflag_ignore_attach.tests @@ -1,5 +1,5 @@ -../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+000D,U+001A,U+000A:[10|15|10] -../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+0015,U+000D,U+0016,U+0017,U+001D,U+001A,U+000A:[10|15|21|22|23|29|10] -../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+0015,U+000D,U+0016,U+001B,U+001A,U+000A:[10|11|21|13|22|27|26|10] -../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+001B,U+000D,U+0016,U+0017,U+001A,U+000A:[10|11|27|13|22|23|26|10] -../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+001B,U+000D,U+000E,U+0017,U+001A,U+000A:[10|11|27|13|14|23|26|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+000D,U+001A,U+000A:[10|15|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+0015,U+000D,U+0016,U+0017,U+001D,U+001A,U+000A:[10|15|21|22|23|29|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+0015,U+000D,U+0016,U+001B,U+001A,U+000A:[10|11|21|13|22|27|26|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+001B,U+000D,U+0016,U+0017,U+001A,U+000A:[10|11|27|13|22|23|26|10] +#../fonts/lookupflag_ignore_attach_f1.otf:--features="test" --no-clusters --no-glyph-names --no-positions:U+000A,U+000B,U+001B,U+000D,U+000E,U+0017,U+001A,U+000A:[10|11|27|13|14|23|26|10] From 20edc70d537b01e8a384ee05673335f2f8a18238 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 14:52:34 -0500 Subject: [PATCH 088/158] [morx/kerx] Fix sanitize regression Broke in 8dcc1913a1670ede7b124f7b5b775d7ab8791386 If sanitizer is left with another object, it wouldn't work. Better fix coming soon. --- src/hb-aat-layout-kerx-table.hh | 6 +----- src/hb-aat-layout-morx-table.hh | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 2d5489324..fbeb35b0c 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -962,11 +962,9 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { + c->reset_object (); if (unlikely (!st->u.header.sanitize (c))) - { - c->reset_object (); return_trace (false); - } /* OpenType kern table has 2-byte subtable lengths. That's limiting. * MS implementation also only supports one subtable, of format 0, * anyway. Certain versions of some fonts, like Calibry, contain @@ -976,8 +974,6 @@ struct KerxTable * the length for the last subtable. */ if (i < count - 1) c->set_object (*st); - else - c->reset_object (); if (unlikely (!st->sanitize (c))) return_trace (false); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 5b44a4cfa..dc406f59f 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1061,11 +1061,9 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { + c->reset_object (); if (unlikely (!c->check_struct (subtable))) - { - c->reset_object (); return_trace (false); - } c->set_object (*subtable); if (!subtable->sanitize (c)) return_trace (false); From ed900ee9afa0dabdbf6bf9d2af46c2343a16773f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 15:22:09 -0500 Subject: [PATCH 089/158] [tests] Rename --- test/shaping/data/in-house/Makefile.sources | 2 +- .../data/in-house/tests/{macos-10.12.tests => macos.tests} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/shaping/data/in-house/tests/{macos-10.12.tests => macos.tests} (100%) diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index 209de079c..d548e961b 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -33,7 +33,7 @@ TESTS = \ tests/khmer-misc.tests \ tests/language-tags.tests \ tests/ligature-id.tests \ - tests/macos-10.12.tests \ + tests/macos.tests \ tests/mark-attachment.tests \ tests/mark-filtering-sets.tests \ tests/mongolian-variation-selector.tests \ diff --git a/test/shaping/data/in-house/tests/macos-10.12.tests b/test/shaping/data/in-house/tests/macos.tests similarity index 100% rename from test/shaping/data/in-house/tests/macos-10.12.tests rename to test/shaping/data/in-house/tests/macos.tests From ee3a3e10d45f5df1a74b65fbe3df77f8dd8f902e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 15:37:01 -0500 Subject: [PATCH 090/158] [tests/shaping] Allow comments in test files Line should start with "# ". --- test/shaping/run-tests.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index c22d45c46..4c7fee1e4 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -47,6 +47,20 @@ for filename in args: f = open (filename) for line in f: + comment = False + if line.startswith ("#"): + comment = True + line = line[1:] + + if line.startswith (' '): + if not reference: + print ("#%s" % line) + continue + + line = line.strip () + if not line: + continue + fontfile, options, unicodes, glyphs_expected = line.split (":") if fontfile.startswith ('/') or fontfile.startswith ('"/'): fontfile, expected_hash = fontfile.split('@') @@ -68,11 +82,10 @@ for filename in args: fontfile = os.path.normpath (os.path.join (cwd, fontfile)) extra_options = ["--shaper=ot"] - glyphs_expected = glyphs_expected.strip() if glyphs_expected != '*': extra_options.append("--verify") - if line.startswith ("#"): + if comment: if not reference: print ("# %s %s --unicodes %s" % (hb_shape, fontfile, unicodes)) continue From 5020affc3877d39377506245ecaf01a659eef82a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 15:42:11 -0500 Subject: [PATCH 091/158] [tests] Minor --- test/shaping/data/in-house/tests/macos.tests | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 6841ef93f..4788f256e 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -1,3 +1,5 @@ + +# 10.12: /Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] /Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] From ea9512e61a7ed333b810918e74cce4c8bd2291b9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 15:49:33 -0500 Subject: [PATCH 092/158] [tests] Redo test runner logging a bit --- test/shaping/run-tests.py | 44 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index 4c7fee1e4..959d08f9e 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -27,7 +27,7 @@ process = subprocess.Popen ([hb_shape, '--batch'], stdout=subprocess.PIPE, stderr=sys.stdout) -ran_once = False +passes = 0 fails = 0 skips = 0 @@ -69,13 +69,13 @@ for filename in args: with open (fontfile, 'rb') as ff: actual_hash = hashlib.sha1 (ff.read()).hexdigest ().strip () if actual_hash != expected_hash: - print ('different versions of the font is found, expected %s hash was %s but got %s, skip' % + print ('different version of %s found; Expected hash %s, got %s; skipping.' % (fontfile, expected_hash, actual_hash)) - skips = skips + 1 + skips += 1 continue except: - print ('%s is not found, skip.' % fontfile) - skips = skips + 1 + print ('%s not found, skip.' % fontfile) + skips += 1 continue else: cwd = os.path.dirname(filename) @@ -108,12 +108,12 @@ for filename in args: fontfile] + extra_options + ["--unicodes", unicodes] + (options.split (' ') if options else [])) - ran_once = True - if glyphs1 != glyphs2 and glyphs_expected != '*': print ("FT funcs: " + glyphs1) # file=sys.stderr print ("OT funcs: " + glyphs2) # file=sys.stderr - fails = fails + 1 + fails += 1 + else: + passes += 1 if reference: print (":".join ([fontfile, options, unicodes, glyphs1])) @@ -122,18 +122,20 @@ for filename in args: if glyphs1.strip() != glyphs_expected and glyphs_expected != '*': print ("Actual: " + glyphs1) # file=sys.stderr print ("Expected: " + glyphs_expected) # file=sys.stderr - fails = fails + 1 + fails += 1 + else: + passes += 1 -if fails != 0 or skips != 0: - if not reference: - print ("%d tests are failed and %d tests are skipped." % (fails, skips)) # file=sys.stderr - if fails != 0: - sys.exit (1) - sys.exit (77) -else: - if not ran_once: - if not reference: - print ("No tests ran.") - sys.exit (77) - elif not reference: +if not reference: + print ("%d tests passed; %d failed; %d skipped." % (passes, fails, skips)) # file=sys.stderr + if not (fails + passes): + print ("No tests ran.") + elif not (fails + skips): print ("All tests passed.") + +if fails: + sys.exit (1) +elif passes: + sys.exit (0) +else: + sys.exit (77) From b7f7950e8fc4b9e229b466ac2453d57b8da9a5a6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 15:56:17 -0500 Subject: [PATCH 093/158] [aat] Add test for recent regression --- test/shaping/data/in-house/tests/macos.tests | 1 + 1 file changed, 1 insertion(+) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 4788f256e..53268fba6 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -1,5 +1,6 @@ # 10.12: +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] /Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] From b518e5af9f66414396752069bb8f43466a9236fa Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 25 Nov 2018 01:39:00 +0330 Subject: [PATCH 094/158] Add 10.13.6 aat fonts tests and bot (#1409) --- .circleci/config.yml | 16 ++++++++++++++-- test/shaping/data/in-house/Makefile.sources | 3 ++- .../tests/{macos.tests => macos-10.12.6.tests} | 2 -- .../data/in-house/tests/macos-10.13.6.tests | 13 +++++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) rename test/shaping/data/in-house/tests/{macos.tests => macos-10.12.6.tests} (99%) create mode 100644 test/shaping/data/in-house/tests/macos-10.13.6.tests diff --git a/.circleci/config.yml b/.circleci/config.yml index e56aabb7f..e546f89ff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: - macos-10.12-aat-fonts: + macos-10.12.6-aat-fonts: macos: xcode: "9.2.0" steps: @@ -13,6 +13,17 @@ jobs: - run: make -j4 - run: make check || .ci/fail.sh + macos-10.13.6-aat-fonts: + macos: + xcode: "10.1.0" + steps: + - checkout + - run: brew update-reset + - run: brew install wget pkg-config libtool ragel freetype glib cairo + - run: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo + - run: make -j4 + - run: make check || .ci/fail.sh + # macos-llvm-gcc-4.2: # macos: # xcode: "8.3.3" @@ -313,7 +324,8 @@ workflows: build: jobs: # macOS - - macos-10.12-aat-fonts + - macos-10.12.6-aat-fonts + - macos-10.13.6-aat-fonts #- macos-llvm-gcc-4.2 #- macos-notest-apple-gcc-i686-4.2 - macos-notest-ios diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index d548e961b..1a3d17755 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -33,7 +33,8 @@ TESTS = \ tests/khmer-misc.tests \ tests/language-tags.tests \ tests/ligature-id.tests \ - tests/macos.tests \ + tests/macos-10.12.6.tests \ + tests/macos-10.13.6.tests \ tests/mark-attachment.tests \ tests/mark-filtering-sets.tests \ tests/mongolian-variation-selector.tests \ diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos-10.12.6.tests similarity index 99% rename from test/shaping/data/in-house/tests/macos.tests rename to test/shaping/data/in-house/tests/macos-10.12.6.tests index 53268fba6..0f10fedf1 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos-10.12.6.tests @@ -1,5 +1,3 @@ - -# 10.12: /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] /Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] diff --git a/test/shaping/data/in-house/tests/macos-10.13.6.tests b/test/shaping/data/in-house/tests/macos-10.13.6.tests new file mode 100644 index 000000000..9d456d2d9 --- /dev/null +++ b/test/shaping/data/in-house/tests/macos-10.13.6.tests @@ -0,0 +1,13 @@ +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +# The following is broken +#/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +# The following is broken +#/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa::U+0056,U+0041,U+0056,U+0041:[gid332=0+1227|gid4=1@-65,0+1162|gid332=2@-65,0+1162|gid4=3@-65,0+1227] From ae8ed58a6e53441d9ccbf67afd8a00b815cde99e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 17:11:09 -0500 Subject: [PATCH 095/158] [aat.morx] Remove set_object() business With OS X 10.13 Apple Chancery fails to ligate if we limit each morx sub-chain to its declared length. Perhaps their newer compiler does object-sharing across sub-chains. Anyway, since that's a valid, if unspecified, way to compile tables, remove enforcement. Probably do the same with kern/kerx. --- src/hb-aat-layout-morx-table.hh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index dc406f59f..77abf457f 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1026,8 +1026,6 @@ struct Chain if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (*subtable); - subtable->dispatch (c); if (reverse) @@ -1041,7 +1039,6 @@ struct Chain subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } - c->sanitizer.reset_object (); } inline unsigned int get_size (void) const { return length; } @@ -1061,15 +1058,10 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { - c->reset_object (); - if (unlikely (!c->check_struct (subtable))) - return_trace (false); - c->set_object (*subtable); if (!subtable->sanitize (c)) return_trace (false); subtable = &StructAfter > (*subtable); } - c->reset_object (); return_trace (true); } From 15905a2a2998f7ddd964f920a4828602235d6b00 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 17:14:39 -0500 Subject: [PATCH 096/158] [aat.kerx] Remove kerx subtable boundary enforcement Have not encountered fonts needing this, but same reasoning as for morx (see previos commit.) --- src/hb-aat-layout-kerx-table.hh | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index fbeb35b0c..b5c1e1d1f 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -926,12 +926,6 @@ struct KerxTable if (reverse) c->buffer->reverse (); - /* See comment in sanitize() for conditional here. */ - if (i < count - 1) - c->sanitizer.set_object (*st); - else - c->sanitizer.reset_object (); - ret |= st->dispatch (c); if (reverse) @@ -943,7 +937,6 @@ struct KerxTable st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } - c->sanitizer.reset_object (); return ret; } @@ -962,24 +955,10 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - c->reset_object (); - if (unlikely (!st->u.header.sanitize (c))) - return_trace (false); - /* OpenType kern table has 2-byte subtable lengths. That's limiting. - * MS implementation also only supports one subtable, of format 0, - * anyway. Certain versions of some fonts, like Calibry, contain - * kern subtable that exceeds 64kb. Looks like, the subtable length - * is simply ignored. Which makes sense. It's only needed if you - * have multiple subtables. To handle such fonts, we just ignore - * the length for the last subtable. */ - if (i < count - 1) - c->set_object (*st); - if (unlikely (!st->sanitize (c))) return_trace (false); st = &StructAfter (*st); } - c->reset_object (); return_trace (true); } From bbdb6edb3e1cea4c5b7076c4f6b3e6998ae36dae Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 17:15:38 -0500 Subject: [PATCH 097/158] [sanitize] Remove now-unused set_object() machinery --- src/hb-machinery.hh | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index edef54053..9ca247d90 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -259,34 +259,11 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - template - inline void set_object (const T& obj) - { - reset_object (); - - const char *obj_start = (const char *) &obj; - const char *obj_end = (const char *) &obj + obj.get_size (); - assert (obj_start <= obj_end); /* Must not overflow. */ - - if (unlikely (obj_end < this->start || this->end < obj_start)) - this->start = this->end = nullptr; - else - { - this->start = MAX (this->start, obj_start); - this->end = MIN (this->end , obj_end ); - } - } - - inline void reset_object (void) + inline void start_processing (void) { this->start = this->blob->data; this->end = this->start + this->blob->length; assert (this->start <= this->end); /* Must not overflow. */ - } - - inline void start_processing (void) - { - reset_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; From 825ea5a4607fafa11c56a72a82bda773f6b44e79 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 25 Nov 2018 01:59:54 +0330 Subject: [PATCH 098/158] [test] Merge 10.12.6 and 10.13.6 tests, update to Apple Chancery fix --- test/shaping/data/in-house/Makefile.sources | 3 +-- .../data/in-house/tests/macos-10.12.6.tests | 11 -------- .../data/in-house/tests/macos-10.13.6.tests | 13 ---------- test/shaping/data/in-house/tests/macos.tests | 26 +++++++++++++++++++ 4 files changed, 27 insertions(+), 26 deletions(-) delete mode 100644 test/shaping/data/in-house/tests/macos-10.12.6.tests delete mode 100644 test/shaping/data/in-house/tests/macos-10.13.6.tests create mode 100644 test/shaping/data/in-house/tests/macos.tests diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index 1a3d17755..d548e961b 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -33,8 +33,7 @@ TESTS = \ tests/khmer-misc.tests \ tests/language-tags.tests \ tests/ligature-id.tests \ - tests/macos-10.12.6.tests \ - tests/macos-10.13.6.tests \ + tests/macos.tests \ tests/mark-attachment.tests \ tests/mark-filtering-sets.tests \ tests/mongolian-variation-selector.tests \ diff --git a/test/shaping/data/in-house/tests/macos-10.12.6.tests b/test/shaping/data/in-house/tests/macos-10.12.6.tests deleted file mode 100644 index 0f10fedf1..000000000 --- a/test/shaping/data/in-house/tests/macos-10.12.6.tests +++ /dev/null @@ -1,11 +0,0 @@ -/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] -/Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] -/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] -/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] -/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] -/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] -/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] diff --git a/test/shaping/data/in-house/tests/macos-10.13.6.tests b/test/shaping/data/in-house/tests/macos-10.13.6.tests deleted file mode 100644 index 9d456d2d9..000000000 --- a/test/shaping/data/in-house/tests/macos-10.13.6.tests +++ /dev/null @@ -1,13 +0,0 @@ -/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] -/Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] -# The following is broken -#/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] -/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] -/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] -# The following is broken -#/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] -/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa::U+0056,U+0041,U+0056,U+0041:[gid332=0+1227|gid4=1@-65,0+1162|gid332=2@-65,0+1162|gid4=3@-65,0+1227] diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests new file mode 100644 index 000000000..4d76d84e7 --- /dev/null +++ b/test/shaping/data/in-house/tests/macos.tests @@ -0,0 +1,26 @@ +# 10.12.6 +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] + +# 10.13.6 +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +# The following is broken https://github.com/harfbuzz/harfbuzz/issues/1410 +#/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa::U+0056,U+0041,U+0056,U+0041:[gid332=0+1227|gid4=1@-65,0+1162|gid332=2@-65,0+1162|gid4=3@-65,0+1227] From e6877e28cd30e89af7cce59d903184a5a01ec970 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 25 Nov 2018 02:12:40 +0330 Subject: [PATCH 099/158] [test] Add the missed aots fonts --- test/shaping/data/aots/fonts/classdef1_font1.otf | Bin 0 -> 6004 bytes test/shaping/data/aots/fonts/classdef1_font2.otf | Bin 0 -> 6020 bytes .../data/aots/tests/classdef1_empty.tests | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test/shaping/data/aots/fonts/classdef1_font1.otf create mode 100644 test/shaping/data/aots/fonts/classdef1_font2.otf diff --git a/test/shaping/data/aots/fonts/classdef1_font1.otf b/test/shaping/data/aots/fonts/classdef1_font1.otf new file mode 100644 index 0000000000000000000000000000000000000000..f0add6983936d966c680e9a86c6e8c34453aa0dd GIT binary patch literal 6004 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/aots/fonts/classdef1_font2.otf b/test/shaping/data/aots/fonts/classdef1_font2.otf new file mode 100644 index 0000000000000000000000000000000000000000..f01876dd19e81cb241e90f9b249b8b46129b5763 GIT binary patch literal 6020 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 bmaOq-tFeZw{>Ag?7YE1f12mTXe~ Date: Sat, 24 Nov 2018 21:32:00 -0500 Subject: [PATCH 100/158] [arrays] Merge ArrayOf's sub_array into hb_array_t's --- src/hb-dsalgs.hh | 44 +++++++++++++++++++++++++++----------------- src/hb-open-type.hh | 30 ++++++++++++++++++------------ 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 1680bf914..577359601 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -567,6 +567,7 @@ struct hb_array_t { static_assert ((bool) (unsigned) hb_static_size (Type), ""); + inline hb_array_t (void) : arrayZ (nullptr), len (0) {} inline hb_array_t (const hb_array_t &o) : arrayZ (o.arrayZ), len (o.len) {} inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {} @@ -582,6 +583,24 @@ struct hb_array_t inline unsigned int get_size (void) const { return len * sizeof (Type); } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const + { + if (!seg_count) return hb_array_t (); + + unsigned int count = len; + if (unlikely (start_offset > count)) + count = 0; + else + count -= start_offset; + count = *seg_count = MIN (count, *seg_count); + return hb_array_t (arrayZ + start_offset, count); + } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + { return sub_array (start_offset, &seg_count); } + + inline hb_bytes_t as_bytes (void) const + { return hb_bytes_t (arrayZ, len * sizeof (Type)); } + template inline Type *lsearch (const T &x, Type *not_found = nullptr) @@ -620,23 +639,8 @@ struct hb_array_t ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp); } - inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const - { - unsigned int count = len; - if (unlikely (start_offset > count)) - count = 0; - else - count -= start_offset; - count = MIN (count, seg_count); - return hb_array_t (arrayZ + start_offset, count); - } - - inline hb_bytes_t as_bytes (void) const - { - return hb_bytes_t (arrayZ, len * sizeof (Type)); - } - - inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } + inline void free (void) + { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } template inline bool sanitize (hb_sanitize_context_t *c) const @@ -660,9 +664,15 @@ enum hb_bfind_not_found_t template struct hb_sorted_array_t : hb_array_t { + inline hb_sorted_array_t (void) : hb_array_t () {} inline hb_sorted_array_t (const hb_array_t &o) : hb_array_t (o) {} inline hb_sorted_array_t (Type *array_, unsigned int len_) : hb_array_t (array_, len_) {} + inline hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const + { return hb_sorted_array_t (((const hb_array_t *) (this))->sub_array (start_offset, seg_count)); } + inline hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + { return sub_array (start_offset, &seg_count); } + template inline Type *bsearch (const T &x, Type *not_found = nullptr) { diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 2e3db31df..83edc7737 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -492,18 +492,6 @@ struct ArrayOf HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); - inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const - { - unsigned int count = len; - if (unlikely (start_offset > count)) - count = 0; - else - count -= start_offset; - count = MIN (count, *pcount); - *pcount = count; - return arrayZ + start_offset; - } - inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= len)) return Null (Type); @@ -523,6 +511,15 @@ struct ArrayOf inline hb_array_t as_array (void) const { return hb_array (arrayZ, len); } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) + { return as_array ().sub_array (start_offset, count);} + inline bool serialize (hb_serialize_context_t *c, unsigned int items_len) { @@ -777,6 +774,15 @@ struct SortedArrayOf : ArrayOf inline hb_sorted_array_t as_array (void) const { return hb_sorted_array (this->arrayZ, this->len); } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int count) + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) + { return as_array ().sub_array (start_offset, count);} + template inline Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } From f47c5da0aa04a88b37d9c3af4730204319a9a36b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 21:36:57 -0500 Subject: [PATCH 101/158] [arrays] Use hb_array_t<> in all places with sub_array() --- src/hb-aat-layout-lcar-table.hh | 6 +++--- src/hb-ot-layout-gdef-table.hh | 14 ++++++++------ src/hb-ot-math-table.hh | 10 ++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/hb-aat-layout-lcar-table.hh b/src/hb-aat-layout-lcar-table.hh index 43ac74f9c..40d34f59b 100644 --- a/src/hb-aat-layout-lcar-table.hh +++ b/src/hb-aat-layout-lcar-table.hh @@ -52,10 +52,10 @@ struct lcar const OffsetTo* entry_offset = lookup.get_value (glyph, font->face->get_num_glyphs ()); const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry); - if (caret_count && *caret_count) + if (caret_count) { - const HBINT16 *arr = array.sub_array (start_offset, caret_count); - unsigned int count = *caret_count; + hb_array_t arr = array.sub_array (start_offset, caret_count); + unsigned int count = arr.len; for (unsigned int i = 0; i < count; ++i) switch (format) { diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 22e07f7a4..2c4cbea85 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -61,9 +61,10 @@ struct AttachList const AttachPoint &points = this+attachPoint[index]; - if (point_count) { - const HBUINT16 *array = points.sub_array (start_offset, point_count); - unsigned int count = *point_count; + if (point_count) + { + hb_array_t array = points.sub_array (start_offset, point_count); + unsigned int count = array.len; for (unsigned int i = 0; i < count; i++) point_array[i] = array[i]; } @@ -216,9 +217,10 @@ struct LigGlyph unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const { - if (caret_count) { - const OffsetTo *array = carets.sub_array (start_offset, caret_count); - unsigned int count = *caret_count; + if (caret_count) + { + hb_array_t > array = carets.sub_array (start_offset, caret_count); + unsigned int count = array.len; for (unsigned int i = 0; i < count; i++) caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store); } diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index b87304979..153a41795 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -509,9 +509,8 @@ struct MathGlyphAssembly if (parts_count) { int scale = font->dir_scale (direction); - const MathGlyphPartRecord *arr = - partRecords.sub_array (start_offset, parts_count); - unsigned int count = *parts_count; + hb_array_t arr = partRecords.sub_array (start_offset, parts_count); + unsigned int count = arr.len; for (unsigned int i = 0; i < count; i++) arr[i].extract (parts[i], scale, font); } @@ -556,9 +555,8 @@ struct MathGlyphConstruction if (variants_count) { int scale = font->dir_scale (direction); - const MathGlyphVariantRecord *arr = - mathGlyphVariantRecord.sub_array (start_offset, variants_count); - unsigned int count = *variants_count; + hb_array_t arr = mathGlyphVariantRecord.sub_array (start_offset, variants_count); + unsigned int count = arr.len; for (unsigned int i = 0; i < count; i++) { variants[i].glyph = arr[i].variantGlyph; From 248ce22857c8918bf3468ef48d906de4c19c3d4d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 22:01:06 -0500 Subject: [PATCH 102/158] [tests] Minor --- test/shaping/run-tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/shaping/run-tests.py b/test/shaping/run-tests.py index 959d08f9e..26853e4ee 100755 --- a/test/shaping/run-tests.py +++ b/test/shaping/run-tests.py @@ -87,11 +87,11 @@ for filename in args: if comment: if not reference: - print ("# %s %s --unicodes %s" % (hb_shape, fontfile, unicodes)) + print ('# %s "%s" --unicodes %s' % (hb_shape, fontfile, unicodes)) continue if not reference: - print ("%s %s %s %s --unicodes %s" % + print ('%s "%s" %s %s --unicodes %s' % (hb_shape, fontfile, ' '.join(extra_options), options, unicodes)) # hack to support fonts with space on run-tests.py, after several other tries... From 9eeebd8ddedb96c03860ce7eb5500aafa3969d6b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 22:16:47 -0500 Subject: [PATCH 103/158] Revert "[sanitize] Remove now-unused set_object() machinery" This reverts commit bbdb6edb3e1cea4c5b7076c4f6b3e6998ae36dae. --- src/hb-machinery.hh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 9ca247d90..edef54053 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -259,11 +259,34 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - inline void start_processing (void) + template + inline void set_object (const T& obj) + { + reset_object (); + + const char *obj_start = (const char *) &obj; + const char *obj_end = (const char *) &obj + obj.get_size (); + assert (obj_start <= obj_end); /* Must not overflow. */ + + if (unlikely (obj_end < this->start || this->end < obj_start)) + this->start = this->end = nullptr; + else + { + this->start = MAX (this->start, obj_start); + this->end = MIN (this->end , obj_end ); + } + } + + inline void reset_object (void) { this->start = this->blob->data; this->end = this->start + this->blob->length; assert (this->start <= this->end); /* Must not overflow. */ + } + + inline void start_processing (void) + { + reset_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; From c8a2dc820eb0ee3124e3762cb1167ac9e528ad28 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 22:16:53 -0500 Subject: [PATCH 104/158] Revert "[aat.kerx] Remove kerx subtable boundary enforcement" This reverts commit 15905a2a2998f7ddd964f920a4828602235d6b00. --- src/hb-aat-layout-kerx-table.hh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index b5c1e1d1f..fbeb35b0c 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -926,6 +926,12 @@ struct KerxTable if (reverse) c->buffer->reverse (); + /* See comment in sanitize() for conditional here. */ + if (i < count - 1) + c->sanitizer.set_object (*st); + else + c->sanitizer.reset_object (); + ret |= st->dispatch (c); if (reverse) @@ -937,6 +943,7 @@ struct KerxTable st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } + c->sanitizer.reset_object (); return ret; } @@ -955,10 +962,24 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { + c->reset_object (); + if (unlikely (!st->u.header.sanitize (c))) + return_trace (false); + /* OpenType kern table has 2-byte subtable lengths. That's limiting. + * MS implementation also only supports one subtable, of format 0, + * anyway. Certain versions of some fonts, like Calibry, contain + * kern subtable that exceeds 64kb. Looks like, the subtable length + * is simply ignored. Which makes sense. It's only needed if you + * have multiple subtables. To handle such fonts, we just ignore + * the length for the last subtable. */ + if (i < count - 1) + c->set_object (*st); + if (unlikely (!st->sanitize (c))) return_trace (false); st = &StructAfter (*st); } + c->reset_object (); return_trace (true); } From 748198a6718adbb200ee24ac013c617f62c946a4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 22:16:59 -0500 Subject: [PATCH 105/158] Revert "[aat.morx] Remove set_object() business" This reverts commit ae8ed58a6e53441d9ccbf67afd8a00b815cde99e. Apparently this broke Apple Chancery from OS X 10.12 :(. Investigating... --- src/hb-aat-layout-morx-table.hh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 77abf457f..dc406f59f 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1026,6 +1026,8 @@ struct Chain if (reverse) c->buffer->reverse (); + c->sanitizer.set_object (*subtable); + subtable->dispatch (c); if (reverse) @@ -1039,6 +1041,7 @@ struct Chain subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } + c->sanitizer.reset_object (); } inline unsigned int get_size (void) const { return length; } @@ -1058,10 +1061,15 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { + c->reset_object (); + if (unlikely (!c->check_struct (subtable))) + return_trace (false); + c->set_object (*subtable); if (!subtable->sanitize (c)) return_trace (false); subtable = &StructAfter > (*subtable); } + c->reset_object (); return_trace (true); } From 1c2302bbf1d2d0e66f49ab54ad98d1b61bc5603d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 22:32:17 -0500 Subject: [PATCH 106/158] [debug] Print function in return_trace() --- src/hb-debug.hh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/hb-debug.hh b/src/hb-debug.hh index d218e4328..f13cfddb9 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -293,14 +293,16 @@ struct hb_auto_trace_t if (plevel) --*plevel; } - inline ret_t ret (ret_t v, unsigned int line = 0) + inline ret_t ret (ret_t v, + const char *func = "", + unsigned int line = 0) { if (unlikely (returned)) { fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n"); return v; } - _hb_debug_msg (what, obj, nullptr, true, plevel ? *plevel : 1, -1, + _hb_debug_msg (what, obj, func, true, plevel ? *plevel : 1, -1, "return %s (line %d)", hb_printer_t().print (v), line); if (plevel) --*plevel; @@ -325,17 +327,21 @@ struct hb_auto_trace_t<0, ret_t> const char *message, ...) HB_PRINTF_FUNC(6, 7) {} - inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } + inline ret_t ret (ret_t v, + const char *func HB_UNUSED = 0, + unsigned int line HB_UNUSED = 0) { return v; } }; /* For disabled tracing; optimize out everything. * https://github.com/harfbuzz/harfbuzz/pull/605 */ template struct hb_no_trace_t { - inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } + inline ret_t ret (ret_t v, + const char *func HB_UNUSED = "", + unsigned int line HB_UNUSED = 0) { return v; } }; -#define return_trace(RET) return trace.ret (RET, __LINE__) +#define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__) /* From 4202a3cde3b6065124feb7f4c662563de1e08126 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 22:48:34 -0500 Subject: [PATCH 107/158] Minor --- src/hb-open-type.hh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 83edc7737..8970ec784 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -443,8 +443,17 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf { inline const Type& operator [] (unsigned int i) const { - return this+this->arrayZ[i]; + const OffsetTo *p = &this->arrayZ[i]; + if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */ + return this+*p; } + inline Type& operator [] (unsigned int i) + { + const OffsetTo *p = &this->arrayZ[i]; + if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */ + return this+*p; + } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { @@ -867,13 +876,15 @@ struct VarSizedBinSearchArrayOf inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= header.nUnits)) return Null (Type); + if (unlikely (i >= get_length ())) return Null (Type); return StructAtOffset (&bytesZ, i * header.unitSize); } inline Type& operator [] (unsigned int i) { + if (unlikely (i >= get_length ())) return Crap (Type); return StructAtOffset (&bytesZ, i * header.unitSize); } + inline unsigned int get_length (void) const { return header.nUnits; } inline unsigned int get_size (void) const { return header.static_size + header.nUnits * header.unitSize; } @@ -897,7 +908,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; + unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, base))) return_trace (false); @@ -908,7 +919,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; + unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, base, user_data))) return_trace (false); @@ -919,7 +930,7 @@ struct VarSizedBinSearchArrayOf inline const Type *bsearch (const T &key) const { unsigned int size = header.unitSize; - int min = 0, max = (int) header.nUnits - 1; + int min = 0, max = (int) get_length () - 1; while (min <= max) { int mid = ((unsigned int) min + (unsigned int) max) / 2; From 3d3097269995aa227b4b198d4da2baf942b65c66 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 23:12:28 -0500 Subject: [PATCH 108/158] [aat] Skip terminator in VarSizedBinSearchArray<> Fixes shaping with Apple Chancery on 10.13 again. In that font, there was a terminator segment, that was tripping off sanitize(). --- src/hb-aat-layout-common.hh | 6 ++++++ src/hb-open-type.hh | 21 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 2c09a796c..3ee96bc91 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -76,6 +76,8 @@ struct LookupFormat0 template struct LookupSegmentSingle { + enum { TerminationWordCount = 2 }; + inline int cmp (hb_codepoint_t g) const { return g < first ? -1 : g <= last ? 0 : +1 ; } @@ -134,6 +136,8 @@ struct LookupFormat2 template struct LookupSegmentArray { + enum { TerminationWordCount = 2 }; + inline const T* get_value (hb_codepoint_t glyph_id, const void *base) const { return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr; @@ -204,6 +208,8 @@ struct LookupFormat4 template struct LookupSingle { + enum { TerminationWordCount = 1 }; + inline int cmp (hb_codepoint_t g) const { return glyph.cmp (g); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 8970ec784..9b412dbce 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -874,6 +874,22 @@ struct VarSizedBinSearchArrayOf HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); + inline bool last_is_terminator (void) const + { + if (unlikely (!header.nUnits)) return false; + + /* Gah. + * + * "The number of termination values that need to be included is table-specific. + * The value that indicates binary search termination is 0xFFFF." */ + const HBUINT16 *words = &StructAtOffset (&bytesZ, (header.nUnits - 1) * header.unitSize); + unsigned int count = Type::TerminationWordCount; + for (unsigned int i = 0; i < count; i++) + if (words[i] != 0xFFFFu) + return false; + return true; + } + inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= get_length ())) return Null (Type); @@ -884,7 +900,10 @@ struct VarSizedBinSearchArrayOf if (unlikely (i >= get_length ())) return Crap (Type); return StructAtOffset (&bytesZ, i * header.unitSize); } - inline unsigned int get_length (void) const { return header.nUnits; } + inline unsigned int get_length (void) const + { + return header.nUnits - last_is_terminator (); + } inline unsigned int get_size (void) const { return header.static_size + header.nUnits * header.unitSize; } From b3c5affc05a3c7bbcfbd98521703d3d3447fcd7d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 23:34:34 -0500 Subject: [PATCH 109/158] Simplify sanitize set_object() --- src/hb-aat-layout-kerx-table.hh | 12 ++++++------ src/hb-aat-layout-morx-table.hh | 10 +++++----- src/hb-machinery.hh | 28 ++++++++++++++-------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index fbeb35b0c..33f626c6f 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -928,9 +928,9 @@ struct KerxTable /* See comment in sanitize() for conditional here. */ if (i < count - 1) - c->sanitizer.set_object (*st); + c->sanitizer.set_object (st); else - c->sanitizer.reset_object (); + c->sanitizer.set_object (); ret |= st->dispatch (c); @@ -943,7 +943,7 @@ struct KerxTable st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } - c->sanitizer.reset_object (); + c->sanitizer.set_object (); return ret; } @@ -962,7 +962,7 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - c->reset_object (); + c->set_object (); if (unlikely (!st->u.header.sanitize (c))) return_trace (false); /* OpenType kern table has 2-byte subtable lengths. That's limiting. @@ -973,13 +973,13 @@ struct KerxTable * have multiple subtables. To handle such fonts, we just ignore * the length for the last subtable. */ if (i < count - 1) - c->set_object (*st); + c->set_object (st); if (unlikely (!st->sanitize (c))) return_trace (false); st = &StructAfter (*st); } - c->reset_object (); + c->set_object (); return_trace (true); } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index dc406f59f..bc7c3c37b 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1026,7 +1026,7 @@ struct Chain if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (*subtable); + c->sanitizer.set_object (subtable); subtable->dispatch (c); @@ -1041,7 +1041,7 @@ struct Chain subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } - c->sanitizer.reset_object (); + c->sanitizer.set_object (); } inline unsigned int get_size (void) const { return length; } @@ -1061,15 +1061,15 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { - c->reset_object (); + c->set_object (); if (unlikely (!c->check_struct (subtable))) return_trace (false); - c->set_object (*subtable); + c->set_object (subtable); if (!subtable->sanitize (c)) return_trace (false); subtable = &StructAfter > (*subtable); } - c->reset_object (); + c->set_object (); return_trace (true); } diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index edef54053..7457a099e 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -259,13 +259,20 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - template - inline void set_object (const T& obj) - { - reset_object (); + struct dummy_get_size_t + { inline unsigned int get_size (void) const { return 0; } }; - const char *obj_start = (const char *) &obj; - const char *obj_end = (const char *) &obj + obj.get_size (); + template + inline void set_object (const T *obj = nullptr) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; + assert (this->start <= this->end); /* Must not overflow. */ + + if (!obj) return; + + const char *obj_start = (const char *) obj; + const char *obj_end = (const char *) obj + obj->get_size (); assert (obj_start <= obj_end); /* Must not overflow. */ if (unlikely (obj_end < this->start || this->end < obj_start)) @@ -277,16 +284,9 @@ struct hb_sanitize_context_t : } } - inline void reset_object (void) - { - this->start = this->blob->data; - this->end = this->start + this->blob->length; - assert (this->start <= this->end); /* Must not overflow. */ - } - inline void start_processing (void) { - reset_object (); + set_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; From 1e8994221fb5cfdb1902d5249c7a75cde6d6e3c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 23:38:06 -0500 Subject: [PATCH 110/158] Add hb_sanitize_with_object_t Context manager. --- src/hb-machinery.hh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 7457a099e..56e279e6c 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -480,6 +480,23 @@ struct hb_sanitize_context_t : bool num_glyphs_set; }; +struct hb_sanitize_with_object_t +{ + template + inline hb_sanitize_with_object_t (hb_sanitize_context_t *c, + const T& obj) : c (c) + { + c->set_object (obj); + } + inline ~hb_sanitize_with_object_t (void) + { + c->set_object (); + } + + private: + hb_sanitize_context_t *c; +}; + /* * Serialize From c405ed0509afaa7c3846e8e461bedfbceb0cd937 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 23:46:15 -0500 Subject: [PATCH 111/158] [morx] Port to hb_sanitize_with_object_t --- src/hb-aat-layout-morx-table.hh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index bc7c3c37b..15332d0f6 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -911,6 +911,13 @@ struct ChainSubtable } } + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + hb_sanitize_with_object_t with (&c->sanitizer, this); + return_trace (dispatch (c)); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -919,6 +926,7 @@ struct ChainSubtable !c->check_range (this, length)) return_trace (false); + hb_sanitize_with_object_t with (c, this); return_trace (dispatch (c)); } @@ -1026,9 +1034,7 @@ struct Chain if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (subtable); - - subtable->dispatch (c); + subtable->apply (c); if (reverse) c->buffer->reverse (); @@ -1041,7 +1047,6 @@ struct Chain subtable = &StructAfter > (*subtable); c->set_lookup_index (c->lookup_index + 1); } - c->sanitizer.set_object (); } inline unsigned int get_size (void) const { return length; } @@ -1061,15 +1066,10 @@ struct Chain unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { - c->set_object (); - if (unlikely (!c->check_struct (subtable))) - return_trace (false); - c->set_object (subtable); if (!subtable->sanitize (c)) return_trace (false); subtable = &StructAfter > (*subtable); } - c->set_object (); return_trace (true); } From c5a6b355e165e90d8d90454ceeca7b100282945f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 23:49:23 -0500 Subject: [PATCH 112/158] [kerx] Port to hb_sanitize_with_object_t --- src/hb-aat-layout-kerx-table.hh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 33f626c6f..8dc74991e 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -926,13 +926,11 @@ struct KerxTable if (reverse) c->buffer->reverse (); - /* See comment in sanitize() for conditional here. */ - if (i < count - 1) - c->sanitizer.set_object (st); - else - c->sanitizer.set_object (); - - ret |= st->dispatch (c); + { + /* See comment in sanitize() for conditional here. */ + hb_sanitize_with_object_t with (&c->sanitizer, i < count - 1 ? st : (const SubTable *) nullptr); + ret |= st->dispatch (c); + } if (reverse) c->buffer->reverse (); @@ -943,7 +941,6 @@ struct KerxTable st = &StructAfter (*st); c->set_lookup_index (c->lookup_index + 1); } - c->sanitizer.set_object (); return ret; } @@ -962,7 +959,6 @@ struct KerxTable unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - c->set_object (); if (unlikely (!st->u.header.sanitize (c))) return_trace (false); /* OpenType kern table has 2-byte subtable lengths. That's limiting. @@ -972,14 +968,13 @@ struct KerxTable * is simply ignored. Which makes sense. It's only needed if you * have multiple subtables. To handle such fonts, we just ignore * the length for the last subtable. */ - if (i < count - 1) - c->set_object (st); + hb_sanitize_with_object_t with (c, i < count - 1 ? st : (const SubTable *) nullptr); if (unlikely (!st->sanitize (c))) return_trace (false); + st = &StructAfter (*st); } - c->set_object (); return_trace (true); } From 6ee401049d475b2a2d9c859e6dbf8ff2750a1609 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 00:21:13 -0500 Subject: [PATCH 113/158] Simplify sanitize set_object() / fix bots --- src/hb-machinery.hh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 56e279e6c..3717c4d33 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -259,17 +259,10 @@ struct hb_sanitize_context_t : inline void set_max_ops (int max_ops_) { max_ops = max_ops_; } - struct dummy_get_size_t - { inline unsigned int get_size (void) const { return 0; } }; - - template - inline void set_object (const T *obj = nullptr) + template + inline void set_object (const T *obj) { - this->start = this->blob->data; - this->end = this->start + this->blob->length; - assert (this->start <= this->end); /* Must not overflow. */ - - if (!obj) return; + reset_object (); const char *obj_start = (const char *) obj; const char *obj_end = (const char *) obj + obj->get_size (); @@ -284,9 +277,16 @@ struct hb_sanitize_context_t : } } + inline void reset_object (void) + { + this->start = this->blob->data; + this->end = this->start + this->blob->length; + assert (this->start <= this->end); /* Must not overflow. */ + } + inline void start_processing (void) { - set_object (); + reset_object (); this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; @@ -482,7 +482,7 @@ struct hb_sanitize_context_t : struct hb_sanitize_with_object_t { - template + template inline hb_sanitize_with_object_t (hb_sanitize_context_t *c, const T& obj) : c (c) { @@ -490,7 +490,7 @@ struct hb_sanitize_with_object_t } inline ~hb_sanitize_with_object_t (void) { - c->set_object (); + c->reset_object (); } private: From 9326912941e5927bcfb4689689c954b9a3995baa Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 00:27:23 -0500 Subject: [PATCH 114/158] [kerx] Fix crash --- src/hb-machinery.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 3717c4d33..537275dba 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -264,6 +264,8 @@ struct hb_sanitize_context_t : { reset_object (); + if (!obj) return; + const char *obj_start = (const char *) obj; const char *obj_end = (const char *) obj + obj->get_size (); assert (obj_start <= obj_end); /* Must not overflow. */ From 264c4a539cbfd8d5e5f143206d9d27230a186897 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 00:30:08 -0500 Subject: [PATCH 115/158] [test] Reorder test suites aots is less interesting. Run text-rendering-tests before aots. --- test/shaping/data/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/shaping/data/Makefile.am b/test/shaping/data/Makefile.am index 2b908b3c3..01f6c5a32 100644 --- a/test/shaping/data/Makefile.am +++ b/test/shaping/data/Makefile.am @@ -3,8 +3,8 @@ NULL = SUBDIRS = \ in-house \ - aots \ text-rendering-tests \ + aots \ $(NULL) # Convenience targets: From 95abd53758e281325b9124f0942aafb382a89090 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 13:14:29 +0330 Subject: [PATCH 116/158] [feat] Expose public API * hb_aat_get_feature_settings --- src/Makefile.sources | 1 + src/hb-aat-layout-feat-table.hh | 68 ++++++++++++++++++++++++- src/hb-aat-layout-morx-table.hh | 6 +-- src/hb-aat-layout.cc | 33 ++++++++++++ src/hb-aat-layout.h | 75 +++++++++++++++++++++++++++ src/hb-aat-layout.hh | 7 +-- src/hb-aat-map.hh | 5 +- src/hb-ot-face.hh | 1 + test/api/Makefile.am | 1 + test/api/test-aat-layout.c | 89 +++++++++++++++++++++++++++++++++ test/api/test-c.c | 1 + 11 files changed, 278 insertions(+), 9 deletions(-) create mode 100644 src/hb-aat-layout.h create mode 100644 test/api/test-aat-layout.c diff --git a/src/Makefile.sources b/src/Makefile.sources index 3dcd771f4..2635cbc31 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -189,6 +189,7 @@ HB_OT_headers = \ hb-ot-name.h \ hb-ot-shape.h \ hb-ot-var.h \ + hb-aat-layout.h \ $(NULL) # Optional Sources and Headers with external deps diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 87ab4abd3..5e7781353 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -45,15 +45,28 @@ struct SettingName return_trace (likely (c->check_struct (this))); } - protected: HBUINT16 setting; /* The setting. */ NameID nameIndex; /* The name table index for the setting's name. */ public: DEFINE_SIZE_STATIC (4); }; +struct feat; + struct FeatureName { +<<<<<<< HEAD +======= + static int cmp (const void *key_, const void *entry_) + { + hb_aat_feature_type_t key = * (hb_aat_feature_type_t *) key_; + const FeatureName * entry = (const FeatureName *) entry_; + return key < entry->feature ? -1 : + key > entry->feature ? 1 : + 0; + } + +>>>>>>> 08982bb4... [feat] Expose public API enum { Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in @@ -68,6 +81,39 @@ struct FeatureName * as the default. */ }; +<<<<<<< HEAD +======= + inline unsigned int get_settings (const feat *feat, + hb_bool_t *is_exclusive, + unsigned int start_offset, + unsigned int *records_count, + hb_aat_feature_option_record_t *records_buffer) const + { + bool exclusive = featureFlags & Exclusive; + bool not_default = featureFlags & NotDefault; + if (is_exclusive) *is_exclusive = exclusive; + const UnsizedArrayOf& settings = feat+settingTable; + unsigned int len = 0; + unsigned int settings_count = nSettings; + if (records_count && records_buffer) + { + len = MIN (settings_count - start_offset, *records_count); + for (unsigned int i = 0; i < len; i++) + { + records_buffer[i].is_default = exclusive && not_default && + i + start_offset == (featureFlags & IndexMask); + records_buffer[i].name_id = settings[start_offset + i].nameIndex; + records_buffer[i].setting = settings[start_offset + i].setting; + } + if (exclusive && !not_default && start_offset == 0 && len != 0) + records_buffer[0].is_default = true; + } + if (is_exclusive) *is_exclusive = exclusive; + if (records_count) *records_count = len; + return settings_count; + } + +>>>>>>> 08982bb4... [feat] Expose public API inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -95,6 +141,26 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; + inline const FeatureName& get_feature (hb_aat_feature_type_t key) const + { + const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &names, + FeatureName::static_size, + sizeof (FeatureName), + FeatureName::cmp); + + return feature ? *feature : Null (FeatureName); + } + + inline unsigned int get_settings (hb_aat_feature_type_t key, + hb_bool_t *is_exclusive, + unsigned int start_offset, + unsigned int *records_count, + hb_aat_feature_option_record_t *records_buffer) const + { + return get_feature (key).get_settings (this, is_exclusive, start_offset, + records_count, records_buffer); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 15332d0f6..a62519755 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -957,9 +957,9 @@ struct Chain unsigned int count = featureCount; for (unsigned i = 0; i < count; i++) { - const Feature &feature = featureZ[i]; - uint16_t type = feature.featureType; - uint16_t setting = feature.featureSetting; + const Feature &feature = featureZ[i]; + hb_aat_feature_type_t type = feature.featureType; + hb_aat_feature_setting_t setting = feature.featureSetting; retry: const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type); if (info && info->setting == setting) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index d9580c152..5eca51756 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -1,5 +1,6 @@ /* * Copyright © 2017 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -27,6 +28,7 @@ #include "hb-open-type.hh" #include "hb-ot-face.hh" +#include "hb-aat-layout.h" #include "hb-aat-layout.hh" #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. @@ -167,6 +169,12 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_, ankr_table = ankr_table_; ankr_end = ankr_end_; } +static inline const AAT::feat& +_get_feat (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::feat); + return *(hb_ot_face_data (face)->feat.get ()); +} /* @@ -297,3 +305,28 @@ _hb_aat_language_get (hb_face_t *face, { return face->table.ltag->get_language (i); } + +/** + * hb_aat_get_feature_settings: + * @face: a font face. + * @identifier: aat feature id you are querying. + * @is_exclusive: (out): is only one of the features can be enabled. + * @start_offset: start offset, if you are iterating + * @records_count: (inout): gets input buffer size, puts number of filled one + * @records_buffer: (out): buffer of records + * + * Returns: Total number of records available for the feature. + * + * Since: REPLACEME + */ +unsigned int +hb_aat_get_feature_settings (hb_face_t *face, + hb_aat_feature_type_t identifier, + hb_bool_t *is_exclusive, + unsigned int start_offset, + unsigned int *records_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */) +{ + return _get_feat (face).get_settings (identifier, is_exclusive, start_offset, + records_count, records_buffer); +} diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h new file mode 100644 index 000000000..186293529 --- /dev/null +++ b/src/hb-aat-layout.h @@ -0,0 +1,75 @@ +/* + * 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_AAT_LAYOUT_H +#define HB_AAT_LAYOUT_H + +#include "hb.h" +#include "hb-ot.h" + +HB_BEGIN_DECLS + +/** + * hb_aat_type_t: + * + * Feature identifier + * + * Since: REPLACEME + */ +typedef uint16_t hb_aat_feature_type_t; + +/** + * hb_aat_feature_t: + * + * Feature value + * + * Since: REPLACEME + */ +typedef uint16_t hb_aat_feature_setting_t; + +/** + * hb_aat_feature_option_record_t: + * + * Feature type record + * + * Since: REPLACEME + **/ +typedef struct hb_aat_feature_option_record_t +{ + hb_bool_t is_default; + hb_aat_feature_setting_t setting; + hb_ot_name_id_t name_id; +} hb_aat_feature_option_record_t; + +HB_EXTERN unsigned int +hb_aat_get_feature_settings (hb_face_t *face, + hb_aat_feature_type_t identifier, + hb_bool_t *is_exclusive, + unsigned int start_offset, + unsigned int *records_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */); + +HB_END_DECLS + +#endif /* HB_AAT_LAYOUT_H */ diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 1d3407971..d7296aa68 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -29,15 +29,16 @@ #include "hb.hh" +#include "hb-aat-layout.h" #include "hb-ot-shape.hh" struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; + hb_aat_feature_type_t aatFeatureType; + hb_aat_feature_setting_t selectorToEnable; + hb_aat_feature_setting_t selectorToDisable; static inline int cmp (const void *key_, const void *entry_) { diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 7d85c7c38..07720e882 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -28,6 +28,7 @@ #define HB_AAT_MAP_HH #include "hb.hh" +#include "hb-aat-layout.h" struct hb_aat_map_t @@ -65,8 +66,8 @@ struct hb_aat_map_builder_t public: struct feature_info_t { - uint16_t type; - uint16_t setting; + hb_aat_feature_type_t type; + hb_aat_feature_setting_t setting; unsigned seq; /* For stable sorting only. */ static int cmp (const void *pa, const void *pb) diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index 3ca875e71..4a3260626 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -65,6 +65,7 @@ HB_OT_TABLE(AAT, trak) \ HB_OT_TABLE(AAT, lcar) \ HB_OT_TABLE(AAT, ltag) \ + HB_OT_TABLE(AAT, feat) \ /* OpenType variations. */ \ HB_OT_TABLE(OT, fvar) \ HB_OT_TABLE(OT, avar) \ diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 4c329408f..89f03b851 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -28,6 +28,7 @@ check_PROGRAMS = $(TEST_PROGS) noinst_PROGRAMS = $(TEST_PROGS) TEST_PROGS = \ + test-aat-layout \ test-baseline \ test-blob \ test-buffer \ diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c new file mode 100644 index 000000000..8019c5f27 --- /dev/null +++ b/test/api/test-aat-layout.c @@ -0,0 +1,89 @@ +/* + * Copyright © 2018 Google, Inc. + * + * 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 "hb-test.h" + +#include + +/* Unit tests for hb-aat-layout.h */ + +static void +test_aat_get_feature_settings (void) +{ + hb_bool_t is_exclusive; + hb_aat_feature_option_record_t records[3]; + unsigned int count = 3; + + hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); + + g_assert_cmpuint (4, ==, hb_aat_get_feature_settings (face, 18, &is_exclusive, + 0, &count, records)); + g_assert_cmpuint (3, ==, count); + g_assert (is_exclusive); + + g_assert_cmpuint (1, ==, records[0].is_default); + g_assert_cmpuint (0, ==, records[0].setting); + g_assert_cmpuint (294, ==, records[0].name_id); + + g_assert_cmpuint (0, ==, records[1].is_default); + g_assert_cmpuint (1, ==, records[1].setting); + g_assert_cmpuint (295, ==, records[1].name_id); + + g_assert_cmpuint (0, ==, records[2].is_default); + g_assert_cmpuint (2, ==, records[2].setting); + g_assert_cmpuint (296, ==, records[2].name_id); + + count = 3; + g_assert_cmpuint (4, ==, hb_aat_get_feature_settings (face, 18, &is_exclusive, + 3, &count, records)); + g_assert_cmpuint (1, ==, count); + g_assert (is_exclusive); + + g_assert_cmpuint (0, ==, records[0].is_default); + g_assert_cmpuint (3, ==, records[0].setting); + g_assert_cmpuint (297, ==, records[0].name_id); + + count = 100; + g_assert_cmpuint (0, ==, hb_aat_get_feature_settings (face, 32, &is_exclusive, + 0, &count, records)); + g_assert_cmpuint (0, ==, count); + g_assert (!is_exclusive); + + hb_face_destroy (face); + + hb_face_t *sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); + g_assert_cmpuint (0, ==, hb_aat_get_feature_settings (face, 100, &is_exclusive, + 0, &count, records)); + hb_face_destroy (sbix); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_aat_get_feature_settings); + + return hb_test_run(); +} diff --git a/test/api/test-c.c b/test/api/test-c.c index 061f35cdc..3d1d6e8c5 100644 --- a/test/api/test-c.c +++ b/test/api/test-c.c @@ -33,6 +33,7 @@ #include #include +#include #ifdef HAVE_GLIB #include From b791bbbae47aa19709da640a1dc5e84590c5c2c2 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 15:15:56 +0330 Subject: [PATCH 117/158] [feat] Apply @jfkthame reviews --- src/hb-aat-layout-feat-table.hh | 27 +++++++++++++++------------ src/hb-aat-layout.cc | 23 ++++++++++++----------- src/hb-aat-layout.h | 14 +++++++++----- test/api/fonts/aat-feat.ttf | Bin 0 -> 1132 bytes test/api/test-aat-layout.c | 30 ++++++++++++++++++------------ 5 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 test/api/fonts/aat-feat.ttf diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 5e7781353..f151d7146 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -84,14 +84,13 @@ struct FeatureName <<<<<<< HEAD ======= inline unsigned int get_settings (const feat *feat, - hb_bool_t *is_exclusive, + hb_aat_feature_setting_t *default_setting, unsigned int start_offset, unsigned int *records_count, hb_aat_feature_option_record_t *records_buffer) const { bool exclusive = featureFlags & Exclusive; bool not_default = featureFlags & NotDefault; - if (is_exclusive) *is_exclusive = exclusive; const UnsizedArrayOf& settings = feat+settingTable; unsigned int len = 0; unsigned int settings_count = nSettings; @@ -100,15 +99,19 @@ struct FeatureName len = MIN (settings_count - start_offset, *records_count); for (unsigned int i = 0; i < len; i++) { - records_buffer[i].is_default = exclusive && not_default && - i + start_offset == (featureFlags & IndexMask); records_buffer[i].name_id = settings[start_offset + i].nameIndex; records_buffer[i].setting = settings[start_offset + i].setting; } - if (exclusive && !not_default && start_offset == 0 && len != 0) - records_buffer[0].is_default = true; } - if (is_exclusive) *is_exclusive = exclusive; + if (default_setting) + { + if (exclusive) + { + if (settings_count && !not_default) *default_setting = settings[0].setting; + else if (not_default) *default_setting = featureFlags & IndexMask; + } + else *default_setting = HB_AAT_FEATURE_NO_DEFAULT_INDEX; + } if (records_count) *records_count = len; return settings_count; } @@ -151,14 +154,14 @@ struct feat return feature ? *feature : Null (FeatureName); } - inline unsigned int get_settings (hb_aat_feature_type_t key, - hb_bool_t *is_exclusive, + inline unsigned int get_settings (hb_aat_feature_type_t type, + hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, - unsigned int *records_count, + unsigned int *records_count, /* IN/OUT. May be NULL. */ hb_aat_feature_option_record_t *records_buffer) const { - return get_feature (key).get_settings (this, is_exclusive, start_offset, - records_count, records_buffer); + return get_feature (type).get_settings (this, default_setting, + start_offset, records_count, records_buffer); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 5eca51756..d9c336b7d 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -308,12 +308,13 @@ _hb_aat_language_get (hb_face_t *face, /** * hb_aat_get_feature_settings: - * @face: a font face. - * @identifier: aat feature id you are querying. - * @is_exclusive: (out): is only one of the features can be enabled. - * @start_offset: start offset, if you are iterating - * @records_count: (inout): gets input buffer size, puts number of filled one - * @records_buffer: (out): buffer of records + * @face: a font face. + * @identifier: aat feature id you are querying. + * @default_setting: (out): default value for the type. If it is HB_AAT_FEATURE_NO_DEFAULT_INDEX + * means non is default and it is not exclusive also. + * @start_offset: start offset, if you are iterating + * @records_count: (inout): gets input buffer size, puts number of filled one + * @records_buffer: (out): buffer of records * * Returns: Total number of records available for the feature. * @@ -322,11 +323,11 @@ _hb_aat_language_get (hb_face_t *face, unsigned int hb_aat_get_feature_settings (hb_face_t *face, hb_aat_feature_type_t identifier, - hb_bool_t *is_exclusive, + hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */) + unsigned int *records_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */) { - return _get_feat (face).get_settings (identifier, is_exclusive, start_offset, - records_count, records_buffer); + return _get_feat (face).get_settings (identifier, default_setting, + start_offset, records_count, records_buffer); } diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h index 186293529..1ca9af728 100644 --- a/src/hb-aat-layout.h +++ b/src/hb-aat-layout.h @@ -57,18 +57,22 @@ typedef uint16_t hb_aat_feature_setting_t; **/ typedef struct hb_aat_feature_option_record_t { - hb_bool_t is_default; hb_aat_feature_setting_t setting; hb_ot_name_id_t name_id; } hb_aat_feature_option_record_t; +/* + * Since: REPLACEME + */ +#define HB_AAT_FEATURE_NO_DEFAULT_INDEX ((hb_aat_feature_setting_t) -1) + HB_EXTERN unsigned int hb_aat_get_feature_settings (hb_face_t *face, - hb_aat_feature_type_t identifier, - hb_bool_t *is_exclusive, + hb_aat_feature_type_t type, + hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */); + unsigned int *records_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */); HB_END_DECLS diff --git a/test/api/fonts/aat-feat.ttf b/test/api/fonts/aat-feat.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1ff99a2dddde9bd0b3a1dfd8110ee7c3bee7a727 GIT binary patch literal 1132 zcmcIjJx>%-6g_WdSeA8GR+JAR(eYyyBSr;L3kp^j*-gkwfPzj27+B(d37fcB7(#4} zh1igoSdiGzsQdt9w6IXAj0G{2SZp-LLK6!TJon84R(8J0d-t4s&wKaYH#1NGY|Oz# z_w~WE?TvNO2Y^b@J2IAa3$V)<$XCeQCOo$|_p1FFU}VTQCo{7Xm*RnL#y7|t(w;kR ze}5k(Ugf-)rXvtDk1}qNA5UkCCDS2-TILeS(R^Ka)-4r`TC_0UO77&`tYabZ%wS} zXnzofFb?kVl{>4P^!HGrpDG-;1zI%)w`^gK4C`-i?&U(umzv|@Krx||Ak zIPkix%4#S3uF^-&c72*E-ht$|VSy2@mhiIL+Va=N?fOJ6_p58JbWP=XX7Y0}a!5|I zYIwpqDt&Bd+>a@g;30z;vKWPnF{Dvs&a1T3$kXd;>@jjv@8HDg<=3%fvMZYX1r~HbU$Ycu9X9&ybE*i5n5tckzjuX6)6N?^typqBZN(97dhq zyFna9z4rekJ`IE4rKL=S6nj^lP^ucH3KEBid2_0knh1hwUnRbuyq=l{%?;H=+rqf~ zBc1dgp*_L9C#h>CKc)Rjond9ty-ZuRAwe6d%-^&q Date: Thu, 1 Nov 2018 19:20:20 +0330 Subject: [PATCH 118/158] [feat] Apply @drott and @jfkthame comments --- src/hb-aat-layout-feat-table.hh | 14 ++++++-------- src/hb-aat-layout.cc | 12 +++++++----- src/hb-aat-layout.h | 10 +++++----- test/api/test-aat-layout.c | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index f151d7146..37c35af71 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -87,7 +87,7 @@ struct FeatureName hb_aat_feature_setting_t *default_setting, unsigned int start_offset, unsigned int *records_count, - hb_aat_feature_option_record_t *records_buffer) const + hb_aat_feature_type_selector_t *records_buffer) const { bool exclusive = featureFlags & Exclusive; bool not_default = featureFlags & NotDefault; @@ -105,12 +105,10 @@ struct FeatureName } if (default_setting) { - if (exclusive) - { - if (settings_count && !not_default) *default_setting = settings[0].setting; - else if (not_default) *default_setting = featureFlags & IndexMask; - } - else *default_setting = HB_AAT_FEATURE_NO_DEFAULT_INDEX; + unsigned int index = not_default ? featureFlags & IndexMask : 0; + if (exclusive && index < settings_count) + *default_setting = settings[index].setting; + else *default_setting = HB_AAT_FEATURE_NO_DEFAULT_SETTING; } if (records_count) *records_count = len; return settings_count; @@ -158,7 +156,7 @@ struct feat hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_option_record_t *records_buffer) const + hb_aat_feature_type_selector_t *records_buffer) const { return get_feature (type).get_settings (this, default_setting, start_offset, records_count, records_buffer); diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index d9c336b7d..5b72e2d6e 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -309,14 +309,16 @@ _hb_aat_language_get (hb_face_t *face, /** * hb_aat_get_feature_settings: * @face: a font face. - * @identifier: aat feature id you are querying. - * @default_setting: (out): default value for the type. If it is HB_AAT_FEATURE_NO_DEFAULT_INDEX - * means non is default and it is not exclusive also. + * @identifier: AAT feature id you are querying, for example 1 for + * "Ligatures" feature, 37 for the "Lower Case" feature, + * 38 for the "Upper Case" feature, etc. + * @default_setting: (out): default value for the type. If it is HB_AAT_FEATURE_NO_DEFAULT_SETTING + * means none is selected as default and the feature is not exclusive. * @start_offset: start offset, if you are iterating * @records_count: (inout): gets input buffer size, puts number of filled one * @records_buffer: (out): buffer of records * - * Returns: Total number of records available for the feature. + * Returns: Total number of feature selector records available for the feature. * * Since: REPLACEME */ @@ -326,7 +328,7 @@ hb_aat_get_feature_settings (hb_face_t *face, hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */) + hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */) { return _get_feat (face).get_settings (identifier, default_setting, start_offset, records_count, records_buffer); diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h index 1ca9af728..83517e584 100644 --- a/src/hb-aat-layout.h +++ b/src/hb-aat-layout.h @@ -49,22 +49,22 @@ typedef uint16_t hb_aat_feature_type_t; typedef uint16_t hb_aat_feature_setting_t; /** - * hb_aat_feature_option_record_t: + * hb_aat_feature_type_selector_t: * * Feature type record * * Since: REPLACEME **/ -typedef struct hb_aat_feature_option_record_t +typedef struct hb_aat_feature_type_selector_t { hb_aat_feature_setting_t setting; hb_ot_name_id_t name_id; -} hb_aat_feature_option_record_t; +} hb_aat_feature_type_selector_t; /* * Since: REPLACEME */ -#define HB_AAT_FEATURE_NO_DEFAULT_INDEX ((hb_aat_feature_setting_t) -1) +#define HB_AAT_FEATURE_NO_DEFAULT_SETTING ((hb_aat_feature_setting_t) -1) HB_EXTERN unsigned int hb_aat_get_feature_settings (hb_face_t *face, @@ -72,7 +72,7 @@ hb_aat_get_feature_settings (hb_face_t *face, hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_option_record_t *records_buffer /* OUT. May be NULL. */); + hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */); HB_END_DECLS diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index e6af36562..1d6b775fb 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -32,7 +32,7 @@ static void test_aat_get_feature_settings (void) { hb_aat_feature_setting_t default_setting; - hb_aat_feature_option_record_t records[3]; + hb_aat_feature_type_selector_t records[3]; unsigned int count = 3; hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); @@ -65,7 +65,7 @@ test_aat_get_feature_settings (void) g_assert_cmpuint (1, ==, hb_aat_get_feature_settings (face, 14, &default_setting, 0, &count, records)); g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (HB_AAT_FEATURE_NO_DEFAULT_INDEX, ==, default_setting); + g_assert_cmpuint (HB_AAT_FEATURE_NO_DEFAULT_SETTING, ==, default_setting); g_assert_cmpuint (8, ==, records[0].setting); g_assert_cmpuint (308, ==, records[0].name_id); From a157b3e4ebd57ad29f217c4cef6519e7398cfa5c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 19:56:16 +0330 Subject: [PATCH 119/158] [feat] Apply @behdad comments --- src/Makefile.sources | 2 +- src/hb-aat-layout-feat-table.hh | 1 + src/hb-aat-layout.cc | 16 ++++++++-------- src/hb-aat-layout.hh | 2 +- src/hb-aat-map.hh | 2 +- src/{hb-aat-layout.h => hb-aat.h} | 22 +++++++++++++--------- src/hb-ot.h | 1 + test/api/test-aat-layout.c | 14 +++++++------- test/api/test-c.c | 1 - 9 files changed, 33 insertions(+), 28 deletions(-) rename src/{hb-aat-layout.h => hb-aat.h} (78%) diff --git a/src/Makefile.sources b/src/Makefile.sources index 2635cbc31..e0dee9408 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -189,7 +189,7 @@ HB_OT_headers = \ hb-ot-name.h \ hb-ot-shape.h \ hb-ot-var.h \ - hb-aat-layout.h \ + hb-aat.h \ $(NULL) # Optional Sources and Headers with external deps diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 37c35af71..14ce9904c 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -45,6 +45,7 @@ struct SettingName return_trace (likely (c->check_struct (this))); } + public: HBUINT16 setting; /* The setting. */ NameID nameIndex; /* The name table index for the setting's name. */ public: diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 5b72e2d6e..04f4d6ee6 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -28,7 +28,7 @@ #include "hb-open-type.hh" #include "hb-ot-face.hh" -#include "hb-aat-layout.h" +#include "hb-aat.h" #include "hb-aat-layout.hh" #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. @@ -307,7 +307,7 @@ _hb_aat_language_get (hb_face_t *face, } /** - * hb_aat_get_feature_settings: + * hb_aat_layout_get_feature_settings: * @face: a font face. * @identifier: AAT feature id you are querying, for example 1 for * "Ligatures" feature, 37 for the "Lower Case" feature, @@ -323,12 +323,12 @@ _hb_aat_language_get (hb_face_t *face, * Since: REPLACEME */ unsigned int -hb_aat_get_feature_settings (hb_face_t *face, - hb_aat_feature_type_t identifier, - hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */) +hb_aat_layout_get_feature_settings (hb_face_t *face, + hb_aat_feature_type_t identifier, + hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *records_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */) { return _get_feat (face).get_settings (identifier, default_setting, start_offset, records_count, records_buffer); diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index d7296aa68..a87ef202b 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -29,7 +29,7 @@ #include "hb.hh" -#include "hb-aat-layout.h" +#include "hb-aat.h" #include "hb-ot-shape.hh" diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 07720e882..77f9114bd 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -28,7 +28,7 @@ #define HB_AAT_MAP_HH #include "hb.hh" -#include "hb-aat-layout.h" +#include "hb-aat.h" struct hb_aat_map_t diff --git a/src/hb-aat-layout.h b/src/hb-aat.h similarity index 78% rename from src/hb-aat-layout.h rename to src/hb-aat.h index 83517e584..b71f67c1e 100644 --- a/src/hb-aat-layout.h +++ b/src/hb-aat.h @@ -22,8 +22,12 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_AAT_LAYOUT_H -#define HB_AAT_LAYOUT_H +#ifndef HB_OT_H_IN +#error "Include instead." +#endif + +#ifndef HB_AAT_H +#define HB_AAT_H #include "hb.h" #include "hb-ot.h" @@ -67,13 +71,13 @@ typedef struct hb_aat_feature_type_selector_t #define HB_AAT_FEATURE_NO_DEFAULT_SETTING ((hb_aat_feature_setting_t) -1) HB_EXTERN unsigned int -hb_aat_get_feature_settings (hb_face_t *face, - hb_aat_feature_type_t type, - hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */); +hb_aat_layout_get_feature_settings (hb_face_t *face, + hb_aat_feature_type_t type, + hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *records_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */); HB_END_DECLS -#endif /* HB_AAT_LAYOUT_H */ +#endif /* HB_AAT_H */ diff --git a/src/hb-ot.h b/src/hb-ot.h index c168175ac..d4f1d3abc 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -37,6 +37,7 @@ #include "hb-ot-name.h" #include "hb-ot-shape.h" #include "hb-ot-var.h" +#include "hb-aat.h" HB_BEGIN_DECLS diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 1d6b775fb..854b58ac8 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -24,9 +24,9 @@ #include "hb-test.h" -#include +#include -/* Unit tests for hb-aat-layout.h */ +/* Unit tests for hb-aat.h */ static void test_aat_get_feature_settings (void) @@ -37,7 +37,7 @@ test_aat_get_feature_settings (void) hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); - g_assert_cmpuint (4, ==, hb_aat_get_feature_settings (face, 18, &default_setting, + g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, 18, &default_setting, 0, &count, records)); g_assert_cmpuint (3, ==, count); g_assert_cmpuint (0, ==, default_setting); @@ -52,7 +52,7 @@ test_aat_get_feature_settings (void) g_assert_cmpuint (296, ==, records[2].name_id); count = 3; - g_assert_cmpuint (4, ==, hb_aat_get_feature_settings (face, 18, &default_setting, + g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, 18, &default_setting, 3, &count, records)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (0, ==, default_setting); @@ -62,7 +62,7 @@ test_aat_get_feature_settings (void) count = 1; - g_assert_cmpuint (1, ==, hb_aat_get_feature_settings (face, 14, &default_setting, + g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, 14, &default_setting, 0, &count, records)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (HB_AAT_FEATURE_NO_DEFAULT_SETTING, ==, default_setting); @@ -72,14 +72,14 @@ test_aat_get_feature_settings (void) count = 100; - g_assert_cmpuint (0, ==, hb_aat_get_feature_settings (face, 32, NULL, + g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, 32, NULL, 0, &count, records)); g_assert_cmpuint (0, ==, count); hb_face_destroy (face); hb_face_t *sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); - g_assert_cmpuint (0, ==, hb_aat_get_feature_settings (sbix, 100, NULL, + g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, 100, NULL, 0, &count, records)); hb_face_destroy (sbix); } diff --git a/test/api/test-c.c b/test/api/test-c.c index 3d1d6e8c5..061f35cdc 100644 --- a/test/api/test-c.c +++ b/test/api/test-c.c @@ -33,7 +33,6 @@ #include #include -#include #ifdef HAVE_GLIB #include From b233fa4bc9cdb1c6677b37106d96d878d6e03bfd Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 20:02:57 +0330 Subject: [PATCH 120/158] [feat] Rename records to selectors as @drott --- src/hb-aat-layout-feat-table.hh | 20 ++++++++++---------- src/hb-aat-layout.cc | 10 +++++----- src/hb-aat.h | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 14ce9904c..0054dadb4 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -87,21 +87,21 @@ struct FeatureName inline unsigned int get_settings (const feat *feat, hb_aat_feature_setting_t *default_setting, unsigned int start_offset, - unsigned int *records_count, - hb_aat_feature_type_selector_t *records_buffer) const + unsigned int *selectors_count, + hb_aat_feature_type_selector_t *selectors_buffer) const { bool exclusive = featureFlags & Exclusive; bool not_default = featureFlags & NotDefault; const UnsizedArrayOf& settings = feat+settingTable; unsigned int len = 0; unsigned int settings_count = nSettings; - if (records_count && records_buffer) + if (selectors_count && selectors_buffer) { - len = MIN (settings_count - start_offset, *records_count); + len = MIN (settings_count - start_offset, *selectors_count); for (unsigned int i = 0; i < len; i++) { - records_buffer[i].name_id = settings[start_offset + i].nameIndex; - records_buffer[i].setting = settings[start_offset + i].setting; + selectors_buffer[i].name_id = settings[start_offset + i].nameIndex; + selectors_buffer[i].setting = settings[start_offset + i].setting; } } if (default_setting) @@ -111,7 +111,7 @@ struct FeatureName *default_setting = settings[index].setting; else *default_setting = HB_AAT_FEATURE_NO_DEFAULT_SETTING; } - if (records_count) *records_count = len; + if (selectors_count) *selectors_count = len; return settings_count; } @@ -156,11 +156,11 @@ struct feat inline unsigned int get_settings (hb_aat_feature_type_t type, hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *records_buffer) const + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) const { return get_feature (type).get_settings (this, default_setting, - start_offset, records_count, records_buffer); + start_offset, selectors_count, selectors_buffer); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 04f4d6ee6..b4990e1fb 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -315,8 +315,8 @@ _hb_aat_language_get (hb_face_t *face, * @default_setting: (out): default value for the type. If it is HB_AAT_FEATURE_NO_DEFAULT_SETTING * means none is selected as default and the feature is not exclusive. * @start_offset: start offset, if you are iterating - * @records_count: (inout): gets input buffer size, puts number of filled one - * @records_buffer: (out): buffer of records + * @selectors_count: (inout): gets input buffer size, puts number of filled one + * @selectors_buffer: (out): buffer of records * * Returns: Total number of feature selector records available for the feature. * @@ -327,9 +327,9 @@ hb_aat_layout_get_feature_settings (hb_face_t *face, hb_aat_feature_type_t identifier, hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */) + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) { return _get_feat (face).get_settings (identifier, default_setting, - start_offset, records_count, records_buffer); + start_offset, selectors_count, selectors_buffer); } diff --git a/src/hb-aat.h b/src/hb-aat.h index b71f67c1e..539abcd9a 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -75,8 +75,8 @@ hb_aat_layout_get_feature_settings (hb_face_t *face, hb_aat_feature_type_t type, hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, - unsigned int *records_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *records_buffer /* OUT. May be NULL. */); + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */); HB_END_DECLS From 7a0471aa356bcd062d31a59bdb19c335249116c7 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 21:38:54 +0330 Subject: [PATCH 121/158] [feat] Turn AAT feature id into enum --- src/hb-aat-layout-feat-table.hh | 20 ++-- src/hb-aat-layout-morx-table.hh | 10 +- src/hb-aat-layout.cc | 170 ++++++++++++++++---------------- src/hb-aat-layout.hh | 6 +- src/hb-aat-map.cc | 2 +- src/hb-aat-map.hh | 4 +- src/hb-aat.h | 64 +++++++----- test/api/test-aat-layout.c | 8 +- test/api/test-c.c | 1 + 9 files changed, 150 insertions(+), 135 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 0054dadb4..2fc71101a 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -60,7 +60,7 @@ struct FeatureName ======= static int cmp (const void *key_, const void *entry_) { - hb_aat_feature_type_t key = * (hb_aat_feature_type_t *) key_; + hb_aat_layout_feature_type_t key = * (hb_aat_layout_feature_type_t *) key_; const FeatureName * entry = (const FeatureName *) entry_; return key < entry->feature ? -1 : key > entry->feature ? 1 : @@ -85,10 +85,10 @@ struct FeatureName <<<<<<< HEAD ======= inline unsigned int get_settings (const feat *feat, - hb_aat_feature_setting_t *default_setting, + hb_aat_layout_feature_setting_t *default_setting, unsigned int start_offset, unsigned int *selectors_count, - hb_aat_feature_type_selector_t *selectors_buffer) const + hb_aat_layout_feature_type_selector_t *selectors_buffer) const { bool exclusive = featureFlags & Exclusive; bool not_default = featureFlags & NotDefault; @@ -109,7 +109,7 @@ struct FeatureName unsigned int index = not_default ? featureFlags & IndexMask : 0; if (exclusive && index < settings_count) *default_setting = settings[index].setting; - else *default_setting = HB_AAT_FEATURE_NO_DEFAULT_SETTING; + else *default_setting = HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED; } if (selectors_count) *selectors_count = len; return settings_count; @@ -143,7 +143,7 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; - inline const FeatureName& get_feature (hb_aat_feature_type_t key) const + inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const { const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &names, FeatureName::static_size, @@ -153,11 +153,11 @@ struct feat return feature ? *feature : Null (FeatureName); } - inline unsigned int get_settings (hb_aat_feature_type_t type, - hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *selectors_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) const + inline unsigned int get_settings (hb_aat_layout_feature_type_t type, + hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) const { return get_feature (type).get_settings (this, default_setting, start_offset, selectors_count, selectors_buffer); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index a62519755..3f862a122 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -958,19 +958,19 @@ struct Chain for (unsigned i = 0; i < count; i++) { const Feature &feature = featureZ[i]; - hb_aat_feature_type_t type = feature.featureType; - hb_aat_feature_setting_t setting = feature.featureSetting; + hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType; + hb_aat_layout_feature_setting_t setting = feature.featureSetting; retry: - const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch (type); + const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch ((uint16_t) type); if (info && info->setting == setting) { flags &= feature.disableFlags; flags |= feature.enableFlags; } - else if (type == 3/*kLetterCaseType*/ && setting == 3/*kSmallCapsSelector*/) + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == 3/*kSmallCapsSelector*/) { /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */ - type = 37/*kLowerCaseType*/; + type = HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE; setting = 1/*kLowerCaseSmallCapsSelector*/; goto retry; } diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index b4990e1fb..573cc10db 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -44,82 +44,82 @@ * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { - {HB_TAG ('a','f','r','c'), 11/*kFractionsType*/, 1/*kVerticalFractionsSelector*/, 0/*kNoFractionsSelector*/}, - {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*/}, + {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, 1/*kVerticalFractionsSelector*/, 0/*kNoFractionsSelector*/}, + {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, + {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, 0/*kCaseSensitiveLayoutOnSelector*/, 1/*kCaseSensitiveLayoutOffSelector*/}, + {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 18/*kContextualLigaturesOnSelector*/, 19/*kContextualLigaturesOffSelector*/}, + {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, 2/*kCaseSensitiveSpacingOnSelector*/, 3/*kCaseSensitiveSpacingOffSelector*/}, + {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, 4/*kContextualSwashAlternatesOnSelector*/, 5/*kContextualSwashAlternatesOffSelector*/}, + {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 4/*kRareLigaturesOnSelector*/, 5/*kRareLigaturesOffSelector*/}, + {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 10/*kExpertCharactersSelector*/, 16}, + {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, 2/*kDiagonalFractionsSelector*/, 0/*kNoFractionsSelector*/}, + {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 1/*kMonospacedTextSelector*/, 7}, + {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, 0/*kAlternateHorizKanaOnSelector*/, 1/*kAlternateHorizKanaOffSelector*/, }, + {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, 1/*kHanjaToHangulSelector*/, 0/*kNoTransliterationSelector*/}, + {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 12/*kHojoCharactersSelector*/, 16}, + {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 2/*kHalfWidthTextSelector*/, 7}, + {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, 2/*kCJKItalicRomanOnSelector*/, 3/*kCJKItalicRomanOffSelector*/}, + {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 11/*kJIS2004CharactersSelector*/, 16}, + {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 2/*kJIS1978CharactersSelector*/, 16}, + {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 3/*kJIS1983CharactersSelector*/, 16}, + {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 4/*kJIS1990CharactersSelector*/, 16}, + {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 2/*kCommonLigaturesOnSelector*/, 3/*kCommonLigaturesOffSelector*/}, + {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, 1/*kUpperCaseNumbersSelector*/, 2}, + {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, 10/*kMathematicalGreekOnSelector*/, 11/*kMathematicalGreekOffSelector*/}, + {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 13/*kNLCCharactersSelector*/, 16}, + {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, 0/*kLowerCaseNumbersSelector*/, 2}, + {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 3/*kOrdinalsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, 2/*kLowerCasePetiteCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, 1/*kProportionalNumbersSelector*/, 4}, + {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 4/*kQuarterWidthTextSelector*/, 7}, + {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBYKANA, 2/*kRubyKanaOnSelector*/, 3/*kRubyKanaOffSelector*/}, + {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 4/*kScientificInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, 1/*kLowerCaseSmallCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 1/*kSimplifiedCharactersSelector*/, 16}, + {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 2/*kStylisticAltOneOnSelector*/, 3/*kStylisticAltOneOffSelector*/}, + {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 4/*kStylisticAltTwoOnSelector*/, 5/*kStylisticAltTwoOffSelector*/}, + {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 6/*kStylisticAltThreeOnSelector*/, 7/*kStylisticAltThreeOffSelector*/}, + {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 8/*kStylisticAltFourOnSelector*/, 9/*kStylisticAltFourOffSelector*/}, + {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 10/*kStylisticAltFiveOnSelector*/, 11/*kStylisticAltFiveOffSelector*/}, + {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 12/*kStylisticAltSixOnSelector*/, 13/*kStylisticAltSixOffSelector*/}, + {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 14/*kStylisticAltSevenOnSelector*/, 15/*kStylisticAltSevenOffSelector*/}, + {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 16/*kStylisticAltEightOnSelector*/, 17/*kStylisticAltEightOffSelector*/}, + {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 18/*kStylisticAltNineOnSelector*/, 19/*kStylisticAltNineOffSelector*/}, + {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 20/*kStylisticAltTenOnSelector*/, 21/*kStylisticAltTenOffSelector*/}, + {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 22/*kStylisticAltElevenOnSelector*/, 23/*kStylisticAltElevenOffSelector*/}, + {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 24/*kStylisticAltTwelveOnSelector*/, 25/*kStylisticAltTwelveOffSelector*/}, + {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 26/*kStylisticAltThirteenOnSelector*/, 27/*kStylisticAltThirteenOffSelector*/}, + {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 28/*kStylisticAltFourteenOnSelector*/, 29/*kStylisticAltFourteenOffSelector*/}, + {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 30/*kStylisticAltFifteenOnSelector*/, 31/*kStylisticAltFifteenOffSelector*/}, + {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 32/*kStylisticAltSixteenOnSelector*/, 33/*kStylisticAltSixteenOffSelector*/}, + {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 34/*kStylisticAltSeventeenOnSelector*/, 35/*kStylisticAltSeventeenOffSelector*/}, + {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 36/*kStylisticAltEighteenOnSelector*/, 37/*kStylisticAltEighteenOffSelector*/}, + {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 38/*kStylisticAltNineteenOnSelector*/, 39/*kStylisticAltNineteenOffSelector*/}, + {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 40/*kStylisticAltTwentyOnSelector*/, 41/*kStylisticAltTwentyOffSelector*/}, + {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 2/*kInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 1/*kSuperiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, 2/*kSwashAlternatesOnSelector*/, 3/*kSwashAlternatesOffSelector*/}, + {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, 4/*kTitlingCapsSelector*/, 0/*kNoStyleOptionsSelector*/}, + {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 14/*kTraditionalNamesCharactersSelector*/, 16}, + {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, 0/*kMonospacedNumbersSelector*/, 4}, + {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 0/*kTraditionalCharactersSelector*/, 16}, + {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 3/*kThirdWidthTextSelector*/, 7}, + {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, 14, 15}, + {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, 2/*kAlternateVertKanaOnSelector*/, 3/*kAlternateVertKanaOffSelector*/}, + {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, 4/*kSlashedZeroOnSelector*/, 5/*kSlashedZeroOffSelector*/}, }; const hb_aat_feature_mapping_t * @@ -309,10 +309,10 @@ _hb_aat_language_get (hb_face_t *face, /** * hb_aat_layout_get_feature_settings: * @face: a font face. - * @identifier: AAT feature id you are querying, for example 1 for + * @type: AAT feature id you are querying, for example 1 for * "Ligatures" feature, 37 for the "Lower Case" feature, * 38 for the "Upper Case" feature, etc. - * @default_setting: (out): default value for the type. If it is HB_AAT_FEATURE_NO_DEFAULT_SETTING + * @default_setting: (out): default value for the type. If it is HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED * means none is selected as default and the feature is not exclusive. * @start_offset: start offset, if you are iterating * @selectors_count: (inout): gets input buffer size, puts number of filled one @@ -323,13 +323,13 @@ _hb_aat_language_get (hb_face_t *face, * Since: REPLACEME */ unsigned int -hb_aat_layout_get_feature_settings (hb_face_t *face, - hb_aat_feature_type_t identifier, - hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *selectors_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) +hb_aat_layout_get_feature_settings (hb_face_t *face, + hb_aat_layout_feature_type_t type, + hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) { - return _get_feat (face).get_settings (identifier, default_setting, + return _get_feat (face).get_settings (type, default_setting, start_offset, selectors_count, selectors_buffer); } diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index a87ef202b..baa4ba193 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -36,9 +36,9 @@ struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; - hb_aat_feature_type_t aatFeatureType; - hb_aat_feature_setting_t selectorToEnable; - hb_aat_feature_setting_t selectorToDisable; + hb_aat_layout_feature_type_t aatFeatureType; + hb_aat_layout_feature_setting_t selectorToEnable; + hb_aat_layout_feature_setting_t selectorToDisable; static inline int cmp (const void *key_, const void *entry_) { diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index 8bc1a0c61..b681348eb 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -37,7 +37,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, if (tag == HB_TAG ('a','a','l','t')) { feature_info_t *info = features.push(); - info->type = 17/*kCharacterAlternativesType*/; + info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; info->setting = value; return; } diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 77f9114bd..619d7758d 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -66,8 +66,8 @@ struct hb_aat_map_builder_t public: struct feature_info_t { - hb_aat_feature_type_t type; - hb_aat_feature_setting_t setting; + hb_aat_layout_feature_type_t type; + hb_aat_layout_feature_setting_t setting; unsigned seq; /* For stable sorting only. */ static int cmp (const void *pa, const void *pb) diff --git a/src/hb-aat.h b/src/hb-aat.h index 539abcd9a..0a061ee33 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -22,10 +22,6 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN -#error "Include instead." -#endif - #ifndef HB_AAT_H #define HB_AAT_H @@ -34,14 +30,35 @@ HB_BEGIN_DECLS -/** - * hb_aat_type_t: - * - * Feature identifier - * +/* * Since: REPLACEME */ -typedef uint16_t hb_aat_feature_type_t; +typedef enum +{ + HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, + HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, + HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, + HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, + HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, + HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, + HB_AAT_LAYOUT_FEATURE_TYPE_RUBYKANA = 28, + HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, + HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, + HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, + HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, + HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, + HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, + HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF +} hb_aat_layout_feature_type_t; /** * hb_aat_feature_t: @@ -50,33 +67,28 @@ typedef uint16_t hb_aat_feature_type_t; * * Since: REPLACEME */ -typedef uint16_t hb_aat_feature_setting_t; +typedef unsigned int hb_aat_layout_feature_setting_t; /** - * hb_aat_feature_type_selector_t: + * hb_aat_layout_feature_type_selector_t: * * Feature type record * * Since: REPLACEME **/ -typedef struct hb_aat_feature_type_selector_t +typedef struct hb_aat_layout_feature_type_selector_t { - hb_aat_feature_setting_t setting; + hb_aat_layout_feature_setting_t setting; hb_ot_name_id_t name_id; -} hb_aat_feature_type_selector_t; - -/* - * Since: REPLACEME - */ -#define HB_AAT_FEATURE_NO_DEFAULT_SETTING ((hb_aat_feature_setting_t) -1) +} hb_aat_layout_feature_type_selector_t; HB_EXTERN unsigned int -hb_aat_layout_get_feature_settings (hb_face_t *face, - hb_aat_feature_type_t type, - hb_aat_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *selectors_count, /* IN/OUT. May be NULL. */ - hb_aat_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */); +hb_aat_layout_get_feature_settings (hb_face_t *face, + hb_aat_layout_feature_type_t type, + hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */); HB_END_DECLS diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 854b58ac8..2f9e9d493 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -24,15 +24,17 @@ #include "hb-test.h" +#include #include +#include /* Unit tests for hb-aat.h */ static void test_aat_get_feature_settings (void) { - hb_aat_feature_setting_t default_setting; - hb_aat_feature_type_selector_t records[3]; + hb_aat_layout_feature_setting_t default_setting; + hb_aat_layout_feature_type_selector_t records[3]; unsigned int count = 3; hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); @@ -65,7 +67,7 @@ test_aat_get_feature_settings (void) g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, 14, &default_setting, 0, &count, records)); g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (HB_AAT_FEATURE_NO_DEFAULT_SETTING, ==, default_setting); + g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, ==, default_setting); g_assert_cmpuint (8, ==, records[0].setting); g_assert_cmpuint (308, ==, records[0].name_id); diff --git a/test/api/test-c.c b/test/api/test-c.c index 061f35cdc..b4518adbc 100644 --- a/test/api/test-c.c +++ b/test/api/test-c.c @@ -33,6 +33,7 @@ #include #include +#include #ifdef HAVE_GLIB #include From fbad794bd2c574363a0c5c5fefabce764496f93c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 1 Nov 2018 22:24:42 +0330 Subject: [PATCH 122/158] [feat] Add feature iteration API --- src/hb-aat-layout-feat-table.hh | 36 +++++++++++++++++------ src/hb-aat-layout.cc | 26 +++++++++-------- src/hb-aat.h | 23 +++++++++++++-- test/api/test-aat-layout.c | 51 ++++++++++++++++++++++----------- 4 files changed, 96 insertions(+), 40 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 2fc71101a..b350e71dd 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -123,6 +123,11 @@ struct FeatureName (base+settingTable).sanitize (c, nSettings))); } + inline hb_aat_layout_feature_type_t get_feature () const + { return (hb_aat_layout_feature_type_t) (unsigned int) feature; } + + inline unsigned int get_name_id () const { return nameIndex; } + protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ @@ -143,14 +148,21 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; - inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const + inline unsigned int get_features (unsigned int start_offset, + unsigned int *record_count, + hb_aat_layout_feature_record_t *record_buffer) const { - const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &names, - FeatureName::static_size, - sizeof (FeatureName), - FeatureName::cmp); - - return feature ? *feature : Null (FeatureName); + unsigned int feature_count = featureNameCount; + if (record_count) + { + unsigned int len = MIN (feature_count - start_offset, *record_count); + for (unsigned int i = 0; i < len; i++) + { + record_buffer[i].feature = names[i + start_offset].get_feature (); + record_buffer[i].name_id = names[i + start_offset].get_name_id (); + } + } + return featureNameCount; } inline unsigned int get_settings (hb_aat_layout_feature_type_t type, @@ -159,8 +171,14 @@ struct feat unsigned int *selectors_count, /* IN/OUT. May be NULL. */ hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) const { - return get_feature (type).get_settings (this, default_setting, - start_offset, selectors_count, selectors_buffer); + const FeatureName* feature = (FeatureName*) hb_bsearch (&type, &names, + FeatureName::static_size, + sizeof (FeatureName), + FeatureName::cmp); + + return (feature ? *feature : Null (FeatureName)).get_settings (this, default_setting, + start_offset, selectors_count, + selectors_buffer); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 573cc10db..12304d64c 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -169,12 +169,6 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_, ankr_table = ankr_table_; ankr_end = ankr_end_; } -static inline const AAT::feat& -_get_feat (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::feat); - return *(hb_ot_face_data (face)->feat.get ()); -} /* @@ -309,9 +303,7 @@ _hb_aat_language_get (hb_face_t *face, /** * hb_aat_layout_get_feature_settings: * @face: a font face. - * @type: AAT feature id you are querying, for example 1 for - * "Ligatures" feature, 37 for the "Lower Case" feature, - * 38 for the "Upper Case" feature, etc. + * @feature: AAT feature id you are querying. * @default_setting: (out): default value for the type. If it is HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED * means none is selected as default and the feature is not exclusive. * @start_offset: start offset, if you are iterating @@ -324,12 +316,22 @@ _hb_aat_language_get (hb_face_t *face, */ unsigned int hb_aat_layout_get_feature_settings (hb_face_t *face, - hb_aat_layout_feature_type_t type, + hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, unsigned int *selectors_count, /* IN/OUT. May be NULL. */ hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) { - return _get_feat (face).get_settings (type, default_setting, - start_offset, selectors_count, selectors_buffer); + return face->table.feat->get_settings (feature, default_setting, + start_offset, selectors_count, selectors_buffer); +} + + +unsigned int +hb_aat_layout_get_features (hb_face_t *face, + unsigned int start_offset, + unsigned int *record_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_record_t *record_buffer /* OUT. May be NULL. */) +{ + return face->table.feat->get_features (start_offset, record_count, record_buffer); } diff --git a/src/hb-aat.h b/src/hb-aat.h index 0a061ee33..2f7e0c4a3 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -60,6 +60,25 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF } hb_aat_layout_feature_type_t; +/** + * hb_aat_layout_feature_record_t: + * + * Feature record and + * + * Since: REPLACEME + **/ +typedef struct hb_aat_layout_feature_record_t +{ + hb_aat_layout_feature_type_t feature; + hb_ot_name_id_t name_id; +} hb_aat_layout_feature_record_t; + +HB_EXTERN unsigned int +hb_aat_layout_get_features (hb_face_t *face, + unsigned int start_offset, + unsigned int *record_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_record_t *record_buffer /* OUT. May be NULL. */); + /** * hb_aat_feature_t: * @@ -72,7 +91,7 @@ typedef unsigned int hb_aat_layout_feature_setting_t; /** * hb_aat_layout_feature_type_selector_t: * - * Feature type record + * Feature type selector * * Since: REPLACEME **/ @@ -84,7 +103,7 @@ typedef struct hb_aat_layout_feature_type_selector_t HB_EXTERN unsigned int hb_aat_layout_get_feature_settings (hb_face_t *face, - hb_aat_layout_feature_type_t type, + hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, unsigned int *selectors_count, /* IN/OUT. May be NULL. */ diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 2f9e9d493..430cb3e43 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -30,6 +30,23 @@ /* Unit tests for hb-aat.h */ +static hb_face_t *face; +static hb_face_t *sbix; + +static void +test_aat_get_features (void) +{ + hb_aat_layout_feature_record_t records[3]; + unsigned int record_count = 3; + g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &record_count, records)); + g_assert_cmpuint (1, ==, records[0].feature); + g_assert_cmpuint (258, ==, records[0].name_id); + g_assert_cmpuint (3, ==, records[1].feature); + g_assert_cmpuint (261, ==, records[1].name_id); + g_assert_cmpuint (6, ==, records[2].feature); + g_assert_cmpuint (265, ==, records[2].name_id); +} + static void test_aat_get_feature_settings (void) { @@ -37,10 +54,8 @@ test_aat_get_feature_settings (void) hb_aat_layout_feature_type_selector_t records[3]; unsigned int count = 3; - hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); - - g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, 18, &default_setting, - 0, &count, records)); + g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, + &default_setting, 0, &count, records)); g_assert_cmpuint (3, ==, count); g_assert_cmpuint (0, ==, default_setting); @@ -54,8 +69,8 @@ test_aat_get_feature_settings (void) g_assert_cmpuint (296, ==, records[2].name_id); count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, 18, &default_setting, - 3, &count, records)); + g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, + &default_setting, 3, &count, records)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (0, ==, default_setting); @@ -64,8 +79,8 @@ test_aat_get_feature_settings (void) count = 1; - g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, 14, &default_setting, - 0, &count, records)); + g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + &default_setting, 0, &count, records)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, ==, default_setting); @@ -74,16 +89,12 @@ test_aat_get_feature_settings (void) count = 100; - g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, 32, NULL, - 0, &count, records)); + g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, + NULL, 0, &count, records)); g_assert_cmpuint (0, ==, count); - hb_face_destroy (face); - - hb_face_t *sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); - g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, 100, NULL, - 0, &count, records)); - hb_face_destroy (sbix); + g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, NULL, + 0, &count, records)); } int @@ -91,7 +102,13 @@ main (int argc, char **argv) { hb_test_init (&argc, &argv); + hb_test_add (test_aat_get_features); hb_test_add (test_aat_get_feature_settings); - return hb_test_run(); + face = hb_test_open_font_file ("fonts/aat-feat.ttf"); + sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); + unsigned int status = hb_test_run (); + hb_face_destroy (sbix); + hb_face_destroy (face); + return status; } From 9212ec203c948e290a1d92b701619ccdbc89377c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 9 Nov 2018 00:50:10 +0330 Subject: [PATCH 123/158] [feat] Complete feature types list --- src/hb-aat-layout-morx-table.hh | 2 +- src/hb-aat-layout.cc | 154 +++---- src/hb-aat.h | 697 ++++++++++++++++++++++++++++++-- 3 files changed, 752 insertions(+), 101 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 3f862a122..1618cf520 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -971,7 +971,7 @@ struct Chain { /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */ type = HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE; - setting = 1/*kLowerCaseSmallCapsSelector*/; + setting = HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS; goto retry; } } diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 12304d64c..5b534c58b 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -32,7 +32,7 @@ #include "hb-aat-layout.hh" #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. -#include "hb-aat-layout-feat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-layout-feat-table.hh" #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" @@ -44,82 +44,82 @@ * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { - {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, 1/*kVerticalFractionsSelector*/, 0/*kNoFractionsSelector*/}, - {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, - {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, - {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, - {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, 0/*kCaseSensitiveLayoutOnSelector*/, 1/*kCaseSensitiveLayoutOffSelector*/}, - {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 18/*kContextualLigaturesOnSelector*/, 19/*kContextualLigaturesOffSelector*/}, - {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, 2/*kCaseSensitiveSpacingOnSelector*/, 3/*kCaseSensitiveSpacingOffSelector*/}, - {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, 4/*kContextualSwashAlternatesOnSelector*/, 5/*kContextualSwashAlternatesOffSelector*/}, - {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 4/*kRareLigaturesOnSelector*/, 5/*kRareLigaturesOffSelector*/}, - {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 10/*kExpertCharactersSelector*/, 16}, - {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, 2/*kDiagonalFractionsSelector*/, 0/*kNoFractionsSelector*/}, - {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 1/*kMonospacedTextSelector*/, 7}, - {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 6/*kAltHalfWidthTextSelector*/, 7}, - {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, - {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, 0/*kAlternateHorizKanaOnSelector*/, 1/*kAlternateHorizKanaOffSelector*/, }, - {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, - {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, 1/*kHanjaToHangulSelector*/, 0/*kNoTransliterationSelector*/}, - {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 12/*kHojoCharactersSelector*/, 16}, - {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 2/*kHalfWidthTextSelector*/, 7}, - {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, 2/*kCJKItalicRomanOnSelector*/, 3/*kCJKItalicRomanOffSelector*/}, - {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 11/*kJIS2004CharactersSelector*/, 16}, - {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 2/*kJIS1978CharactersSelector*/, 16}, - {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 3/*kJIS1983CharactersSelector*/, 16}, - {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 4/*kJIS1990CharactersSelector*/, 16}, - {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, 2/*kCommonLigaturesOnSelector*/, 3/*kCommonLigaturesOffSelector*/}, - {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, 1/*kUpperCaseNumbersSelector*/, 2}, - {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, 10/*kMathematicalGreekOnSelector*/, 11/*kMathematicalGreekOffSelector*/}, - {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 13/*kNLCCharactersSelector*/, 16}, - {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, 0/*kLowerCaseNumbersSelector*/, 2}, - {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 3/*kOrdinalsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 5/*kAltProportionalTextSelector*/, 7}, - {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, 2/*kLowerCasePetiteCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, - {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 0/*kProportionalTextSelector*/, 7}, - {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, 1/*kProportionalNumbersSelector*/, 4}, - {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 0/*kProportionalTextSelector*/, 7}, - {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 4/*kQuarterWidthTextSelector*/, 7}, - {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBYKANA, 2/*kRubyKanaOnSelector*/, 3/*kRubyKanaOffSelector*/}, - {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 4/*kScientificInferiorsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, 1/*kLowerCaseSmallCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, - {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 1/*kSimplifiedCharactersSelector*/, 16}, - {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 2/*kStylisticAltOneOnSelector*/, 3/*kStylisticAltOneOffSelector*/}, - {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 4/*kStylisticAltTwoOnSelector*/, 5/*kStylisticAltTwoOffSelector*/}, - {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 6/*kStylisticAltThreeOnSelector*/, 7/*kStylisticAltThreeOffSelector*/}, - {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 8/*kStylisticAltFourOnSelector*/, 9/*kStylisticAltFourOffSelector*/}, - {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 10/*kStylisticAltFiveOnSelector*/, 11/*kStylisticAltFiveOffSelector*/}, - {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 12/*kStylisticAltSixOnSelector*/, 13/*kStylisticAltSixOffSelector*/}, - {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 14/*kStylisticAltSevenOnSelector*/, 15/*kStylisticAltSevenOffSelector*/}, - {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 16/*kStylisticAltEightOnSelector*/, 17/*kStylisticAltEightOffSelector*/}, - {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 18/*kStylisticAltNineOnSelector*/, 19/*kStylisticAltNineOffSelector*/}, - {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 20/*kStylisticAltTenOnSelector*/, 21/*kStylisticAltTenOffSelector*/}, - {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 22/*kStylisticAltElevenOnSelector*/, 23/*kStylisticAltElevenOffSelector*/}, - {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 24/*kStylisticAltTwelveOnSelector*/, 25/*kStylisticAltTwelveOffSelector*/}, - {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 26/*kStylisticAltThirteenOnSelector*/, 27/*kStylisticAltThirteenOffSelector*/}, - {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 28/*kStylisticAltFourteenOnSelector*/, 29/*kStylisticAltFourteenOffSelector*/}, - {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 30/*kStylisticAltFifteenOnSelector*/, 31/*kStylisticAltFifteenOffSelector*/}, - {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 32/*kStylisticAltSixteenOnSelector*/, 33/*kStylisticAltSixteenOffSelector*/}, - {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 34/*kStylisticAltSeventeenOnSelector*/, 35/*kStylisticAltSeventeenOffSelector*/}, - {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 36/*kStylisticAltEighteenOnSelector*/, 37/*kStylisticAltEighteenOffSelector*/}, - {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 38/*kStylisticAltNineteenOnSelector*/, 39/*kStylisticAltNineteenOffSelector*/}, - {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, 40/*kStylisticAltTwentyOnSelector*/, 41/*kStylisticAltTwentyOffSelector*/}, - {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 2/*kInferiorsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, 1/*kSuperiorsSelector*/, 0/*kNormalPositionSelector*/}, - {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, 2/*kSwashAlternatesOnSelector*/, 3/*kSwashAlternatesOffSelector*/}, - {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, 4/*kTitlingCapsSelector*/, 0/*kNoStyleOptionsSelector*/}, - {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 14/*kTraditionalNamesCharactersSelector*/, 16}, - {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, 0/*kMonospacedNumbersSelector*/, 4}, - {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, 0/*kTraditionalCharactersSelector*/, 16}, - {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 3/*kThirdWidthTextSelector*/, 7}, - {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, 14, 15}, - {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 5/*kAltProportionalTextSelector*/, 7}, - {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, - {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 6/*kAltHalfWidthTextSelector*/, 7}, - {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, 2/*kAlternateVertKanaOnSelector*/, 3/*kAlternateVertKanaOffSelector*/}, - {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, 5/*kAltProportionalTextSelector*/, 7}, - {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, - {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, 4/*kSlashedZeroOnSelector*/, 5/*kSlashedZeroOffSelector*/}, + {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS}, + {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE}, + {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE}, + {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF}, + {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF}, + {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF}, + {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, + {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, + {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF}, + {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS, 16}, + {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS}, + {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT, 7}, + {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, 7}, + {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, + {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, + {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, + {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION}, + {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS, 16}, + {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT, 7}, + {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF}, + {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS, 16}, + {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS, 16}, + {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS, 16}, + {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS, 16}, + {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF}, + {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS, 2}, + {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF}, + {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS, 16}, + {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS, 2}, + {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_ORDINALS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, + {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS, 4}, + {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT, 7}, + {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF}, + {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, + {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS, 16}, + {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF}, + {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF}, + {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF}, + {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_OFF}, + {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_OFF}, + {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_OFF}, + {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_OFF}, + {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_OFF}, + {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_OFF}, + {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_OFF}, + {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF}, + {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_OFF}, + {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF}, + {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF}, + {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF}, + {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF}, + {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF}, + {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF}, + {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF}, + {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF}, + {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_INFERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF}, + {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS}, + {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, 16}, + {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS, 4}, + {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS, 16}, + {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT, 7}, + {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, 14, 15}, + {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, + {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, 7}, + {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF}, + {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, + {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF}, }; const hb_aat_feature_mapping_t * diff --git a/src/hb-aat.h b/src/hb-aat.h index 2f7e0c4a3..11e5825fa 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -31,35 +31,686 @@ HB_BEGIN_DECLS /* + * AAT available features + * * Since: REPLACEME */ typedef enum { - HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, - HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, - HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, - HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, - HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, - HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, - HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, - HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, - HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, - HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, - HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, - HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, - HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, - HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, - HB_AAT_LAYOUT_FEATURE_TYPE_RUBYKANA = 28, - HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, - HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, - HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, - HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, - HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, - HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, - HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, - HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF + HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, + HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, + HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, + HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, + HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8, + HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, + HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, + HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, + HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, + HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, + HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, + HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, + HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24, + HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26, + HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27, + HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31, + HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, + HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, + HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, + HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, + HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, + HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, + HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103, + HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF } hb_aat_layout_feature_type_t; + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_OFF = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON = 2, + HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON = 4, + HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_LOGOS_ON = 6, + HB_AAT_LAYOUT_SELECTOR_LOGOS_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_ON = 8, + HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, + HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, + HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_ON = 12, + HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_OFF = 13, + HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, + HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, + HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_ON = 16, + HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_OFF = 17, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, + HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON = 20, + HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF = 21 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_UNCONNECTED = 0, + HB_AAT_LAYOUT_SELECTOR_PARTIALLY_CONNECTED = 1, + HB_AAT_LAYOUT_SELECTOR_CURSIVE = 2 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_ALL_CAPS = 1, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS = 3, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5 /* deprecated */ +}; + + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, + HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, + HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS = 1, + HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_NUMBERS = 2, + HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_NUMBERS = 3 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_ON = 2, + HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, + HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_ON = 6, + HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_ON = 8, + HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_OFF = 9 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_SHOW_DIACRITICS = 0, + HB_AAT_LAYOUT_SELECTOR_HIDE_DIACRITICS = 1, + HB_AAT_LAYOUT_SELECTOR_DECOMPOSE_DIACRITICS = 2 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION = 0, + HB_AAT_LAYOUT_SELECTOR_SUPERIORS = 1, + HB_AAT_LAYOUT_SELECTOR_INFERIORS = 2, + HB_AAT_LAYOUT_SELECTOR_ORDINALS = 3, + HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS = 4 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS = 0, + HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS = 1, + HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS = 2 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_ON = 0, + HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_OFF = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, + HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON = 4, + HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_ON = 6, + HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_ON = 8, + HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, + HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_ON = 0, + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, + HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_ON = 4, + HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_ON = 6, + HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_EXPONENTS_ON = 8, + HB_AAT_LAYOUT_SELECTOR_EXPONENTS_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON = 10, + HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF = 11 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_ORNAMENTS = 0, + HB_AAT_LAYOUT_SELECTOR_DINGBATS = 1, + HB_AAT_LAYOUT_SELECTOR_PI_CHARACTERS = 2, + HB_AAT_LAYOUT_SELECTOR_FLEURONS = 3, + HB_AAT_LAYOUT_SELECTOR_DECORATIVE_BORDERS = 4, + HB_AAT_LAYOUT_SELECTOR_INTERNATIONAL_SYMBOLS = 5, + HB_AAT_LAYOUT_SELECTOR_MATH_SYMBOLS = 6 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_ALTERNATES = 0 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL1 = 0, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL2 = 1, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL3 = 2, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL4 = 3, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL5 = 4 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS = 0, + HB_AAT_LAYOUT_SELECTOR_DISPLAY_TEXT = 1, + HB_AAT_LAYOUT_SELECTOR_ENGRAVED_TEXT = 2, + HB_AAT_LAYOUT_SELECTOR_ILLUMINATED_CAPS = 3, + HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS = 4, + HB_AAT_LAYOUT_SELECTOR_TALL_CAPS = 5 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS = 0, + HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS = 1, + HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS = 2, + HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS = 3, + HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS = 4, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_ONE = 5, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_TWO = 6, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_THREE = 7, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FOUR = 8, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FIVE = 9, + HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS = 10, + HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS = 11, + HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS = 12, + HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS = 13, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS = 0, + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT = 0, + HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT = 1, + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT = 2, + HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT = 3, + HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT = 4, + HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, + HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT = 6 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION = 0, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL = 1, + HB_AAT_LAYOUT_SELECTOR_HIRAGANA_TO_KATAKANA = 2, + HB_AAT_LAYOUT_SELECTOR_KATAKANA_TO_HIRAGANA = 3, + HB_AAT_LAYOUT_SELECTOR_KANA_TO_ROMANIZATION = 4, + HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, + HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_ANNOTATION = 0, + HB_AAT_LAYOUT_SELECTOR_BOX_ANNOTATION = 1, + HB_AAT_LAYOUT_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, + HB_AAT_LAYOUT_SELECTOR_CIRCLE_ANNOTATION = 3, + HB_AAT_LAYOUT_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, + HB_AAT_LAYOUT_SELECTOR_PARENTHESIS_ANNOTATION = 5, + HB_AAT_LAYOUT_SELECTOR_PERIOD_ANNOTATION = 6, + HB_AAT_LAYOUT_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, + HB_AAT_LAYOUT_SELECTOR_DIAMOND_ANNOTATION = 8, + HB_AAT_LAYOUT_SELECTOR_INVERTED_BOX_ANNOTATION = 9, + HB_AAT_LAYOUT_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION = 10 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_KANA = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_KANA = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_ON = 0, + HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, + HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, + HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF instead */ + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON instead */ + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON = 2, + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF = 3 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, + HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON = 2, + HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF = 5 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE = 0, + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS = 2 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE = 0, + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS = 2 +}; + + +/* + * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE + * + * Since: REPLACEME + */ +enum +{ + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, + HB_AAT_LAYOUT_SELECTOR_DEFAULT_CJK_ROMAN = 2, + HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 +}; + + /** * hb_aat_layout_feature_record_t: * From 19b6025534a98df96d67eee45c5c1ea6fbc1cc43 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 17 Nov 2018 01:07:09 +0330 Subject: [PATCH 124/158] [feat] Address @behdad comments --- src/Makefile.sources | 2 +- src/hb-aat-layout-feat-table.hh | 82 ++--- src/hb-aat-layout-morx-table.hh | 2 +- src/hb-aat-layout.cc | 110 +++---- src/hb-aat-map.cc | 2 +- src/hb-aat.h | 533 +++++++++----------------------- src/hb-ot.h | 1 - test/api/test-aat-layout.c | 84 ++--- 8 files changed, 285 insertions(+), 531 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index e0dee9408..c5925b9b0 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -181,6 +181,7 @@ HB_OT_RAGEL_sources = \ $(NULL) HB_OT_headers = \ + hb-aat.h \ hb-ot.h \ hb-ot-color.h \ hb-ot-font.h \ @@ -189,7 +190,6 @@ HB_OT_headers = \ hb-ot-name.h \ hb-ot-shape.h \ hb-ot-var.h \ - hb-aat.h \ $(NULL) # Optional Sources and Headers with external deps diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index b350e71dd..2834de954 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -45,7 +45,6 @@ struct SettingName return_trace (likely (c->check_struct (this))); } - public: HBUINT16 setting; /* The setting. */ NameID nameIndex; /* The name table index for the setting's name. */ public: @@ -56,18 +55,15 @@ struct feat; struct FeatureName { -<<<<<<< HEAD -======= static int cmp (const void *key_, const void *entry_) { - hb_aat_layout_feature_type_t key = * (hb_aat_layout_feature_type_t *) key_; + hb_aat_feature_type_t key = * (hb_aat_feature_type_t *) key_; const FeatureName * entry = (const FeatureName *) entry_; return key < entry->feature ? -1 : key > entry->feature ? 1 : 0; } ->>>>>>> 08982bb4... [feat] Expose public API enum { Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in @@ -82,40 +78,36 @@ struct FeatureName * as the default. */ }; -<<<<<<< HEAD -======= inline unsigned int get_settings (const feat *feat, - hb_aat_layout_feature_setting_t *default_setting, + hb_bool_t *is_exclusive, unsigned int start_offset, - unsigned int *selectors_count, - hb_aat_layout_feature_type_selector_t *selectors_buffer) const + unsigned int *records_count, + hb_aat_feature_option_record_t *records_buffer) const { bool exclusive = featureFlags & Exclusive; bool not_default = featureFlags & NotDefault; + if (is_exclusive) *is_exclusive = exclusive; const UnsizedArrayOf& settings = feat+settingTable; unsigned int len = 0; unsigned int settings_count = nSettings; - if (selectors_count && selectors_buffer) + if (records_count && records_buffer) { - len = MIN (settings_count - start_offset, *selectors_count); + len = MIN (settings_count - start_offset, *records_count); for (unsigned int i = 0; i < len; i++) { - selectors_buffer[i].name_id = settings[start_offset + i].nameIndex; - selectors_buffer[i].setting = settings[start_offset + i].setting; + records_buffer[i].is_default = exclusive && not_default && + i + start_offset == (featureFlags & IndexMask); + records_buffer[i].name_id = settings[start_offset + i].nameIndex; + records_buffer[i].setting = settings[start_offset + i].setting; } + if (exclusive && !not_default && start_offset == 0 && len != 0) + records_buffer[0].is_default = true; } - if (default_setting) - { - unsigned int index = not_default ? featureFlags & IndexMask : 0; - if (exclusive && index < settings_count) - *default_setting = settings[index].setting; - else *default_setting = HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED; - } - if (selectors_count) *selectors_count = len; + if (is_exclusive) *is_exclusive = exclusive; + if (records_count) *records_count = len; return settings_count; } ->>>>>>> 08982bb4... [feat] Expose public API inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -123,11 +115,6 @@ struct FeatureName (base+settingTable).sanitize (c, nSettings))); } - inline hb_aat_layout_feature_type_t get_feature () const - { return (hb_aat_layout_feature_type_t) (unsigned int) feature; } - - inline unsigned int get_name_id () const { return nameIndex; } - protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ @@ -148,37 +135,24 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; - inline unsigned int get_features (unsigned int start_offset, - unsigned int *record_count, - hb_aat_layout_feature_record_t *record_buffer) const + inline const FeatureName& get_feature (hb_aat_feature_type_t key) const { - unsigned int feature_count = featureNameCount; - if (record_count) - { - unsigned int len = MIN (feature_count - start_offset, *record_count); - for (unsigned int i = 0; i < len; i++) - { - record_buffer[i].feature = names[i + start_offset].get_feature (); - record_buffer[i].name_id = names[i + start_offset].get_name_id (); - } - } - return featureNameCount; - } - - inline unsigned int get_settings (hb_aat_layout_feature_type_t type, - hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *selectors_count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) const - { - const FeatureName* feature = (FeatureName*) hb_bsearch (&type, &names, + const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &names, FeatureName::static_size, sizeof (FeatureName), FeatureName::cmp); - return (feature ? *feature : Null (FeatureName)).get_settings (this, default_setting, - start_offset, selectors_count, - selectors_buffer); + return feature ? *feature : Null (FeatureName); + } + + inline unsigned int get_settings (hb_aat_feature_type_t key, + hb_bool_t *is_exclusive, + unsigned int start_offset, + unsigned int *records_count, + hb_aat_feature_option_record_t *records_buffer) const + { + return get_feature (key).get_settings (this, is_exclusive, start_offset, + records_count, records_buffer); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 1618cf520..04ef804cd 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -959,7 +959,7 @@ struct Chain { const Feature &feature = featureZ[i]; hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType; - hb_aat_layout_feature_setting_t setting = feature.featureSetting; + hb_aat_layout_feature_setting_t setting = (hb_aat_layout_feature_setting_t) (unsigned int) feature.featureSetting; retry: const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch ((uint16_t) type); if (info && info->setting == setting) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 5b534c58b..0f8304cba 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -53,37 +53,37 @@ static const hb_aat_feature_mapping_t feature_mappings[] = {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF}, - {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS, 16}, + {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS}, - {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT, 7}, - {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, 7}, + {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION}, - {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS, 16}, - {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT, 7}, + {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF}, - {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS, 16}, - {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS, 16}, - {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS, 16}, - {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS, 16}, + {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF}, - {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS, 2}, + {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_setting_t) 2}, {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF}, - {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS, 16}, - {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS, 2}, + {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_setting_t) 2}, {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_ORDINALS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, - {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, - {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, 7}, - {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS, 4}, - {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, 7}, - {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT, 7}, + {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_setting_t) 4}, + {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF}, {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, - {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS, 16}, + {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF}, {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF}, {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF}, @@ -108,16 +108,16 @@ static const hb_aat_feature_mapping_t feature_mappings[] = {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF}, {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS}, - {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, 16}, - {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS, 4}, - {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS, 16}, - {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT, 7}, - {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, 14, 15}, - {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_setting_t) 4}, + {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, (hb_aat_layout_feature_setting_t) 14, (hb_aat_layout_feature_setting_t) 15}, + {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, - {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, 7}, + {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF}, - {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, 7}, + {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF}, }; @@ -301,37 +301,43 @@ _hb_aat_language_get (hb_face_t *face, } /** - * hb_aat_layout_get_feature_settings: - * @face: a font face. - * @feature: AAT feature id you are querying. - * @default_setting: (out): default value for the type. If it is HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED - * means none is selected as default and the feature is not exclusive. - * @start_offset: start offset, if you are iterating - * @selectors_count: (inout): gets input buffer size, puts number of filled one - * @selectors_buffer: (out): buffer of records - * - * Returns: Total number of feature selector records available for the feature. + * hb_aat_layout_get_features: * * Since: REPLACEME */ unsigned int -hb_aat_layout_get_feature_settings (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *selectors_count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) +hb_aat_layout_get_features (hb_face_t *face, + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) +{ + return face->table.feat->get_features (start_offset, count, features); +} + +hb_ot_name_id_t +hb_aat_layout_get_feature_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature) +{ return HB_OT_NAME_ID_INVALID; } + +/** + * hb_aat_layout_get_feature_settings: + * + * Since: REPLACEME + */ +unsigned int +hb_aat_layout_get_feature_settings (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_setting_t *settings /* OUT. May be NULL. */) { return face->table.feat->get_settings (feature, default_setting, - start_offset, selectors_count, selectors_buffer); + start_offset, count, settings); } - -unsigned int -hb_aat_layout_get_features (hb_face_t *face, - unsigned int start_offset, - unsigned int *record_count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_record_t *record_buffer /* OUT. May be NULL. */) -{ - return face->table.feat->get_features (start_offset, record_count, record_buffer); -} +hb_ot_name_id_t +hb_aat_layout_get_feature_setting_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_setting_t setting) +{ return HB_OT_NAME_ID_INVALID; } diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index b681348eb..f5d41b5c7 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -38,7 +38,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, { feature_info_t *info = features.push(); info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; - info->setting = value; + info->setting = (hb_aat_layout_feature_setting_t) value; return; } diff --git a/src/hb-aat.h b/src/hb-aat.h index 11e5825fa..7aa47fa51 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -37,10 +37,10 @@ HB_BEGIN_DECLS */ typedef enum { - HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, - HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, - HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, - HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, + HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, + HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, + HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, @@ -79,199 +79,123 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF } hb_aat_layout_feature_type_t; - /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC + * AAT available settings * * Since: REPLACEME */ -enum +typedef enum { - HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_OFF = 1 -}; - - + HB_AAT_LAYOUT_SELECTOR_UNDEFINED = 0xFFFF, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */ + HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ + HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON = 2, + HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON = 4, + HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_LOGOS_ON = 6, + HB_AAT_LAYOUT_SELECTOR_LOGOS_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_ON = 8, + HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, + HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, + HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_ON = 12, + HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_OFF = 13, + HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, + HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, + HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_ON = 16, + HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_OFF = 17, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, + HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON = 20, + HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ + HB_AAT_LAYOUT_SELECTOR_UNCONNECTED = 0, + HB_AAT_LAYOUT_SELECTOR_PARTIALLY_CONNECTED = 1, + HB_AAT_LAYOUT_SELECTOR_CURSIVE = 2, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */ + HB_AAT_LAYOUT_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_ALL_CAPS = 1, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS = 3, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */ + HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, + HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON = 2, - HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_LOGOS_ON = 6, - HB_AAT_LAYOUT_SELECTOR_LOGOS_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_ON = 8, - HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, - HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, - HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_ON = 12, - HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_OFF = 13, - HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, - HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, - HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_ON = 16, - HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_OFF = 17, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, - HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON = 20, - HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF = 21 -}; - - + HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, + HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_UNCONNECTED = 0, - HB_AAT_LAYOUT_SELECTOR_PARTIALLY_CONNECTED = 1, - HB_AAT_LAYOUT_SELECTOR_CURSIVE = 2 -}; - - + HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS = 1, + HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_NUMBERS = 2, + HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_ALL_CAPS = 1, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS = 3, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5 /* deprecated */ -}; - - - + HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_ON = 2, + HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, + HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_ON = 6, + HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_ON = 8, + HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_OFF = 9, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, - HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1 -}; - - + HB_AAT_LAYOUT_SELECTOR_SHOW_DIACRITICS = 0, + HB_AAT_LAYOUT_SELECTOR_HIDE_DIACRITICS = 1, + HB_AAT_LAYOUT_SELECTOR_DECOMPOSE_DIACRITICS = 2, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, - HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1 -}; - - + HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION = 0, + HB_AAT_LAYOUT_SELECTOR_SUPERIORS = 1, + HB_AAT_LAYOUT_SELECTOR_INFERIORS = 2, + HB_AAT_LAYOUT_SELECTOR_ORDINALS = 3, + HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS = 4, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS = 1, - HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_NUMBERS = 2, - HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_NUMBERS = 3 -}; - - + HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS = 0, + HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS = 1, + HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS = 2, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_ON = 2, - HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_ON = 6, - HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_ON = 8, - HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_OFF = 9 -}; - - + HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_ON = 0, + HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_OFF = 1, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_SHOW_DIACRITICS = 0, - HB_AAT_LAYOUT_SELECTOR_HIDE_DIACRITICS = 1, - HB_AAT_LAYOUT_SELECTOR_DECOMPOSE_DIACRITICS = 2 -}; - - -/* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION - * - * Since: REPLACEME - */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION = 0, - HB_AAT_LAYOUT_SELECTOR_SUPERIORS = 1, - HB_AAT_LAYOUT_SELECTOR_INFERIORS = 2, - HB_AAT_LAYOUT_SELECTOR_ORDINALS = 3, - HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS = 4 -}; - - -/* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS - * - * Since: REPLACEME - */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS = 0, - HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS = 1, - HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS = 2 -}; - - -/* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE - * - * Since: REPLACEME - */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_ON = 0, - HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_OFF = 1 -}; - - -/* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS - * - * Since: REPLACEME - */ -enum -{ HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, @@ -283,17 +207,12 @@ enum HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_ON = 8, HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_OFF = 9, HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, - HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11 -}; - - + HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_ON = 0, HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, @@ -305,76 +224,52 @@ enum HB_AAT_LAYOUT_SELECTOR_EXPONENTS_ON = 8, HB_AAT_LAYOUT_SELECTOR_EXPONENTS_OFF = 9, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON = 10, - HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF = 11 -}; - - + HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_ORNAMENTS = 0, HB_AAT_LAYOUT_SELECTOR_DINGBATS = 1, HB_AAT_LAYOUT_SELECTOR_PI_CHARACTERS = 2, HB_AAT_LAYOUT_SELECTOR_FLEURONS = 3, HB_AAT_LAYOUT_SELECTOR_DECORATIVE_BORDERS = 4, HB_AAT_LAYOUT_SELECTOR_INTERNATIONAL_SYMBOLS = 5, - HB_AAT_LAYOUT_SELECTOR_MATH_SYMBOLS = 6 -}; - - + HB_AAT_LAYOUT_SELECTOR_MATH_SYMBOLS = 6, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES * * Since: REPLACEME */ -enum -{ - HB_AAT_LAYOUT_SELECTOR_NO_ALTERNATES = 0 -}; - - + HB_AAT_LAYOUT_SELECTOR_NO_ALTERNATES = 0, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL1 = 0, HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL2 = 1, HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL3 = 2, HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL4 = 3, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL5 = 4 -}; - - + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL5 = 4, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS = 0, HB_AAT_LAYOUT_SELECTOR_DISPLAY_TEXT = 1, HB_AAT_LAYOUT_SELECTOR_ENGRAVED_TEXT = 2, HB_AAT_LAYOUT_SELECTOR_ILLUMINATED_CAPS = 3, HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS = 4, - HB_AAT_LAYOUT_SELECTOR_TALL_CAPS = 5 -}; - + HB_AAT_LAYOUT_SELECTOR_TALL_CAPS = 5, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS = 0, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS = 1, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS = 2, @@ -389,46 +284,31 @@ enum HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS = 11, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS = 12, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS = 13, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14 -}; - - + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS = 0, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS = 1 -}; - - + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS = 1, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT = 0, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT = 1, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT = 2, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT = 3, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT = 4, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, - HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT = 6 -}; - - + HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION = 0, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL = 1, HB_AAT_LAYOUT_SELECTOR_HIRAGANA_TO_KATAKANA = 2, @@ -438,17 +318,12 @@ enum HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9 -}; - - + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_ANNOTATION = 0, HB_AAT_LAYOUT_SELECTOR_BOX_ANNOTATION = 1, HB_AAT_LAYOUT_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, @@ -459,158 +334,104 @@ enum HB_AAT_LAYOUT_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, HB_AAT_LAYOUT_SELECTOR_DIAMOND_ANNOTATION = 8, HB_AAT_LAYOUT_SELECTOR_INVERTED_BOX_ANNOTATION = 9, - HB_AAT_LAYOUT_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION = 10 -}; - - + HB_AAT_LAYOUT_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION = 10, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_KANA = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_KANA = 1 -}; - + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_KANA = 1, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2 -}; - - + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_ON = 0, HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, - HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5 -}; - - + HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF instead */ HB_AAT_LAYOUT_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON instead */ HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON = 2, - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF = 3 -}; - - + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF = 3, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5 -}; - - + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5 -}; - - + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, - HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1 -}; - - + HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3 -}; - - + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3 -}; - - + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3 -}; - - + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, @@ -651,114 +472,68 @@ enum HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41 -}; - - + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES * * Since: REPLACEME */ -enum -{ + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON = 2, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF = 3, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF = 5 -}; - - + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF = 5, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE = 0, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS = 2 -}; - + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, /* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE + * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE * * Since: REPLACEME */ -enum -{ HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE = 0, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS = 2 -}; + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, -/* - * Selectors for HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE - * - * Since: REPLACEME - */ -enum -{ + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */ HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, HB_AAT_LAYOUT_SELECTOR_DEFAULT_CJK_ROMAN = 2, HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 -}; - - -/** - * hb_aat_layout_feature_record_t: - * - * Feature record and - * - * Since: REPLACEME - **/ -typedef struct hb_aat_layout_feature_record_t -{ - hb_aat_layout_feature_type_t feature; - hb_ot_name_id_t name_id; -} hb_aat_layout_feature_record_t; +} hb_aat_layout_feature_setting_t; HB_EXTERN unsigned int -hb_aat_layout_get_features (hb_face_t *face, - unsigned int start_offset, - unsigned int *record_count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_record_t *record_buffer /* OUT. May be NULL. */); +hb_aat_layout_get_features (hb_face_t *face, + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); -/** - * hb_aat_feature_t: - * - * Feature value - * - * Since: REPLACEME - */ -typedef unsigned int hb_aat_layout_feature_setting_t; +HB_EXTERN hb_ot_name_id_t +hb_aat_layout_get_feature_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature); -/** - * hb_aat_layout_feature_type_selector_t: - * - * Feature type selector - * - * Since: REPLACEME - **/ -typedef struct hb_aat_layout_feature_type_selector_t -{ - hb_aat_layout_feature_setting_t setting; - hb_ot_name_id_t name_id; -} hb_aat_layout_feature_type_selector_t; HB_EXTERN unsigned int -hb_aat_layout_get_feature_settings (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *selectors_count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */); +hb_aat_layout_get_feature_settings (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_setting_t *settings /* OUT. May be NULL. */); + +HB_EXTERN hb_ot_name_id_t +hb_aat_layout_get_feature_setting_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_setting_t setting); HB_END_DECLS diff --git a/src/hb-ot.h b/src/hb-ot.h index d4f1d3abc..c168175ac 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -37,7 +37,6 @@ #include "hb-ot-name.h" #include "hb-ot-shape.h" #include "hb-ot-var.h" -#include "hb-aat.h" HB_BEGIN_DECLS diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 430cb3e43..bd404e194 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -36,65 +36,65 @@ static hb_face_t *sbix; static void test_aat_get_features (void) { - hb_aat_layout_feature_record_t records[3]; - unsigned int record_count = 3; - g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &record_count, records)); - g_assert_cmpuint (1, ==, records[0].feature); - g_assert_cmpuint (258, ==, records[0].name_id); - g_assert_cmpuint (3, ==, records[1].feature); - g_assert_cmpuint (261, ==, records[1].name_id); - g_assert_cmpuint (6, ==, records[2].feature); - g_assert_cmpuint (265, ==, records[2].name_id); +// hb_aat_layout_feature_record_t records[3]; +// unsigned int record_count = 3; +// g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &record_count, records)); +// g_assert_cmpuint (1, ==, records[0].feature); +// g_assert_cmpuint (258, ==, records[0].name_id); +// g_assert_cmpuint (3, ==, records[1].feature); +// g_assert_cmpuint (261, ==, records[1].name_id); +// g_assert_cmpuint (6, ==, records[2].feature); +// g_assert_cmpuint (265, ==, records[2].name_id); } static void test_aat_get_feature_settings (void) { - hb_aat_layout_feature_setting_t default_setting; - hb_aat_layout_feature_type_selector_t records[3]; - unsigned int count = 3; +// hb_aat_layout_feature_setting_t default_setting; +// hb_aat_layout_feature_type_selector_t records[3]; +// unsigned int count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, - &default_setting, 0, &count, records)); - g_assert_cmpuint (3, ==, count); - g_assert_cmpuint (0, ==, default_setting); +// g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, +// &default_setting, 0, &count, records)); +// g_assert_cmpuint (3, ==, count); +// g_assert_cmpuint (0, ==, default_setting); - g_assert_cmpuint (0, ==, records[0].setting); - g_assert_cmpuint (294, ==, records[0].name_id); +// g_assert_cmpuint (0, ==, records[0].setting); +// g_assert_cmpuint (294, ==, records[0].name_id); - g_assert_cmpuint (1, ==, records[1].setting); - g_assert_cmpuint (295, ==, records[1].name_id); +// g_assert_cmpuint (1, ==, records[1].setting); +// g_assert_cmpuint (295, ==, records[1].name_id); - g_assert_cmpuint (2, ==, records[2].setting); - g_assert_cmpuint (296, ==, records[2].name_id); +// g_assert_cmpuint (2, ==, records[2].setting); +// g_assert_cmpuint (296, ==, records[2].name_id); - count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, - &default_setting, 3, &count, records)); - g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (0, ==, default_setting); +// count = 3; +// g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, +// &default_setting, 3, &count, records)); +// g_assert_cmpuint (1, ==, count); +// g_assert_cmpuint (0, ==, default_setting); - g_assert_cmpuint (3, ==, records[0].setting); - g_assert_cmpuint (297, ==, records[0].name_id); +// g_assert_cmpuint (3, ==, records[0].setting); +// g_assert_cmpuint (297, ==, records[0].name_id); - count = 1; - g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, - &default_setting, 0, &count, records)); - g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, ==, default_setting); +// count = 1; +// g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, +// &default_setting, 0, &count, records)); +// g_assert_cmpuint (1, ==, count); +// g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, ==, default_setting); - g_assert_cmpuint (8, ==, records[0].setting); - g_assert_cmpuint (308, ==, records[0].name_id); +// g_assert_cmpuint (8, ==, records[0].setting); +// g_assert_cmpuint (308, ==, records[0].name_id); - count = 100; - g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, - NULL, 0, &count, records)); - g_assert_cmpuint (0, ==, count); +// count = 100; +// g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, +// NULL, 0, &count, records)); +// g_assert_cmpuint (0, ==, count); - g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, NULL, - 0, &count, records)); +// g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, NULL, +// 0, &count, records)); } int From 4009a05ca7de21fff2176621597cd0cd01e9d80e Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 17 Nov 2018 11:30:50 +0330 Subject: [PATCH 125/158] [feat] Address Behdad comments --- src/hb-aat-layout-feat-table.hh | 114 ++++-- src/hb-aat-layout.cc | 14 +- src/hb-aat.h | 673 ++++++++++++++------------------ test/api/test-aat-layout.c | 88 +++-- 4 files changed, 423 insertions(+), 466 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 2834de954..ee1715736 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -45,6 +45,13 @@ struct SettingName return_trace (likely (c->check_struct (this))); } + inline hb_aat_layout_feature_setting_t get_setting () const + { return (hb_aat_layout_feature_setting_t) (unsigned int) setting; } + + inline hb_ot_name_id_t get_name_id () const + { return (hb_ot_name_id_t) nameIndex; } + + protected: HBUINT16 setting; /* The setting. */ NameID nameIndex; /* The name table index for the setting's name. */ public: @@ -57,10 +64,10 @@ struct FeatureName { static int cmp (const void *key_, const void *entry_) { - hb_aat_feature_type_t key = * (hb_aat_feature_type_t *) key_; + hb_aat_layout_feature_setting_t key = * (hb_aat_layout_feature_setting_t *) key_; const FeatureName * entry = (const FeatureName *) entry_; return key < entry->feature ? -1 : - key > entry->feature ? 1 : + key > entry->feature ? +1 : 0; } @@ -78,48 +85,59 @@ struct FeatureName * as the default. */ }; - inline unsigned int get_settings (const feat *feat, - hb_bool_t *is_exclusive, - unsigned int start_offset, - unsigned int *records_count, - hb_aat_feature_option_record_t *records_buffer) const + inline unsigned int get_settings (const feat *feat, + hb_aat_layout_feature_setting_t *default_setting, + unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_setting_t *settings) const { - bool exclusive = featureFlags & Exclusive; - bool not_default = featureFlags & NotDefault; - if (is_exclusive) *is_exclusive = exclusive; - const UnsizedArrayOf& settings = feat+settingTable; - unsigned int len = 0; + const UnsizedArrayOf& settings_table = feat+settingTableZ; unsigned int settings_count = nSettings; - if (records_count && records_buffer) + if (count && *count) { - len = MIN (settings_count - start_offset, *records_count); + unsigned int len = MIN (settings_count - start_offset, *count); for (unsigned int i = 0; i < len; i++) - { - records_buffer[i].is_default = exclusive && not_default && - i + start_offset == (featureFlags & IndexMask); - records_buffer[i].name_id = settings[start_offset + i].nameIndex; - records_buffer[i].setting = settings[start_offset + i].setting; - } - if (exclusive && !not_default && start_offset == 0 && len != 0) - records_buffer[0].is_default = true; + settings[i] = settings_table[start_offset + i].get_setting (); + *count = len; + } + if (default_setting) + { + unsigned int index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0; + *default_setting = ((featureFlags & Exclusive) && index < settings_count) + ? settings_table[index].get_setting () + : HB_AAT_LAYOUT_SELECTOR_INVALID; } - if (is_exclusive) *is_exclusive = exclusive; - if (records_count) *records_count = len; return settings_count; } + inline hb_aat_layout_feature_type_t get_feature_type () const + { return (hb_aat_layout_feature_type_t) (unsigned int) feature; } + + inline hb_ot_name_id_t get_feature_name_id () const + { return (hb_ot_name_id_t) nameIndex; } + + inline hb_ot_name_id_t get_feature_setting_name_id (const feat *feat, + hb_aat_layout_feature_setting_t setting) const + { + const UnsizedArrayOf& settings_table = feat+settingTableZ; + for (unsigned int i = 0; i < nSettings; i++) + if (settings_table[i].get_setting () == setting) + return settings_table[i].get_name_id (); + return HB_OT_NAME_ID_INVALID; + } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - (base+settingTable).sanitize (c, nSettings))); + (base+settingTableZ).sanitize (c, nSettings))); } protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ LOffsetTo, false> - settingTable; /* Offset in bytes from the beginning of this table to + settingTableZ; /* Offset in bytes from the beginning of this table to * this feature's setting name array. The actual type of * record this offset refers to will depend on the * exclusivity value, as described below. */ @@ -135,9 +153,24 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; - inline const FeatureName& get_feature (hb_aat_feature_type_t key) const + inline unsigned int get_features (unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_type_t *features) const { - const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &names, + unsigned int feature_count = featureNameCount; + if (count && *count) + { + unsigned int len = MIN (feature_count - start_offset, *count); + for (unsigned int i = 0; i < len; i++) + features[i] = namesZ[i + start_offset].get_feature_type (); + *count = len; + } + return featureNameCount; + } + + inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const + { + const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &namesZ, FeatureName::static_size, sizeof (FeatureName), FeatureName::cmp); @@ -145,21 +178,28 @@ struct feat return feature ? *feature : Null (FeatureName); } - inline unsigned int get_settings (hb_aat_feature_type_t key, - hb_bool_t *is_exclusive, - unsigned int start_offset, - unsigned int *records_count, - hb_aat_feature_option_record_t *records_buffer) const + inline hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const + { return get_feature (feature).get_feature_name_id (); } + + inline hb_ot_name_id_t get_feature_setting_name_id (hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_setting_t setting) const + { return get_feature (feature).get_feature_setting_name_id (this, setting); } + + inline unsigned int get_settings (hb_aat_layout_feature_type_t key, + hb_aat_layout_feature_setting_t *default_setting, + unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_setting_t *settings) const { - return get_feature (key).get_settings (this, is_exclusive, start_offset, - records_count, records_buffer); + return get_feature (key).get_settings (this, default_setting, start_offset, + count, settings); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - names.sanitize (c, featureNameCount, this))); + namesZ.sanitize (c, featureNameCount, this))); } protected: @@ -170,7 +210,7 @@ struct feat HBUINT16 reserved1; /* Reserved (set to zero). */ HBUINT32 reserved2; /* Reserved (set to zero). */ UnsizedArrayOf - names; /* The feature name array. */ + namesZ; /* The feature name array. */ public: DEFINE_SIZE_STATIC (24); }; diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 0f8304cba..9fefd8f96 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -314,10 +314,15 @@ hb_aat_layout_get_features (hb_face_t *face, return face->table.feat->get_features (start_offset, count, features); } +/** + * hb_aat_layout_get_feature_name_id: + * + * Since: REPLACEME + */ hb_ot_name_id_t hb_aat_layout_get_feature_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature) -{ return HB_OT_NAME_ID_INVALID; } +{ return face->table.feat->get_feature_name_id (feature); } /** * hb_aat_layout_get_feature_settings: @@ -336,8 +341,13 @@ hb_aat_layout_get_feature_settings (hb_face_t *face, start_offset, count, settings); } +/** + * hb_aat_layout_get_feature_setting_name_id: + * + * Since: REPLACEME + */ hb_ot_name_id_t hb_aat_layout_get_feature_setting_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t setting) -{ return HB_OT_NAME_ID_INVALID; } +{ return face->table.feat->get_feature_setting_name_id (feature, setting); } diff --git a/src/hb-aat.h b/src/hb-aat.h index 7aa47fa51..16a5fad5b 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -37,46 +37,47 @@ HB_BEGIN_DECLS */ typedef enum { + HB_AAT_LAYOUT_FEATURE_TYPE_INVALID = 0xFFFF, + HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, - HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, - HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, - HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, - HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8, - HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9, - HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, - HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, - HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13, - HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, - HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, - HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16, - HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, - HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18, - HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, - HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, - HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, - HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, - HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, - HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24, - HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25, - HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26, - HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27, - HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29, - HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31, - HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, - HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, - HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, - HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, - HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, - HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, - HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, - HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103, - HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, + HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, + HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8, + HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, + HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, + HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, + HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, + HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, + HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, + HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, + HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24, + HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26, + HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27, + HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31, + HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, + HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, + HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, + HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, + HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, + HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, + HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103 } hb_aat_layout_feature_type_t; /* @@ -86,10 +87,12 @@ typedef enum */ typedef enum { - HB_AAT_LAYOUT_SELECTOR_UNDEFINED = 0xFFFF, + HB_AAT_LAYOUT_SELECTOR_INVALID = 0xFFFF, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */ HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_ON = 0, HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_ON = 0, HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_OFF = 1, @@ -113,41 +116,35 @@ typedef enum HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON = 20, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ HB_AAT_LAYOUT_SELECTOR_UNCONNECTED = 0, HB_AAT_LAYOUT_SELECTOR_PARTIALLY_CONNECTED = 1, HB_AAT_LAYOUT_SELECTOR_CURSIVE = 2, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */ HB_AAT_LAYOUT_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ HB_AAT_LAYOUT_SELECTOR_ALL_CAPS = 1, /* deprecated */ HB_AAT_LAYOUT_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS = 3, /* deprecated */ HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ + HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */ HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */ HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING */ HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS = 0, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS = 1, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_NUMBERS = 2, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE */ HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_ON = 2, @@ -158,357 +155,265 @@ typedef enum HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_ON = 8, HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_OFF = 9, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE */ HB_AAT_LAYOUT_SELECTOR_SHOW_DIACRITICS = 0, HB_AAT_LAYOUT_SELECTOR_HIDE_DIACRITICS = 1, HB_AAT_LAYOUT_SELECTOR_DECOMPOSE_DIACRITICS = 2, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION */ HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION = 0, HB_AAT_LAYOUT_SELECTOR_SUPERIORS = 1, HB_AAT_LAYOUT_SELECTOR_INFERIORS = 2, HB_AAT_LAYOUT_SELECTOR_ORDINALS = 3, HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS = 4, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS */ HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS = 0, HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS = 1, HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS = 2, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE - * - * Since: REPLACEME - */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */ HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_ON = 0, HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_OFF = 1, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, - HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON = 4, - HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_ON = 6, - HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_ON = 8, - HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, - HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_ON = 0, - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, - HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_ON = 4, - HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_ON = 6, - HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_EXPONENTS_ON = 8, - HB_AAT_LAYOUT_SELECTOR_EXPONENTS_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON = 10, - HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_ORNAMENTS = 0, - HB_AAT_LAYOUT_SELECTOR_DINGBATS = 1, - HB_AAT_LAYOUT_SELECTOR_PI_CHARACTERS = 2, - HB_AAT_LAYOUT_SELECTOR_FLEURONS = 3, - HB_AAT_LAYOUT_SELECTOR_DECORATIVE_BORDERS = 4, - HB_AAT_LAYOUT_SELECTOR_INTERNATIONAL_SYMBOLS = 5, - HB_AAT_LAYOUT_SELECTOR_MATH_SYMBOLS = 6, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_ALTERNATES = 0, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL1 = 0, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL2 = 1, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL3 = 2, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL4 = 3, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL5 = 4, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS = 0, - HB_AAT_LAYOUT_SELECTOR_DISPLAY_TEXT = 1, - HB_AAT_LAYOUT_SELECTOR_ENGRAVED_TEXT = 2, - HB_AAT_LAYOUT_SELECTOR_ILLUMINATED_CAPS = 3, - HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS = 4, - HB_AAT_LAYOUT_SELECTOR_TALL_CAPS = 5, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS = 0, - HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS = 1, - HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS = 2, - HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS = 3, - HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS = 4, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_ONE = 5, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_TWO = 6, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_THREE = 7, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FOUR = 8, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FIVE = 9, - HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS = 10, - HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS = 11, - HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS = 12, - HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS = 13, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS = 0, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS = 1, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT = 0, - HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT = 1, - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT = 2, - HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT = 3, - HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT = 4, - HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, - HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION = 0, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL = 1, - HB_AAT_LAYOUT_SELECTOR_HIRAGANA_TO_KATAKANA = 2, - HB_AAT_LAYOUT_SELECTOR_KATAKANA_TO_HIRAGANA = 3, - HB_AAT_LAYOUT_SELECTOR_KANA_TO_ROMANIZATION = 4, - HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, - HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_ANNOTATION = 0, - HB_AAT_LAYOUT_SELECTOR_BOX_ANNOTATION = 1, - HB_AAT_LAYOUT_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, - HB_AAT_LAYOUT_SELECTOR_CIRCLE_ANNOTATION = 3, - HB_AAT_LAYOUT_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, - HB_AAT_LAYOUT_SELECTOR_PARENTHESIS_ANNOTATION = 5, - HB_AAT_LAYOUT_SELECTOR_PERIOD_ANNOTATION = 6, - HB_AAT_LAYOUT_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, - HB_AAT_LAYOUT_SELECTOR_DIAMOND_ANNOTATION = 8, - HB_AAT_LAYOUT_SELECTOR_INVERTED_BOX_ANNOTATION = 9, - HB_AAT_LAYOUT_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION = 10, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_KANA = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_KANA = 1, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */ + HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, + HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON = 4, + HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_ON = 6, + HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_ON = 8, + HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, + HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_ON = 0, - HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, - HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, - HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF instead */ - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON instead */ - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON = 2, - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF = 3, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, - HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES - * - * Since: REPLACEME - */ + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS */ + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_ON = 0, + HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, + HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_ON = 4, + HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_ON = 6, + HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_EXPONENTS_ON = 8, + HB_AAT_LAYOUT_SELECTOR_EXPONENTS_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON = 10, + HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON = 2, - HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF = 5, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE = 0, - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE */ + HB_AAT_LAYOUT_SELECTOR_NO_ORNAMENTS = 0, + HB_AAT_LAYOUT_SELECTOR_DINGBATS = 1, + HB_AAT_LAYOUT_SELECTOR_PI_CHARACTERS = 2, + HB_AAT_LAYOUT_SELECTOR_FLEURONS = 3, + HB_AAT_LAYOUT_SELECTOR_DECORATIVE_BORDERS = 4, + HB_AAT_LAYOUT_SELECTOR_INTERNATIONAL_SYMBOLS = 5, + HB_AAT_LAYOUT_SELECTOR_MATH_SYMBOLS = 6, -/* - * Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE - * - * Since: REPLACEME - */ - HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE = 0, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES */ + HB_AAT_LAYOUT_SELECTOR_NO_ALTERNATES = 0, + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */ + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL1 = 0, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL2 = 1, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL3 = 2, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL4 = 3, + HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL5 = 4, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS */ + HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS = 0, + HB_AAT_LAYOUT_SELECTOR_DISPLAY_TEXT = 1, + HB_AAT_LAYOUT_SELECTOR_ENGRAVED_TEXT = 2, + HB_AAT_LAYOUT_SELECTOR_ILLUMINATED_CAPS = 3, + HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS = 4, + HB_AAT_LAYOUT_SELECTOR_TALL_CAPS = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE */ + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS = 0, + HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS = 1, + HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS = 2, + HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS = 3, + HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS = 4, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_ONE = 5, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_TWO = 6, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_THREE = 7, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FOUR = 8, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FIVE = 9, + HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS = 10, + HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS = 11, + HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS = 12, + HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS = 13, + HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE */ + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS = 0, + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING */ + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT = 0, + HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT = 1, + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT = 2, + HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT = 3, + HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT = 4, + HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, + HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION */ + HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION = 0, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL = 1, + HB_AAT_LAYOUT_SELECTOR_HIRAGANA_TO_KATAKANA = 2, + HB_AAT_LAYOUT_SELECTOR_KATAKANA_TO_HIRAGANA = 3, + HB_AAT_LAYOUT_SELECTOR_KANA_TO_ROMANIZATION = 4, + HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, + HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, + HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE */ + HB_AAT_LAYOUT_SELECTOR_NO_ANNOTATION = 0, + HB_AAT_LAYOUT_SELECTOR_BOX_ANNOTATION = 1, + HB_AAT_LAYOUT_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, + HB_AAT_LAYOUT_SELECTOR_CIRCLE_ANNOTATION = 3, + HB_AAT_LAYOUT_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, + HB_AAT_LAYOUT_SELECTOR_PARENTHESIS_ANNOTATION = 5, + HB_AAT_LAYOUT_SELECTOR_PERIOD_ANNOTATION = 6, + HB_AAT_LAYOUT_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, + HB_AAT_LAYOUT_SELECTOR_DIAMOND_ANNOTATION = 8, + HB_AAT_LAYOUT_SELECTOR_INVERTED_BOX_ANNOTATION = 9, + HB_AAT_LAYOUT_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE */ + HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_KANA = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_KANA = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */ + HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */ + HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_ON = 0, + HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, + HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, + HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA */ + HB_AAT_LAYOUT_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF instead */ + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON instead */ + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON = 2, + HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */ + HB_AAT_LAYOUT_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, + HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */ + HB_AAT_LAYOUT_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, + HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */ + HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, + HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN */ + HB_AAT_LAYOUT_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, + HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */ + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, + HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA */ + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, + HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES */ + HB_AAT_LAYOUT_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, + HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */ + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, + HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON = 2, + HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF = 3, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, + HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE */ + HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE = 0, + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE */ + HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE = 0, + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */ - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, - HB_AAT_LAYOUT_SELECTOR_DEFAULT_CJK_ROMAN = 2, - HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 + HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, + HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, + HB_AAT_LAYOUT_SELECTOR_DEFAULT_CJK_ROMAN = 2, + HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 } hb_aat_layout_feature_setting_t; HB_EXTERN unsigned int diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index bd404e194..9d1330366 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -36,65 +36,67 @@ static hb_face_t *sbix; static void test_aat_get_features (void) { -// hb_aat_layout_feature_record_t records[3]; -// unsigned int record_count = 3; -// g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &record_count, records)); -// g_assert_cmpuint (1, ==, records[0].feature); -// g_assert_cmpuint (258, ==, records[0].name_id); -// g_assert_cmpuint (3, ==, records[1].feature); -// g_assert_cmpuint (261, ==, records[1].name_id); -// g_assert_cmpuint (6, ==, records[2].feature); -// g_assert_cmpuint (265, ==, records[2].name_id); + hb_aat_layout_feature_type_t features[3]; + unsigned int count = 3; + g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &count, features)); + + g_assert_cmpuint (1, ==, features[0]); + g_assert_cmpuint (3, ==, features[1]); + g_assert_cmpuint (6, ==, features[2]); + + g_assert_cmpuint (258, ==, hb_aat_layout_get_feature_name_id (face, features[0])); + g_assert_cmpuint (261, ==, hb_aat_layout_get_feature_name_id (face, features[1])); + g_assert_cmpuint (265, ==, hb_aat_layout_get_feature_name_id (face, features[2])); } static void test_aat_get_feature_settings (void) { -// hb_aat_layout_feature_setting_t default_setting; -// hb_aat_layout_feature_type_selector_t records[3]; -// unsigned int count = 3; + hb_aat_layout_feature_setting_t default_setting; + hb_aat_layout_feature_setting_t settings[3]; + unsigned int count = 3; -// g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, -// &default_setting, 0, &count, records)); -// g_assert_cmpuint (3, ==, count); -// g_assert_cmpuint (0, ==, default_setting); + g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + &default_setting, 0, &count, settings)); + g_assert_cmpuint (3, ==, count); + g_assert_cmpuint (0, ==, default_setting); -// g_assert_cmpuint (0, ==, records[0].setting); -// g_assert_cmpuint (294, ==, records[0].name_id); + g_assert_cmpuint (0, ==, settings[0]); + g_assert_cmpuint (294, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); -// g_assert_cmpuint (1, ==, records[1].setting); -// g_assert_cmpuint (295, ==, records[1].name_id); + g_assert_cmpuint (1, ==, settings[1]); + g_assert_cmpuint (295, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[1])); -// g_assert_cmpuint (2, ==, records[2].setting); -// g_assert_cmpuint (296, ==, records[2].name_id); + g_assert_cmpuint (2, ==, settings[2]); + g_assert_cmpuint (296, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); -// count = 3; -// g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18, -// &default_setting, 3, &count, records)); -// g_assert_cmpuint (1, ==, count); -// g_assert_cmpuint (0, ==, default_setting); + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); -// g_assert_cmpuint (3, ==, records[0].setting); -// g_assert_cmpuint (297, ==, records[0].name_id); + count = 3; + g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + &default_setting, 3, &count, settings)); + g_assert_cmpuint (1, ==, count); + g_assert_cmpuint (0, ==, default_setting); + g_assert_cmpuint (3, ==, settings[0]); + g_assert_cmpuint (297, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); -// count = 1; -// g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, -// &default_setting, 0, &count, records)); -// g_assert_cmpuint (1, ==, count); -// g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, ==, default_setting); + count = 1; + g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + &default_setting, 0, &count, settings)); + g_assert_cmpuint (1, ==, count); + g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, ==, default_setting); -// g_assert_cmpuint (8, ==, records[0].setting); -// g_assert_cmpuint (308, ==, records[0].name_id); + g_assert_cmpuint (8, ==, settings[0]); + g_assert_cmpuint (308, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); + count = 100; + g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + NULL, 0, &count, settings)); + g_assert_cmpuint (0, ==, count); -// count = 100; -// g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, -// NULL, 0, &count, records)); -// g_assert_cmpuint (0, ==, count); - -// g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, NULL, -// 0, &count, records)); + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_get_feature_setting_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + (hb_aat_layout_feature_setting_t) 0)); } int From a8726cb4830f51a820db4bc6346ed09c91493817 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 17 Nov 2018 14:23:11 +0330 Subject: [PATCH 126/158] [feat] Use bsearch --- src/hb-aat-layout-feat-table.hh | 36 ++++++++++++++++++++------------- src/hb-aat-layout-morx-table.hh | 2 +- src/hb.hh | 2 ++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index ee1715736..02adaf7d2 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -39,17 +39,25 @@ namespace AAT { struct SettingName { - inline bool sanitize (hb_sanitize_context_t *c) const + static int cmp (const void *key_, const void *entry_) { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + hb_aat_layout_feature_setting_t key = * (hb_aat_layout_feature_setting_t *) key_; + const SettingName * entry = (const SettingName *) entry_; + return key < entry->setting ? -1 : + key > entry->setting ? +1 : + 0; } inline hb_aat_layout_feature_setting_t get_setting () const { return (hb_aat_layout_feature_setting_t) (unsigned int) setting; } - inline hb_ot_name_id_t get_name_id () const - { return (hb_ot_name_id_t) nameIndex; } + inline hb_ot_name_id_t get_name_id () const { return nameIndex; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } protected: HBUINT16 setting; /* The setting. */ @@ -113,17 +121,17 @@ struct FeatureName inline hb_aat_layout_feature_type_t get_feature_type () const { return (hb_aat_layout_feature_type_t) (unsigned int) feature; } - inline hb_ot_name_id_t get_feature_name_id () const - { return (hb_ot_name_id_t) nameIndex; } + inline hb_ot_name_id_t get_feature_name_id () const { return nameIndex; } inline hb_ot_name_id_t get_feature_setting_name_id (const feat *feat, - hb_aat_layout_feature_setting_t setting) const + hb_aat_layout_feature_setting_t key) const { - const UnsizedArrayOf& settings_table = feat+settingTableZ; - for (unsigned int i = 0; i < nSettings; i++) - if (settings_table[i].get_setting () == setting) - return settings_table[i].get_name_id (); - return HB_OT_NAME_ID_INVALID; + const SettingName* setting = (SettingName*) hb_bsearch (&key, feat+settingTableZ, + nSettings, + SettingName::static_size, + SettingName::cmp); + + return setting ? setting->get_name_id () : HB_OT_NAME_ID_INVALID; } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -171,8 +179,8 @@ struct feat inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const { const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &namesZ, + featureNameCount, FeatureName::static_size, - sizeof (FeatureName), FeatureName::cmp); return feature ? *feature : Null (FeatureName); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 04ef804cd..7fce99495 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -967,7 +967,7 @@ struct Chain flags &= feature.disableFlags; flags |= feature.enableFlags; } - else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == 3/*kSmallCapsSelector*/) + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS) { /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */ type = HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE; diff --git a/src/hb.hh b/src/hb.hh index c771d1fb9..467af966b 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -48,6 +48,8 @@ #include "hb-ot.h" #define HB_OT_H_IN +#include "hb-aat.h" + #include #include #include From 9c64b216ec7ae2c2c124ebd00dc6fa568752be78 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 23 Nov 2018 11:44:53 +0330 Subject: [PATCH 127/158] [feat] Apply renamings and add documentation --- docs/harfbuzz-sections.txt | 10 +++++++++ src/hb-aat-layout.cc | 44 ++++++++++++++++++++++++++++++++------ src/hb-aat.h | 6 +++--- test/api/test-aat-layout.c | 28 ++++++++++++------------ 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 5f5dcef7d..42cb7c5a4 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -3,6 +3,16 @@ HB_H_IN HB_OT_H_IN +

+hb-aat +hb_aat_layout_feature_get_name_id +hb_aat_layout_feature_get_settings +hb_aat_layout_feature_setting_get_name_id +hb_aat_layout_feature_setting_t +hb_aat_layout_feature_type_t +hb_aat_layout_get_features +
+
hb-blob hb_blob_create diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 9fefd8f96..8fbd29632 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -302,6 +302,12 @@ _hb_aat_language_get (hb_face_t *face, /** * hb_aat_layout_get_features: + * @face: a face object + * @start_offset: iteration's start offset + * @count: (inout): buffer size as input, filled size as output + * @features: (out): features buffer + * + * Return value: Number of all available features * * Since: REPLACEME */ @@ -315,22 +321,43 @@ hb_aat_layout_get_features (hb_face_t *face, } /** - * hb_aat_layout_get_feature_name_id: + * hb_aat_layout_feature_get_name_id: + * @face: a face object + * @feature: feature id + * + * Return value: Name ID index * * Since: REPLACEME */ hb_ot_name_id_t -hb_aat_layout_get_feature_name_id (hb_face_t *face, +hb_aat_layout_feature_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature) { return face->table.feat->get_feature_name_id (feature); } /** - * hb_aat_layout_get_feature_settings: + * hb_aat_layout_feature_get_settings: + * @face: a face object + * @feature: feature id + * @default_setting: (out): if is set, the feature is exclusive + * @start_offset: iteration's start offset + * @count: (inout): buffer size as input, filled size as output + * @settings: (out): settings buffer + * + * Per spec: + * For feature types that don't have exclusive settings, + * there will always be a pair of values. One value turns + * a selector on and a second value turns the selector off. + * The on setting must be even and the off setting must be one + * greater than the corresponding on setting. The off setting + * is therefore always odd. As a result, only the on setting + * should have an entry in the setting name array. + * + * Return value: Number of all available features * * Since: REPLACEME */ unsigned int -hb_aat_layout_get_feature_settings (hb_face_t *face, +hb_aat_layout_feature_get_settings (hb_face_t *face, hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, @@ -342,12 +369,17 @@ hb_aat_layout_get_feature_settings (hb_face_t *face, } /** - * hb_aat_layout_get_feature_setting_name_id: + * hb_aat_layout_feature_setting_get_name_id: + * @face: a face object + * @feature: feature id + * @setting: setting value + * + * Return value: Name ID index * * Since: REPLACEME */ hb_ot_name_id_t -hb_aat_layout_get_feature_setting_name_id (hb_face_t *face, +hb_aat_layout_feature_setting_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t setting) { return face->table.feat->get_feature_setting_name_id (feature, setting); } diff --git a/src/hb-aat.h b/src/hb-aat.h index 16a5fad5b..27f455270 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -423,12 +423,12 @@ hb_aat_layout_get_features (hb_face_t *face, hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); HB_EXTERN hb_ot_name_id_t -hb_aat_layout_get_feature_name_id (hb_face_t *face, +hb_aat_layout_feature_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature); HB_EXTERN unsigned int -hb_aat_layout_get_feature_settings (hb_face_t *face, +hb_aat_layout_feature_get_settings (hb_face_t *face, hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ unsigned int start_offset, @@ -436,7 +436,7 @@ hb_aat_layout_get_feature_settings (hb_face_t *face, hb_aat_layout_feature_setting_t *settings /* OUT. May be NULL. */); HB_EXTERN hb_ot_name_id_t -hb_aat_layout_get_feature_setting_name_id (hb_face_t *face, +hb_aat_layout_feature_setting_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_setting_t setting); diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 9d1330366..571090396 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -44,9 +44,9 @@ test_aat_get_features (void) g_assert_cmpuint (3, ==, features[1]); g_assert_cmpuint (6, ==, features[2]); - g_assert_cmpuint (258, ==, hb_aat_layout_get_feature_name_id (face, features[0])); - g_assert_cmpuint (261, ==, hb_aat_layout_get_feature_name_id (face, features[1])); - g_assert_cmpuint (265, ==, hb_aat_layout_get_feature_name_id (face, features[2])); + g_assert_cmpuint (258, ==, hb_aat_layout_feature_get_name_id (face, features[0])); + g_assert_cmpuint (261, ==, hb_aat_layout_feature_get_name_id (face, features[1])); + g_assert_cmpuint (265, ==, hb_aat_layout_feature_get_name_id (face, features[2])); } static void @@ -56,46 +56,46 @@ test_aat_get_feature_settings (void) hb_aat_layout_feature_setting_t settings[3]; unsigned int count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, &default_setting, 0, &count, settings)); g_assert_cmpuint (3, ==, count); g_assert_cmpuint (0, ==, default_setting); g_assert_cmpuint (0, ==, settings[0]); - g_assert_cmpuint (294, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); + g_assert_cmpuint (294, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); g_assert_cmpuint (1, ==, settings[1]); - g_assert_cmpuint (295, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[1])); + g_assert_cmpuint (295, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[1])); g_assert_cmpuint (2, ==, settings[2]); - g_assert_cmpuint (296, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); + g_assert_cmpuint (296, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, &default_setting, 3, &count, settings)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (0, ==, default_setting); g_assert_cmpuint (3, ==, settings[0]); - g_assert_cmpuint (297, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); + g_assert_cmpuint (297, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); count = 1; - g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + g_assert_cmpuint (1, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, &default_setting, 0, &count, settings)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, ==, default_setting); g_assert_cmpuint (8, ==, settings[0]); - g_assert_cmpuint (308, ==, hb_aat_layout_get_feature_setting_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); + g_assert_cmpuint (308, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); count = 100; - g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + g_assert_cmpuint (0, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, NULL, 0, &count, settings)); g_assert_cmpuint (0, ==, count); - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_get_feature_setting_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_setting_get_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, (hb_aat_layout_feature_setting_t) 0)); } From 54f4c17f0a932b0ca0317e1ad5e5e43a11a83fd1 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 23 Nov 2018 12:05:06 +0330 Subject: [PATCH 128/158] [feat] Rename API uses of setting to selector --- docs/harfbuzz-sections.txt | 6 +-- src/hb-aat-layout-feat-table.hh | 52 +++++++++---------- src/hb-aat-layout-morx-table.hh | 2 +- src/hb-aat-layout.cc | 88 ++++++++++++++++----------------- src/hb-aat-layout.hh | 4 +- src/hb-aat-map.cc | 2 +- src/hb-aat-map.hh | 2 +- src/hb-aat.h | 20 ++++---- test/api/test-aat-layout.c | 46 ++++++++--------- 9 files changed, 111 insertions(+), 111 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 42cb7c5a4..221e6f04d 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -6,9 +6,9 @@ HB_OT_H_IN
hb-aat hb_aat_layout_feature_get_name_id -hb_aat_layout_feature_get_settings -hb_aat_layout_feature_setting_get_name_id -hb_aat_layout_feature_setting_t +hb_aat_layout_feature_get_selectors +hb_aat_layout_feature_selector_get_name_id +hb_aat_layout_feature_selector_t hb_aat_layout_feature_type_t hb_aat_layout_get_features
diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 02adaf7d2..5bb718330 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -41,15 +41,15 @@ struct SettingName { static int cmp (const void *key_, const void *entry_) { - hb_aat_layout_feature_setting_t key = * (hb_aat_layout_feature_setting_t *) key_; + hb_aat_layout_feature_selector_t key = * (hb_aat_layout_feature_selector_t *) key_; const SettingName * entry = (const SettingName *) entry_; return key < entry->setting ? -1 : key > entry->setting ? +1 : 0; } - inline hb_aat_layout_feature_setting_t get_setting () const - { return (hb_aat_layout_feature_setting_t) (unsigned int) setting; } + inline hb_aat_layout_feature_selector_t get_selector () const + { return (hb_aat_layout_feature_selector_t) (unsigned int) setting; } inline hb_ot_name_id_t get_name_id () const { return nameIndex; } @@ -72,7 +72,7 @@ struct FeatureName { static int cmp (const void *key_, const void *entry_) { - hb_aat_layout_feature_setting_t key = * (hb_aat_layout_feature_setting_t *) key_; + hb_aat_layout_feature_selector_t key = * (hb_aat_layout_feature_selector_t *) key_; const FeatureName * entry = (const FeatureName *) entry_; return key < entry->feature ? -1 : key > entry->feature ? +1 : @@ -93,11 +93,11 @@ struct FeatureName * as the default. */ }; - inline unsigned int get_settings (const feat *feat, - hb_aat_layout_feature_setting_t *default_setting, - unsigned int start_offset, - unsigned int *count, - hb_aat_layout_feature_setting_t *settings) const + inline unsigned int get_selectors (const feat *feat, + hb_aat_layout_feature_selector_t *default_selector, + unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_selector_t *selectors) const { const UnsizedArrayOf& settings_table = feat+settingTableZ; unsigned int settings_count = nSettings; @@ -105,15 +105,15 @@ struct FeatureName { unsigned int len = MIN (settings_count - start_offset, *count); for (unsigned int i = 0; i < len; i++) - settings[i] = settings_table[start_offset + i].get_setting (); + selectors[i] = settings_table[start_offset + i].get_selector (); *count = len; } - if (default_setting) + if (default_selector) { unsigned int index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0; - *default_setting = ((featureFlags & Exclusive) && index < settings_count) - ? settings_table[index].get_setting () - : HB_AAT_LAYOUT_SELECTOR_INVALID; + *default_selector = ((featureFlags & Exclusive) && index < settings_count) + ? settings_table[index].get_selector () + : HB_AAT_LAYOUT_SELECTOR_INVALID; } return settings_count; } @@ -123,8 +123,8 @@ struct FeatureName inline hb_ot_name_id_t get_feature_name_id () const { return nameIndex; } - inline hb_ot_name_id_t get_feature_setting_name_id (const feat *feat, - hb_aat_layout_feature_setting_t key) const + inline hb_ot_name_id_t get_feature_selector_name_id (const feat *feat, + hb_aat_layout_feature_selector_t key) const { const SettingName* setting = (SettingName*) hb_bsearch (&key, feat+settingTableZ, nSettings, @@ -189,18 +189,18 @@ struct feat inline hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const { return get_feature (feature).get_feature_name_id (); } - inline hb_ot_name_id_t get_feature_setting_name_id (hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t setting) const - { return get_feature (feature).get_feature_setting_name_id (this, setting); } + inline hb_ot_name_id_t get_feature_selector_name_id (hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t selector) const + { return get_feature (feature).get_feature_selector_name_id (this, selector); } - inline unsigned int get_settings (hb_aat_layout_feature_type_t key, - hb_aat_layout_feature_setting_t *default_setting, - unsigned int start_offset, - unsigned int *count, - hb_aat_layout_feature_setting_t *settings) const + inline unsigned int get_selectors (hb_aat_layout_feature_type_t key, + hb_aat_layout_feature_selector_t *default_selector, + unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_selector_t *selectors) const { - return get_feature (key).get_settings (this, default_setting, start_offset, - count, settings); + return get_feature (key).get_selectors (this, default_selector, start_offset, + count, selectors); } inline bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 7fce99495..05936c3e1 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -959,7 +959,7 @@ struct Chain { const Feature &feature = featureZ[i]; hb_aat_layout_feature_type_t type = (hb_aat_layout_feature_type_t) (unsigned int) feature.featureType; - hb_aat_layout_feature_setting_t setting = (hb_aat_layout_feature_setting_t) (unsigned int) feature.featureSetting; + hb_aat_layout_feature_selector_t setting = (hb_aat_layout_feature_selector_t) (unsigned int) feature.featureSetting; retry: const hb_aat_map_builder_t::feature_info_t *info = map->features.bsearch ((uint16_t) type); if (info && info->setting == setting) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 8fbd29632..0ba305aaf 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -53,37 +53,37 @@ static const hb_aat_feature_mapping_t feature_mappings[] = {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF}, - {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS}, - {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_setting_t) 7}, - {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION}, - {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF}, - {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF}, - {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_setting_t) 2}, + {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF}, - {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_setting_t) 2}, + {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_ORDINALS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, - {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, - {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, - {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_setting_t) 4}, - {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, - {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, + {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF}, {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, - {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, + {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF}, {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF}, {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF}, @@ -108,16 +108,16 @@ static const hb_aat_feature_mapping_t feature_mappings[] = {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF}, {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS}, - {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_setting_t) 4}, - {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_setting_t) 16}, - {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, - {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, (hb_aat_layout_feature_setting_t) 14, (hb_aat_layout_feature_setting_t) 15}, - {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, + {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, (hb_aat_layout_feature_selector_t) 14, (hb_aat_layout_feature_selector_t) 15}, + {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, - {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF}, - {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_setting_t) 7}, + {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF}, }; @@ -335,10 +335,10 @@ hb_aat_layout_feature_get_name_id (hb_face_t *face, { return face->table.feat->get_feature_name_id (feature); } /** - * hb_aat_layout_feature_get_settings: + * hb_aat_layout_feature_get_selectors: * @face: a face object * @feature: feature id - * @default_setting: (out): if is set, the feature is exclusive + * @default_selector: (out): if is set, the feature is exclusive * @start_offset: iteration's start offset * @count: (inout): buffer size as input, filled size as output * @settings: (out): settings buffer @@ -357,29 +357,29 @@ hb_aat_layout_feature_get_name_id (hb_face_t *face, * Since: REPLACEME */ unsigned int -hb_aat_layout_feature_get_settings (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_setting_t *settings /* OUT. May be NULL. */) +hb_aat_layout_feature_get_selectors (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_t *selectors /* OUT. May be NULL. */) { - return face->table.feat->get_settings (feature, default_setting, - start_offset, count, settings); + return face->table.feat->get_selectors (feature, default_selector, + start_offset, count, selectors); } /** - * hb_aat_layout_feature_setting_get_name_id: - * @face: a face object - * @feature: feature id - * @setting: setting value + * hb_aat_layout_feature_selector_get_name_id: + * @face: a face object + * @feature: feature id + * @selector: selector value * * Return value: Name ID index * * Since: REPLACEME */ hb_ot_name_id_t -hb_aat_layout_feature_setting_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t setting) -{ return face->table.feat->get_feature_setting_name_id (feature, setting); } +hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t selector) +{ return face->table.feat->get_feature_selector_name_id (feature, selector); } diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index baa4ba193..d56402029 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -37,8 +37,8 @@ struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; hb_aat_layout_feature_type_t aatFeatureType; - hb_aat_layout_feature_setting_t selectorToEnable; - hb_aat_layout_feature_setting_t selectorToDisable; + hb_aat_layout_feature_selector_t selectorToEnable; + hb_aat_layout_feature_selector_t selectorToDisable; static inline int cmp (const void *key_, const void *entry_) { diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index f5d41b5c7..1c65a6759 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -38,7 +38,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, { feature_info_t *info = features.push(); info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES; - info->setting = (hb_aat_layout_feature_setting_t) value; + info->setting = (hb_aat_layout_feature_selector_t) value; return; } diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 619d7758d..1352bd325 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -67,7 +67,7 @@ struct hb_aat_map_builder_t struct feature_info_t { hb_aat_layout_feature_type_t type; - hb_aat_layout_feature_setting_t setting; + hb_aat_layout_feature_selector_t setting; unsigned seq; /* For stable sorting only. */ static int cmp (const void *pa, const void *pb) diff --git a/src/hb-aat.h b/src/hb-aat.h index 27f455270..9706470c8 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -414,7 +414,7 @@ typedef enum HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, HB_AAT_LAYOUT_SELECTOR_DEFAULT_CJK_ROMAN = 2, HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 -} hb_aat_layout_feature_setting_t; +} hb_aat_layout_feature_selector_t; HB_EXTERN unsigned int hb_aat_layout_get_features (hb_face_t *face, @@ -428,17 +428,17 @@ hb_aat_layout_feature_get_name_id (hb_face_t *face, HB_EXTERN unsigned int -hb_aat_layout_feature_get_settings (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_setting_t *settings /* OUT. May be NULL. */); +hb_aat_layout_feature_get_selectors (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_t *settings /* OUT. May be NULL. */); HB_EXTERN hb_ot_name_id_t -hb_aat_layout_feature_setting_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_setting_t setting); +hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t selector); HB_END_DECLS diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 571090396..c50494bee 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -50,53 +50,53 @@ test_aat_get_features (void) } static void -test_aat_get_feature_settings (void) +test_aat_get_feature_selectors (void) { - hb_aat_layout_feature_setting_t default_setting; - hb_aat_layout_feature_setting_t settings[3]; + hb_aat_layout_feature_selector_t default_selector; + hb_aat_layout_feature_selector_t settings[3]; unsigned int count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, - &default_setting, 0, &count, settings)); + g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + &default_selector, 0, &count, settings)); g_assert_cmpuint (3, ==, count); - g_assert_cmpuint (0, ==, default_setting); + g_assert_cmpuint (0, ==, default_selector); g_assert_cmpuint (0, ==, settings[0]); - g_assert_cmpuint (294, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); + g_assert_cmpuint (294, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); g_assert_cmpuint (1, ==, settings[1]); - g_assert_cmpuint (295, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[1])); + g_assert_cmpuint (295, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[1])); g_assert_cmpuint (2, ==, settings[2]); - g_assert_cmpuint (296, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); + g_assert_cmpuint (296, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, - &default_setting, 3, &count, settings)); + g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + &default_selector, 3, &count, settings)); g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (0, ==, default_setting); + g_assert_cmpuint (0, ==, default_selector); g_assert_cmpuint (3, ==, settings[0]); - g_assert_cmpuint (297, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); + g_assert_cmpuint (297, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); count = 1; - g_assert_cmpuint (1, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, - &default_setting, 0, &count, settings)); + g_assert_cmpuint (1, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + &default_selector, 0, &count, settings)); g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, ==, default_setting); + g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, ==, default_selector); g_assert_cmpuint (8, ==, settings[0]); - g_assert_cmpuint (308, ==, hb_aat_layout_feature_setting_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); + g_assert_cmpuint (308, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); count = 100; - g_assert_cmpuint (0, ==, hb_aat_layout_feature_get_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, - NULL, 0, &count, settings)); + g_assert_cmpuint (0, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + NULL, 0, &count, settings)); g_assert_cmpuint (0, ==, count); - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_setting_get_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, - (hb_aat_layout_feature_setting_t) 0)); + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + (hb_aat_layout_feature_selector_t) 0)); } int @@ -105,7 +105,7 @@ main (int argc, char **argv) hb_test_init (&argc, &argv); hb_test_add (test_aat_get_features); - hb_test_add (test_aat_get_feature_settings); + hb_test_add (test_aat_get_feature_selectors); face = hb_test_open_font_file ("fonts/aat-feat.ttf"); sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf"); From e20f81f4fa977a8d22c6afee1e46fbf46bc182d9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 11:57:42 -0500 Subject: [PATCH 129/158] [aat] Rename feat API a bit more --- docs/harfbuzz-sections.txt | 10 +++++----- src/hb-aat-layout-feat-table.hh | 8 ++++---- src/hb-aat-layout.cc | 32 ++++++++++++++++---------------- src/hb-aat.h | 26 +++++++++++++------------- test/api/test-aat-layout.c | 28 ++++++++++++++-------------- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 221e6f04d..0498a2790 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -5,12 +5,12 @@ HB_OT_H_IN
hb-aat -hb_aat_layout_feature_get_name_id -hb_aat_layout_feature_get_selectors -hb_aat_layout_feature_selector_get_name_id -hb_aat_layout_feature_selector_t hb_aat_layout_feature_type_t -hb_aat_layout_get_features +hb_aat_layout_get_feature_types +hb_aat_layout_feature_type_get_name_id +hb_aat_layout_feature_selector_t +hb_aat_layout_feature_type_get_selectors +hb_aat_layout_feature_selector_get_name_id
diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 5bb718330..d30aceefe 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -131,7 +131,7 @@ struct FeatureName SettingName::static_size, SettingName::cmp); - return setting ? setting->get_name_id () : HB_OT_NAME_ID_INVALID; + return setting ? setting->get_name_id () : (hb_ot_name_id_t) HB_OT_NAME_ID_INVALID; } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -161,9 +161,9 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; - inline unsigned int get_features (unsigned int start_offset, - unsigned int *count, - hb_aat_layout_feature_type_t *features) const + inline unsigned int get_feature_types (unsigned int start_offset, + unsigned int *count, + hb_aat_layout_feature_type_t *features) const { unsigned int feature_count = featureNameCount; if (count && *count) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 0ba305aaf..71bb71a45 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -301,7 +301,7 @@ _hb_aat_language_get (hb_face_t *face, } /** - * hb_aat_layout_get_features: + * hb_aat_layout_get_feature_types: * @face: a face object * @start_offset: iteration's start offset * @count: (inout): buffer size as input, filled size as output @@ -312,16 +312,16 @@ _hb_aat_language_get (hb_face_t *face, * Since: REPLACEME */ unsigned int -hb_aat_layout_get_features (hb_face_t *face, - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) +hb_aat_layout_get_feature_types (hb_face_t *face, + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) { - return face->table.feat->get_features (start_offset, count, features); + return face->table.feat->get_feature_types (start_offset, count, features); } /** - * hb_aat_layout_feature_get_name_id: + * hb_aat_layout_feature_type_get_name_id: * @face: a face object * @feature: feature id * @@ -330,12 +330,12 @@ hb_aat_layout_get_features (hb_face_t *face, * Since: REPLACEME */ hb_ot_name_id_t -hb_aat_layout_feature_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature) +hb_aat_layout_feature_type_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature) { return face->table.feat->get_feature_name_id (feature); } /** - * hb_aat_layout_feature_get_selectors: + * hb_aat_layout_feature_type_get_selectors: * @face: a face object * @feature: feature id * @default_selector: (out): if is set, the feature is exclusive @@ -357,12 +357,12 @@ hb_aat_layout_feature_get_name_id (hb_face_t *face, * Since: REPLACEME */ unsigned int -hb_aat_layout_feature_get_selectors (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_selector_t *selectors /* OUT. May be NULL. */) +hb_aat_layout_feature_type_get_selectors (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_t *selectors /* OUT. May be NULL. */) { return face->table.feat->get_selectors (feature, default_selector, start_offset, count, selectors); diff --git a/src/hb-aat.h b/src/hb-aat.h index 9706470c8..26dfb5f60 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -417,26 +417,26 @@ typedef enum } hb_aat_layout_feature_selector_t; HB_EXTERN unsigned int -hb_aat_layout_get_features (hb_face_t *face, - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); +hb_aat_layout_get_feature_types (hb_face_t *face, + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); HB_EXTERN hb_ot_name_id_t -hb_aat_layout_feature_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature); +hb_aat_layout_feature_type_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature); HB_EXTERN unsigned int -hb_aat_layout_feature_get_selectors (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_selector_t *settings /* OUT. May be NULL. */); +hb_aat_layout_feature_type_get_selectors (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_t *settings /* OUT. May be NULL. */); HB_EXTERN hb_ot_name_id_t -hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, +hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature, hb_aat_layout_feature_selector_t selector); diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index c50494bee..8139f197d 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -34,19 +34,19 @@ static hb_face_t *face; static hb_face_t *sbix; static void -test_aat_get_features (void) +test_aat_get_feature_types (void) { hb_aat_layout_feature_type_t features[3]; unsigned int count = 3; - g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &count, features)); + g_assert_cmpuint (11, ==, hb_aat_layout_get_feature_types (face, 0, &count, features)); g_assert_cmpuint (1, ==, features[0]); g_assert_cmpuint (3, ==, features[1]); g_assert_cmpuint (6, ==, features[2]); - g_assert_cmpuint (258, ==, hb_aat_layout_feature_get_name_id (face, features[0])); - g_assert_cmpuint (261, ==, hb_aat_layout_feature_get_name_id (face, features[1])); - g_assert_cmpuint (265, ==, hb_aat_layout_feature_get_name_id (face, features[2])); + g_assert_cmpuint (258, ==, hb_aat_layout_feature_type_get_name_id (face, features[0])); + g_assert_cmpuint (261, ==, hb_aat_layout_feature_type_get_name_id (face, features[1])); + g_assert_cmpuint (265, ==, hb_aat_layout_feature_type_get_name_id (face, features[2])); } static void @@ -56,8 +56,8 @@ test_aat_get_feature_selectors (void) hb_aat_layout_feature_selector_t settings[3]; unsigned int count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, - &default_selector, 0, &count, settings)); + g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + &default_selector, 0, &count, settings)); g_assert_cmpuint (3, ==, count); g_assert_cmpuint (0, ==, default_selector); @@ -73,8 +73,8 @@ test_aat_get_feature_selectors (void) g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, - &default_selector, 3, &count, settings)); + g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + &default_selector, 3, &count, settings)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (0, ==, default_selector); @@ -82,8 +82,8 @@ test_aat_get_feature_selectors (void) g_assert_cmpuint (297, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); count = 1; - g_assert_cmpuint (1, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, - &default_selector, 0, &count, settings)); + g_assert_cmpuint (1, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + &default_selector, 0, &count, settings)); g_assert_cmpuint (1, ==, count); g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, ==, default_selector); @@ -91,8 +91,8 @@ test_aat_get_feature_selectors (void) g_assert_cmpuint (308, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); count = 100; - g_assert_cmpuint (0, ==, hb_aat_layout_feature_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, - NULL, 0, &count, settings)); + g_assert_cmpuint (0, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + NULL, 0, &count, settings)); g_assert_cmpuint (0, ==, count); g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, @@ -104,7 +104,7 @@ main (int argc, char **argv) { hb_test_init (&argc, &argv); - hb_test_add (test_aat_get_features); + hb_test_add (test_aat_get_feature_types); hb_test_add (test_aat_get_feature_selectors); face = hb_test_open_font_file ("fonts/aat-feat.ttf"); From 712762cabbbe85e6ab8361cd115c22a176827734 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 12:21:02 -0500 Subject: [PATCH 130/158] Minor --- src/hb-aat.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hb-aat.h b/src/hb-aat.h index 26dfb5f60..9eb88871e 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -30,8 +30,9 @@ HB_BEGIN_DECLS -/* - * AAT available features +/** + * hb_aat_layout_feature_type_t: + * * * Since: REPLACEME */ @@ -80,8 +81,9 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103 } hb_aat_layout_feature_type_t; -/* - * AAT available settings +/** + * hb_aat_layout_feature_selector_t: + * * * Since: REPLACEME */ From 2cb235d0210e74ea4ee123767b489301a9c340ab Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 12:23:35 -0500 Subject: [PATCH 131/158] [aat.feat] Fix enum namespace --- src/hb-aat-layout-feat-table.hh | 2 +- src/hb-aat-layout-morx-table.hh | 4 +- src/hb-aat-layout.cc | 150 +++++----- src/hb-aat.h | 502 ++++++++++++++++---------------- test/api/test-aat-layout.c | 2 +- 5 files changed, 330 insertions(+), 330 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index d30aceefe..41fa7da70 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -113,7 +113,7 @@ struct FeatureName unsigned int index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0; *default_selector = ((featureFlags & Exclusive) && index < settings_count) ? settings_table[index].get_selector () - : HB_AAT_LAYOUT_SELECTOR_INVALID; + : HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID; } return settings_count; } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 05936c3e1..171ee4a10 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -967,11 +967,11 @@ struct Chain flags &= feature.disableFlags; flags |= feature.enableFlags; } - else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS) + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE && setting == HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS) { /* Deprecated. https://github.com/harfbuzz/harfbuzz/issues/1342 */ type = HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE; - setting = HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS; + setting = HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS; goto retry; } } diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 71bb71a45..e25dcc8a8 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -44,82 +44,82 @@ * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = { - {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS}, - {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE}, - {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE}, - {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF}, - {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF}, - {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF}, - {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, - {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, - {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF}, - {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS}, - {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, - {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, - {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF}, - {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION}, - {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF}, - {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF}, - {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, - {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF}, - {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, - {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_ORDINALS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, - {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, - {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, - {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF}, - {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, - {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE}, - {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF}, - {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF}, - {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF}, - {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_OFF}, - {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_OFF}, - {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_OFF}, - {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_OFF}, - {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_OFF}, - {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_OFF}, - {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_OFF}, - {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF}, - {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_OFF}, - {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF}, - {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF}, - {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF}, - {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF}, - {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF}, - {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF}, - {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF}, - {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON, HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF}, - {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_INFERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, - {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION}, - {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF}, - {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS}, - {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, - {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, - {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('a','f','r','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS}, + {HB_TAG ('c','2','p','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE}, + {HB_TAG ('c','2','s','c'), HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE}, + {HB_TAG ('c','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF}, + {HB_TAG ('c','a','s','e'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF}, + {HB_TAG ('c','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF}, + {HB_TAG ('c','p','s','p'), HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF}, + {HB_TAG ('c','s','w','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF}, + {HB_TAG ('d','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF}, + {HB_TAG ('e','x','p','t'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('f','r','a','c'), HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS}, + {HB_TAG ('f','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('h','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('h','i','s','t'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF}, + {HB_TAG ('h','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF}, + {HB_TAG ('h','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF}, + {HB_TAG ('h','n','g','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION, HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION}, + {HB_TAG ('h','o','j','o'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('h','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('i','t','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN, HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF}, + {HB_TAG ('j','p','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','7','8'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','8','3'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('j','p','9','0'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('l','i','g','a'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF}, + {HB_TAG ('l','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, + {HB_TAG ('m','g','r','k'), HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF}, + {HB_TAG ('n','l','c','k'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('o','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS, (hb_aat_layout_feature_selector_t) 2}, + {HB_TAG ('o','r','d','n'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('p','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('p','c','a','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, + {HB_TAG ('p','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, + {HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF}, + {HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE}, + {HB_TAG ('s','m','p','l'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('s','s','0','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF}, + {HB_TAG ('s','s','0','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF}, + {HB_TAG ('s','s','0','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF}, + {HB_TAG ('s','s','0','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF}, + {HB_TAG ('s','s','0','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF}, + {HB_TAG ('s','s','0','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF}, + {HB_TAG ('s','s','0','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF}, + {HB_TAG ('s','s','0','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF}, + {HB_TAG ('s','s','0','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF}, + {HB_TAG ('s','s','1','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF}, + {HB_TAG ('s','s','1','1'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF}, + {HB_TAG ('s','s','1','2'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF}, + {HB_TAG ('s','s','1','3'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF}, + {HB_TAG ('s','s','1','4'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF}, + {HB_TAG ('s','s','1','5'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF}, + {HB_TAG ('s','s','1','6'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF}, + {HB_TAG ('s','s','1','7'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF}, + {HB_TAG ('s','s','1','8'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF}, + {HB_TAG ('s','s','1','9'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF}, + {HB_TAG ('s','s','2','0'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF}, + {HB_TAG ('s','u','b','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','u','p','s'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION}, + {HB_TAG ('s','w','s','h'), HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF}, + {HB_TAG ('t','i','t','l'), HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS, HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS}, + {HB_TAG ('t','n','a','m'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('t','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS, (hb_aat_layout_feature_selector_t) 4}, + {HB_TAG ('t','r','a','d'), HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS, (hb_aat_layout_feature_selector_t) 16}, + {HB_TAG ('t','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, {HB_TAG ('u','n','i','c'), HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE, (hb_aat_layout_feature_selector_t) 14, (hb_aat_layout_feature_selector_t) 15}, - {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, - {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF}, - {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, - {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, - {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF}, + {HB_TAG ('v','a','l','t'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('v','e','r','t'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, + {HB_TAG ('v','h','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('v','k','n','a'), HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF}, + {HB_TAG ('v','p','a','l'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7}, + {HB_TAG ('v','r','t','2'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF}, + {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF}, }; const hb_aat_feature_mapping_t * diff --git a/src/hb-aat.h b/src/hb-aat.h index 9eb88871e..b6c58017b 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -89,333 +89,333 @@ typedef enum */ typedef enum { - HB_AAT_LAYOUT_SELECTOR_INVALID = 0xFFFF, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID = 0xFFFF, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */ - HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ - HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_REQUIRED_LIGATURES_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_ON = 2, - HB_AAT_LAYOUT_SELECTOR_COMMON_LIGATURES_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_RARE_LIGATURES_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_LOGOS_ON = 6, - HB_AAT_LAYOUT_SELECTOR_LOGOS_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_ON = 8, - HB_AAT_LAYOUT_SELECTOR_REBUS_PICTURES_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, - HB_AAT_LAYOUT_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, - HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_ON = 12, - HB_AAT_LAYOUT_SELECTOR_SQUARED_LIGATURES_OFF = 13, - HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, - HB_AAT_LAYOUT_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, - HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_ON = 16, - HB_AAT_LAYOUT_SELECTOR_SYMBOL_LIGATURES_OFF = 17, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, - HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_ON = 20, - HB_AAT_LAYOUT_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON = 16, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF = 17, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON = 20, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ - HB_AAT_LAYOUT_SELECTOR_UNCONNECTED = 0, - HB_AAT_LAYOUT_SELECTOR_PARTIALLY_CONNECTED = 1, - HB_AAT_LAYOUT_SELECTOR_CURSIVE = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */ - HB_AAT_LAYOUT_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_ALL_CAPS = 1, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_SMALL_CAPS = 3, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ - HB_AAT_LAYOUT_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS = 1, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS = 3, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */ - HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, - HB_AAT_LAYOUT_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */ - HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, - HB_AAT_LAYOUT_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING */ - HB_AAT_LAYOUT_SELECTOR_MONOSPACED_NUMBERS = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_NUMBERS = 1, - HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_NUMBERS = 2, - HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE */ - HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_ON = 2, - HB_AAT_LAYOUT_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_ON = 6, - HB_AAT_LAYOUT_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_ON = 8, - HB_AAT_LAYOUT_SELECTOR_NON_FINAL_SWASHES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF = 9, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE */ - HB_AAT_LAYOUT_SELECTOR_SHOW_DIACRITICS = 0, - HB_AAT_LAYOUT_SELECTOR_HIDE_DIACRITICS = 1, - HB_AAT_LAYOUT_SELECTOR_DECOMPOSE_DIACRITICS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION */ - HB_AAT_LAYOUT_SELECTOR_NORMAL_POSITION = 0, - HB_AAT_LAYOUT_SELECTOR_SUPERIORS = 1, - HB_AAT_LAYOUT_SELECTOR_INFERIORS = 2, - HB_AAT_LAYOUT_SELECTOR_ORDINALS = 3, - HB_AAT_LAYOUT_SELECTOR_SCIENTIFIC_INFERIORS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS = 4, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS */ - HB_AAT_LAYOUT_SELECTOR_NO_FRACTIONS = 0, - HB_AAT_LAYOUT_SELECTOR_VERTICAL_FRACTIONS = 1, - HB_AAT_LAYOUT_SELECTOR_DIAGONAL_FRACTIONS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */ - HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_ON = 0, - HB_AAT_LAYOUT_SELECTOR_PREVENT_OVERLAP_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */ - HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, - HB_AAT_LAYOUT_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_ON = 4, - HB_AAT_LAYOUT_SELECTOR_SLASHED_ZERO_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_ON = 6, - HB_AAT_LAYOUT_SELECTOR_FORM_INTERROBANG_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_ON = 8, - HB_AAT_LAYOUT_SELECTOR_SMART_QUOTES_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, - HB_AAT_LAYOUT_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS */ - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_ON = 0, - HB_AAT_LAYOUT_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, - HB_AAT_LAYOUT_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_ON = 4, - HB_AAT_LAYOUT_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_ON = 6, - HB_AAT_LAYOUT_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_EXPONENTS_ON = 8, - HB_AAT_LAYOUT_SELECTOR_EXPONENTS_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_ON = 10, - HB_AAT_LAYOUT_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE */ - HB_AAT_LAYOUT_SELECTOR_NO_ORNAMENTS = 0, - HB_AAT_LAYOUT_SELECTOR_DINGBATS = 1, - HB_AAT_LAYOUT_SELECTOR_PI_CHARACTERS = 2, - HB_AAT_LAYOUT_SELECTOR_FLEURONS = 3, - HB_AAT_LAYOUT_SELECTOR_DECORATIVE_BORDERS = 4, - HB_AAT_LAYOUT_SELECTOR_INTERNATIONAL_SYMBOLS = 5, - HB_AAT_LAYOUT_SELECTOR_MATH_SYMBOLS = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS = 6, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES */ - HB_AAT_LAYOUT_SELECTOR_NO_ALTERNATES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES = 0, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */ - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL1 = 0, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL2 = 1, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL3 = 2, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL4 = 3, - HB_AAT_LAYOUT_SELECTOR_DESIGN_LEVEL5 = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1 = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2 = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3 = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4 = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5 = 4, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS */ - HB_AAT_LAYOUT_SELECTOR_NO_STYLE_OPTIONS = 0, - HB_AAT_LAYOUT_SELECTOR_DISPLAY_TEXT = 1, - HB_AAT_LAYOUT_SELECTOR_ENGRAVED_TEXT = 2, - HB_AAT_LAYOUT_SELECTOR_ILLUMINATED_CAPS = 3, - HB_AAT_LAYOUT_SELECTOR_TITLING_CAPS = 4, - HB_AAT_LAYOUT_SELECTOR_TALL_CAPS = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS = 5, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE */ - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_CHARACTERS = 0, - HB_AAT_LAYOUT_SELECTOR_SIMPLIFIED_CHARACTERS = 1, - HB_AAT_LAYOUT_SELECTOR_JIS1978_CHARACTERS = 2, - HB_AAT_LAYOUT_SELECTOR_JIS1983_CHARACTERS = 3, - HB_AAT_LAYOUT_SELECTOR_JIS1990_CHARACTERS = 4, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_ONE = 5, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_TWO = 6, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_THREE = 7, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FOUR = 8, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_ALT_FIVE = 9, - HB_AAT_LAYOUT_SELECTOR_EXPERT_CHARACTERS = 10, - HB_AAT_LAYOUT_SELECTOR_JIS2004_CHARACTERS = 11, - HB_AAT_LAYOUT_SELECTOR_HOJO_CHARACTERS = 12, - HB_AAT_LAYOUT_SELECTOR_NLCCHARACTERS = 13, - HB_AAT_LAYOUT_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE */ - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_NUMBERS = 0, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_NUMBERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING */ - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_TEXT = 0, - HB_AAT_LAYOUT_SELECTOR_MONOSPACED_TEXT = 1, - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_TEXT = 2, - HB_AAT_LAYOUT_SELECTOR_THIRD_WIDTH_TEXT = 3, - HB_AAT_LAYOUT_SELECTOR_QUARTER_WIDTH_TEXT = 4, - HB_AAT_LAYOUT_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, - HB_AAT_LAYOUT_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION */ - HB_AAT_LAYOUT_SELECTOR_NO_TRANSLITERATION = 0, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL = 1, - HB_AAT_LAYOUT_SELECTOR_HIRAGANA_TO_KATAKANA = 2, - HB_AAT_LAYOUT_SELECTOR_KATAKANA_TO_HIRAGANA = 3, - HB_AAT_LAYOUT_SELECTOR_KANA_TO_ROMANIZATION = 4, - HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, - HB_AAT_LAYOUT_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, - HB_AAT_LAYOUT_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE */ - HB_AAT_LAYOUT_SELECTOR_NO_ANNOTATION = 0, - HB_AAT_LAYOUT_SELECTOR_BOX_ANNOTATION = 1, - HB_AAT_LAYOUT_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, - HB_AAT_LAYOUT_SELECTOR_CIRCLE_ANNOTATION = 3, - HB_AAT_LAYOUT_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, - HB_AAT_LAYOUT_SELECTOR_PARENTHESIS_ANNOTATION = 5, - HB_AAT_LAYOUT_SELECTOR_PERIOD_ANNOTATION = 6, - HB_AAT_LAYOUT_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, - HB_AAT_LAYOUT_SELECTOR_DIAMOND_ANNOTATION = 8, - HB_AAT_LAYOUT_SELECTOR_INVERTED_BOX_ANNOTATION = 9, - HB_AAT_LAYOUT_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE */ - HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_KANA = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_KANA = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */ - HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */ - HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_ON = 0, - HB_AAT_LAYOUT_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, - HB_AAT_LAYOUT_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, - HB_AAT_LAYOUT_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA */ - HB_AAT_LAYOUT_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF instead */ - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON instead */ - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_ON = 2, - HB_AAT_LAYOUT_SELECTOR_RUBY_KANA_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF = 3, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */ - HB_AAT_LAYOUT_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, - HB_AAT_LAYOUT_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */ - HB_AAT_LAYOUT_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, - HB_AAT_LAYOUT_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */ - HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, - HB_AAT_LAYOUT_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN */ - HB_AAT_LAYOUT_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, - HB_AAT_LAYOUT_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */ - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, - HB_AAT_LAYOUT_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA */ - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, - HB_AAT_LAYOUT_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES */ - HB_AAT_LAYOUT_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, - HB_AAT_LAYOUT_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */ - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, - HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_ON = 2, - HB_AAT_LAYOUT_SELECTOR_SWASH_ALTERNATES_OFF = 3, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, - HB_AAT_LAYOUT_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE */ - HB_AAT_LAYOUT_SELECTOR_DEFAULT_LOWER_CASE = 0, - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE */ - HB_AAT_LAYOUT_SELECTOR_DEFAULT_UPPER_CASE = 0, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */ - HB_AAT_LAYOUT_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, - HB_AAT_LAYOUT_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, - HB_AAT_LAYOUT_SELECTOR_DEFAULT_CJK_ROMAN = 2, - HB_AAT_LAYOUT_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 } hb_aat_layout_feature_selector_t; HB_EXTERN unsigned int diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 8139f197d..516b46191 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -70,7 +70,7 @@ test_aat_get_feature_selectors (void) g_assert_cmpuint (2, ==, settings[2]); g_assert_cmpuint (296, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_SELECTOR_INVALID)); + g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID)); count = 3; g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, From b206133d1f616339a57996b634dadc7f0a2c4cfb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 23 Nov 2018 14:05:11 -0500 Subject: [PATCH 132/158] [aat] Move contents of hb-aat.h to hb-aat-layout.h Since it was pages and pages... --- src/Makefile.sources | 1 + src/hb-aat-layout.cc | 1 - src/hb-aat-layout.h | 452 +++++++++++++++++++++++++++++++++++++++++++ src/hb-aat-layout.hh | 1 - src/hb-aat-map.hh | 1 - src/hb-aat.h | 417 +-------------------------------------- src/hb.hh | 2 + 7 files changed, 458 insertions(+), 417 deletions(-) create mode 100644 src/hb-aat-layout.h diff --git a/src/Makefile.sources b/src/Makefile.sources index c5925b9b0..ba90ef022 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -182,6 +182,7 @@ HB_OT_RAGEL_sources = \ HB_OT_headers = \ hb-aat.h \ + hb-aat-layout.h \ hb-ot.h \ hb-ot-color.h \ hb-ot-font.h \ diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index e25dcc8a8..75545adbc 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -28,7 +28,6 @@ #include "hb-open-type.hh" #include "hb-ot-face.hh" -#include "hb-aat.h" #include "hb-aat-layout.hh" #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h new file mode 100644 index 000000000..f72cf79fe --- /dev/null +++ b/src/hb-aat-layout.h @@ -0,0 +1,452 @@ +/* + * 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_AAT_H_IN +#error "Include instead." +#endif + +#ifndef HB_AAT_LAYOUT_H +#define HB_AAT_LAYOUT_H + +#include "hb.h" + +#include "hb-ot.h" + +HB_BEGIN_DECLS + +/** + * hb_aat_layout_feature_type_t: + * + * + * Since: REPLACEME + */ +typedef enum +{ + HB_AAT_LAYOUT_FEATURE_TYPE_INVALID = 0xFFFF, + + HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, + HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, + HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, + HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, + HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, + HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8, + HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9, + HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, + HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, + HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, + HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, + HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, + HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, + HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, + HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, + HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, + HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24, + HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26, + HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27, + HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29, + HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31, + HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, + HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, + HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, + HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, + HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, + HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, + HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, + HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103 +} hb_aat_layout_feature_type_t; + +/** + * hb_aat_layout_feature_selector_t: + * + * + * Since: REPLACEME + */ +typedef enum +{ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID = 0xFFFF, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON = 16, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF = 17, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON = 20, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS = 1, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS = 3, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF = 9, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS = 4, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS = 6, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES = 0, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1 = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2 = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3 = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4 = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5 = 4, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, + HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF = 3, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, + HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, + + /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */ + HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, + HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, + HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2, + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 +} hb_aat_layout_feature_selector_t; + +HB_EXTERN unsigned int +hb_aat_layout_get_feature_types (hb_face_t *face, + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); + +HB_EXTERN hb_ot_name_id_t +hb_aat_layout_feature_type_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature); + + +HB_EXTERN unsigned int +hb_aat_layout_feature_type_get_selectors (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ + unsigned int start_offset, + unsigned int *count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_t *settings /* OUT. May be NULL. */); + +HB_EXTERN hb_ot_name_id_t +hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, + hb_aat_layout_feature_type_t feature, + hb_aat_layout_feature_selector_t selector); + +HB_END_DECLS + +#endif /* HB_AAT_LAYOUT_H */ diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index d56402029..5fd47ed62 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -29,7 +29,6 @@ #include "hb.hh" -#include "hb-aat.h" #include "hb-ot-shape.hh" diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index 1352bd325..b033e3368 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -28,7 +28,6 @@ #define HB_AAT_MAP_HH #include "hb.hh" -#include "hb-aat.h" struct hb_aat_map_t diff --git a/src/hb-aat.h b/src/hb-aat.h index b6c58017b..6bba931fa 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -24,424 +24,13 @@ #ifndef HB_AAT_H #define HB_AAT_H +#define HB_AAT_H_IN -#include "hb.h" -#include "hb-ot.h" +#include "hb-aat-layout.h" HB_BEGIN_DECLS -/** - * hb_aat_layout_feature_type_t: - * - * - * Since: REPLACEME - */ -typedef enum -{ - HB_AAT_LAYOUT_FEATURE_TYPE_INVALID = 0xFFFF, - - HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC = 0, - HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES = 1, - HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION = 2, - HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE = 3, - HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION = 4, - HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT = 5, - HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING = 6, - HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE = 8, - HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE = 9, - HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION = 10, - HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS = 11, - HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE = 13, - HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS = 14, - HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS = 15, - HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE = 16, - HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES = 17, - HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE = 18, - HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS = 19, - HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE = 20, - HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE = 21, - HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING = 22, - HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION = 23, - HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE = 24, - HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE = 25, - HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE = 26, - HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE = 27, - HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA = 28, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE = 29, - HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE = 30, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE = 31, - HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN = 32, - HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT = 33, - HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA = 34, - HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES = 35, - HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES = 36, - HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, - HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, - HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103 -} hb_aat_layout_feature_type_t; - -/** - * hb_aat_layout_feature_selector_t: - * - * - * Since: REPLACEME - */ -typedef enum -{ - HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID = 0xFFFF, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_COMMON_LIGATURES_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_RARE_LIGATURES_OFF = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_ON = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LOGOS_OFF = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_ON = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_REBUS_PICTURES_OFF = 9, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON = 10, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF = 11, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_ON = 12, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SQUARED_LIGATURES_OFF = 13, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON = 14, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF = 15, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_ON = 16, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF = 17, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON = 18, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF = 19, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON = 20, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF = 21, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_UNCONNECTED = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PARTIALLY_CONNECTED = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CURSIVE = 2, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_AND_LOWER_CASE = 0, /* deprecated */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_CAPS = 1, /* deprecated */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALL_LOWER_CASE = 2, /* deprecated */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_SMALL_CAPS = 3, /* deprecated */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS = 4, /* deprecated */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS = 5, /* deprecated */ - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_NUMBERS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS = 3, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_ON = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF = 9, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_SHOW_DIACRITICS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HIDE_DIACRITICS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DECOMPOSE_DIACRITICS = 2, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SUPERIORS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INFERIORS = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ORDINALS = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS = 4, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_FRACTIONS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_VERTICAL_FRACTIONS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAGONAL_FRACTIONS = 2, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PREVENT_OVERLAP_OFF = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_ON = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_FORM_INTERROBANG_OFF = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_ON = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SMART_QUOTES_OFF = 9, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON = 10, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF = 11, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_ON = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPONENTS_OFF = 9, - HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON = 10, - HB_AAT_LAYOUT_FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF = 11, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ORNAMENTS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DINGBATS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PI_CHARACTERS = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_FLEURONS = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DECORATIVE_BORDERS = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_MATH_SYMBOLS = 6, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ALTERNATES = 0, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL1 = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL2 = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL3 = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL4 = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DESIGN_LEVEL5 = 4, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLE_OPTIONS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DISPLAY_TEXT = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ENGRAVED_TEXT = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ILLUMINATED_CAPS = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TITLING_CAPS = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TALL_CAPS = 5, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_CHARACTERS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1978_CHARACTERS = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1983_CHARACTERS = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS1990_CHARACTERS = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_ONE = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_TWO = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_THREE = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE = 9, - HB_AAT_LAYOUT_FEATURE_SELECTOR_EXPERT_CHARACTERS = 10, - HB_AAT_LAYOUT_FEATURE_SELECTOR_JIS2004_CHARACTERS = 11, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HOJO_CHARACTERS = 12, - HB_AAT_LAYOUT_FEATURE_SELECTOR_NLCCHARACTERS = 13, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS = 14, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_NUMBERS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_NUMBERS = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_MONOSPACED_TEXT = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_TEXT = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_THIRD_WIDTH_TEXT = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT = 6, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_TRANSLITERATION = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_KANA_TO_ROMANIZATION = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE = 9, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_ANNOTATION = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_BOX_ANNOTATION = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CIRCLE_ANNOTATION = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PARENTHESIS_ANNOTATION = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PERIOD_ANNOTATION = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DIAMOND_ANNOTATION = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION = 9, - HB_AAT_LAYOUT_FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION= 10, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_KANA = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_KANA = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS = 2, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF = 5, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_RUBY_KANA = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF instead */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON instead */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF = 3, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE = 5, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE = 5, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE = 1, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN = 0, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN = 1, /* deprecated - use HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF = 3, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF = 3, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF = 3, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF = 5, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON = 6, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF = 7, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON = 8, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF = 9, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON = 10, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF = 11, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON = 12, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF = 13, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON = 14, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF = 15, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON = 16, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF = 17, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON = 18, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF = 19, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON = 20, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF = 21, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON = 22, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF = 23, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON = 24, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF = 25, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON = 26, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF = 27, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON = 28, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF = 29, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON = 30, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF = 31, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON = 32, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF = 33, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON = 34, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF = 35, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON = 36, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF = 37, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON = 38, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF = 39, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON = 40, - HB_AAT_LAYOUT_FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF = 41, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_ON = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_SWASH_ALTERNATES_OFF = 3, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON = 4, - HB_AAT_LAYOUT_FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF= 5, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS = 2, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_UPPER_CASE = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS = 2, - - /* Selectors for #HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */ - HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, - HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, - HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 -} hb_aat_layout_feature_selector_t; - -HB_EXTERN unsigned int -hb_aat_layout_get_feature_types (hb_face_t *face, - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); - -HB_EXTERN hb_ot_name_id_t -hb_aat_layout_feature_type_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature); - - -HB_EXTERN unsigned int -hb_aat_layout_feature_type_get_selectors (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_selector_t *settings /* OUT. May be NULL. */); - -HB_EXTERN hb_ot_name_id_t -hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t selector); - HB_END_DECLS +#undef HB_AAT_H_IN #endif /* HB_AAT_H */ diff --git a/src/hb.hh b/src/hb.hh index 467af966b..6df0a55b1 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -47,6 +47,8 @@ #define HB_H_IN #include "hb-ot.h" #define HB_OT_H_IN +#include "hb-aat.h" +#define HB_AAT_H_IN #include "hb-aat.h" From 44b9331f663c09174d94e06baf36d48a50599c42 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:30:35 -0500 Subject: [PATCH 133/158] [aat] Fix include issues --- src/Makefile.am | 2 ++ src/hb-aat.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index b3cc42f3f..c726cf2a6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -424,6 +424,8 @@ HarfBuzz_0_0_gir_CFLAGS = \ -DHB_H_IN \ -DHB_OT_H \ -DHB_OT_H_IN \ + -DHB_AAT_H \ + -DHB_AAT_H_IN \ -DHB_GOBJECT_H \ -DHB_GOBJECT_H_IN \ -DHB_EXTERN= \ diff --git a/src/hb-aat.h b/src/hb-aat.h index 6bba931fa..c14313d1e 100644 --- a/src/hb-aat.h +++ b/src/hb-aat.h @@ -26,6 +26,8 @@ #define HB_AAT_H #define HB_AAT_H_IN +#include "hb.h" + #include "hb-aat-layout.h" HB_BEGIN_DECLS From 52ae9867efd6520d17306b9f3ad612fe5463e93d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:46:56 -0500 Subject: [PATCH 134/158] [AAT.feat] Use lsearch for looking up SettingName's They are not sorted. --- src/hb-aat-layout-feat-table.hh | 18 ++++++------------ src/hb-open-type.hh | 16 ++++++++-------- src/hb-static.cc | 8 +++++--- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 41fa7da70..899a9b9b6 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -39,12 +39,10 @@ namespace AAT { struct SettingName { - static int cmp (const void *key_, const void *entry_) + int cmp (hb_aat_layout_feature_selector_t key) const { - hb_aat_layout_feature_selector_t key = * (hb_aat_layout_feature_selector_t *) key_; - const SettingName * entry = (const SettingName *) entry_; - return key < entry->setting ? -1 : - key > entry->setting ? +1 : + return key < setting ? -1 : + key > setting ? +1 : 0; } @@ -65,6 +63,7 @@ struct SettingName public: DEFINE_SIZE_STATIC (4); }; +DECLARE_NULL_NAMESPACE_BYTES (AAT, SettingName); struct feat; @@ -123,15 +122,10 @@ struct FeatureName inline hb_ot_name_id_t get_feature_name_id () const { return nameIndex; } - inline hb_ot_name_id_t get_feature_selector_name_id (const feat *feat, + inline hb_ot_name_id_t get_feature_selector_name_id (const feat *feat, hb_aat_layout_feature_selector_t key) const { - const SettingName* setting = (SettingName*) hb_bsearch (&key, feat+settingTableZ, - nSettings, - SettingName::static_size, - SettingName::cmp); - - return setting ? setting->get_name_id () : (hb_ot_name_id_t) HB_OT_NAME_ID_INVALID; + return (feat+settingTableZ).lsearch (nSettings, key).get_name_id (); } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9b412dbce..f4d0238ea 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -376,11 +376,11 @@ struct UnsizedArrayOf { return hb_array (arrayZ, len); } template - inline Type &lsearch (unsigned int len, const T &x) - { return *as_array (len).lsearch (x, &Crap (T)); } + inline Type &lsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) + { return *as_array (len).lsearch (x, ¬_found); } template - inline const Type &lsearch (unsigned int len, const T &x) const - { return *as_array (len).lsearch (x, &Null (T)); } + inline const Type &lsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const + { return *as_array (len).lsearch (x, ¬_found); } inline void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array (len).qsort (start, end); } @@ -589,11 +589,11 @@ struct ArrayOf } template - inline Type &lsearch (const T &x) - { return *as_array ().lsearch (x, &Crap (T)); } + inline Type &lsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().lsearch (x, ¬_found); } template - inline const Type &lsearch (const T &x) const - { return *as_array ().lsearch (x, &Null (T)); } + inline const Type &lsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().lsearch (x, ¬_found); } inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array ().qsort (start, end); } diff --git a/src/hb-static.cc b/src/hb-static.cc index 3ea640246..a22f729ef 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -27,10 +27,11 @@ #include "hb.hh" #include "hb-open-type.hh" -#include "hb-aat-layout-common.hh" -#include "hb-ot-layout-common.hh" - #include "hb-face.hh" + +#include "hb-aat-layout-common.hh" +#include "hb-aat-layout-feat-table.hh" +#include "hb-ot-layout-common.hh" #include "hb-ot-cmap-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" @@ -44,6 +45,7 @@ DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; +DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF}; /* Hand-coded because Lookup is a template. Sad. */ const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; From c2256068339c9e10c8e6df5d1749be4b4eb04ad4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 10:54:40 -0500 Subject: [PATCH 135/158] [aat.feat] Port to SortedUnsizedArrayOf.bsearch() --- src/hb-aat-layout-feat-table.hh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 899a9b9b6..ab7483fda 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -69,12 +69,10 @@ struct feat; struct FeatureName { - static int cmp (const void *key_, const void *entry_) + int cmp (hb_aat_layout_feature_type_t key) const { - hb_aat_layout_feature_selector_t key = * (hb_aat_layout_feature_selector_t *) key_; - const FeatureName * entry = (const FeatureName *) entry_; - return key < entry->feature ? -1 : - key > entry->feature ? +1 : + return key < feature ? -1 : + key > feature ? +1 : 0; } @@ -155,6 +153,8 @@ struct feat { static const hb_tag_t tableTag = HB_AAT_TAG_feat; + inline bool has_data (void) const { return version.to_int (); } + inline unsigned int get_feature_types (unsigned int start_offset, unsigned int *count, hb_aat_layout_feature_type_t *features) const @@ -172,12 +172,7 @@ struct feat inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const { - const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &namesZ, - featureNameCount, - FeatureName::static_size, - FeatureName::cmp); - - return feature ? *feature : Null (FeatureName); + return namesZ.bsearch (featureNameCount, key); } inline hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const @@ -211,7 +206,7 @@ struct feat /* The number of entries in the feature name array. */ HBUINT16 reserved1; /* Reserved (set to zero). */ HBUINT32 reserved2; /* Reserved (set to zero). */ - UnsizedArrayOf + SortedUnsizedArrayOf namesZ; /* The feature name array. */ public: DEFINE_SIZE_STATIC (24); From 0f8e98eca2463da3b83d1b66a19259a584df1682 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 11:00:42 -0500 Subject: [PATCH 136/158] [aat.feat] Whitespace --- src/hb-aat-layout-feat-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index ab7483fda..155b6c85f 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -77,14 +77,14 @@ struct FeatureName } enum { - Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ - NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in + Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ + NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in * the setting name array for this feature should * be taken as the default for the feature * (if one is required). If set, then bits 0-15 of this * featureFlags field contain the index of the setting * which is to be taken as the default. */ - IndexMask = 0x00FF /* If bits 30 and 31 are set, then these sixteen bits + IndexMask = 0x00FF /* If bits 30 and 31 are set, then these sixteen bits * indicate the index of the setting in the setting name * array for this feature which should be taken * as the default. */ From 3922aae1620958768d3257c0988432d5609dca1b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 11:02:04 -0500 Subject: [PATCH 137/158] [aat.feat] Minor --- src/hb-aat-layout-feat-table.hh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 155b6c85f..98d628693 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -40,11 +40,7 @@ namespace AAT { struct SettingName { int cmp (hb_aat_layout_feature_selector_t key) const - { - return key < setting ? -1 : - key > setting ? +1 : - 0; - } + { return (int) key - (int) setting; } inline hb_aat_layout_feature_selector_t get_selector () const { return (hb_aat_layout_feature_selector_t) (unsigned int) setting; } @@ -70,11 +66,7 @@ struct feat; struct FeatureName { int cmp (hb_aat_layout_feature_type_t key) const - { - return key < feature ? -1 : - key > feature ? +1 : - 0; - } + { return (int) key - (int) feature; } enum { Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ From 84dacbca7ea54a3ca2d5d711d50272a7f3baf456 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 24 Nov 2018 12:08:36 -0500 Subject: [PATCH 138/158] [aat.feat] Add _MAX_VALUE to enums --- src/hb-aat-layout.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h index f72cf79fe..8bd4af27d 100644 --- a/src/hb-aat-layout.h +++ b/src/hb-aat-layout.h @@ -83,7 +83,9 @@ typedef enum HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE = 37, HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE = 38, HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39, - HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103 + HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103, + + _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ } hb_aat_layout_feature_type_t; /** @@ -420,7 +422,9 @@ typedef enum HB_AAT_LAYOUT_FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN = 0, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN = 1, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2, - HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3 + HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3, + + _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/ } hb_aat_layout_feature_selector_t; HB_EXTERN unsigned int From 926f512f354835f8323bb2c2e58789dd918a9b65 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 01:14:40 -0500 Subject: [PATCH 139/158] [aat.feat] Rework API and implementation Fixes https://github.com/harfbuzz/harfbuzz/pull/1346 --- docs/harfbuzz-docs.xml | 5 ++ docs/harfbuzz-sections.txt | 7 +-- src/hb-aat-layout-feat-table.hh | 89 ++++++++++++++++++--------------- src/hb-aat-layout.cc | 80 +++++++++++++---------------- src/hb-aat-layout.h | 32 +++++++----- test/api/test-aat-layout.c | 58 ++++++++++----------- 6 files changed, 141 insertions(+), 130 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 66a64d8f9..27353389d 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -112,6 +112,11 @@ + + Apple Advanced Typography API + + + Integration API diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 0498a2790..5c45153c3 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -4,13 +4,14 @@ HB_OT_H_IN
-hb-aat +hb-aat-layout +HB_AAT_LAYOUT_NO_SELECTOR_INDEX hb_aat_layout_feature_type_t hb_aat_layout_get_feature_types hb_aat_layout_feature_type_get_name_id hb_aat_layout_feature_selector_t -hb_aat_layout_feature_type_get_selectors -hb_aat_layout_feature_selector_get_name_id +hb_aat_layout_feature_selector_info_t +hb_aat_layout_feature_type_get_selector_infos
diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index 98d628693..4e63ec8e8 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -39,13 +39,26 @@ namespace AAT { struct SettingName { + friend struct FeatureName; + int cmp (hb_aat_layout_feature_selector_t key) const { return (int) key - (int) setting; } - inline hb_aat_layout_feature_selector_t get_selector () const - { return (hb_aat_layout_feature_selector_t) (unsigned int) setting; } + inline hb_aat_layout_feature_selector_t get_selector (void) const + { return (hb_aat_layout_feature_selector_t) (unsigned) setting; } - inline hb_ot_name_id_t get_name_id () const { return nameIndex; } + inline void get_info (hb_aat_layout_feature_selector_info_t *s, + hb_aat_layout_feature_selector_t default_selector) const + { + s->name_id = nameIndex; + + s->enable = (hb_aat_layout_feature_selector_t) (unsigned int) setting; + s->disable = default_selector == HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID ? + (hb_aat_layout_feature_selector_t) (s->enable + 1) : + default_selector; + + s->reserved = 0; + } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -82,29 +95,34 @@ struct FeatureName * as the default. */ }; - inline unsigned int get_selectors (const feat *feat, - hb_aat_layout_feature_selector_t *default_selector, - unsigned int start_offset, - unsigned int *count, - hb_aat_layout_feature_selector_t *selectors) const + inline unsigned int get_selector_infos (unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *pdefault_index, /* OUT. May be NULL. */ + const void *base) const { - const UnsizedArrayOf& settings_table = feat+settingTableZ; - unsigned int settings_count = nSettings; - if (count && *count) + hb_array_t< const SettingName> settings_table = (base+settingTableZ).as_array (nSettings); + + static_assert (Index::NOT_FOUND_INDEX == HB_AAT_LAYOUT_NO_SELECTOR_INDEX, ""); + + hb_aat_layout_feature_selector_t default_selector = HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID; + unsigned int default_index = Index::NOT_FOUND_INDEX; + if (featureFlags & Exclusive) { - unsigned int len = MIN (settings_count - start_offset, *count); - for (unsigned int i = 0; i < len; i++) - selectors[i] = settings_table[start_offset + i].get_selector (); - *count = len; + default_index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0; + default_selector = settings_table[default_index].get_selector (); } - if (default_selector) + if (pdefault_index) + *pdefault_index = default_index; + + if (selectors_count) { - unsigned int index = (featureFlags & NotDefault) ? featureFlags & IndexMask : 0; - *default_selector = ((featureFlags & Exclusive) && index < settings_count) - ? settings_table[index].get_selector () - : HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID; + hb_array_t arr = settings_table.sub_array (start_offset, selectors_count); + unsigned int count = arr.len; + for (unsigned int i = 0; i < count; i++) + settings_table[start_offset + i].get_info (&selectors[i], default_selector); } - return settings_count; + return settings_table.len; } inline hb_aat_layout_feature_type_t get_feature_type () const @@ -112,12 +130,6 @@ struct FeatureName inline hb_ot_name_id_t get_feature_name_id () const { return nameIndex; } - inline hb_ot_name_id_t get_feature_selector_name_id (const feat *feat, - hb_aat_layout_feature_selector_t key) const - { - return (feat+settingTableZ).lsearch (nSettings, key).get_name_id (); - } - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -162,32 +174,29 @@ struct feat return featureNameCount; } - inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const + inline const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const { - return namesZ.bsearch (featureNameCount, key); + return namesZ.bsearch (featureNameCount, feature_type); } inline hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const { return get_feature (feature).get_feature_name_id (); } - inline hb_ot_name_id_t get_feature_selector_name_id (hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t selector) const - { return get_feature (feature).get_feature_selector_name_id (this, selector); } - - inline unsigned int get_selectors (hb_aat_layout_feature_type_t key, - hb_aat_layout_feature_selector_t *default_selector, - unsigned int start_offset, - unsigned int *count, - hb_aat_layout_feature_selector_t *selectors) const + inline unsigned int get_selector_infos (hb_aat_layout_feature_type_t feature_type, + unsigned int start_offset, + unsigned int *selectors_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *default_index /* OUT. May be NULL. */) const { - return get_feature (key).get_selectors (this, default_selector, start_offset, - count, selectors); + return get_feature (feature_type).get_selector_infos (start_offset, selectors_count, selectors, + default_index, this); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && + version.major == 1 && namesZ.sanitize (c, featureNameCount, this))); } diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 75545adbc..727da42a8 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -39,6 +39,16 @@ #include "hb-aat-ltag-table.hh" +/** + * SECTION:hb-aat-layout + * @title: hb-aat-layout + * @short_description: Apple Advanced Typography Layout + * @include: hb-aat.h + * + * Functions for querying OpenType Layout features in the font face. + **/ + + /* Table data courtesy of Apple. Converted from mnemonics to integers * when moving to this file. */ static const hb_aat_feature_mapping_t feature_mappings[] = @@ -303,26 +313,26 @@ _hb_aat_language_get (hb_face_t *face, * hb_aat_layout_get_feature_types: * @face: a face object * @start_offset: iteration's start offset - * @count: (inout): buffer size as input, filled size as output - * @features: (out): features buffer + * @feature_count:(inout) (allow-none): buffer size as input, filled size as output + * @features: (out caller-allocates) (array length=feature_count): features buffer * - * Return value: Number of all available features + * Return value: Number of all available feature types. * * Since: REPLACEME */ unsigned int hb_aat_layout_get_feature_types (hb_face_t *face, unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) + unsigned int *feature_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) { - return face->table.feat->get_feature_types (start_offset, count, features); + return face->table.feat->get_feature_types (start_offset, feature_count, features); } /** * hb_aat_layout_feature_type_get_name_id: * @face: a face object - * @feature: feature id + * @feature_type: feature id * * Return value: Name ID index * @@ -330,55 +340,33 @@ hb_aat_layout_get_feature_types (hb_face_t *face, */ hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature) -{ return face->table.feat->get_feature_name_id (feature); } + hb_aat_layout_feature_type_t feature_type) +{ return face->table.feat->get_feature_name_id (feature_type); } /** * hb_aat_layout_feature_type_get_selectors: * @face: a face object - * @feature: feature id - * @default_selector: (out): if is set, the feature is exclusive + * @feature_type: feature id * @start_offset: iteration's start offset - * @count: (inout): buffer size as input, filled size as output - * @settings: (out): settings buffer + * @selector_count: (inout) (allow-none): buffer size as input, filled size as output + * @selectors: (out caller-allocates) (array length=selector_count): settings buffer + * @default_index: (out) (allow-none): index of default selector if any * - * Per spec: - * For feature types that don't have exclusive settings, - * there will always be a pair of values. One value turns - * a selector on and a second value turns the selector off. - * The on setting must be even and the off setting must be one - * greater than the corresponding on setting. The off setting - * is therefore always odd. As a result, only the on setting - * should have an entry in the setting name array. + * If upon return, @default_index is set to #HB_AAT_LAYOUT_NO_SELECTOR_INDEX, then + * the feature type is non-exclusive. Otherwise, @default_index is the index of + * the selector that is selected by default. * - * Return value: Number of all available features + * Return value: Number of all available feature selectors. * * Since: REPLACEME */ unsigned int -hb_aat_layout_feature_type_get_selectors (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_selector_t *selectors /* OUT. May be NULL. */) +hb_aat_layout_feature_type_get_selector_infos (hb_face_t *face, + hb_aat_layout_feature_type_t feature_type, + unsigned int start_offset, + unsigned int *selector_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *default_index /* OUT. May be NULL. */) { - return face->table.feat->get_selectors (feature, default_selector, - start_offset, count, selectors); + return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index); } - -/** - * hb_aat_layout_feature_selector_get_name_id: - * @face: a face object - * @feature: feature id - * @selector: selector value - * - * Return value: Name ID index - * - * Since: REPLACEME - */ -hb_ot_name_id_t -hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t selector) -{ return face->table.feat->get_feature_selector_name_id (feature, selector); } diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h index 8bd4af27d..5912e012b 100644 --- a/src/hb-aat-layout.h +++ b/src/hb-aat-layout.h @@ -430,26 +430,32 @@ typedef enum HB_EXTERN unsigned int hb_aat_layout_get_feature_types (hb_face_t *face, unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); + unsigned int *feature_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */); HB_EXTERN hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature); + hb_aat_layout_feature_type_t feature_type); +typedef struct hb_aat_layout_feature_selector_info_t +{ + hb_ot_name_id_t name_id; + hb_aat_layout_feature_selector_t enable; + hb_aat_layout_feature_selector_t disable; + /*< private >*/ + unsigned int reserved; +} hb_aat_layout_feature_selector_info_t; + +#define HB_AAT_LAYOUT_NO_SELECTOR_INDEX 0xFFFFu HB_EXTERN unsigned int -hb_aat_layout_feature_type_get_selectors (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t *default_selector, /* OUT. May be NULL. */ - unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ - hb_aat_layout_feature_selector_t *settings /* OUT. May be NULL. */); +hb_aat_layout_feature_type_get_selector_infos (hb_face_t *face, + hb_aat_layout_feature_type_t feature_type, + unsigned int start_offset, + unsigned int *selector_count, /* IN/OUT. May be NULL. */ + hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ + unsigned int *default_index /* OUT. May be NULL. */); -HB_EXTERN hb_ot_name_id_t -hb_aat_layout_feature_selector_get_name_id (hb_face_t *face, - hb_aat_layout_feature_type_t feature, - hb_aat_layout_feature_selector_t selector); HB_END_DECLS diff --git a/test/api/test-aat-layout.c b/test/api/test-aat-layout.c index 516b46191..358fac879 100644 --- a/test/api/test-aat-layout.c +++ b/test/api/test-aat-layout.c @@ -52,51 +52,53 @@ test_aat_get_feature_types (void) static void test_aat_get_feature_selectors (void) { - hb_aat_layout_feature_selector_t default_selector; - hb_aat_layout_feature_selector_t settings[3]; + unsigned int default_index; + hb_aat_layout_feature_selector_info_t settings[3]; unsigned int count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, - &default_selector, 0, &count, settings)); + g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selector_infos (face, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + 0, &count, settings, + &default_index)); g_assert_cmpuint (3, ==, count); - g_assert_cmpuint (0, ==, default_selector); + g_assert_cmpuint (0, ==, default_index); - g_assert_cmpuint (0, ==, settings[0]); - g_assert_cmpuint (294, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); + g_assert_cmpuint (0, ==, settings[0].enable); + g_assert_cmpuint (294, ==, settings[0].name_id); - g_assert_cmpuint (1, ==, settings[1]); - g_assert_cmpuint (295, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[1])); + g_assert_cmpuint (1, ==, settings[1].enable); + g_assert_cmpuint (295, ==, settings[1].name_id); - g_assert_cmpuint (2, ==, settings[2]); - g_assert_cmpuint (296, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[2])); - - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID)); + g_assert_cmpuint (2, ==, settings[2].enable); + g_assert_cmpuint (296, ==, settings[2].name_id); count = 3; - g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, - &default_selector, 3, &count, settings)); + g_assert_cmpuint (4, ==, hb_aat_layout_feature_type_get_selector_infos (face, + HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, + 3, &count, settings, + &default_index)); g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (0, ==, default_selector); + g_assert_cmpuint (0, ==, default_index); - g_assert_cmpuint (3, ==, settings[0]); - g_assert_cmpuint (297, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, settings[0])); + g_assert_cmpuint (3, ==, settings[0].enable); + g_assert_cmpuint (297, ==, settings[0].name_id); count = 1; - g_assert_cmpuint (1, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, - &default_selector, 0, &count, settings)); + g_assert_cmpuint (1, ==, hb_aat_layout_feature_type_get_selector_infos (face, + HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, + 0, &count, settings, + &default_index)); g_assert_cmpuint (1, ==, count); - g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, ==, default_selector); + g_assert_cmpuint (HB_AAT_LAYOUT_NO_SELECTOR_INDEX, ==, default_index); - g_assert_cmpuint (8, ==, settings[0]); - g_assert_cmpuint (308, ==, hb_aat_layout_feature_selector_get_name_id (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, settings[0])); + g_assert_cmpuint (8, ==, settings[0].enable); + g_assert_cmpuint (308, ==, settings[0].name_id); count = 100; - g_assert_cmpuint (0, ==, hb_aat_layout_feature_type_get_selectors (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, - NULL, 0, &count, settings)); + g_assert_cmpuint (0, ==, hb_aat_layout_feature_type_get_selector_infos (face, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, + 0, &count, settings, + NULL)); g_assert_cmpuint (0, ==, count); - - g_assert_cmpuint (HB_OT_NAME_ID_INVALID, ==, hb_aat_layout_feature_selector_get_name_id (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_INVALID, - (hb_aat_layout_feature_selector_t) 0)); } int From fa26ad0f48462063f2160a43cb62b018bb21e251 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 25 Nov 2018 11:25:17 +0330 Subject: [PATCH 140/158] [aat] Fix macos expectation --- test/shaping/data/in-house/tests/macos.tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 4d76d84e7..78b5112ed 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -1,7 +1,7 @@ # 10.12.6 /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] -/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] +/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] /System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] /Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] @@ -15,7 +15,7 @@ /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] # The following is broken https://github.com/harfbuzz/harfbuzz/issues/1410 -#/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1074|tgc_ka=2@-74,0+1518|tgm_u=2+1205|tgc_ka=4+1592|tgm_pulli=4+503|tgc_ka=6+1592|tgc_pa=7+1370|tgm_pulli=7+503|tgc_pa=9+1370|tgc_tta=10+1566|tgm_pulli=10+503|tgc_tta=12+1566|tgm_u=12+1205] +#/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] /System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] /Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] From cbc541b426f01717641f1f3529a7c9703aec7a28 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 25 Nov 2018 12:50:30 +0330 Subject: [PATCH 141/158] [aat] Add m grave test (#1412) --- test/shaping/data/in-house/tests/macos.tests | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 78b5112ed..06bdacba4 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -1,4 +1,6 @@ # 10.12.6 +/System/Library/Fonts/Helvetica.dfont@c7bec2785a4c402b7809b5e35337c3d24c18e281::U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+006D,U+0300:[mgrave=0+1912] /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] /Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] @@ -12,6 +14,8 @@ /System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] # 10.13.6 +/System/Library/Fonts/Helvetica.ttc@8a928f9866299d2455f41360202b7a3b48503a5e::U+006D,U+0300:[m=0+1422|gravecmb=0@0,96+283] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+006D,U+0300:[mgrave=0+1912] /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] # The following is broken https://github.com/harfbuzz/harfbuzz/issues/1410 From 0e3a48e54248d69197e8fb23c824d987f91b3bf7 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 25 Nov 2018 13:37:23 +0330 Subject: [PATCH 142/158] [test][aat] fix 10.13.6 Helvetica expectation --- test/shaping/data/in-house/tests/macos.tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 06bdacba4..05dafd199 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -14,7 +14,7 @@ /System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] # 10.13.6 -/System/Library/Fonts/Helvetica.ttc@8a928f9866299d2455f41360202b7a3b48503a5e::U+006D,U+0300:[m=0+1422|gravecmb=0@0,96+283] +/System/Library/Fonts/Helvetica.ttc@8a928f9866299d2455f41360202b7a3b48503a5e::U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] /System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+006D,U+0300:[mgrave=0+1912] /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] From 4ed9fb1a0050f3151f9332f08c8bb2c13652c607 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 15:51:01 -0500 Subject: [PATCH 143/158] [GDEF] Minor --- src/hb-ot-layout.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 9488fe82c..3cc1ef137 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -117,7 +117,7 @@ _hb_ot_blacklist_gdef (unsigned int gdef_len, * https://bugzilla.mozilla.org/show_bug.cgi?id=1279693 * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875 */ -#define ENCODE(x,y,z) ((int64_t) (x) << 32 | (int64_t) (y) << 16 | (z)) +#define ENCODE(x,y,z) (((uint64_t) (x) << 48) | ((uint64_t) (y) << 24) | (uint64_t) (z)) switch ENCODE(gdef_len, gsub_len, gpos_len) { /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */ From 4f21703f225b6977196ef180e8d7300ea86d2cc3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 15:59:18 -0500 Subject: [PATCH 144/158] [GDEF] Move code around --- src/hb-ot-layout-gdef-table.hh | 3 +++ src/hb-ot-layout.cc | 16 +++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 2c4cbea85..a7ba9511d 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -408,6 +408,9 @@ struct GDEF } } + HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const; + struct accelerator_t { HB_INTERNAL void init (hb_face_t *face); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 3cc1ef137..bb87b5e5f 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -95,10 +95,9 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, * GDEF */ -static bool -_hb_ot_blacklist_gdef (unsigned int gdef_len, - unsigned int gsub_len, - unsigned int gpos_len) +bool +OT::GDEF::is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const { /* The ugly business of blacklisting individual fonts' tables happen here! * See this thread for why we finally had to bend in and do this: @@ -118,7 +117,9 @@ _hb_ot_blacklist_gdef (unsigned int gdef_len, * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875 */ #define ENCODE(x,y,z) (((uint64_t) (x) << 48) | ((uint64_t) (y) << 24) | (uint64_t) (z)) - switch ENCODE(gdef_len, gsub_len, gpos_len) + switch ENCODE(blob->length, + face->table.GSUB->table.get_length (), + face->table.GPOS->table.get_length ()) { /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */ case ENCODE (442, 2874, 42038): @@ -201,10 +202,7 @@ void OT::GDEF::accelerator_t::init (hb_face_t *face) { this->table = hb_sanitize_context_t().reference_table (face); - - if (unlikely (_hb_ot_blacklist_gdef (this->table.get_length (), - face->table.GSUB->table.get_length (), - face->table.GPOS->table.get_length ()))) + if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) { hb_blob_destroy (this->table.get_blob ()); this->table = hb_blob_get_empty (); From 4151c2848d8df75b6d0a4f5d79bee843158aa4a4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 16:38:36 -0500 Subject: [PATCH 145/158] [GDEF] Move more code --- src/hb-ot-layout-gdef-table.hh | 10 +++++++++- src/hb-ot-layout.cc | 11 ----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index a7ba9511d..a0ae27e75 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -413,7 +413,15 @@ struct GDEF struct accelerator_t { - HB_INTERNAL void init (hb_face_t *face); + inline void init (hb_face_t *face) + { + this->table = hb_sanitize_context_t().reference_table (face); + if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } + } inline void fini (void) { diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index bb87b5e5f..6d6834fc7 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -198,17 +198,6 @@ OT::GDEF::is_blacklisted (hb_blob_t *blob, return false; } -void -OT::GDEF::accelerator_t::init (hb_face_t *face) -{ - this->table = hb_sanitize_context_t().reference_table (face); - if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) - { - hb_blob_destroy (this->table.get_blob ()); - this->table = hb_blob_get_empty (); - } -} - static void _hb_ot_layout_set_glyph_props (hb_font_t *font, hb_buffer_t *buffer) From 574d888c8a409295a952361a39c8e83a52a0fc3d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 25 Nov 2018 16:51:22 -0500 Subject: [PATCH 146/158] [aat] Ignore GSUB table of Muthu Foundry if they have morx table Fixes https://github.com/harfbuzz/harfbuzz/issues/1410 --- src/hb-ot-layout-gpos-table.hh | 3 +++ src/hb-ot-layout-gsub-table.hh | 3 +++ src/hb-ot-layout-gsubgpos.hh | 5 +++++ src/hb-ot-layout.cc | 36 +++++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 907fd4631..2589218de 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1643,6 +1643,9 @@ struct GPOS : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { return GSUBGPOS::sanitize (c); } + HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const; + typedef GSUBGPOS::accelerator_t accelerator_t; }; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 501f2308c..27bd440da 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1486,6 +1486,9 @@ struct GSUB : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { return GSUBGPOS::sanitize (c); } + HB_INTERNAL bool is_blacklisted (hb_blob_t *blob, + hb_face_t *face) const; + typedef GSUBGPOS::accelerator_t accelerator_t; }; diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3d70c55c2..a9bfee155 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2753,6 +2753,11 @@ struct GSUBGPOS inline void init (hb_face_t *face) { this->table = hb_sanitize_context_t().reference_table (face); + if (unlikely (this->table->is_blacklisted (this->table.get_blob (), face))) + { + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); + } this->lookup_count = table->get_lookup_count (); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 6d6834fc7..d0b22efe3 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -34,15 +34,17 @@ #include "hb-ot-map.hh" #include "hb-map.hh" +#include "hb-ot-kern-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-base-table.hh" // Just so we compile it; unused otherwise #include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise -#include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" +#include "hb-ot-os2-table.hh" #include "hb-aat-layout-lcar-table.hh" +#include "hb-aat-layout-morx-table.hh" /** @@ -284,6 +286,38 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, * GSUB/GPOS */ +bool +OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED, + hb_face_t *face) const +{ + /* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts, + * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken + * GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by + * our morx/GSUB preference code. But if GSUB has non-zero scripts, we tend + * to prefer it over morx because we want to be consistent with other OpenType + * shapers. + * + * To work around broken Indic Mac system fonts, we ignore GSUB table if + * OS/2 VendorId is 'MUTF' and font has morx table as well. + * + * https://github.com/harfbuzz/harfbuzz/issues/1410 + * https://github.com/harfbuzz/harfbuzz/issues/1348 + * https://github.com/harfbuzz/harfbuzz/issues/1391 + */ + if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') && + face->table.morx->has_data ())) + return true; + + return false; +} + +bool +OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED, + hb_face_t *face HB_UNUSED) const +{ + return false; +} + static const OT::GSUBGPOS& get_gsubgpos_table (hb_face_t *face, hb_tag_t table_tag) From 97eaedca5de76c74534bab41562aee130098558a Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 26 Nov 2018 16:58:58 +0330 Subject: [PATCH 147/158] [test][aat] Enable Tamil MN test (#1414) --- test/shaping/data/in-house/tests/macos.tests | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 05dafd199..9f1f9fa16 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -18,8 +18,7 @@ /System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+006D,U+0300:[mgrave=0+1912] /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] /Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] -# The following is broken https://github.com/harfbuzz/harfbuzz/issues/1410 -#/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] +/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] /System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] /Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] From 1042d9fbc05aff9d51f15c2824a8521e963d0acd Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 26 Nov 2018 18:58:39 +0330 Subject: [PATCH 148/158] [ci] Add .codecov.yml Similar to https://github.com/GoogleChrome/lighthouse/blob/master/.codecov.yml No strong preference on commenting, feel free to enable it again --- .codecov.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 000000000..e9b8ab481 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,7 @@ +comment: off + +coverage: + status: + project: + default: + threshold: 1% From 4a719a7f4c997ea7e47588bc0288c97706dae015 Mon Sep 17 00:00:00 2001 From: Adenilson Cavalcanti Date: Tue, 20 Nov 2018 14:41:19 -0800 Subject: [PATCH 149/158] Optimize harfbuzz big integer conversions Profiling showed that type conversions were adding considerable cycles in time spent doing text shaping. The idea is to optimize it using native processor instructions to help Blink layout performance. Doing further investigation revelead that compilers may not use the proper instruction on ARM 32bits builds (i.e. REV16). One way to insure that the generated ASM was ideal for both gcc/clang was using __builtin_bswap16. Added bonus is that we no longer need to test for CPU architecture. --- src/hb-machinery.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 3c11243f5..c38484158 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -691,6 +691,10 @@ struct BEInt } inline operator Type (void) const { +#if defined(__GNUC__) || defined(__clang__) + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; + return __builtin_bswap16(((packed_uint16_t *) this)->v); +#endif return (v[0] << 8) + (v[1] ); } From 4e2a03b6b6e0c0d1c4edea10dc1aae63eeb6c581 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 27 Nov 2018 17:40:09 -0500 Subject: [PATCH 150/158] Comment --- src/hb-machinery.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index c38484158..0e75c8246 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -692,8 +692,10 @@ struct BEInt inline operator Type (void) const { #if defined(__GNUC__) || defined(__clang__) + /* Spoon-feed the compiler a big-endian integer with alignment 1. + * https://github.com/harfbuzz/harfbuzz/pull/1398 */ struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; - return __builtin_bswap16(((packed_uint16_t *) this)->v); + return __builtin_bswap16 (((packed_uint16_t *) this)->v); #endif return (v[0] << 8) + (v[1] ); From 19863c805982d5d1d059d4dd9376039d3fdaabcd Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 28 Nov 2018 20:28:42 +0330 Subject: [PATCH 151/158] [test][aat] Add a test and make macOS runners faster (#1422) --- .circleci/config.yml | 15 ++---- test/shaping/data/in-house/tests/macos.tests | 54 ++++++++++---------- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e546f89ff..320813ad3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,8 +7,7 @@ jobs: xcode: "9.2.0" steps: - checkout - - run: brew update-reset - - run: brew install wget pkg-config libtool ragel freetype glib cairo + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel freetype glib cairo - run: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo - run: make -j4 - run: make check || .ci/fail.sh @@ -18,8 +17,7 @@ jobs: xcode: "10.1.0" steps: - checkout - - run: brew update-reset - - run: brew install wget pkg-config libtool ragel freetype glib cairo + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel freetype glib cairo - run: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo - run: make -j4 - run: make check || .ci/fail.sh @@ -29,8 +27,7 @@ jobs: # xcode: "8.3.3" # steps: # - checkout - # - run: brew update-reset - # - run: brew install wget pkg-config libtool ragel freetype glib cairo + # - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel freetype glib cairo # - run: wget https://packages.macports.org/llvm-gcc42/llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf llvm-gcc42-2336.11_3+universal.darwin_15.i386-x86_64.tbz2 # - run: CC=$PWD/opt/local/bin/llvm-gcc-4.2 CXX=$PWD/opt/local/bin/llvm-g++-4.2 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo # # Ignoring assembler complains, https://stackoverflow.com/a/39867021 @@ -42,8 +39,7 @@ jobs: # xcode: "8.3.3" # steps: # - checkout - # - run: brew update-reset - # - run: brew install wget pkg-config libtool ragel + # - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget pkg-config libtool ragel # - run: wget https://packages.macports.org/apple-gcc42/apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 && tar zxvf apple-gcc42-5666.3_15+universal.darwin_15.i386-x86_64.tbz2 # - run: CPP=$PWD/opt/local/bin/i686-apple-darwin15-cpp-apple-4.2.1 CC=$PWD/opt/local/bin/i686-apple-darwin15-gcc-apple-4.2.1 CXX=$PWD/opt/local/bin/i686-apple-darwin15-g++-apple-4.2.1 ./autogen.sh # # Ignoring assembler complains, https://stackoverflow.com/a/39867021 @@ -54,8 +50,7 @@ jobs: xcode: "10.0.0" steps: - checkout - - run: brew update-reset - - run: brew install cmake + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake # not needed to be a framework but we like to test that also # TODO: wrong way of targeting iOS as it doesn't point to iOS headers thus building # CoreText support is not possible, after the fix feel free HB_IOS from CMake altogether diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index 9f1f9fa16..f788a9879 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -1,29 +1,31 @@ # 10.12.6 -/System/Library/Fonts/Helvetica.dfont@c7bec2785a4c402b7809b5e35337c3d24c18e281::U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] -/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+006D,U+0300:[mgrave=0+1912] -/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0066,U+0069:[fi=0+1139] -/Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] -/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] -/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] -/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] -/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] -/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] -/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced::U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] +/System/Library/Fonts/Helvetica.dfont@c7bec2785a4c402b7809b5e35337c3d24c18e281:--shaper ot --font-funcs ot:U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062:--shaper ot --font-funcs ot:U+006D,U+0300:[mgrave=0+1912] +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39:--shaper ot --font-funcs ot:U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@5f5b1072df99b7355d3066ea85fe82969d13c94a:--shaper ot --font-funcs ot:U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +/Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d:--shaper ot --font-funcs ot:U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] +/System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39:--shaper ot --font-funcs ot:U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062:--shaper ot --font-funcs ot:U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced:--shaper ot --font-funcs ot:U+0056,U+0041,U+0056,U+0041:[gid265=0+1227|gid4=1@-65,0+1162|gid265=2@-65,0+1162|gid4=3@-65,0+1227] +/System/Library/Fonts/Apple Color Emoji.ttc@d2fe8a134483aa48a43a9d1e4b7204d37a4abdf5:--remove-default-ignorables --shaper ot --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800] # 10.13.6 -/System/Library/Fonts/Helvetica.ttc@8a928f9866299d2455f41360202b7a3b48503a5e::U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] -/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+006D,U+0300:[mgrave=0+1912] -/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0066,U+0069:[fi=0+1139] -/Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c::U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] -/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d::U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] -/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c::U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] -/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269::U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] -/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac::U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] -/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334::U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] -/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa::U+0056,U+0041,U+0056,U+0041:[gid332=0+1227|gid4=1@-65,0+1162|gid332=2@-65,0+1162|gid4=3@-65,0+1227] +/System/Library/Fonts/Helvetica.ttc@8a928f9866299d2455f41360202b7a3b48503a5e:--shaper ot --font-funcs ot:U+006D,U+0300:[m=0+1706|gravecmb=0@-284,10+0] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269:--shaper ot --font-funcs ot:U+006D,U+0300:[mgrave=0+1912] +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c:--shaper ot --font-funcs ot:U+0066,U+0069:[fi=0+1139] +/Library/Fonts/Khmer MN.ttc@782ba6cf3fca0512ab348dfe08345a2d5dc5bf2c:--shaper ot --font-funcs ot:U+17A2,U+1780,U+17D2,U+179F,U+179A,U+1781,U+17D2,U+1798,U+17C2,U+179A:[km_qa=0+1025|km_ka=1+1025|km_sa.sub=1+517|km_ro=4+593|km_vs_ae=5+605|km_kha=5+1025|km_mo.sub=5+0|km_ro=9+593] +/Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d:--shaper ot --font-funcs ot:U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] +/System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c:--shaper ot --font-funcs ot:U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] +/System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269:--shaper ot --font-funcs ot:U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] +/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] +/System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165] +/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa:--shaper ot --font-funcs ot:U+0056,U+0041,U+0056,U+0041:[gid332=0+1227|gid4=1@-65,0+1162|gid332=2@-65,0+1162|gid4=3@-65,0+1227] +/System/Library/Fonts/Apple Color Emoji.ttc@2e09b1f3d42c3821cc6c4ac5b6ce16237ab0d496:--remove-default-ignorables --shaper ot --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800] From 5b4a789ca857664668ff69936574dcd09bee6065 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 28 Nov 2018 14:46:26 -0500 Subject: [PATCH 152/158] [aat] Towards adding two ClassTable's --- src/hb-aat-layout-common.hh | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 3ee96bc91..948852164 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -363,6 +363,14 @@ struct Lookup } } + inline typename T::type get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs, + unsigned int outOfRange) const + { + const T *v = get_value (glyph_id, num_glyphs); + return v ? *v : outOfRange; + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -638,6 +646,7 @@ struct StateTable DEFINE_SIZE_STATIC (4 * sizeof (HBUINT)); }; +template struct ClassTable { inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const @@ -645,6 +654,12 @@ struct ClassTable unsigned int i = glyph_id - firstGlyph; return i >= classArray.len ? outOfRange : classArray.arrayZ[i]; } + inline unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs HB_UNUSED, + unsigned int outOfRange) const + { + return get_class (glyph_id, outOfRange); + } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -652,7 +667,7 @@ struct ClassTable } protected: GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ - ArrayOf classArray; /* The class codes (indexed by glyph index minus + ArrayOf classArray; /* The class codes (indexed by glyph index minus * firstGlyph). */ public: DEFINE_SIZE_ARRAY (4, classArray); @@ -663,15 +678,8 @@ struct ObsoleteTypes static const bool extended = false; typedef HBUINT16 HBUINT; typedef HBUINT8 HBUSHORT; - struct ClassType : ClassTable - { - inline unsigned int get_class (hb_codepoint_t glyph_id, - unsigned int num_glyphs HB_UNUSED, - unsigned int outOfRange) const - { - return ClassTable::get_class (glyph_id, outOfRange); - } - }; + typedef ClassTable ClassType; + template static inline unsigned int offsetToIndex (unsigned int offset, const void *base, @@ -692,16 +700,8 @@ struct ExtendedTypes static const bool extended = true; typedef HBUINT32 HBUINT; typedef HBUINT16 HBUSHORT; - struct ClassType : Lookup - { - inline unsigned int get_class (hb_codepoint_t glyph_id, - unsigned int num_glyphs, - unsigned int outOfRange) const - { - const HBUINT16 *v = get_value (glyph_id, num_glyphs); - return v ? *v : outOfRange; - } - }; + typedef Lookup ClassType; + template static inline unsigned int offsetToIndex (unsigned int offset, const void *base, From f9a9c0fd1e561715d696c7bd840bab552d0718ee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 28 Nov 2018 14:51:56 -0500 Subject: [PATCH 153/158] [kerx] Fix ClassTable implementation for 'kern' table Format 2 --- src/hb-aat-layout-common.hh | 8 +++++--- src/hb-aat-layout-kerx-table.hh | 10 ++-------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 948852164..253b56fea 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -488,7 +488,7 @@ struct StateTable { typedef typename Types::HBUINT HBUINT; typedef typename Types::HBUSHORT HBUSHORT; - typedef typename Types::ClassType ClassType; + typedef typename Types::ClassTypeNarrow ClassType; enum State { @@ -678,7 +678,8 @@ struct ObsoleteTypes static const bool extended = false; typedef HBUINT16 HBUINT; typedef HBUINT8 HBUSHORT; - typedef ClassTable ClassType; + typedef ClassTable ClassTypeNarrow; + typedef ClassTable ClassTypeWide; template static inline unsigned int offsetToIndex (unsigned int offset, @@ -700,7 +701,8 @@ struct ExtendedTypes static const bool extended = true; typedef HBUINT32 HBUINT; typedef HBUINT16 HBUSHORT; - typedef Lookup ClassType; + typedef Lookup ClassTypeNarrow; + typedef Lookup ClassTypeWide; template static inline unsigned int offsetToIndex (unsigned int offset, diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 8dc74991e..48526edf4 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -437,19 +437,13 @@ struct KerxSubTableFormat2 c->check_range (this, array))); } - /* Note: - * OT kern table specifies ClassTable as having 16-bit entries, whereas - * AAT kern table specifies them as having 8bit entries. - * I've not seen any fonts with this format in kern table. - * We follow AAT. */ - protected: KernSubTableHeader header; HBUINT rowWidth; /* The width, in bytes, of a row in the table. */ - OffsetTo + OffsetTo leftClassTable; /* Offset from beginning of this subtable to * left-hand class table. */ - OffsetTo + OffsetTo rightClassTable;/* Offset from beginning of this subtable to * right-hand class table. */ OffsetTo, HBUINT, false> From a3267cf803082af157a7f2b0026af2633b14f8e3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 28 Nov 2018 15:06:01 -0500 Subject: [PATCH 154/158] [kern] Fix kern table Format2 offsetToIndex Fixes https://github.com/harfbuzz/harfbuzz/issues/1421 --- src/hb-aat-layout-kerx-table.hh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 48526edf4..abd577b9d 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -392,9 +392,13 @@ struct KerxSubTableFormat2 unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); unsigned int l = (this+leftClassTable).get_class (left, num_glyphs, 0); unsigned int r = (this+rightClassTable).get_class (right, num_glyphs, 0); - unsigned int offset = l + r; - const FWORD *v = &StructAtOffset (&(this+array), offset); + + const UnsizedArrayOf &arrayZ = this+array; + unsigned int kern_idx = l + r; + kern_idx = Types::offsetToIndex (kern_idx, this, &arrayZ); + const FWORD *v = &arrayZ[kern_idx]; if (unlikely (!v->sanitize (&c->sanitizer))) return 0; + return kerxTupleKern (*v, header.tuple_count (), this, c); } From 42a2b496e428521151ff5cb07454d2e993f892cc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 28 Nov 2018 15:24:30 -0500 Subject: [PATCH 155/158] [kerx] Fix Format2 index calc again --- src/hb-aat-layout-common.hh | 14 ++++++++++++++ src/hb-aat-layout-kerx-table.hh | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 253b56fea..c0b0e3751 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -689,6 +689,13 @@ struct ObsoleteTypes return (offset - ((const char *) array - (const char *) base)) / sizeof (T); } template + static inline unsigned int byteOffsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offsetToIndex (offset, base, array); + } + template static inline unsigned int wordOffsetToIndex (unsigned int offset, const void *base, const T *array) @@ -712,6 +719,13 @@ struct ExtendedTypes return offset; } template + static inline unsigned int byteOffsetToIndex (unsigned int offset, + const void *base, + const T *array) + { + return offset / 2; + } + template static inline unsigned int wordOffsetToIndex (unsigned int offset, const void *base, const T *array) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index abd577b9d..7caf45d5d 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -255,7 +255,7 @@ struct KerxSubTableFormat1 unsigned int tuple_count = MAX (1u, table->header.tuple_count ()); unsigned int kern_idx = Format1EntryT::kernActionIndex (entry); - kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); + kern_idx = Types::byteOffsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); const FWORD *actions = &kernAction[kern_idx]; if (!c->sanitizer.check_array (actions, depth, tuple_count)) { From 5155067e10011f78f1ce35b3dadb062bccd3a706 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 29 Nov 2018 00:07:00 +0330 Subject: [PATCH 156/158] [test] Add test for format2 kern (#1423) --- test/shaping/data/in-house/Makefile.sources | 1 + ...e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf | Bin 0 -> 34116 bytes .../data/in-house/tests/kern-format2.tests | 3 +++ 3 files changed, 4 insertions(+) create mode 100644 test/shaping/data/in-house/fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf create mode 100644 test/shaping/data/in-house/tests/kern-format2.tests diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index d548e961b..0e9a3a21e 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -29,6 +29,7 @@ TESTS = \ tests/indic-special-cases.tests \ tests/indic-syllable.tests \ tests/indic-vowel-letter-spoofing.tests \ + tests/kern-format2.tests \ tests/khmer-mark-order.tests \ tests/khmer-misc.tests \ tests/language-tags.tests \ diff --git a/test/shaping/data/in-house/fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf b/test/shaping/data/in-house/fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b1605c45d74afe7efe83807b69de3b452d7265a6 GIT binary patch literal 34116 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 literal 0 HcmV?d00001 diff --git a/test/shaping/data/in-house/tests/kern-format2.tests b/test/shaping/data/in-house/tests/kern-format2.tests new file mode 100644 index 000000000..f7cd840df --- /dev/null +++ b/test/shaping/data/in-house/tests/kern-format2.tests @@ -0,0 +1,3 @@ +../fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf::U+0061,U+0062,U+0063,U+0064,U+0065,U+0066,U+0067,U+0068,U+0069,U+006A,U+006B,U+006C,U+006D,U+006E,U+006F,U+0070:[a=0+626|b=1+672|c=2+564|d=3@-15,0+657|e=4+621|f=5+403|g=6@-10,0+662|h=7+666|i=8+316|j=9+316|k=10+591|l=11+316|m=12+1021|n=13+666|o=14+644|p=15+672] +../fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf::U+0063,U+006B,U+0063,U+006B,U+0063,U+006B:[c=0+579|k=1+591|c=2+579|k=3+591|c=4+579|k=5+591] +../fonts/e39391c77a6321c2ac7a2d644de0396470cd4bfe.ttf::U+0041,U+0056:[A=0+701|V=1@-40,0+703] From 7b78d2233df0e51e2967bc54a9202b3f9e05059a Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Thu, 29 Nov 2018 00:55:05 +0330 Subject: [PATCH 157/158] [test][aat] Update expectency It is not visually noticeable but apparently affected by kern format2 correct implementation. I should've checked CoreText result which can't as CircleCI outage. --- test/shaping/data/in-house/tests/macos.tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/shaping/data/in-house/tests/macos.tests b/test/shaping/data/in-house/tests/macos.tests index f788a9879..8bce25302 100644 --- a/test/shaping/data/in-house/tests/macos.tests +++ b/test/shaping/data/in-house/tests/macos.tests @@ -6,7 +6,7 @@ /Library/Fonts/Tamil MN.ttc@37a2020c3f86ebcc45e02c1de5fdf81e2676989d:--shaper ot --font-funcs ot:U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] /System/Library/Fonts/Times.dfont@39c954614d3f3317b28564db06d5b7b7a6ff0e39:--shaper ot --font-funcs ot:U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] /System/Library/Fonts/LucidaGrande.ttc@d89a9d7e57767bfe3b5a4cfd22bb1e9dbe03a062:--shaper ot --font-funcs ot:U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] -/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/Library/Fonts/Apple Chancery.ttf@5fc49ae9bce39e2105864323183b68ea34c9e562:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1098] /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--shaper ot --font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] @@ -22,7 +22,7 @@ /Library/Fonts/Tamil MN.ttc@3de37f3f8f3cb6015b093fbd6e9d323daaf6fb1d:--shaper ot --font-funcs ot:U+0BA4,U+0BCA,U+0B95,U+0BC1,U+0B95,U+0BCD,U+0B95,U+0BAA,U+0BCD,U+0BAA,U+0B9F,U+0BCD,U+0B9F,U+0BC1:[tgm_e=0+1702|tgc_ta=0+1598|tgm_aa=0+1149|tgc_ku=2+1962|tgc_k=4+1592|tgc_ka=6+1592|tgc_p=7+1370|tgc_pa=9+1370|tgc_tt=10+1596|tgc_ttu=12+1833] /System/Library/Fonts/Times.ttc@896098b6979306ad84355025459f7c68b029139c:--shaper ot --font-funcs ot:U+0041,U+0066,U+0300,U+0066,U+0069,U+005A:[A=0+1479|f=1+682|gravecmb=1@-480,588+0|fi=3+1139|Z=5+1251] /System/Library/Fonts/LucidaGrande.ttc@63ba1b1de4709bd832ca76bd62368dd99fc34269:--shaper ot --font-funcs ot:U+05E1,U+05B0:[shevahebrew=0@-7,0+0|samekhhebrew=0+1361] -/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1073] +/Library/Fonts/Apple Chancery.ttf@4ec49cba0d4e68d025ada0498c4df1b2f9fd57ac:--shaper ot --font-funcs ot:U+0054,U+0068,U+0020,U+0074,U+0068,U+0020,U+006C,U+006C,U+0020,U+0074,U+0065,U+0020,U+0074,U+006F,U+0020,U+0074,U+0072,U+0020,U+0066,U+0072,U+0020,U+0066,U+0075,U+0020,U+0066,U+006A:[T_h=0+2308|space=2+569|t_h=3+1687|space=5+569|l_l=6+1108|space=8+569|t_e=9+1408|space=11+569|t_o=12+1531|space=14+569|t_r=15+1385|space=17+569|f_r=18+1432|space=20+569|f_u=21+1733|space=23+569|f_j=24+1098] /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0627,U+0644,U+0623,U+064E,U+0628,U+0652,U+062C,U+064E,U+062F,U+0650,U+064A,U+064E,U+0651,U+0629,U+0640,U+0627,U+0644,U+0639,U+064E,U+0631,U+064E,U+0628,U+0650,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=26+713|u064e_u0651.shaddaFatha=23@0,-200+0|u064a.medial.yeh=23+656|u0650.kasra=21@80,290+80|u0628.initial.beh=21@-80,0+576|u064e.fatha=19@200,-570+200|u0631.final.reh=19@-200,0+702|u064e.fatha=17@200,-200+200|u0639.medial.ain=17@-200,0+738|u0644.initial.lam=16+515|u0627.final.alef=15+647|u0640.tatweel=14+449|u0629.final.tehMarbuta=13+713|u064e_u0651.shaddaFatha=10@0,-200+0|u064a.initial.yeh=10+656|u0650.kasra=8@80,570+80|u062f.final.dal=8@-80,0+822|u064e.fatha=6@290,-160+290|u062c.medial.jeem=6@-290,0+1069|u0652.sukun=4@0,-200+0|u0628.initial.beh=4+656|u064e.fatha=1@-252,120+-252|u0644_u0623.isolated.lamHamzaOnAlef=1@120,0+1282|u0627.alef=0+647] /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0628,U+064A,U+064E,U+0651,U+0629:[u0629.final.tehMarbuta=4+713|u064e_u0651.shaddaFatha=1@0,-200+0|u064a.medial.yeh=1+656|u0628.initial.beh=0+656] /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--shaper ot --font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700] From d3d0f15f7d20bedf7018fb2fb652f92ff4159bd7 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Wed, 28 Nov 2018 13:46:12 -0800 Subject: [PATCH 158/158] =?UTF-8?q?update=20simple=20shaping=20example?= =?UTF-8?q?=C2=A0(closes=20#298)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add call to `FT_Set_Char_Size`, otherwise default size remains at `0`, and glyph positions come back as `0` too --- docs/usermanual-getting-started.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/usermanual-getting-started.xml b/docs/usermanual-getting-started.xml index 9e16ecbf2..932bd9471 100644 --- a/docs/usermanual-getting-started.xml +++ b/docs/usermanual-getting-started.xml @@ -157,7 +157,8 @@ #include <hb-ft.h> - FT_New_Face(ft_library, font_path, index, &face) + FT_New_Face(ft_library, font_path, index, &face); + FT_Set_Char_Size(face, 0, 1000, 0, 0); hb_font_t *font = hb_ft_font_create(face);