From 8db058d20c1b7efce33157c676d4aee97591deb1 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 5 Dec 2017 17:43:09 +0000 Subject: [PATCH 001/336] Indic: always hyphenate pre-base-reordering, for clarity. --- src/hb-ot-shape-complex-indic.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 7d0e7c5a4..97d6d3828 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -714,7 +714,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * following algorithm: starting from the end of the syllable, move backwards * until a consonant is found that does not have a below-base or post-base * form (post-base forms have to follow below-base forms), or that is not a - * pre-base reordering Ra, or arrive at the first consonant. The consonant + * pre-base-reordering Ra, or arrive at the first consonant. The consonant * stopped at will be the base. * * o If the syllable starts with Ra + Halant (in a script that has Reph) @@ -785,11 +785,11 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, if (info[i].indic_position() == POS_BELOW_C) seen_below = true; - /* -> or that is not a pre-base reordering Ra, + /* -> or that is not a pre-base-reordering Ra, * * IMPLEMENTATION NOTES: * - * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped + * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped * by the logic above already. */ @@ -1124,7 +1124,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, unsigned int pref_len = 2; if (indic_plan->mask_array[PREF] && base + pref_len < end) { - /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */ + /* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */ for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) { hb_codepoint_t glyphs[2]; for (unsigned int j = 0; j < pref_len; j++) @@ -1518,7 +1518,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* 3. If reph should be repositioned after the main consonant: find the * first consonant not ligated with main, or find the first - * consonant that is not a potential pre-base reordering Ra. + * consonant that is not a potential pre-base-reordering Ra. */ if (reph_pos == REPH_POS_AFTER_MAIN) { @@ -1607,13 +1607,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, } - /* o Reorder pre-base reordering consonants: + /* o Reorder pre-base-reordering consonants: * - * If a pre-base reordering consonant is found, reorder it according to + * If a pre-base-reordering consonant is found, reorder it according to * the following rules: */ - if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */ + if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */ { for (unsigned int i = base + 1; i < end; i++) if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) From 160c4d8b2d9f6c205b713236f043081e6dd532ee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 14:57:49 -0400 Subject: [PATCH 002/336] Add HB_NO_OT_FONT_CFF Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-ot-font.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 94a9fdc47..fc863276e 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -183,10 +183,12 @@ hb_ot_get_glyph_extents (hb_font_t *font, bool ret = ot_face->sbix->get_extents (font, glyph, extents); if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); +#if !defined(HB_NO_OT_FONT_CFF) if (!ret) ret = ot_face->cff1->get_extents (glyph, extents); if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents); +#endif if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents); // TODO Hook up side-bearings variations. From 60a58aa61c09cafd12c432fdc1f7325f2a6d44bd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 14:58:53 -0400 Subject: [PATCH 003/336] Add HB_NO_OT_FONT_BITMAP Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-ot-font.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index fc863276e..77e42cc53 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -189,8 +189,10 @@ hb_ot_get_glyph_extents (hb_font_t *font, if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents); #endif +#if !defined(HB_NO_OT_FONT_BITMAP) if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents); +#endif // TODO Hook up side-bearings variations. extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); From 079d2dcbb2607cda3daa497199090c5813a51de5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 15:00:37 -0400 Subject: [PATCH 004/336] Add HB_NO_NAME_TABLE_AAT Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-ot-name-table.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index c8ababd7b..fca509149 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -60,8 +60,10 @@ struct NameRecord if (p == 1) return _hb_ot_name_language_for_mac_code (l); +#if !defined(HB_NO_NAME_TABLE_AAT) if (p == 0) return _hb_aat_language_get (face, l); +#endif return HB_LANGUAGE_INVALID; } From 2f4be4ba54b539fbadc31fc53bdcfca81d7db77a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 16:21:58 -0400 Subject: [PATCH 005/336] Add HB_NO_OPTIONS Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-debug.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-debug.hh b/src/hb-debug.hh index d81483bed..52d5942c6 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -63,6 +63,9 @@ extern HB_INTERNAL hb_atomic_int_t _hb_options; static inline hb_options_t hb_options () { +#if defined(HB_NO_OPTIONS) + return hb_options_t (); +#endif /* Make a local copy, so we can access bitfield threadsafely. */ hb_options_union_t u; u.i = _hb_options.get_relaxed (); From 95df00aec1996d521acdff6deff063ba98214fb9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 17:50:03 -0400 Subject: [PATCH 006/336] Hide a few static methods Looks like static methods that do not get inlined end up exported. We have a lot more. Need to protect all at some point. Wish there was an easier way, like the visibility flag we pass that automatically hides all inline methods. Was exposed by check-symbols.sh when compiling on OS X 10.14 with: $ make CPPFLAGS=-Oz CXXFLAGS=-flto=thin LDFLAGS=-lc++ --- src/hb-aat-layout.hh | 2 +- src/hb-aat-map.hh | 2 +- src/hb-array.hh | 2 +- src/hb-coretext.cc | 4 ++-- src/hb-open-file.hh | 2 +- src/hb-open-type.hh | 3 ++- src/hb-ot-cmap-table.hh | 14 +++++++------- src/hb-ot-layout-base-table.hh | 6 +++--- src/hb-ot-layout-gpos-table.hh | 8 ++++---- src/hb-ot-layout-gsub-table.hh | 8 ++++---- src/hb-ot-layout-gsubgpos.hh | 2 +- src/hb-ot-map.hh | 4 ++-- src/hb-uniscribe.cc | 4 ++-- 13 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 8346d9f00..6340924bf 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -39,7 +39,7 @@ struct hb_aat_feature_mapping_t hb_aat_layout_feature_selector_t selectorToEnable; hb_aat_layout_feature_selector_t selectorToDisable; - static int cmp (const void *key_, const void *entry_) + HB_INTERNAL static int cmp (const void *key_, const void *entry_) { hb_tag_t key = * (unsigned int *) key_; const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh index f103d276c..984a59cca 100644 --- a/src/hb-aat-map.hh +++ b/src/hb-aat-map.hh @@ -66,7 +66,7 @@ struct hb_aat_map_builder_t hb_aat_layout_feature_selector_t setting; unsigned seq; /* For stable sorting only. */ - static int cmp (const void *pa, const void *pb) + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const feature_info_t *a = (const feature_info_t *) pa; const feature_info_t *b = (const feature_info_t *) pb; diff --git a/src/hb-array.hh b/src/hb-array.hh index 2bfbdd4f5..cfef75dba 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -100,7 +100,7 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> return (int) a.length - (int) length; return hb_memcmp (a.arrayZ, arrayZ, get_size ()); } - static int cmp (const void *pa, const void *pb) + HB_INTERNAL static int cmp (const void *pa, const void *pb) { hb_array_t *a = (hb_array_t *) pa; hb_array_t *b = (hb_array_t *) pb; diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 492356155..66f0fce1a 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -410,7 +410,7 @@ struct active_feature_t { feature_record_t rec; unsigned int order; - static int cmp (const void *pa, const void *pb) { + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const active_feature_t *a = (const active_feature_t *) pa; const active_feature_t *b = (const active_feature_t *) pb; return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 : @@ -428,7 +428,7 @@ struct feature_event_t { bool start; active_feature_t feature; - static int cmp (const void *pa, const void *pb) { + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const feature_event_t *a = (const feature_event_t *) pa; const feature_event_t *b = (const feature_event_t *) pb; return a->index < b->index ? -1 : a->index > b->index ? 1 : diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 03d27c118..7b140fa7c 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -56,7 +56,7 @@ typedef struct TableRecord { int cmp (Tag t) const { return -t.cmp (tag); } - static int cmp (const void *pa, const void *pb) + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const TableRecord *a = (const TableRecord *) pa; const TableRecord *b = (const TableRecord *) pb; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index c4707294f..05b8c72d7 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -63,7 +63,8 @@ struct IntType operator wide_type () const { return v; } bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } bool operator != (const IntType &o) const { return !(*this == o); } - static int cmp (const IntType *a, const IntType *b) { return b->cmp (*a); } + HB_INTERNAL static int cmp (const IntType *a, const IntType *b) + { return b->cmp (*a); } template int cmp (Type2 a) const { diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index add5325a4..08f186e8c 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -285,7 +285,7 @@ struct CmapSubtableFormat4 *glyph = gid; return true; } - static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) + HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); } @@ -1096,18 +1096,18 @@ struct cmap hb_codepoint_t *glyph); template - static bool get_glyph_from (const void *obj, - hb_codepoint_t codepoint, - hb_codepoint_t *glyph) + HB_INTERNAL static bool get_glyph_from (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) { const Type *typed_obj = (const Type *) obj; return typed_obj->get_glyph (codepoint, glyph); } template - static bool get_glyph_from_symbol (const void *obj, - hb_codepoint_t codepoint, - hb_codepoint_t *glyph) + HB_INTERNAL static bool get_glyph_from_symbol (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) { const Type *typed_obj = (const Type *) obj; if (likely (typed_obj->get_glyph (codepoint, glyph))) diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index dd0fba1ff..7ef573ea8 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -153,7 +153,7 @@ struct BaseCoord struct FeatMinMaxRecord { - static int cmp (const void *key_, const void *entry_) + HB_INTERNAL static int cmp (const void *key_, const void *entry_) { hb_tag_t key = * (hb_tag_t *) key_; const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_; @@ -271,7 +271,7 @@ struct BaseValues struct BaseLangSysRecord { - static int cmp (const void *key_, const void *entry_) + HB_INTERNAL static int cmp (const void *key_, const void *entry_) { hb_tag_t key = * (hb_tag_t *) key_; const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_; @@ -345,7 +345,7 @@ struct BaseScript struct BaseScriptList; struct BaseScriptRecord { - static int cmp (const void *key_, const void *entry_) + HB_INTERNAL static int cmp (const void *key_, const void *entry_) { hb_tag_t key = * (hb_tag_t *) key_; const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_; diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 795853af5..a7257dfbb 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -173,15 +173,15 @@ struct ValueFormat : HBUINT16 return true; } - static OffsetTo& get_device (Value* value) + HB_INTERNAL static OffsetTo& get_device (Value* value) { return *CastP > (value); } - static const OffsetTo& get_device (const Value* value, bool *worked=nullptr) + HB_INTERNAL static const OffsetTo& get_device (const Value* value, bool *worked=nullptr) { if (worked) *worked |= bool (*value); return *CastP > (value); } - static const HBINT16& get_short (const Value* value, bool *worked=nullptr) + HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr) { if (worked) *worked |= bool (*value); return *CastP (value); @@ -1576,7 +1576,7 @@ struct PosLookup : Lookup dispatch (&c); } - static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); + HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); template static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 6c82bf203..e664e06f4 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1194,7 +1194,7 @@ struct SubstLookup : Lookup const SubTable& get_subtable (unsigned int i) const { return Lookup::get_subtable (i); } - static bool lookup_type_is_reverse (unsigned int lookup_type) + HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type) { return lookup_type == SubTable::ReverseChainSingle; } bool is_reverse () const @@ -1252,7 +1252,7 @@ struct SubstLookup : Lookup return dispatch (c); } - static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); + HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); SubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) @@ -1315,9 +1315,9 @@ struct SubstLookup : Lookup } template - static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); + HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) + HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) { if (!c->should_visit_lookup (lookup_index)) return hb_void_t (); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 96777dead..2e9165be2 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -613,7 +613,7 @@ struct hb_get_subtables_context_t : hb_dispatch_context_t { template - static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) + HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) { const Type *typed_obj = (const Type *) obj; return typed_obj->apply (c); diff --git a/src/hb-ot-map.hh b/src/hb-ot-map.hh index 132da55c7..dd6778638 100644 --- a/src/hb-ot-map.hh +++ b/src/hb-ot-map.hh @@ -68,7 +68,7 @@ struct hb_ot_map_t unsigned short random : 1; hb_mask_t mask; - static int cmp (const void *pa, const void *pb) + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const lookup_map_t *a = (const lookup_map_t *) pa; const lookup_map_t *b = (const lookup_map_t *) pb; @@ -247,7 +247,7 @@ struct hb_ot_map_builder_t unsigned int default_value; /* for non-global features, what should the unset glyphs take */ unsigned int stage[2]; /* GSUB/GPOS */ - static int cmp (const void *pa, const void *pb) + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const feature_info_t *a = (const feature_info_t *) pa; const feature_info_t *b = (const feature_info_t *) pb; diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index f9d9f3d0f..4bbbf6122 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -283,7 +283,7 @@ struct active_feature_t { OPENTYPE_FEATURE_RECORD rec; unsigned int order; - static int cmp (const void *pa, const void *pb) { + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const active_feature_t *a = (const active_feature_t *) pa; const active_feature_t *b = (const active_feature_t *) pb; return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 : @@ -300,7 +300,7 @@ struct feature_event_t { bool start; active_feature_t feature; - static int cmp (const void *pa, const void *pb) + HB_INTERNAL static int cmp (const void *pa, const void *pb) { const feature_event_t *a = (const feature_event_t *) pa; const feature_event_t *b = (const feature_event_t *) pb; From caa20e4ef9dff61a86312daec5d5a1df27d95ff7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 17:59:18 -0400 Subject: [PATCH 007/336] Hide a few more symbols Exposed by: $ make CPPFLAGS=-O0 --- src/hb-array.hh | 4 ++-- src/hb-meta.hh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index cfef75dba..c744a2fd9 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -86,8 +86,8 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> operator hb_array_t () { return hb_array_t (arrayZ, length); } template operator T * () const { return arrayZ; } - bool operator == (const hb_array_t &o) const; - uint32_t hash () const; + HB_INTERNAL bool operator == (const hb_array_t &o) const; + HB_INTERNAL uint32_t hash () const; /* * Compare, Sort, and Search. diff --git a/src/hb-meta.hh b/src/hb-meta.hh index c0095637e..c7c91ea50 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -75,12 +75,12 @@ static const struct /* std::move and std::forward */ template -hb_remove_reference (T)&& hb_move (T&& t) { return (hb_remove_reference (T)&&) (t); } +static hb_remove_reference (T)&& hb_move (T&& t) { return (hb_remove_reference (T)&&) (t); } template -T&& hb_forward (hb_remove_reference (T)& t) { return (T&&) t; } +static T&& hb_forward (hb_remove_reference (T)& t) { return (T&&) t; } template -T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; } +static T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; } /* Void! For when we need a expression-type of void. */ From 2e86d50915cf1a791da9acb95245aa820a3d70f4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 18:07:42 -0400 Subject: [PATCH 008/336] Hide more symbols Exposed by: $ make -j5 CPPFLAGS="-O0" CXXFLAGS=-flto=thin LDFLAGS=-lc++ && ./check-symbols.sh --- 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 3a30efe55..d941bf6a9 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -55,7 +55,7 @@ struct hb_blob_t HB_INTERNAL bool try_make_writable_inplace_unix (); template - const Type* as () const + HB_INTERNAL const Type* as () const { return length < hb_null_size (Type) ? &Null(Type) : reinterpret_cast (data); } From 98f14c4cdb837a962083a6702f401d41b4c1ec5c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 18:11:18 -0400 Subject: [PATCH 009/336] Hide symbols in hb-iter Painful. All template methods need to be explicitly hidden :(. Maybe we should switch to -fvisibility=hidden pragma. A LOT more to go. --- src/hb-iter.hh | 88 +++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 6f8e7ece1..2f9acf974 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -58,8 +58,8 @@ struct hb_iter_t private: /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - const iter_t* thiz () const { return static_cast (this); } - iter_t* thiz () { return static_cast< iter_t *> (this); } + HB_INTERNAL const iter_t* thiz () const { return static_cast (this); } + HB_INTERNAL iter_t* thiz () { return static_cast< iter_t *> (this); } public: /* TODO: @@ -67,39 +67,39 @@ struct hb_iter_t * an operator and use it, and remove hb_iter_fallback_mixin_t completely. */ /* Operators. */ - iter_t iter () const { return *thiz(); } - iter_t operator + () const { return *thiz(); } - explicit operator bool () const { return thiz()->__more__ (); } - unsigned len () const { return thiz()->__len__ (); } + HB_INTERNAL iter_t iter () const { return *thiz(); } + HB_INTERNAL iter_t operator + () const { return *thiz(); } + HB_INTERNAL explicit operator bool () const { return thiz()->__more__ (); } + HB_INTERNAL unsigned len () const { return thiz()->__len__ (); } /* The following can only be enabled if item_t is reference type. Otherwise * it will be returning pointer to temporary rvalue. */ template - hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } - item_t operator * () const { return thiz()->__item__ (); } - item_t operator * () { return thiz()->__item__ (); } - item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } - item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); } - iter_t& operator += (unsigned count) { thiz()->__forward__ (count); return *thiz(); } - iter_t& operator ++ () { thiz()->__next__ (); return *thiz(); } - iter_t& operator -= (unsigned count) { thiz()->__rewind__ (count); return *thiz(); } - iter_t& operator -- () { thiz()->__prev__ (); return *thiz(); } - iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; } - friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; } - iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; } - iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; } - iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } + HB_INTERNAL hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } + HB_INTERNAL item_t operator * () const { return thiz()->__item__ (); } + HB_INTERNAL item_t operator * () { return thiz()->__item__ (); } + HB_INTERNAL item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } + HB_INTERNAL item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); } + HB_INTERNAL iter_t& operator += (unsigned count) { thiz()->__forward__ (count); return *thiz(); } + HB_INTERNAL iter_t& operator ++ () { thiz()->__next__ (); return *thiz(); } + HB_INTERNAL iter_t& operator -= (unsigned count) { thiz()->__rewind__ (count); return *thiz(); } + HB_INTERNAL iter_t& operator -- () { thiz()->__prev__ (); return *thiz(); } + HB_INTERNAL iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; } + HB_INTERNAL friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; } + HB_INTERNAL iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; } + HB_INTERNAL iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; } + HB_INTERNAL iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } template - iter_t& operator >> (T &v) { v = **thiz(); ++*thiz(); return *thiz(); } + HB_INTERNAL iter_t& operator >> (T &v) { v = **thiz(); ++*thiz(); return *thiz(); } template - iter_t& operator >> (T &v) const { v = **thiz(); ++*thiz(); return *thiz(); } + HB_INTERNAL iter_t& operator >> (T &v) const { v = **thiz(); ++*thiz(); return *thiz(); } template - iter_t& operator << (const T v) { **thiz() = v; ++*thiz(); return *thiz(); } + HB_INTERNAL iter_t& operator << (const T v) { **thiz() = v; ++*thiz(); return *thiz(); } protected: - hb_iter_t () {} - hb_iter_t (const hb_iter_t &o HB_UNUSED) {} - void operator = (const hb_iter_t &o HB_UNUSED) {} + HB_INTERNAL hb_iter_t () {} + HB_INTERNAL hb_iter_t (const hb_iter_t &o HB_UNUSED) {} + HB_INTERNAL void operator = (const hb_iter_t &o HB_UNUSED) {} }; #define HB_ITER_USING(Name) \ @@ -140,11 +140,11 @@ static const struct /* Specialization for C arrays. */ template inline hb_array_t - operator () (Type *array, unsigned int length) const + HB_INTERNAL operator () (Type *array, unsigned int length) const { return hb_array_t (array, length); } template hb_array_t - operator () (Type (&array)[length]) const + HB_INTERNAL operator () (Type (&array)[length]) const { return hb_array_t (array, length); } } hb_iter HB_UNUSED; @@ -156,31 +156,31 @@ struct hb_iter_fallback_mixin_t { private: /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - const iter_t* thiz () const { return static_cast (this); } - iter_t* thiz () { return static_cast< iter_t *> (this); } + HB_INTERNAL const iter_t* thiz () const { return static_cast (this); } + HB_INTERNAL iter_t* thiz () { return static_cast< iter_t *> (this); } public: /* Access: Implement __item__(), or __item_at__() if random-access. */ - item_t __item__ () const { return (*thiz())[0]; } - item_t __item_at__ (unsigned i) const { return *(*thiz() + i); } + HB_INTERNAL item_t __item__ () const { return (*thiz())[0]; } + HB_INTERNAL item_t __item_at__ (unsigned i) const { return *(*thiz() + i); } /* Termination: Implement __more__(), or __len__() if random-access. */ - bool __more__ () const { return thiz()->len (); } - unsigned __len__ () const + HB_INTERNAL bool __more__ () const { return thiz()->len (); } + HB_INTERNAL unsigned __len__ () const { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } /* Advancing: Implement __next__(), or __forward__() if random-access. */ - void __next__ () { *thiz() += 1; } - void __forward__ (unsigned n) { while (n--) ++*thiz(); } + HB_INTERNAL void __next__ () { *thiz() += 1; } + HB_INTERNAL void __forward__ (unsigned n) { while (n--) ++*thiz(); } /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */ - void __prev__ () { *thiz() -= 1; } - void __rewind__ (unsigned n) { while (n--) --*thiz(); } + HB_INTERNAL void __prev__ () { *thiz() -= 1; } + HB_INTERNAL void __rewind__ (unsigned n) { while (n--) --*thiz(); } protected: - hb_iter_fallback_mixin_t () {} - hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} - void operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} + HB_INTERNAL hb_iter_fallback_mixin_t () {} + HB_INTERNAL hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} + HB_INTERNAL void operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} }; template @@ -189,11 +189,11 @@ struct hb_iter_with_fallback_t : hb_iter_fallback_mixin_t { protected: - hb_iter_with_fallback_t () {} - hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) : + HB_INTERNAL hb_iter_with_fallback_t () {} + HB_INTERNAL hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) : hb_iter_t (o), hb_iter_fallback_mixin_t (o) {} - void operator = (const hb_iter_with_fallback_t &o HB_UNUSED) {} + HB_INTERNAL void operator = (const hb_iter_with_fallback_t &o HB_UNUSED) {} }; /* From dab92bdd4623aa7dac8eb00b14131566d75d095e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 22:39:38 -0400 Subject: [PATCH 010/336] Revert "Hide more symbols" This reverts commit 2e86d50915cf1a791da9acb95245aa820a3d70f4. I think the setup that caused me to do this is faulty and not hiding inlines. --- 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 d941bf6a9..3a30efe55 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -55,7 +55,7 @@ struct hb_blob_t HB_INTERNAL bool try_make_writable_inplace_unix (); template - HB_INTERNAL const Type* as () const + const Type* as () const { return length < hb_null_size (Type) ? &Null(Type) : reinterpret_cast (data); } From a98e4068e76d50bd9562d85a452b56e681f1d62b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 22:42:44 -0400 Subject: [PATCH 011/336] Revert "Hide symbols in hb-iter" This reverts commit 98f14c4cdb837a962083a6702f401d41b4c1ec5c. Same as previous commit. --- src/hb-iter.hh | 88 +++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2f9acf974..6f8e7ece1 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -58,8 +58,8 @@ struct hb_iter_t private: /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - HB_INTERNAL const iter_t* thiz () const { return static_cast (this); } - HB_INTERNAL iter_t* thiz () { return static_cast< iter_t *> (this); } + const iter_t* thiz () const { return static_cast (this); } + iter_t* thiz () { return static_cast< iter_t *> (this); } public: /* TODO: @@ -67,39 +67,39 @@ struct hb_iter_t * an operator and use it, and remove hb_iter_fallback_mixin_t completely. */ /* Operators. */ - HB_INTERNAL iter_t iter () const { return *thiz(); } - HB_INTERNAL iter_t operator + () const { return *thiz(); } - HB_INTERNAL explicit operator bool () const { return thiz()->__more__ (); } - HB_INTERNAL unsigned len () const { return thiz()->__len__ (); } + iter_t iter () const { return *thiz(); } + iter_t operator + () const { return *thiz(); } + explicit operator bool () const { return thiz()->__more__ (); } + unsigned len () const { return thiz()->__len__ (); } /* The following can only be enabled if item_t is reference type. Otherwise * it will be returning pointer to temporary rvalue. */ template - HB_INTERNAL hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } - HB_INTERNAL item_t operator * () const { return thiz()->__item__ (); } - HB_INTERNAL item_t operator * () { return thiz()->__item__ (); } - HB_INTERNAL item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } - HB_INTERNAL item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); } - HB_INTERNAL iter_t& operator += (unsigned count) { thiz()->__forward__ (count); return *thiz(); } - HB_INTERNAL iter_t& operator ++ () { thiz()->__next__ (); return *thiz(); } - HB_INTERNAL iter_t& operator -= (unsigned count) { thiz()->__rewind__ (count); return *thiz(); } - HB_INTERNAL iter_t& operator -- () { thiz()->__prev__ (); return *thiz(); } - HB_INTERNAL iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; } - HB_INTERNAL friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; } - HB_INTERNAL iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; } - HB_INTERNAL iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; } - HB_INTERNAL iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } + hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } + item_t operator * () const { return thiz()->__item__ (); } + item_t operator * () { return thiz()->__item__ (); } + item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } + item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); } + iter_t& operator += (unsigned count) { thiz()->__forward__ (count); return *thiz(); } + iter_t& operator ++ () { thiz()->__next__ (); return *thiz(); } + iter_t& operator -= (unsigned count) { thiz()->__rewind__ (count); return *thiz(); } + iter_t& operator -- () { thiz()->__prev__ (); return *thiz(); } + iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; } + friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; } + iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; } + iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; } + iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } template - HB_INTERNAL iter_t& operator >> (T &v) { v = **thiz(); ++*thiz(); return *thiz(); } + iter_t& operator >> (T &v) { v = **thiz(); ++*thiz(); return *thiz(); } template - HB_INTERNAL iter_t& operator >> (T &v) const { v = **thiz(); ++*thiz(); return *thiz(); } + iter_t& operator >> (T &v) const { v = **thiz(); ++*thiz(); return *thiz(); } template - HB_INTERNAL iter_t& operator << (const T v) { **thiz() = v; ++*thiz(); return *thiz(); } + iter_t& operator << (const T v) { **thiz() = v; ++*thiz(); return *thiz(); } protected: - HB_INTERNAL hb_iter_t () {} - HB_INTERNAL hb_iter_t (const hb_iter_t &o HB_UNUSED) {} - HB_INTERNAL void operator = (const hb_iter_t &o HB_UNUSED) {} + hb_iter_t () {} + hb_iter_t (const hb_iter_t &o HB_UNUSED) {} + void operator = (const hb_iter_t &o HB_UNUSED) {} }; #define HB_ITER_USING(Name) \ @@ -140,11 +140,11 @@ static const struct /* Specialization for C arrays. */ template inline hb_array_t - HB_INTERNAL operator () (Type *array, unsigned int length) const + operator () (Type *array, unsigned int length) const { return hb_array_t (array, length); } template hb_array_t - HB_INTERNAL operator () (Type (&array)[length]) const + operator () (Type (&array)[length]) const { return hb_array_t (array, length); } } hb_iter HB_UNUSED; @@ -156,31 +156,31 @@ struct hb_iter_fallback_mixin_t { private: /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - HB_INTERNAL const iter_t* thiz () const { return static_cast (this); } - HB_INTERNAL iter_t* thiz () { return static_cast< iter_t *> (this); } + const iter_t* thiz () const { return static_cast (this); } + iter_t* thiz () { return static_cast< iter_t *> (this); } public: /* Access: Implement __item__(), or __item_at__() if random-access. */ - HB_INTERNAL item_t __item__ () const { return (*thiz())[0]; } - HB_INTERNAL item_t __item_at__ (unsigned i) const { return *(*thiz() + i); } + item_t __item__ () const { return (*thiz())[0]; } + item_t __item_at__ (unsigned i) const { return *(*thiz() + i); } /* Termination: Implement __more__(), or __len__() if random-access. */ - HB_INTERNAL bool __more__ () const { return thiz()->len (); } - HB_INTERNAL unsigned __len__ () const + bool __more__ () const { return thiz()->len (); } + unsigned __len__ () const { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } /* Advancing: Implement __next__(), or __forward__() if random-access. */ - HB_INTERNAL void __next__ () { *thiz() += 1; } - HB_INTERNAL void __forward__ (unsigned n) { while (n--) ++*thiz(); } + void __next__ () { *thiz() += 1; } + void __forward__ (unsigned n) { while (n--) ++*thiz(); } /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */ - HB_INTERNAL void __prev__ () { *thiz() -= 1; } - HB_INTERNAL void __rewind__ (unsigned n) { while (n--) --*thiz(); } + void __prev__ () { *thiz() -= 1; } + void __rewind__ (unsigned n) { while (n--) --*thiz(); } protected: - HB_INTERNAL hb_iter_fallback_mixin_t () {} - HB_INTERNAL hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} - HB_INTERNAL void operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} + hb_iter_fallback_mixin_t () {} + hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} + void operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} }; template @@ -189,11 +189,11 @@ struct hb_iter_with_fallback_t : hb_iter_fallback_mixin_t { protected: - HB_INTERNAL hb_iter_with_fallback_t () {} - HB_INTERNAL hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) : + hb_iter_with_fallback_t () {} + hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) : hb_iter_t (o), hb_iter_fallback_mixin_t (o) {} - HB_INTERNAL void operator = (const hb_iter_with_fallback_t &o HB_UNUSED) {} + void operator = (const hb_iter_with_fallback_t &o HB_UNUSED) {} }; /* From 47e538a35f9072e5775a65e2bf110ae895818321 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 12 Apr 2019 22:50:22 -0400 Subject: [PATCH 012/336] Add HB_NO_SUBSET_LAYOUT Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-subset.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 655e495fb..4362eef60 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -47,7 +47,7 @@ #include "hb-ot-layout-gpos-table.hh" -static unsigned int +static HB_UNUSED unsigned int _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned int table_len) { @@ -196,6 +196,8 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_VORG: result = _subset (plan); break; + +#if !defined(HB_NO_SUBSET_LAYOUT) case HB_OT_TAG_GDEF: result = _subset2 (plan); break; @@ -205,6 +207,7 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_GPOS: result = _subset2 (plan); break; +#endif default: hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); @@ -230,11 +233,16 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */ case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */ return plan->drop_hints; + // Drop Layout Tables if requested. case HB_OT_TAG_GDEF: case HB_OT_TAG_GPOS: case HB_OT_TAG_GSUB: +#if defined(HB_NO_SUBSET_LAYOUT) + return true; +#endif return plan->drop_layout; + // Drop these tables below by default, list pulled // from fontTools: case HB_TAG ('B', 'A', 'S', 'E'): From c0ea37b557f53b50094042f11fe2611b1b30d725 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 15 Apr 2019 00:34:04 +0430 Subject: [PATCH 013/336] [ci] Fix macOS glib issue --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a747ec5c2..1c901ebf1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,7 +28,7 @@ jobs: steps: - checkout - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget autoconf automake libtool pkg-config ragel freetype glib cairo icu4c graphite2 - - run: export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig" && ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-coretext --with-graphite2 + - run: export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" && ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-coretext --with-graphite2 - run: make -j4 - run: make check || .ci/fail.sh @@ -250,7 +250,7 @@ jobs: steps: - checkout - run: git clone https://github.com/vitasdk/vdpm && cd vdpm && ./bootstrap-vitasdk.sh - - run: echo "#""!""/bin/true" > /usr/bin/ragel && chmod +x /usr/bin/ragel + - run: echo '#!/bin/true' > /usr/bin/ragel && chmod +x /usr/bin/ragel - run: ./autogen.sh --prefix=/usr/local/vitasdk/arm-vita-eabi --host=arm-vita-eabi - run: make -j32 From 1ae265888e144328dbf1df796d379bf742c4151a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 11:31:40 -0400 Subject: [PATCH 014/336] Fix gcc warning --- src/hb-array.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index c744a2fd9..d42e086bd 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -43,7 +43,9 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> * Constructors. */ hb_array_t () : arrayZ (nullptr), length (0) {} - hb_array_t (const hb_array_t &o) : arrayZ (o.arrayZ), length (o.length) {} + hb_array_t (const hb_array_t &o) : + hb_iter_with_fallback_t, Type&> (), + arrayZ (o.arrayZ), length (o.length) {} template hb_array_t (const hb_array_t &o) : arrayZ (o.arrayZ), length (o.length) {} From 3a88f55c15b625a0ad10fbfadf4562bcbb41ae53 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 11:59:57 -0400 Subject: [PATCH 015/336] Move location of HB_UNUSED to make MSVC happy --- src/hb-subset.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 4362eef60..4c7fbf92b 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -47,9 +47,9 @@ #include "hb-ot-layout-gpos-table.hh" -static HB_UNUSED unsigned int +static unsigned int _plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned int table_len) + unsigned int table_len) HB_UNUSED { unsigned int src_glyphs = plan->source->get_num_glyphs (); unsigned int dst_glyphs = plan->glyphset ()->get_population (); From 19e800c9d881ec016ab2e5fcaadab55ab5188398 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 12:07:00 -0400 Subject: [PATCH 016/336] Ugh. Another try, to unbreak gcc this time! Jenga. --- src/hb-subset.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 4c7fbf92b..bccb98d62 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -47,9 +47,12 @@ #include "hb-ot-layout-gpos-table.hh" -static unsigned int +HB_UNUSED static inline unsigned int _plan_estimate_subset_table_size (hb_subset_plan_t *plan, - unsigned int table_len) HB_UNUSED + unsigned int table_len); +static inline unsigned int +_plan_estimate_subset_table_size (hb_subset_plan_t *plan, + unsigned int table_len) { unsigned int src_glyphs = plan->source->get_num_glyphs (); unsigned int dst_glyphs = plan->glyphset ()->get_population (); From 38b1d0b9b2e798dd808a816a397323ed7ba697ab Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 12:44:31 -0400 Subject: [PATCH 017/336] Move static const to post-struct for a function object Just sending this to bots to see if all happy, then turn it into macro and apply everywhere. Part of https://github.com/harfbuzz/harfbuzz/issues/1651 --- src/hb-algs.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 2765e1ced..c52ffec32 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -32,7 +32,7 @@ #include "hb-null.hh" -static const struct +struct { /* Don't know how to set priority of following. Doesn't work right now. */ //template @@ -54,7 +54,7 @@ static const struct /* Knuth's multiplicative method: */ return (uint32_t) v * 2654435761u; } -} hb_hash HB_UNUSED; +} static const hb_hash HB_UNUSED; static const struct { From 60be1450ad04612a6c2a6116036dbf3e436018de Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Mon, 15 Apr 2019 18:05:14 +0100 Subject: [PATCH 018/336] [Usermanual]: fix Tamil error in Why-do-I-need-a-shaping-engine section. --- docs/usermanual-what-is-harfbuzz.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml index ed053f9ae..3513fb285 100644 --- a/docs/usermanual-what-is-harfbuzz.xml +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -151,9 +151,9 @@ For example, in Tamil, when the letter "TTA" (ட) - letter is followed by "U" (உ), the pair + letter is followed by the vowel sign "U" (ு), the pair must be replaced by the single glyph "டு". The - sequence of Unicode characters "டஉ" needs to be + sequence of Unicode characters "ட,ு" needs to be substituted with a single "டு" glyph from the font. From 02d864aa26359b7f057e2aa81404309e17180d47 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 15:39:03 -0400 Subject: [PATCH 019/336] Add HB_FUNCOBJ() Fixes https://github.com/harfbuzz/harfbuzz/issues/1651 --- src/hb-algs.hh | 28 +++++++++++++------------ src/hb-iter.hh | 56 +++++++++++++++++++++++++------------------------- src/hb-meta.hh | 22 ++++++++++++-------- src/hb.hh | 7 +++++++ 4 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index c52ffec32..5ee0a4cac 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -1,5 +1,6 @@ /* * Copyright © 2017 Google, Inc. + * Copyright © 2019 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -22,6 +23,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Google Author(s): Behdad Esfahbod + * Facebook Author(s): Behdad Esfahbod */ #ifndef HB_ALGS_HH @@ -54,19 +56,19 @@ struct /* Knuth's multiplicative method: */ return (uint32_t) v * 2654435761u; } -} static const hb_hash HB_UNUSED; +} HB_FUNCOBJ (hb_hash); -static const struct +struct { template T operator () (const T& v) const { return v; } -} hb_identity HB_UNUSED; +} HB_FUNCOBJ (hb_identity); -static const struct +struct { template bool operator () (const T& v) const { return bool (v); } -} hb_bool HB_UNUSED; +} HB_FUNCOBJ (hb_bool); template struct hb_pair_t @@ -86,28 +88,28 @@ struct hb_pair_t template static inline hb_pair_t hb_pair (T1&& a, T2&& b) { return hb_pair_t (a, b); } -static const struct +struct { template decltype (hb_declval (Pair).first) operator () (const Pair& pair) const { return pair.first; } -} hb_first HB_UNUSED; +} HB_FUNCOBJ (hb_first); -static const struct +struct { template decltype (hb_declval (Pair).second) operator () (const Pair& pair) const { return pair.second; } -} hb_second HB_UNUSED; +} HB_FUNCOBJ (hb_second); -static const struct +struct { template T operator () (const T& a, const T2& b) const { return a <= b ? a : b; } -} hb_min HB_UNUSED; -static const struct +} HB_FUNCOBJ (hb_min); +struct { template T operator () (const T& a, const T2& b) const { return a >= b ? a : b; } -} hb_max HB_UNUSED; +} HB_FUNCOBJ (hb_max); /* diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 6f8e7ece1..a75be85f0 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -1,5 +1,6 @@ /* * Copyright © 2018 Google, Inc. + * Copyright © 2019 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -22,6 +23,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Google Author(s): Behdad Esfahbod + * Facebook Author(s): Behdad Esfahbod */ #ifndef HB_ITER_HH @@ -130,7 +132,7 @@ struct hb_iter_t template struct hb_array_t; -static const struct +struct { template hb_iter_t (T) @@ -147,7 +149,7 @@ static const struct operator () (Type (&array)[length]) const { return hb_array_t (array, length); } -} hb_iter HB_UNUSED; +} HB_FUNCOBJ (hb_iter); /* Mixin to fill in what the subclass doesn't provide. */ @@ -298,13 +300,13 @@ struct hb_map_iter_factory_t private: Proj f; }; -static const struct +struct { template hb_map_iter_factory_t operator () (Proj&& f) const { return hb_map_iter_factory_t (f); } -} hb_map HB_UNUSED; +} HB_FUNCOBJ (hb_map); template @@ -342,14 +344,14 @@ struct hb_filter_iter_factory_t Pred p; Proj f; }; -static const struct +struct { template hb_filter_iter_factory_t operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const { return hb_filter_iter_factory_t (p, f); } -} hb_filter HB_UNUSED; +} HB_FUNCOBJ (hb_filter); template struct hb_reduce_t @@ -372,13 +374,13 @@ struct hb_reduce_t Redu r; InitT init_value; }; -static const struct +struct { template hb_reduce_t operator () (Redu&& r, InitT init_value) const { return hb_reduce_t (r, init_value); } -} hb_reduce HB_UNUSED; +} HB_FUNCOBJ (hb_reduce); /* hb_zip() */ @@ -411,14 +413,14 @@ struct hb_zip_iter_t : A a; B b; }; -static const struct +struct { template hb_zip_iter_t operator () (A& a, B &b) const { return hb_zip_iter_t (hb_iter (a), hb_iter (b)); } -} hb_zip HB_UNUSED; +} HB_FUNCOBJ (hb_zip); /* hb_enumerate */ @@ -446,14 +448,14 @@ struct hb_enumerate_iter_t : unsigned i; Iter it; }; -static const struct +struct { template hb_enumerate_iter_t operator () (Iterable& it) const { return hb_enumerate_iter_t (hb_iter (it)); } -} hb_enumerate HB_UNUSED; +} HB_FUNCOBJ (hb_enumerate); /* hb_apply() */ @@ -474,7 +476,7 @@ struct hb_apply_t private: Appl a; }; -static const struct +struct { template hb_apply_t operator () (Appl&& a) const @@ -483,7 +485,7 @@ static const struct template hb_apply_t operator () (Appl *a) const { return hb_apply_t (*a); } -} hb_apply HB_UNUSED; +} HB_FUNCOBJ (hb_apply); /* hb_sink() */ @@ -504,7 +506,7 @@ struct hb_sink_t private: Sink s; }; -static const struct +struct { template hb_sink_t operator () (Sink&& s) const @@ -513,11 +515,11 @@ static const struct template hb_sink_t operator () (Sink *s) const { return hb_sink_t (*s); } -} hb_sink HB_UNUSED; +} HB_FUNCOBJ (hb_sink); /* hb-drain: hb_sink to void / blackhole / /dev/null. */ -static const struct +struct { template @@ -527,7 +529,7 @@ static const struct for (; it; ++it) (void) *it; } -} hb_drain HB_UNUSED; +} HB_FUNCOBJ (hb_drain); /* hb_unzip(): unzip and sink to two sinks. */ @@ -553,7 +555,7 @@ struct hb_unzip_t Sink1 s1; Sink2 s2; }; -static const struct +struct { template hb_unzip_t operator () (Sink1&& s1, Sink2&& s2) const @@ -562,12 +564,12 @@ static const struct template hb_unzip_t operator () (Sink1 *s1, Sink2 *s2) const { return hb_unzip_t (*s1, *s2); } -} hb_unzip HB_UNUSED; +} HB_FUNCOBJ (hb_unzip); /* hb-all, hb-any, hb-none. */ -static const struct +struct { template @@ -579,9 +581,8 @@ static const struct return false; return true; } -} hb_all HB_UNUSED; - -static const struct +} HB_FUNCOBJ (hb_all); +struct { template @@ -593,9 +594,8 @@ static const struct return true; return false; } -} hb_any HB_UNUSED; - -static const struct +} HB_FUNCOBJ (hb_any); +struct { template @@ -607,7 +607,7 @@ static const struct return false; return true; } -} hb_none HB_UNUSED; +} HB_FUNCOBJ (hb_none); /* * Algorithms operating on iterators. diff --git a/src/hb-meta.hh b/src/hb-meta.hh index c7c91ea50..a71121991 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -34,18 +34,22 @@ * C++ template meta-programming & fundamentals used with them. */ +#define HB_FUNCOBJ(x) static_const x HB_UNUSED -template static inline T* -hb_addressof (const T& arg) +struct { + template + T* operator () (const T& arg) const + { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - /* https://en.cppreference.com/w/cpp/memory/addressof */ - return reinterpret_cast( - &const_cast( - reinterpret_cast(arg))); + /* https://en.cppreference.com/w/cpp/memory/addressof */ + return reinterpret_cast ( + &const_cast ( + reinterpret_cast (arg))); #pragma GCC diagnostic pop -} + } +} HB_FUNCOBJ (hb_addressof); template static inline T hb_declval (); #define hb_declval(T) (hb_declval ()) @@ -63,13 +67,13 @@ template struct hb_match_pointer { typedef T type; enum { valu #define hb_remove_pointer(T) typename hb_match_pointer::type #define hb_is_pointer(T) hb_match_pointer::value -static const struct +struct { template T operator () (T v) const { return v; } template T& operator () (T *v) const { return *v; } -} hb_deref_pointer HB_UNUSED; +} HB_FUNCOBJ (hb_deref_pointer); /* std::move and std::forward */ diff --git a/src/hb.hh b/src/hb.hh index 4ea10976e..172b6ac6f 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -260,6 +260,13 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); # endif #endif +/* https://github.com/harfbuzz/harfbuzz/issues/1651 */ +#if defined(__clang__) && __clang_major__ < 10 +#define static_const static +#else +#define static_const static const +#endif + #if defined(__GNUC__) && (__GNUC__ >= 3) #define HB_FUNC __PRETTY_FUNCTION__ #elif defined(_MSC_VER) From 699de689e9aa2246ba9207c07140ccd564f5ec20 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 16:00:20 -0400 Subject: [PATCH 020/336] Delete default assignment operator Offset<> --- src/hb-open-type.hh | 3 +++ src/hb-ot-cmap-table.hh | 2 +- src/hb-ot-layout-common.hh | 14 +++++++------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 05b8c72d7..b43bd40a1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -173,6 +173,9 @@ typedef Index NameID; template struct Offset : Type { + HB_DELETE_COPY_ASSIGN (Offset); + Offset () = default; + Offset& operator = (typename Type::type i) { Type::operator= (i); return *this; } typedef Type type; diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 08f186e8c..0a7d1ef67 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -904,7 +904,7 @@ struct cmap // Write out format 4 sub table { CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table); - format4_plat3_rec.subtable = format4_plat0_rec.subtable; + format4_plat3_rec.subtable = (unsigned int) format4_plat0_rec.subtable; subtable.u.format = 4; CmapSubtableFormat4 &format4 = subtable.u.format4; diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 8882efd68..b85d1226e 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -583,25 +583,25 @@ struct Feature * Adobe tools, only the 'size' feature had FeatureParams defined. */ - OffsetTo orig_offset = featureParams; + if (likely (featureParams.is_null ())) + return_trace (true); + + unsigned int orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) return_trace (false); - if (likely (orig_offset.is_null ())) - return_trace (true); - if (featureParams == 0 && closure && closure->tag == HB_TAG ('s','i','z','e') && closure->list_base && closure->list_base < this) { - unsigned int new_offset_int = (unsigned int) orig_offset - + unsigned int new_offset_int = orig_offset - (((char *) this) - ((char *) closure->list_base)); OffsetTo new_offset; - /* Check that it did not overflow. */ + /* Check that it would not overflow. */ new_offset = new_offset_int; if (new_offset == new_offset_int && - c->try_set (&featureParams, new_offset) && + c->try_set (&featureParams, new_offset_int) && !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) return_trace (false); } From 07776b60965d503dfb7fb5c611397e40759b0bdc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 16:43:34 -0400 Subject: [PATCH 021/336] More tweaks to previous commit Delete assignment operator of OffsetTo<> instead of Offset<>. In simple ArrayOf<>::sanitize() assert that Type has assignment operator. Ideally we should SFINAE this and fallback to calling Type::sanitize() if assignment operator is not available. But we don't have a case of that in the codebase. --- src/hb-open-file.hh | 4 ++-- src/hb-open-type.hh | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 7b140fa7c..7e916aeb6 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -86,8 +86,8 @@ typedef struct OffsetTable const TableRecord& get_table (unsigned int i) const { return tables[i]; } unsigned int get_table_tags (unsigned int start_offset, - unsigned int *table_count, /* IN/OUT */ - hb_tag_t *table_tags /* OUT */) const + unsigned int *table_count, /* IN/OUT */ + hb_tag_t *table_tags /* OUT */) const { if (table_count) { diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index b43bd40a1..23f7511b1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -173,9 +173,6 @@ typedef Index NameID; template struct Offset : Type { - HB_DELETE_COPY_ASSIGN (Offset); - Offset () = default; - Offset& operator = (typename Type::type i) { Type::operator= (i); return *this; } typedef Type type; @@ -266,6 +263,9 @@ struct _hb_has_null template struct OffsetTo : Offset { + HB_DELETE_COPY_ASSIGN (OffsetTo); + OffsetTo () = default; + OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; } const Type& operator () (const void *base) const @@ -609,10 +609,16 @@ struct ArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && arrayZ[0].sanitize (c)); + if (false) + { + arrayZ[0].sanitize (c); + Type v; + v = arrayZ[0]; + } return_trace (true); } From 3ff66c00292b20325b0d991dfd5eee80284cb9a8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 16:52:21 -0400 Subject: [PATCH 022/336] [fuzzing] Fail if valgrind is requested but not found --- test/fuzzing/run-shape-fuzzer-tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index e3d180f2b..54fddfbe9 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -70,6 +70,9 @@ fails = 0 valgrind = None if os.environ.get('RUN_VALGRIND', ''): valgrind = which ('valgrind') + if valgrind is None: + print ("""Valgrind requested but not found.""") + sys.exit (1) parent_path = os.path.join (srcdir, "fonts") for file in os.listdir (parent_path): From b7384c89e2685cec1b6761c918ec7d91e8ae3af8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 16:53:10 -0400 Subject: [PATCH 023/336] [fuzzing] Run valgrind with --leak-check=full --- test/fuzzing/run-shape-fuzzer-tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index 54fddfbe9..90ed509c7 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -88,7 +88,7 @@ for file in os.listdir (parent_path): failed = True if valgrind: - text, returncode = cmd ([valgrind, '--error-exitcode=1', hb_shape_fuzzer, path]) + text, returncode = cmd ([valgrind, '--error-exitcode=1', '--leak-check=full', hb_shape_fuzzer, path]) if returncode: print (text) print ('failure on %s' % file) From 89fea21697adfbba5057dd1d69c9806ee86e5ca8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 15 Apr 2019 17:36:09 -0400 Subject: [PATCH 024/336] Fix copyright --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a75be85f0..98290921e 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -1,6 +1,6 @@ /* * Copyright © 2018 Google, Inc. - * Copyright © 2019 Google, Inc. + * Copyright © 2019 Facebook, Inc. * * This is part of HarfBuzz, a text shaping library. * From ff68be31bf2ea82bf6bfcc6f993fb6806a895f97 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 09:59:08 -0400 Subject: [PATCH 025/336] Add hb_void_tt<> ala std::void_t --- src/hb-meta.hh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index a71121991..d2733d716 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -90,6 +90,13 @@ static T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; } /* Void! For when we need a expression-type of void. */ struct hb_void_t { typedef void value; }; +/* Void meta-function ala std::void_t + * https://en.cppreference.com/w/cpp/types/void_t */ +template +struct _hb_make_void { typedef void type; }; +template +using hb_void_tt = typename _hb_make_void::type; + /* Bool! For when we need to evaluate type-dependent expressions * in a template argument. */ template struct hb_bool_tt { enum { value = b }; }; From a3fcb9a370ad7a3c205342f831d8529c81660466 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 10:45:20 -0400 Subject: [PATCH 026/336] [meta] Add HB_AUTO_RETURN_EXPR, HB_VOID_RETURN_EXPR, hb_priority, hb_has(), hb_get() The first three based on range-v3. --- src/hb-algs.hh | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/hb-iter.hh | 7 ++++--- src/hb-meta.hh | 32 +++++++++++++++----------------- src/hb.hh | 2 +- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 5ee0a4cac..1cda64f9b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -70,6 +70,52 @@ struct operator () (const T& v) const { return bool (v); } } HB_FUNCOBJ (hb_bool); +struct +{ + private: + + template auto + impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v)) + + template auto + impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v)) + + template auto + impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR (p (v)) + + public: + + template auto + operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR ( + (bool) impl (hb_forward (p), + hb_forward (v), + hb_prioritize) + ) +} HB_FUNCOBJ (hb_has); + +struct +{ + private: + + template auto + impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f->get (hb_forward (v))) + + template auto + impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward (v))) + + template auto + impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f (hb_forward (v))) + + public: + + template auto + operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR ( + impl (hb_forward (f), + hb_forward (v), + hb_prioritize) + ) +} HB_FUNCOBJ (hb_get); + template struct hb_pair_t { diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 98290921e..719987dea 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -30,6 +30,7 @@ #define HB_ITER_HH #include "hb.hh" +#include "hb-algs.hh" #include "hb-meta.hh" @@ -272,8 +273,8 @@ struct hb_map_iter_t : typedef decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t))) __item_t__; static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - __item_t__ __item__ () const { return f (*it); } - __item_t__ __item_at__ (unsigned i) const { return f (it[i]); } + __item_t__ __item__ () const { return hb_get (f, *it); } + __item_t__ __item_at__ (unsigned i) const { return hb_get (f, it[i]); } bool __more__ () const { return bool (it); } unsigned __len__ () const { return it.len (); } void __next__ () { ++it; } @@ -315,7 +316,7 @@ struct hb_filter_iter_t : typename Iter::item_t> { hb_filter_iter_t (const Iter& it_, Pred p, Proj f) : it (it_), p (p), f (f) - { while (it && !p (f (*it))) ++it; } + { while (it && !hb_has (p, hb_get (f, *it))) ++it; } typedef typename Iter::item_t __item_t__; static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; diff --git a/src/hb-meta.hh b/src/hb-meta.hh index d2733d716..83b0ad6b3 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -92,10 +92,8 @@ struct hb_void_t { typedef void value; }; /* Void meta-function ala std::void_t * https://en.cppreference.com/w/cpp/types/void_t */ -template -struct _hb_make_void { typedef void type; }; -template -using hb_void_tt = typename _hb_make_void::type; +template struct _hb_void_tt { typedef void type; }; +template using hb_void_tt = typename _hb_void_tt::type; /* Bool! For when we need to evaluate type-dependent expressions * in a template argument. */ @@ -103,23 +101,14 @@ template struct hb_bool_tt { enum { value = b }; }; typedef hb_bool_tt hb_true_t; typedef hb_bool_tt hb_false_t; -template -struct hb_enable_if {}; -template -struct hb_enable_if { typedef T type; }; +template struct hb_enable_if {}; +template struct hb_enable_if { typedef T type; }; #define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr -template -struct hb_is_same : hb_false_t {}; -template -struct hb_is_same : hb_true_t {}; +template struct hb_is_same : hb_false_t {}; +template struct hb_is_same : hb_true_t {}; #define hb_is_same(T, T2) hb_is_same::value - -/* - * Meta-functions. - */ - template struct hb_is_signed; /* https://github.com/harfbuzz/harfbuzz/issues/1535 */ template <> struct hb_is_signed { enum { value = true }; }; @@ -151,5 +140,14 @@ template <> struct hb_is_integer { enum { value = true }; }; template <> struct hb_is_integer { enum { value = true }; }; #define hb_is_integer(T) hb_is_integer::value +/* Function overloading SFINAE and priority. */ + +#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); } +#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt { (E); } + +template struct hb_priority : hb_priority {}; +template <> struct hb_priority<0> {}; +#define hb_prioritize hb_priority<16> () + #endif /* HB_META_HH */ diff --git a/src/hb.hh b/src/hb.hh index 172b6ac6f..ee35c4dd9 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -651,7 +651,7 @@ struct BEInt #include "hb-atomic.hh" // Requires: hb-meta #include "hb-null.hh" // Requires: hb-meta #include "hb-algs.hh" // Requires: hb-meta hb-null -#include "hb-iter.hh" // Requires: hb-meta +#include "hb-iter.hh" // Requires: hb-algs hb-meta #include "hb-debug.hh" // Requires: hb-algs hb-atomic #include "hb-array.hh" // Requires: hb-algs hb-iter hb-null #include "hb-vector.hh" // Requires: hb-array hb-null From b8e763fd7140b3e298863e04053ec0f3c73a6a70 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 10:50:22 -0400 Subject: [PATCH 027/336] [meta] Add hb_invoke() --- src/hb-algs.hh | 34 ++++++++++++++++++++++++++++++++-- src/hb-iter.hh | 2 +- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 1cda64f9b..1460e72fb 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -70,6 +70,29 @@ struct operator () (const T& v) const { return bool (v); } } HB_FUNCOBJ (hb_bool); + +struct +{ + private: + + // TODO Add overload to for pointer-to-member-function + + template auto + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward (v))) + + template auto + impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ((*a) (hb_forward (v))) + + public: + + template auto + operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR ( + impl (hb_forward (a), + hb_forward (v), + hb_prioritize) + ) +} HB_FUNCOBJ (hb_invoke); + struct { private: @@ -81,7 +104,10 @@ struct impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v)) template auto - impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR (p (v)) + impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ( + hb_invoke (hb_forward (p), + hb_forward (v)) + ) public: @@ -104,7 +130,10 @@ struct impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward (v))) template auto - impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f (hb_forward (v))) + impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR ( + hb_invoke (hb_forward (f), + hb_forward (v)) + ) public: @@ -116,6 +145,7 @@ struct ) } HB_FUNCOBJ (hb_get); + template struct hb_pair_t { diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 719987dea..7e7673326 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -471,7 +471,7 @@ struct hb_apply_t operator () (Iter it) const { for (; it; ++it) - a (*it); + (void) hb_invoke (a, *it); } private: From e03d9395aa79a29d731607bfd46533b700dc1a37 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 11:20:16 -0400 Subject: [PATCH 028/336] Comment --- src/hb-algs.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 1460e72fb..7d19bd899 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -75,7 +75,7 @@ struct { private: - // TODO Add overload to for pointer-to-member-function + // TODO Add overload to for pointer-to-member and pointer-to-member-function ala std::invoke template auto impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward (v))) From 4fc2d2d7248171c386c39630aa2612f240669a58 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 11:24:42 -0400 Subject: [PATCH 029/336] [meta] Flesh out hb_invoke() --- src/hb-algs.hh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 7d19bd899..6981d06ae 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -75,11 +75,21 @@ struct { private: - // TODO Add overload to for pointer-to-member and pointer-to-member-function ala std::invoke + /* Pointer-to-member-function. */ + template auto + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a ()) + template auto + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a ()) + /* Pointer-to-member. */ + template auto + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a) + template auto + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a) + + /* Operator(). */ template auto impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward (v))) - template auto impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ((*a) (hb_forward (v))) From 155e92f25908830bef192304a2039853f6f5d4b5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 11:35:09 -0400 Subject: [PATCH 030/336] Reduce NullPool size --- 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 9d23d50c3..6d4a68360 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -37,7 +37,7 @@ /* Global nul-content Null pool. Enlarge as necessary. */ -#define HB_NULL_POOL_SIZE 9880 +#define HB_NULL_POOL_SIZE 384 /* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, * otherwise return sizeof(T). */ From 1ce11b44375dae74e8984ace1db4f08c51ac9c38 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Tue, 16 Apr 2019 10:04:45 -0400 Subject: [PATCH 031/336] Reduce LangTag from 3 language system tags to 1 --- src/gen-tag-table.py | 13 +- src/hb-ot-tag-table.hh | 2078 ++++++++++++++++++++-------------------- src/hb-ot-tag.cc | 22 +- 3 files changed, 1053 insertions(+), 1060 deletions(-) diff --git a/src/gen-tag-table.py b/src/gen-tag-table.py index 13004629d..1e225c4bd 100755 --- a/src/gen-tag-table.py +++ b/src/gen-tag-table.py @@ -895,20 +895,11 @@ def language_name_intersection (a, b): def get_matching_language_name (intersection, candidates): return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) -maximum_tags = 0 for language, tags in sorted (ot.from_bcp_47.items ()): if language == '' or '-' in language: continue - print (' {\"%s\",\t{' % language, end='') - maximum_tags = max (maximum_tags, len (tags)) - tag_count = len (tags) for i, tag in enumerate (tags, start=1): - if i > 1: - print ('\t\t ', end='') - print (hb_tag (tag), end='') - if i == tag_count: - print ('}}', end='') - print (',\t/* ', end='') + print (' {\"%s\",\t%s},\t/* ' % (language, hb_tag (tag)), end='') bcp_47_name = bcp_47.names.get (language, '') bcp_47_name_candidates = bcp_47_name.split ('\n') intersection = language_name_intersection (bcp_47_name, ot.names[tag]) @@ -923,8 +914,6 @@ for language, tags in sorted (ot.from_bcp_47.items ()): print ('};') print () -print ('static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == %iu, "");' % maximum_tags) -print () print ('/**') print (' * hb_ot_tags_from_complex_language:') diff --git a/src/hb-ot-tag-table.hh b/src/hb-ot-tag-table.hh index 09e162718..c7717a347 100644 --- a/src/hb-ot-tag-table.hh +++ b/src/hb-ot-tag-table.hh @@ -7,1054 +7,1052 @@ * on files with these headers: * * - * File-Date: 2019-02-20 + * File-Date: 2019-04-03 */ #ifndef HB_OT_TAG_TABLE_HH #define HB_OT_TAG_TABLE_HH static const LangTag ot_languages[] = { - {"aa", {HB_TAG('A','F','R',' ')}}, /* Afar */ - {"aae", {HB_TAG('S','Q','I',' ')}}, /* Arbëreshë Albanian -> Albanian */ - {"aao", {HB_TAG('A','R','A',' ')}}, /* Algerian Saharan Arabic -> Arabic */ - {"aat", {HB_TAG('S','Q','I',' ')}}, /* Arvanitika Albanian -> Albanian */ - {"ab", {HB_TAG('A','B','K',' ')}}, /* Abkhazian */ - {"abh", {HB_TAG('A','R','A',' ')}}, /* Tajiki Arabic -> Arabic */ - {"abq", {HB_TAG('A','B','A',' ')}}, /* Abaza */ - {"abv", {HB_TAG('A','R','A',' ')}}, /* Baharna Arabic -> Arabic */ - {"acf", {HB_TAG('F','A','N',' ')}}, /* Saint Lucian Creole French -> French Antillean */ - {"ach", {HB_TAG('A','C','H',' ')}}, /* Acoli -> Acholi */ - {"acm", {HB_TAG('A','R','A',' ')}}, /* Mesopotamian Arabic -> Arabic */ - {"acq", {HB_TAG('A','R','A',' ')}}, /* Ta'izzi-Adeni Arabic -> Arabic */ - {"acr", {HB_TAG('A','C','R',' ')}}, /* Achi */ - {"acw", {HB_TAG('A','R','A',' ')}}, /* Hijazi Arabic -> Arabic */ - {"acx", {HB_TAG('A','R','A',' ')}}, /* Omani Arabic -> Arabic */ - {"acy", {HB_TAG('A','R','A',' ')}}, /* Cypriot Arabic -> Arabic */ - {"ada", {HB_TAG('D','N','G',' ')}}, /* Adangme -> Dangme */ - {"adf", {HB_TAG('A','R','A',' ')}}, /* Dhofari Arabic -> Arabic */ - {"adp", {HB_TAG('D','Z','N',' ')}}, /* Adap (retired code) -> Dzongkha */ - {"ady", {HB_TAG('A','D','Y',' ')}}, /* Adyghe */ - {"aeb", {HB_TAG('A','R','A',' ')}}, /* Tunisian Arabic -> Arabic */ - {"aec", {HB_TAG('A','R','A',' ')}}, /* Saidi Arabic -> Arabic */ - {"af", {HB_TAG('A','F','K',' ')}}, /* Afrikaans */ - {"afb", {HB_TAG('A','R','A',' ')}}, /* Gulf Arabic -> Arabic */ - {"ahg", {HB_TAG('A','G','W',' ')}}, /* Qimant -> Agaw */ - {"aht", {HB_TAG('A','T','H',' ')}}, /* Ahtena -> Athapaskan */ - {"aii", {HB_TAG('S','W','A',' '), /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ - HB_TAG('S','Y','R',' ')}}, /* Assyrian Neo-Aramaic -> Syriac */ - {"aio", {HB_TAG('A','I','O',' ')}}, /* Aiton */ - {"aiw", {HB_TAG('A','R','I',' ')}}, /* Aari */ - {"ajp", {HB_TAG('A','R','A',' ')}}, /* South Levantine Arabic -> Arabic */ - {"ak", {HB_TAG('A','K','A',' '), /* Akan [macrolanguage] */ - HB_TAG('T','W','I',' ')}}, /* Akan [macrolanguage] -> Twi */ - {"aln", {HB_TAG('S','Q','I',' ')}}, /* Gheg Albanian -> Albanian */ - {"als", {HB_TAG('S','Q','I',' ')}}, /* Tosk Albanian -> Albanian */ - {"alt", {HB_TAG('A','L','T',' ')}}, /* Southern Altai -> Altai */ - {"am", {HB_TAG('A','M','H',' ')}}, /* Amharic */ - {"amf", {HB_TAG('H','B','N',' ')}}, /* Hamer-Banna -> Hammer-Banna */ - {"amw", {HB_TAG('S','Y','R',' ')}}, /* Western Neo-Aramaic -> Syriac */ - {"an", {HB_TAG('A','R','G',' ')}}, /* Aragonese */ - {"ang", {HB_TAG('A','N','G',' ')}}, /* Old English (ca. 450-1100) -> Anglo-Saxon */ - {"apc", {HB_TAG('A','R','A',' ')}}, /* North Levantine Arabic -> Arabic */ - {"apd", {HB_TAG('A','R','A',' ')}}, /* Sudanese Arabic -> Arabic */ - {"apj", {HB_TAG('A','T','H',' ')}}, /* Jicarilla Apache -> Athapaskan */ - {"apk", {HB_TAG('A','T','H',' ')}}, /* Kiowa Apache -> Athapaskan */ - {"apl", {HB_TAG('A','T','H',' ')}}, /* Lipan Apache -> Athapaskan */ - {"apm", {HB_TAG('A','T','H',' ')}}, /* Mescalero-Chiricahua Apache -> Athapaskan */ - {"apw", {HB_TAG('A','T','H',' ')}}, /* Western Apache -> Athapaskan */ - {"ar", {HB_TAG('A','R','A',' ')}}, /* Arabic [macrolanguage] */ - {"arb", {HB_TAG('A','R','A',' ')}}, /* Standard Arabic -> Arabic */ - {"arn", {HB_TAG('M','A','P',' ')}}, /* Mapudungun */ - {"arq", {HB_TAG('A','R','A',' ')}}, /* Algerian Arabic -> Arabic */ - {"ars", {HB_TAG('A','R','A',' ')}}, /* Najdi Arabic -> Arabic */ - {"ary", {HB_TAG('M','O','R',' ')}}, /* Moroccan Arabic -> Moroccan */ - {"arz", {HB_TAG('A','R','A',' ')}}, /* Egyptian Arabic -> Arabic */ - {"as", {HB_TAG('A','S','M',' ')}}, /* Assamese */ - {"ast", {HB_TAG('A','S','T',' ')}}, /* Asturian */ - {"ath", {HB_TAG('A','T','H',' ')}}, /* Athapascan [family] -> Athapaskan */ - {"atj", {HB_TAG('R','C','R',' ')}}, /* Atikamekw -> R-Cree */ - {"atv", {HB_TAG('A','L','T',' ')}}, /* Northern Altai -> Altai */ - {"auz", {HB_TAG('A','R','A',' ')}}, /* Uzbeki Arabic -> Arabic */ - {"av", {HB_TAG('A','V','R',' ')}}, /* Avaric -> Avar */ - {"avl", {HB_TAG('A','R','A',' ')}}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ - {"awa", {HB_TAG('A','W','A',' ')}}, /* Awadhi */ - {"ay", {HB_TAG('A','Y','M',' ')}}, /* Aymara [macrolanguage] */ - {"ayc", {HB_TAG('A','Y','M',' ')}}, /* Southern Aymara -> Aymara */ - {"ayh", {HB_TAG('A','R','A',' ')}}, /* Hadrami Arabic -> Arabic */ - {"ayl", {HB_TAG('A','R','A',' ')}}, /* Libyan Arabic -> Arabic */ - {"ayn", {HB_TAG('A','R','A',' ')}}, /* Sanaani Arabic -> Arabic */ - {"ayp", {HB_TAG('A','R','A',' ')}}, /* North Mesopotamian Arabic -> Arabic */ - {"ayr", {HB_TAG('A','Y','M',' ')}}, /* Central Aymara -> Aymara */ - {"az", {HB_TAG('A','Z','E',' ')}}, /* Azerbaijani [macrolanguage] */ - {"azb", {HB_TAG('A','Z','B',' ')}}, /* South Azerbaijani -> Torki */ - {"azj", {HB_TAG('A','Z','E',' ')}}, /* North Azerbaijani -> Azerbaijani */ - {"ba", {HB_TAG('B','S','H',' ')}}, /* Bashkir */ - {"bad", {HB_TAG('B','A','D','0')}}, /* Banda [family] */ - {"bai", {HB_TAG('B','M','L',' ')}}, /* Bamileke [family] */ - {"bal", {HB_TAG('B','L','I',' ')}}, /* Baluchi [macrolanguage] */ - {"ban", {HB_TAG('B','A','N',' ')}}, /* Balinese */ - {"bar", {HB_TAG('B','A','R',' ')}}, /* Bavarian */ - {"bbc", {HB_TAG('B','B','C',' ')}}, /* Batak Toba */ - {"bbz", {HB_TAG('A','R','A',' ')}}, /* Babalia Creole Arabic -> Arabic */ - {"bcc", {HB_TAG('B','L','I',' ')}}, /* Southern Balochi -> Baluchi */ - {"bci", {HB_TAG('B','A','U',' ')}}, /* Baoulé -> Baulé */ - {"bcl", {HB_TAG('B','I','K',' ')}}, /* Central Bikol -> Bikol */ - {"bcq", {HB_TAG('B','C','H',' ')}}, /* Bench */ - {"bcr", {HB_TAG('A','T','H',' ')}}, /* Babine -> Athapaskan */ - {"bdy", {HB_TAG('B','D','Y',' ')}}, /* Bandjalang */ - {"be", {HB_TAG('B','E','L',' ')}}, /* Belarusian -> Belarussian */ - {"bea", {HB_TAG('A','T','H',' ')}}, /* Beaver -> Athapaskan */ - {"beb", {HB_TAG('B','T','I',' ')}}, /* Bebele -> Beti */ - {"bem", {HB_TAG('B','E','M',' ')}}, /* Bemba (Zambia) */ - {"ber", {HB_TAG('B','B','R',' ')}}, /* Berber [family] */ - {"bfq", {HB_TAG('B','A','D',' ')}}, /* Badaga */ - {"bft", {HB_TAG('B','L','T',' ')}}, /* Balti */ - {"bfu", {HB_TAG('L','A','H',' ')}}, /* Gahri -> Lahuli */ - {"bfy", {HB_TAG('B','A','G',' ')}}, /* Bagheli -> Baghelkhandi */ - {"bg", {HB_TAG('B','G','R',' ')}}, /* Bulgarian */ - {"bgc", {HB_TAG('B','G','C',' ')}}, /* Haryanvi */ - {"bgn", {HB_TAG('B','L','I',' ')}}, /* Western Balochi -> Baluchi */ - {"bgp", {HB_TAG('B','L','I',' ')}}, /* Eastern Balochi -> Baluchi */ - {"bgq", {HB_TAG('B','G','Q',' ')}}, /* Bagri */ - {"bgr", {HB_TAG('Q','I','N',' ')}}, /* Bawm Chin -> Chin */ - {"bhb", {HB_TAG('B','H','I',' ')}}, /* Bhili */ - {"bhi", {HB_TAG('B','H','I',' ')}}, /* Bhilali -> Bhili */ - {"bhk", {HB_TAG('B','I','K',' ')}}, /* Albay Bicolano (retired code) -> Bikol */ - {"bho", {HB_TAG('B','H','O',' ')}}, /* Bhojpuri */ - {"bhr", {HB_TAG('M','L','G',' ')}}, /* Bara Malagasy -> Malagasy */ - {"bi", {HB_TAG('B','I','S',' ')}}, /* Bislama */ - {"bik", {HB_TAG('B','I','K',' ')}}, /* Bikol [macrolanguage] */ - {"bin", {HB_TAG('E','D','O',' ')}}, /* Edo */ - {"bjj", {HB_TAG('B','J','J',' ')}}, /* Kanauji */ - {"bjn", {HB_TAG('M','L','Y',' ')}}, /* Banjar -> Malay */ - {"bjq", {HB_TAG('M','L','G',' ')}}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */ - {"bjt", {HB_TAG('B','L','N',' ')}}, /* Balanta-Ganja -> Balante */ - {"bla", {HB_TAG('B','K','F',' ')}}, /* Siksika -> Blackfoot */ - {"ble", {HB_TAG('B','L','N',' ')}}, /* Balanta-Kentohe -> Balante */ - {"blk", {HB_TAG('B','L','K',' ')}}, /* Pa’o Karen */ - {"bln", {HB_TAG('B','I','K',' ')}}, /* Southern Catanduanes Bikol -> Bikol */ - {"bm", {HB_TAG('B','M','B',' ')}}, /* Bambara (Bamanankan) */ - {"bmm", {HB_TAG('M','L','G',' ')}}, /* Northern Betsimisaraka Malagasy -> Malagasy */ - {"bn", {HB_TAG('B','E','N',' ')}}, /* Bengali */ - {"bo", {HB_TAG('T','I','B',' ')}}, /* Tibetan */ - {"bpy", {HB_TAG('B','P','Y',' ')}}, /* Bishnupriya -> Bishnupriya Manipuri */ - {"bqi", {HB_TAG('L','R','C',' ')}}, /* Bakhtiari -> Luri */ - {"br", {HB_TAG('B','R','E',' ')}}, /* Breton */ - {"bra", {HB_TAG('B','R','I',' ')}}, /* Braj -> Braj Bhasha */ - {"brh", {HB_TAG('B','R','H',' ')}}, /* Brahui */ - {"brx", {HB_TAG('B','R','X',' ')}}, /* Bodo (India) */ - {"bs", {HB_TAG('B','O','S',' ')}}, /* Bosnian */ - {"bsk", {HB_TAG('B','S','K',' ')}}, /* Burushaski */ - {"btb", {HB_TAG('B','T','I',' ')}}, /* Beti (Cameroon) (retired code) */ - {"btj", {HB_TAG('M','L','Y',' ')}}, /* Bacanese Malay -> Malay */ - {"bto", {HB_TAG('B','I','K',' ')}}, /* Rinconada Bikol -> Bikol */ - {"bts", {HB_TAG('B','T','S',' ')}}, /* Batak Simalungun */ - {"bug", {HB_TAG('B','U','G',' ')}}, /* Buginese -> Bugis */ - {"bum", {HB_TAG('B','T','I',' ')}}, /* Bulu (Cameroon) -> Beti */ - {"bve", {HB_TAG('M','L','Y',' ')}}, /* Berau Malay -> Malay */ - {"bvu", {HB_TAG('M','L','Y',' ')}}, /* Bukit Malay -> Malay */ - {"bxk", {HB_TAG('L','U','H',' ')}}, /* Bukusu -> Luyia */ - {"bxp", {HB_TAG('B','T','I',' ')}}, /* Bebil -> Beti */ - {"bxr", {HB_TAG('R','B','U',' ')}}, /* Russia Buriat -> Russian Buriat */ - {"byn", {HB_TAG('B','I','L',' ')}}, /* Bilin -> Bilen */ - {"byv", {HB_TAG('B','Y','V',' ')}}, /* Medumba */ - {"bzc", {HB_TAG('M','L','G',' ')}}, /* Southern Betsimisaraka Malagasy -> Malagasy */ - {"ca", {HB_TAG('C','A','T',' ')}}, /* Catalan */ - {"caf", {HB_TAG('C','R','R',' '), /* Southern Carrier -> Carrier */ - HB_TAG('A','T','H',' ')}}, /* Southern Carrier -> Athapaskan */ - {"cak", {HB_TAG('C','A','K',' ')}}, /* Kaqchikel */ - {"cbk", {HB_TAG('C','B','K',' ')}}, /* Chavacano -> Zamboanga Chavacano */ - {"cbl", {HB_TAG('Q','I','N',' ')}}, /* Bualkhaw Chin -> Chin */ - {"cco", {HB_TAG('C','C','H','N')}}, /* Comaltepec Chinantec -> Chinantec */ - {"ccq", {HB_TAG('A','R','K',' ')}}, /* Chaungtha (retired code) -> Rakhine */ - {"cdo", {HB_TAG('Z','H','S',' ')}}, /* Min Dong Chinese -> Chinese Simplified */ - {"ce", {HB_TAG('C','H','E',' ')}}, /* Chechen */ - {"ceb", {HB_TAG('C','E','B',' ')}}, /* Cebuano */ - {"cfm", {HB_TAG('H','A','L',' ')}}, /* Halam (Falam Chin) */ - {"cgg", {HB_TAG('C','G','G',' ')}}, /* Chiga */ - {"ch", {HB_TAG('C','H','A',' ')}}, /* Chamorro */ - {"chj", {HB_TAG('C','C','H','N')}}, /* Ojitlán Chinantec -> Chinantec */ - {"chk", {HB_TAG('C','H','K','0')}}, /* Chuukese */ - {"cho", {HB_TAG('C','H','O',' ')}}, /* Choctaw */ - {"chp", {HB_TAG('C','H','P',' '), /* Chipewyan */ - HB_TAG('S','A','Y',' '), /* Chipewyan -> Sayisi */ - HB_TAG('A','T','H',' ')}}, /* Chipewyan -> Athapaskan */ - {"chq", {HB_TAG('C','C','H','N')}}, /* Quiotepec Chinantec -> Chinantec */ - {"chr", {HB_TAG('C','H','R',' ')}}, /* Cherokee */ - {"chy", {HB_TAG('C','H','Y',' ')}}, /* Cheyenne */ - {"chz", {HB_TAG('C','C','H','N')}}, /* Ozumacín Chinantec -> Chinantec */ - {"ciw", {HB_TAG('O','J','B',' ')}}, /* Chippewa -> Ojibway */ - {"cja", {HB_TAG('C','J','A',' ')}}, /* Western Cham */ - {"cjm", {HB_TAG('C','J','M',' ')}}, /* Eastern Cham */ - {"cjy", {HB_TAG('Z','H','S',' ')}}, /* Jinyu Chinese -> Chinese Simplified */ - {"cka", {HB_TAG('Q','I','N',' ')}}, /* Khumi Awa Chin (retired code) -> Chin */ - {"ckb", {HB_TAG('K','U','R',' ')}}, /* Central Kurdish -> Kurdish */ - {"ckt", {HB_TAG('C','H','K',' ')}}, /* Chukot -> Chukchi */ - {"clc", {HB_TAG('A','T','H',' ')}}, /* Chilcotin -> Athapaskan */ - {"cld", {HB_TAG('S','Y','R',' ')}}, /* Chaldean Neo-Aramaic -> Syriac */ - {"cle", {HB_TAG('C','C','H','N')}}, /* Lealao Chinantec -> Chinantec */ - {"cmn", {HB_TAG('Z','H','S',' ')}}, /* Mandarin Chinese -> Chinese Simplified */ - {"cmr", {HB_TAG('Q','I','N',' ')}}, /* Mro-Khimi Chin -> Chin */ - {"cnb", {HB_TAG('Q','I','N',' ')}}, /* Chinbon Chin -> Chin */ - {"cnh", {HB_TAG('Q','I','N',' ')}}, /* Hakha Chin -> Chin */ - {"cnk", {HB_TAG('Q','I','N',' ')}}, /* Khumi Chin -> Chin */ - {"cnl", {HB_TAG('C','C','H','N')}}, /* Lalana Chinantec -> Chinantec */ - {"cnt", {HB_TAG('C','C','H','N')}}, /* Tepetotutla Chinantec -> Chinantec */ - {"cnw", {HB_TAG('Q','I','N',' ')}}, /* Ngawn Chin -> Chin */ - {"co", {HB_TAG('C','O','S',' ')}}, /* Corsican */ - {"coa", {HB_TAG('M','L','Y',' ')}}, /* Cocos Islands Malay -> Malay */ - {"cop", {HB_TAG('C','O','P',' ')}}, /* Coptic */ - {"coq", {HB_TAG('A','T','H',' ')}}, /* Coquille -> Athapaskan */ - {"cpa", {HB_TAG('C','C','H','N')}}, /* Palantla Chinantec -> Chinantec */ - {"cpe", {HB_TAG('C','P','P',' ')}}, /* English-based creoles and pidgins [family] -> Creoles */ - {"cpf", {HB_TAG('C','P','P',' ')}}, /* French-based creoles and pidgins [family] -> Creoles */ - {"cpp", {HB_TAG('C','P','P',' ')}}, /* Portuguese-based creoles and pidgins [family] -> Creoles */ - {"cpx", {HB_TAG('Z','H','S',' ')}}, /* Pu-Xian Chinese -> Chinese Simplified */ - {"cqd", {HB_TAG('H','M','N',' ')}}, /* Chuanqiandian Cluster Miao -> Hmong */ - {"cqu", {HB_TAG('Q','U','H',' ')}}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ - {"cr", {HB_TAG('C','R','E',' '), /* Cree [macrolanguage] */ - HB_TAG('Y','C','R',' ')}}, /* Cree [macrolanguage] -> Y-Cree */ - {"crh", {HB_TAG('C','R','T',' ')}}, /* Crimean Tatar */ - {"crj", {HB_TAG('E','C','R',' ')}}, /* Southern East Cree -> Eastern Cree */ - {"crk", {HB_TAG('W','C','R',' ')}}, /* Plains Cree -> West-Cree */ - {"crl", {HB_TAG('E','C','R',' ')}}, /* Northern East Cree -> Eastern Cree */ - {"crm", {HB_TAG('M','C','R',' '), /* Moose Cree */ - HB_TAG('L','C','R',' ')}}, /* Moose Cree -> L-Cree */ - {"crp", {HB_TAG('C','P','P',' ')}}, /* Creoles and pidgins [family] -> Creoles */ - {"crx", {HB_TAG('C','R','R',' '), /* Carrier */ - HB_TAG('A','T','H',' ')}}, /* Carrier -> Athapaskan */ - {"cs", {HB_TAG('C','S','Y',' ')}}, /* Czech */ - {"csa", {HB_TAG('C','C','H','N')}}, /* Chiltepec Chinantec -> Chinantec */ - {"csb", {HB_TAG('C','S','B',' ')}}, /* Kashubian */ - {"csh", {HB_TAG('Q','I','N',' ')}}, /* Asho Chin -> Chin */ - {"cso", {HB_TAG('C','C','H','N')}}, /* Sochiapam Chinantec -> Chinantec */ - {"csw", {HB_TAG('N','C','R',' '), /* Swampy Cree -> N-Cree */ - HB_TAG('N','H','C',' ')}}, /* Swampy Cree -> Norway House Cree */ - {"csy", {HB_TAG('Q','I','N',' ')}}, /* Siyin Chin -> Chin */ - {"ctc", {HB_TAG('A','T','H',' ')}}, /* Chetco -> Athapaskan */ - {"ctd", {HB_TAG('Q','I','N',' ')}}, /* Tedim Chin -> Chin */ - {"cte", {HB_TAG('C','C','H','N')}}, /* Tepinapa Chinantec -> Chinantec */ - {"ctg", {HB_TAG('C','T','G',' ')}}, /* Chittagonian */ - {"ctl", {HB_TAG('C','C','H','N')}}, /* Tlacoatzintepec Chinantec -> Chinantec */ - {"cts", {HB_TAG('B','I','K',' ')}}, /* Northern Catanduanes Bikol -> Bikol */ - {"cu", {HB_TAG('C','S','L',' ')}}, /* Church Slavonic */ - {"cuc", {HB_TAG('C','C','H','N')}}, /* Usila Chinantec -> Chinantec */ - {"cuk", {HB_TAG('C','U','K',' ')}}, /* San Blas Kuna */ - {"cv", {HB_TAG('C','H','U',' ')}}, /* Chuvash */ - {"cvn", {HB_TAG('C','C','H','N')}}, /* Valle Nacional Chinantec -> Chinantec */ - {"cwd", {HB_TAG('D','C','R',' '), /* Woods Cree */ - HB_TAG('T','C','R',' ')}}, /* Woods Cree -> TH-Cree */ - {"cy", {HB_TAG('W','E','L',' ')}}, /* Welsh */ - {"czh", {HB_TAG('Z','H','S',' ')}}, /* Huizhou Chinese -> Chinese Simplified */ - {"czo", {HB_TAG('Z','H','S',' ')}}, /* Min Zhong Chinese -> Chinese Simplified */ - {"czt", {HB_TAG('Q','I','N',' ')}}, /* Zotung Chin -> Chin */ - {"da", {HB_TAG('D','A','N',' ')}}, /* Danish */ - {"dao", {HB_TAG('Q','I','N',' ')}}, /* Daai Chin -> Chin */ - {"dap", {HB_TAG('N','I','S',' ')}}, /* Nisi (India) (retired code) */ - {"dar", {HB_TAG('D','A','R',' ')}}, /* Dargwa */ - {"dax", {HB_TAG('D','A','X',' ')}}, /* Dayi */ - {"de", {HB_TAG('D','E','U',' ')}}, /* German */ - {"den", {HB_TAG('S','L','A',' '), /* Slave (Athapascan) [macrolanguage] -> Slavey */ - HB_TAG('A','T','H',' ')}}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ - {"dgo", {HB_TAG('D','G','O',' ')}}, /* Dogri */ - {"dgr", {HB_TAG('A','T','H',' ')}}, /* Dogrib -> Athapaskan */ - {"dhd", {HB_TAG('M','A','W',' ')}}, /* Dhundari -> Marwari */ - {"dhg", {HB_TAG('D','H','G',' ')}}, /* Dhangu */ - {"dib", {HB_TAG('D','N','K',' ')}}, /* South Central Dinka -> Dinka */ - {"dik", {HB_TAG('D','N','K',' ')}}, /* Southwestern Dinka -> Dinka */ - {"din", {HB_TAG('D','N','K',' ')}}, /* Dinka [macrolanguage] */ - {"dip", {HB_TAG('D','N','K',' ')}}, /* Northeastern Dinka -> Dinka */ - {"diq", {HB_TAG('D','I','Q',' ')}}, /* Dimli */ - {"diw", {HB_TAG('D','N','K',' ')}}, /* Northwestern Dinka -> Dinka */ - {"dje", {HB_TAG('D','J','R',' ')}}, /* Zarma */ - {"djr", {HB_TAG('D','J','R','0')}}, /* Djambarrpuyngu */ - {"dks", {HB_TAG('D','N','K',' ')}}, /* Southeastern Dinka -> Dinka */ - {"dng", {HB_TAG('D','U','N',' ')}}, /* Dungan */ - {"dnj", {HB_TAG('D','N','J',' ')}}, /* Dan */ - {"doi", {HB_TAG('D','G','R',' ')}}, /* Dogri [macrolanguage] */ - {"drh", {HB_TAG('M','N','G',' ')}}, /* Darkhat (retired code) -> Mongolian */ - {"drw", {HB_TAG('D','R','I',' ')}}, /* Darwazi (retired code) -> Dari */ - {"dsb", {HB_TAG('L','S','B',' ')}}, /* Lower Sorbian */ - {"dty", {HB_TAG('N','E','P',' ')}}, /* Dotyali -> Nepali */ - {"duj", {HB_TAG('D','U','J',' ')}}, /* Dhuwal (retired code) */ - {"dup", {HB_TAG('M','L','Y',' ')}}, /* Duano -> Malay */ - {"dv", {HB_TAG('D','I','V',' '), /* Divehi (Dhivehi, Maldivian) */ - HB_TAG('D','H','V',' ')}}, /* Divehi (Dhivehi, Maldivian) (deprecated) */ - {"dwu", {HB_TAG('D','U','J',' ')}}, /* Dhuwal */ - {"dwy", {HB_TAG('D','U','J',' ')}}, /* Dhuwaya -> Dhuwal */ - {"dyu", {HB_TAG('J','U','L',' ')}}, /* Dyula -> Jula */ - {"dz", {HB_TAG('D','Z','N',' ')}}, /* Dzongkha */ - {"ee", {HB_TAG('E','W','E',' ')}}, /* Ewe */ - {"efi", {HB_TAG('E','F','I',' ')}}, /* Efik */ - {"ekk", {HB_TAG('E','T','I',' ')}}, /* Standard Estonian -> Estonian */ - {"el", {HB_TAG('E','L','L',' ')}}, /* Modern Greek (1453-) -> Greek */ - {"emk", {HB_TAG('E','M','K',' '), /* Eastern Maninkakan */ - HB_TAG('M','N','K',' ')}}, /* Eastern Maninkakan -> Maninka */ - {"en", {HB_TAG('E','N','G',' ')}}, /* English */ - {"enb", {HB_TAG('K','A','L',' ')}}, /* Markweeta -> Kalenjin */ - {"enf", {HB_TAG('F','N','E',' ')}}, /* Forest Enets -> Forest Nenets */ - {"enh", {HB_TAG('T','N','E',' ')}}, /* Tundra Enets -> Tundra Nenets */ - {"eo", {HB_TAG('N','T','O',' ')}}, /* Esperanto */ - {"es", {HB_TAG('E','S','P',' ')}}, /* Spanish */ - {"esg", {HB_TAG('G','O','N',' ')}}, /* Aheri Gondi -> Gondi */ - {"esi", {HB_TAG('I','P','K',' ')}}, /* North Alaskan Inupiatun -> Inupiat */ - {"esk", {HB_TAG('I','P','K',' ')}}, /* Northwest Alaska Inupiatun -> Inupiat */ - {"esu", {HB_TAG('E','S','U',' ')}}, /* Central Yupik */ - {"et", {HB_TAG('E','T','I',' ')}}, /* Estonian [macrolanguage] */ - {"eto", {HB_TAG('B','T','I',' ')}}, /* Eton (Cameroon) -> Beti */ - {"eu", {HB_TAG('E','U','Q',' ')}}, /* Basque */ - {"eve", {HB_TAG('E','V','N',' ')}}, /* Even */ - {"evn", {HB_TAG('E','V','K',' ')}}, /* Evenki */ - {"ewo", {HB_TAG('B','T','I',' ')}}, /* Ewondo -> Beti */ - {"eyo", {HB_TAG('K','A','L',' ')}}, /* Keiyo -> Kalenjin */ - {"fa", {HB_TAG('F','A','R',' ')}}, /* Persian [macrolanguage] */ - {"fan", {HB_TAG('F','A','N','0')}}, /* Fang (Equatorial Guinea) */ - {"fat", {HB_TAG('F','A','T',' ')}}, /* Fanti */ - {"fbl", {HB_TAG('B','I','K',' ')}}, /* West Albay Bikol -> Bikol */ - {"ff", {HB_TAG('F','U','L',' ')}}, /* Fulah [macrolanguage] */ - {"ffm", {HB_TAG('F','U','L',' ')}}, /* Maasina Fulfulde -> Fulah */ - {"fi", {HB_TAG('F','I','N',' ')}}, /* Finnish */ - {"fil", {HB_TAG('P','I','L',' ')}}, /* Filipino */ - {"fj", {HB_TAG('F','J','I',' ')}}, /* Fijian */ - {"flm", {HB_TAG('H','A','L',' '), /* Halam (Falam Chin) (retired code) */ - HB_TAG('Q','I','N',' ')}}, /* Falam Chin (retired code) -> Chin */ - {"fmp", {HB_TAG('F','M','P',' ')}}, /* Fe’fe’ */ - {"fo", {HB_TAG('F','O','S',' ')}}, /* Faroese */ - {"fon", {HB_TAG('F','O','N',' ')}}, /* Fon */ - {"fr", {HB_TAG('F','R','A',' ')}}, /* French */ - {"frc", {HB_TAG('F','R','C',' ')}}, /* Cajun French */ - {"frp", {HB_TAG('F','R','P',' ')}}, /* Arpitan */ - {"fub", {HB_TAG('F','U','L',' ')}}, /* Adamawa Fulfulde -> Fulah */ - {"fuc", {HB_TAG('F','U','L',' ')}}, /* Pulaar -> Fulah */ - {"fue", {HB_TAG('F','U','L',' ')}}, /* Borgu Fulfulde -> Fulah */ - {"fuf", {HB_TAG('F','T','A',' ')}}, /* Pular -> Futa */ - {"fuh", {HB_TAG('F','U','L',' ')}}, /* Western Niger Fulfulde -> Fulah */ - {"fui", {HB_TAG('F','U','L',' ')}}, /* Bagirmi Fulfulde -> Fulah */ - {"fuq", {HB_TAG('F','U','L',' ')}}, /* Central-Eastern Niger Fulfulde -> Fulah */ - {"fur", {HB_TAG('F','R','L',' ')}}, /* Friulian */ - {"fuv", {HB_TAG('F','U','V',' ')}}, /* Nigerian Fulfulde */ - {"fy", {HB_TAG('F','R','I',' ')}}, /* Western Frisian -> Frisian */ - {"ga", {HB_TAG('I','R','I',' ')}}, /* Irish */ - {"gaa", {HB_TAG('G','A','D',' ')}}, /* Ga */ - {"gag", {HB_TAG('G','A','G',' ')}}, /* Gagauz */ - {"gan", {HB_TAG('Z','H','S',' ')}}, /* Gan Chinese -> Chinese Simplified */ - {"gax", {HB_TAG('O','R','O',' ')}}, /* Borana-Arsi-Guji Oromo -> Oromo */ - {"gaz", {HB_TAG('O','R','O',' ')}}, /* West Central Oromo -> Oromo */ - {"gbm", {HB_TAG('G','A','W',' ')}}, /* Garhwali */ - {"gce", {HB_TAG('A','T','H',' ')}}, /* Galice -> Athapaskan */ - {"gd", {HB_TAG('G','A','E',' ')}}, /* Scottish Gaelic (Gaelic) */ - {"gda", {HB_TAG('R','A','J',' ')}}, /* Gade Lohar -> Rajasthani */ - {"gez", {HB_TAG('G','E','Z',' ')}}, /* Geez */ - {"ggo", {HB_TAG('G','O','N',' ')}}, /* Southern Gondi (retired code) -> Gondi */ - {"gih", {HB_TAG('G','I','H',' ')}}, /* Githabul */ - {"gil", {HB_TAG('G','I','L','0')}}, /* Kiribati (Gilbertese) */ - {"gju", {HB_TAG('R','A','J',' ')}}, /* Gujari -> Rajasthani */ - {"gkp", {HB_TAG('G','K','P',' ')}}, /* Guinea Kpelle -> Kpelle (Guinea) */ - {"gl", {HB_TAG('G','A','L',' ')}}, /* Galician */ - {"gld", {HB_TAG('N','A','N',' ')}}, /* Nanai */ - {"glk", {HB_TAG('G','L','K',' ')}}, /* Gilaki */ - {"gn", {HB_TAG('G','U','A',' ')}}, /* Guarani [macrolanguage] */ - {"gnn", {HB_TAG('G','N','N',' ')}}, /* Gumatj */ - {"gno", {HB_TAG('G','O','N',' ')}}, /* Northern Gondi -> Gondi */ - {"gnw", {HB_TAG('G','U','A',' ')}}, /* Western Bolivian Guaraní -> Guarani */ - {"gog", {HB_TAG('G','O','G',' ')}}, /* Gogo */ - {"gom", {HB_TAG('K','O','K',' ')}}, /* Goan Konkani -> Konkani */ - {"gon", {HB_TAG('G','O','N',' ')}}, /* Gondi [macrolanguage] */ - {"grt", {HB_TAG('G','R','O',' ')}}, /* Garo */ - {"gru", {HB_TAG('S','O','G',' ')}}, /* Kistane -> Sodo Gurage */ - {"gsw", {HB_TAG('A','L','S',' ')}}, /* Alsatian */ - {"gu", {HB_TAG('G','U','J',' ')}}, /* Gujarati */ - {"guc", {HB_TAG('G','U','C',' ')}}, /* Wayuu */ - {"guf", {HB_TAG('G','U','F',' ')}}, /* Gupapuyngu */ - {"gug", {HB_TAG('G','U','A',' ')}}, /* Paraguayan Guaraní -> Guarani */ - {"gui", {HB_TAG('G','U','A',' ')}}, /* Eastern Bolivian Guaraní -> Guarani */ - {"guk", {HB_TAG('G','M','Z',' '), /* Gumuz */ - HB_TAG('G','U','K',' ')}}, /* Gumuz (SIL fonts) */ - {"gun", {HB_TAG('G','U','A',' ')}}, /* Mbyá Guaraní -> Guarani */ - {"guz", {HB_TAG('G','U','Z',' ')}}, /* Gusii */ - {"gv", {HB_TAG('M','N','X',' ')}}, /* Manx */ - {"gwi", {HB_TAG('A','T','H',' ')}}, /* Gwichʼin -> Athapaskan */ - {"ha", {HB_TAG('H','A','U',' ')}}, /* Hausa */ - {"haa", {HB_TAG('A','T','H',' ')}}, /* Han -> Athapaskan */ - {"hae", {HB_TAG('O','R','O',' ')}}, /* Eastern Oromo -> Oromo */ - {"hak", {HB_TAG('Z','H','S',' ')}}, /* Hakka Chinese -> Chinese Simplified */ - {"har", {HB_TAG('H','R','I',' ')}}, /* Harari */ - {"haw", {HB_TAG('H','A','W',' ')}}, /* Hawaiian */ - {"hay", {HB_TAG('H','A','Y',' ')}}, /* Haya */ - {"haz", {HB_TAG('H','A','Z',' ')}}, /* Hazaragi */ - {"he", {HB_TAG('I','W','R',' ')}}, /* Hebrew */ - {"hea", {HB_TAG('H','M','N',' ')}}, /* Northern Qiandong Miao -> Hmong */ - {"hi", {HB_TAG('H','I','N',' ')}}, /* Hindi */ - {"hil", {HB_TAG('H','I','L',' ')}}, /* Hiligaynon */ - {"hji", {HB_TAG('M','L','Y',' ')}}, /* Haji -> Malay */ - {"hlt", {HB_TAG('Q','I','N',' ')}}, /* Matu Chin -> Chin */ - {"hma", {HB_TAG('H','M','N',' ')}}, /* Southern Mashan Hmong -> Hmong */ - {"hmc", {HB_TAG('H','M','N',' ')}}, /* Central Huishui Hmong -> Hmong */ - {"hmd", {HB_TAG('H','M','N',' ')}}, /* Large Flowery Miao -> Hmong */ - {"hme", {HB_TAG('H','M','N',' ')}}, /* Eastern Huishui Hmong -> Hmong */ - {"hmg", {HB_TAG('H','M','N',' ')}}, /* Southwestern Guiyang Hmong -> Hmong */ - {"hmh", {HB_TAG('H','M','N',' ')}}, /* Southwestern Huishui Hmong -> Hmong */ - {"hmi", {HB_TAG('H','M','N',' ')}}, /* Northern Huishui Hmong -> Hmong */ - {"hmj", {HB_TAG('H','M','N',' ')}}, /* Ge -> Hmong */ - {"hml", {HB_TAG('H','M','N',' ')}}, /* Luopohe Hmong -> Hmong */ - {"hmm", {HB_TAG('H','M','N',' ')}}, /* Central Mashan Hmong -> Hmong */ - {"hmn", {HB_TAG('H','M','N',' ')}}, /* Hmong [macrolanguage] */ - {"hmp", {HB_TAG('H','M','N',' ')}}, /* Northern Mashan Hmong -> Hmong */ - {"hmq", {HB_TAG('H','M','N',' ')}}, /* Eastern Qiandong Miao -> Hmong */ - {"hms", {HB_TAG('H','M','N',' ')}}, /* Southern Qiandong Miao -> Hmong */ - {"hmw", {HB_TAG('H','M','N',' ')}}, /* Western Mashan Hmong -> Hmong */ - {"hmy", {HB_TAG('H','M','N',' ')}}, /* Southern Guiyang Hmong -> Hmong */ - {"hmz", {HB_TAG('H','M','N',' ')}}, /* Hmong Shua -> Hmong */ - {"hnd", {HB_TAG('H','N','D',' ')}}, /* Southern Hindko -> Hindko */ - {"hne", {HB_TAG('C','H','H',' ')}}, /* Chhattisgarhi -> Chattisgarhi */ - {"hnj", {HB_TAG('H','M','N',' ')}}, /* Hmong Njua -> Hmong */ - {"hno", {HB_TAG('H','N','D',' ')}}, /* Northern Hindko -> Hindko */ - {"ho", {HB_TAG('H','M','O',' ')}}, /* Hiri Motu */ - {"hoc", {HB_TAG('H','O',' ',' ')}}, /* Ho */ - {"hoi", {HB_TAG('A','T','H',' ')}}, /* Holikachuk -> Athapaskan */ - {"hoj", {HB_TAG('H','A','R',' ')}}, /* Hadothi -> Harauti */ - {"hr", {HB_TAG('H','R','V',' ')}}, /* Croatian */ - {"hrm", {HB_TAG('H','M','N',' ')}}, /* Horned Miao -> Hmong */ - {"hsb", {HB_TAG('U','S','B',' ')}}, /* Upper Sorbian */ - {"hsn", {HB_TAG('Z','H','S',' ')}}, /* Xiang Chinese -> Chinese Simplified */ - {"ht", {HB_TAG('H','A','I',' ')}}, /* Haitian (Haitian Creole) */ - {"hu", {HB_TAG('H','U','N',' ')}}, /* Hungarian */ - {"huj", {HB_TAG('H','M','N',' ')}}, /* Northern Guiyang Hmong -> Hmong */ - {"hup", {HB_TAG('A','T','H',' ')}}, /* Hupa -> Athapaskan */ - {"hy", {HB_TAG('H','Y','E','0'), /* Armenian -> Armenian East */ - HB_TAG('H','Y','E',' ')}}, /* Armenian */ - {"hyw", {HB_TAG('H','Y','E',' ')}}, /* Western Armenian -> Armenian */ - {"hz", {HB_TAG('H','E','R',' ')}}, /* Herero */ - {"ia", {HB_TAG('I','N','A',' ')}}, /* Interlingua (International Auxiliary Language Association) */ - {"iba", {HB_TAG('I','B','A',' ')}}, /* Iban */ - {"ibb", {HB_TAG('I','B','B',' ')}}, /* Ibibio */ - {"id", {HB_TAG('I','N','D',' ')}}, /* Indonesian */ - {"ida", {HB_TAG('L','U','H',' ')}}, /* Idakho-Isukha-Tiriki -> Luyia */ - {"ie", {HB_TAG('I','L','E',' ')}}, /* Interlingue */ - {"ig", {HB_TAG('I','B','O',' ')}}, /* Igbo */ - {"igb", {HB_TAG('E','B','I',' ')}}, /* Ebira */ - {"ii", {HB_TAG('Y','I','M',' ')}}, /* Sichuan Yi -> Yi Modern */ - {"ijc", {HB_TAG('I','J','O',' ')}}, /* Izon -> Ijo */ - {"ijo", {HB_TAG('I','J','O',' ')}}, /* Ijo [family] */ - {"ik", {HB_TAG('I','P','K',' ')}}, /* Inupiaq [macrolanguage] -> Inupiat */ - {"ike", {HB_TAG('I','N','U',' ')}}, /* Eastern Canadian Inuktitut -> Inuktitut */ - {"ikt", {HB_TAG('I','N','U',' ')}}, /* Inuinnaqtun -> Inuktitut */ - {"ilo", {HB_TAG('I','L','O',' ')}}, /* Iloko -> Ilokano */ - {"in", {HB_TAG('I','N','D',' ')}}, /* Indonesian (retired code) */ - {"ing", {HB_TAG('A','T','H',' ')}}, /* Degexit'an -> Athapaskan */ - {"inh", {HB_TAG('I','N','G',' ')}}, /* Ingush */ - {"io", {HB_TAG('I','D','O',' ')}}, /* Ido */ - {"is", {HB_TAG('I','S','L',' ')}}, /* Icelandic */ - {"it", {HB_TAG('I','T','A',' ')}}, /* Italian */ - {"iu", {HB_TAG('I','N','U',' ')}}, /* Inuktitut [macrolanguage] */ - {"iw", {HB_TAG('I','W','R',' ')}}, /* Hebrew (retired code) */ - {"ja", {HB_TAG('J','A','N',' ')}}, /* Japanese */ - {"jak", {HB_TAG('M','L','Y',' ')}}, /* Jakun -> Malay */ - {"jam", {HB_TAG('J','A','M',' ')}}, /* Jamaican Creole English -> Jamaican Creole */ - {"jax", {HB_TAG('M','L','Y',' ')}}, /* Jambi Malay -> Malay */ - {"jbo", {HB_TAG('J','B','O',' ')}}, /* Lojban */ - {"jct", {HB_TAG('J','C','T',' ')}}, /* Krymchak */ - {"ji", {HB_TAG('J','I','I',' ')}}, /* Yiddish (retired code) */ - {"jv", {HB_TAG('J','A','V',' ')}}, /* Javanese */ - {"jw", {HB_TAG('J','A','V',' ')}}, /* Javanese (retired code) */ - {"ka", {HB_TAG('K','A','T',' ')}}, /* Georgian */ - {"kaa", {HB_TAG('K','R','K',' ')}}, /* Kara-Kalpak -> Karakalpak */ - {"kab", {HB_TAG('K','A','B','0')}}, /* Kabyle */ - {"kam", {HB_TAG('K','M','B',' ')}}, /* Kamba (Kenya) */ - {"kar", {HB_TAG('K','R','N',' ')}}, /* Karen [family] */ - {"kbd", {HB_TAG('K','A','B',' ')}}, /* Kabardian */ - {"kby", {HB_TAG('K','N','R',' ')}}, /* Manga Kanuri -> Kanuri */ - {"kca", {HB_TAG('K','H','K',' '), /* Khanty -> Khanty-Kazim */ - HB_TAG('K','H','S',' '), /* Khanty -> Khanty-Shurishkar */ - HB_TAG('K','H','V',' ')}}, /* Khanty -> Khanty-Vakhi */ - {"kde", {HB_TAG('K','D','E',' ')}}, /* Makonde */ - {"kdr", {HB_TAG('K','R','M',' ')}}, /* Karaim */ - {"kdt", {HB_TAG('K','U','Y',' ')}}, /* Kuy */ - {"kea", {HB_TAG('K','E','A',' ')}}, /* Kabuverdianu (Crioulo) */ - {"kek", {HB_TAG('K','E','K',' ')}}, /* Kekchi */ - {"kex", {HB_TAG('K','K','N',' ')}}, /* Kukna -> Kokni */ - {"kfa", {HB_TAG('K','O','D',' ')}}, /* Kodava -> Kodagu */ - {"kfr", {HB_TAG('K','A','C',' ')}}, /* Kachhi -> Kachchi */ - {"kfx", {HB_TAG('K','U','L',' ')}}, /* Kullu Pahari -> Kulvi */ - {"kfy", {HB_TAG('K','M','N',' ')}}, /* Kumaoni */ - {"kg", {HB_TAG('K','O','N','0')}}, /* Kongo [macrolanguage] */ - {"kha", {HB_TAG('K','S','I',' ')}}, /* Khasi */ - {"khb", {HB_TAG('X','B','D',' ')}}, /* Lü */ - {"khk", {HB_TAG('M','N','G',' ')}}, /* Halh Mongolian -> Mongolian */ - {"kht", {HB_TAG('K','H','N',' '), /* Khamti -> Khamti Shan (Microsoft fonts) */ - HB_TAG('K','H','T',' ')}}, /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */ - {"khw", {HB_TAG('K','H','W',' ')}}, /* Khowar */ - {"ki", {HB_TAG('K','I','K',' ')}}, /* Kikuyu (Gikuyu) */ - {"kiu", {HB_TAG('K','I','U',' ')}}, /* Kirmanjki */ - {"kj", {HB_TAG('K','U','A',' ')}}, /* Kuanyama */ - {"kjd", {HB_TAG('K','J','D',' ')}}, /* Southern Kiwai */ - {"kjh", {HB_TAG('K','H','A',' ')}}, /* Khakas -> Khakass */ - {"kjp", {HB_TAG('K','J','P',' ')}}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ - {"kjz", {HB_TAG('K','J','Z',' ')}}, /* Bumthangkha */ - {"kk", {HB_TAG('K','A','Z',' ')}}, /* Kazakh */ - {"kkz", {HB_TAG('A','T','H',' ')}}, /* Kaska -> Athapaskan */ - {"kl", {HB_TAG('G','R','N',' ')}}, /* Greenlandic */ - {"kln", {HB_TAG('K','A','L',' ')}}, /* Kalenjin [macrolanguage] */ - {"km", {HB_TAG('K','H','M',' ')}}, /* Khmer */ - {"kmb", {HB_TAG('M','B','N',' ')}}, /* Kimbundu -> Mbundu */ - {"kmr", {HB_TAG('K','U','R',' ')}}, /* Northern Kurdish -> Kurdish */ - {"kmw", {HB_TAG('K','M','O',' ')}}, /* Komo (Democratic Republic of Congo) */ - {"kmz", {HB_TAG('K','M','Z',' ')}}, /* Khorasani Turkish -> Khorasani Turkic */ - {"kn", {HB_TAG('K','A','N',' ')}}, /* Kannada */ - {"knc", {HB_TAG('K','N','R',' ')}}, /* Central Kanuri -> Kanuri */ - {"kng", {HB_TAG('K','O','N','0')}}, /* Koongo -> Kongo */ - {"knn", {HB_TAG('K','O','K',' ')}}, /* Konkani */ - {"ko", {HB_TAG('K','O','R',' ')}}, /* Korean */ - {"koi", {HB_TAG('K','O','P',' ')}}, /* Komi-Permyak */ - {"kok", {HB_TAG('K','O','K',' ')}}, /* Konkani [macrolanguage] */ - {"kos", {HB_TAG('K','O','S',' ')}}, /* Kosraean */ - {"koy", {HB_TAG('A','T','H',' ')}}, /* Koyukon -> Athapaskan */ - {"kpe", {HB_TAG('K','P','L',' ')}}, /* Kpelle [macrolanguage] */ - {"kpv", {HB_TAG('K','O','Z',' ')}}, /* Komi-Zyrian */ - {"kpy", {HB_TAG('K','Y','K',' ')}}, /* Koryak */ - {"kqs", {HB_TAG('K','I','S',' ')}}, /* Northern Kissi -> Kisii */ - {"kqy", {HB_TAG('K','R','T',' ')}}, /* Koorete */ - {"kr", {HB_TAG('K','N','R',' ')}}, /* Kanuri [macrolanguage] */ - {"krc", {HB_TAG('K','A','R',' '), /* Karachay-Balkar -> Karachay */ - HB_TAG('B','A','L',' ')}}, /* Karachay-Balkar -> Balkar */ - {"kri", {HB_TAG('K','R','I',' ')}}, /* Krio */ - {"krl", {HB_TAG('K','R','L',' ')}}, /* Karelian */ - {"krt", {HB_TAG('K','N','R',' ')}}, /* Tumari Kanuri -> Kanuri */ - {"kru", {HB_TAG('K','U','U',' ')}}, /* Kurukh */ - {"ks", {HB_TAG('K','S','H',' ')}}, /* Kashmiri */ - {"ksh", {HB_TAG('K','S','H','0')}}, /* Kölsch -> Ripuarian */ - {"kss", {HB_TAG('K','I','S',' ')}}, /* Southern Kisi -> Kisii */ - {"ksw", {HB_TAG('K','S','W',' ')}}, /* S’gaw Karen */ - {"ktb", {HB_TAG('K','E','B',' ')}}, /* Kambaata -> Kebena */ - {"ktu", {HB_TAG('K','O','N',' ')}}, /* Kituba (Democratic Republic of Congo) -> Kikongo */ - {"ktw", {HB_TAG('A','T','H',' ')}}, /* Kato -> Athapaskan */ - {"ku", {HB_TAG('K','U','R',' ')}}, /* Kurdish [macrolanguage] */ - {"kum", {HB_TAG('K','U','M',' ')}}, /* Kumyk */ - {"kuu", {HB_TAG('A','T','H',' ')}}, /* Upper Kuskokwim -> Athapaskan */ - {"kv", {HB_TAG('K','O','M',' ')}}, /* Komi [macrolanguage] */ - {"kvb", {HB_TAG('M','L','Y',' ')}}, /* Kubu -> Malay */ - {"kvr", {HB_TAG('M','L','Y',' ')}}, /* Kerinci -> Malay */ - {"kw", {HB_TAG('C','O','R',' ')}}, /* Cornish */ - {"kwy", {HB_TAG('K','O','N','0')}}, /* San Salvador Kongo -> Kongo */ - {"kxc", {HB_TAG('K','M','S',' ')}}, /* Konso -> Komso */ - {"kxd", {HB_TAG('M','L','Y',' ')}}, /* Brunei -> Malay */ - {"kxu", {HB_TAG('K','U','I',' ')}}, /* Kui (India) */ - {"ky", {HB_TAG('K','I','R',' ')}}, /* Kirghiz (Kyrgyz) */ - {"kyu", {HB_TAG('K','Y','U',' ')}}, /* Western Kayah */ - {"la", {HB_TAG('L','A','T',' ')}}, /* Latin */ - {"lad", {HB_TAG('J','U','D',' ')}}, /* Ladino */ - {"lb", {HB_TAG('L','T','Z',' ')}}, /* Luxembourgish */ - {"lbe", {HB_TAG('L','A','K',' ')}}, /* Lak */ - {"lbj", {HB_TAG('L','D','K',' ')}}, /* Ladakhi */ - {"lbl", {HB_TAG('B','I','K',' ')}}, /* Libon Bikol -> Bikol */ - {"lce", {HB_TAG('M','L','Y',' ')}}, /* Loncong -> Malay */ - {"lcf", {HB_TAG('M','L','Y',' ')}}, /* Lubu -> Malay */ - {"ldi", {HB_TAG('K','O','N','0')}}, /* Laari -> Kongo */ - {"lez", {HB_TAG('L','E','Z',' ')}}, /* Lezghian -> Lezgi */ - {"lg", {HB_TAG('L','U','G',' ')}}, /* Ganda */ - {"li", {HB_TAG('L','I','M',' ')}}, /* Limburgish */ - {"lif", {HB_TAG('L','M','B',' ')}}, /* Limbu */ - {"lij", {HB_TAG('L','I','J',' ')}}, /* Ligurian */ - {"lis", {HB_TAG('L','I','S',' ')}}, /* Lisu */ - {"liw", {HB_TAG('M','L','Y',' ')}}, /* Col -> Malay */ - {"ljp", {HB_TAG('L','J','P',' ')}}, /* Lampung Api -> Lampung */ - {"lkb", {HB_TAG('L','U','H',' ')}}, /* Kabras -> Luyia */ - {"lki", {HB_TAG('L','K','I',' ')}}, /* Laki */ - {"lko", {HB_TAG('L','U','H',' ')}}, /* Khayo -> Luyia */ - {"lks", {HB_TAG('L','U','H',' ')}}, /* Kisa -> Luyia */ - {"lld", {HB_TAG('L','A','D',' ')}}, /* Ladin */ - {"lmn", {HB_TAG('L','A','M',' ')}}, /* Lambadi -> Lambani */ - {"lmo", {HB_TAG('L','M','O',' ')}}, /* Lombard */ - {"ln", {HB_TAG('L','I','N',' ')}}, /* Lingala */ - {"lo", {HB_TAG('L','A','O',' ')}}, /* Lao */ - {"lom", {HB_TAG('L','O','M',' ')}}, /* Loma (Liberia) */ - {"lrc", {HB_TAG('L','R','C',' ')}}, /* Northern Luri -> Luri */ - {"lri", {HB_TAG('L','U','H',' ')}}, /* Marachi -> Luyia */ - {"lrm", {HB_TAG('L','U','H',' ')}}, /* Marama -> Luyia */ - {"lsm", {HB_TAG('L','U','H',' ')}}, /* Saamia -> Luyia */ - {"lt", {HB_TAG('L','T','H',' ')}}, /* Lithuanian */ - {"ltg", {HB_TAG('L','V','I',' ')}}, /* Latgalian -> Latvian */ - {"lto", {HB_TAG('L','U','H',' ')}}, /* Tsotso -> Luyia */ - {"lts", {HB_TAG('L','U','H',' ')}}, /* Tachoni -> Luyia */ - {"lu", {HB_TAG('L','U','B',' ')}}, /* Luba-Katanga */ - {"lua", {HB_TAG('L','U','A',' ')}}, /* Luba-Lulua */ - {"luo", {HB_TAG('L','U','O',' ')}}, /* Luo (Kenya and Tanzania) */ - {"lus", {HB_TAG('M','I','Z',' ')}}, /* Lushai -> Mizo */ - {"luy", {HB_TAG('L','U','H',' ')}}, /* Luyia [macrolanguage] */ - {"luz", {HB_TAG('L','R','C',' ')}}, /* Southern Luri -> Luri */ - {"lv", {HB_TAG('L','V','I',' ')}}, /* Latvian [macrolanguage] */ - {"lvs", {HB_TAG('L','V','I',' ')}}, /* Standard Latvian -> Latvian */ - {"lwg", {HB_TAG('L','U','H',' ')}}, /* Wanga -> Luyia */ - {"lzh", {HB_TAG('Z','H','T',' ')}}, /* Literary Chinese -> Chinese Traditional */ - {"lzz", {HB_TAG('L','A','Z',' ')}}, /* Laz */ - {"mad", {HB_TAG('M','A','D',' ')}}, /* Madurese -> Madura */ - {"mag", {HB_TAG('M','A','G',' ')}}, /* Magahi */ - {"mai", {HB_TAG('M','T','H',' ')}}, /* Maithili */ - {"mak", {HB_TAG('M','K','R',' ')}}, /* Makasar */ - {"mam", {HB_TAG('M','A','M',' ')}}, /* Mam */ - {"man", {HB_TAG('M','N','K',' ')}}, /* Mandingo [macrolanguage] -> Maninka */ - {"max", {HB_TAG('M','L','Y',' ')}}, /* North Moluccan Malay -> Malay */ - {"mbo", {HB_TAG('M','B','O',' ')}}, /* Mbo (Cameroon) */ - {"mct", {HB_TAG('B','T','I',' ')}}, /* Mengisa -> Beti */ - {"mdf", {HB_TAG('M','O','K',' ')}}, /* Moksha */ - {"mdr", {HB_TAG('M','D','R',' ')}}, /* Mandar */ - {"mdy", {HB_TAG('M','L','E',' ')}}, /* Male (Ethiopia) */ - {"men", {HB_TAG('M','D','E',' ')}}, /* Mende (Sierra Leone) */ - {"meo", {HB_TAG('M','L','Y',' ')}}, /* Kedah Malay -> Malay */ - {"mer", {HB_TAG('M','E','R',' ')}}, /* Meru */ - {"mfa", {HB_TAG('M','F','A',' ')}}, /* Pattani Malay */ - {"mfb", {HB_TAG('M','L','Y',' ')}}, /* Bangka -> Malay */ - {"mfe", {HB_TAG('M','F','E',' ')}}, /* Morisyen */ - {"mg", {HB_TAG('M','L','G',' ')}}, /* Malagasy [macrolanguage] */ - {"mh", {HB_TAG('M','A','H',' ')}}, /* Marshallese */ - {"mhr", {HB_TAG('L','M','A',' ')}}, /* Eastern Mari -> Low Mari */ - {"mhv", {HB_TAG('A','R','K',' ')}}, /* Arakanese (retired code) -> Rakhine */ - {"mi", {HB_TAG('M','R','I',' ')}}, /* Maori */ - {"min", {HB_TAG('M','I','N',' ')}}, /* Minangkabau */ - {"mk", {HB_TAG('M','K','D',' ')}}, /* Macedonian */ - {"mku", {HB_TAG('M','N','K',' ')}}, /* Konyanka Maninka -> Maninka */ - {"mkw", {HB_TAG('M','K','W',' ')}}, /* Kituba (Congo) */ - {"ml", {HB_TAG('M','A','L',' '), /* Malayalam -> Malayalam Traditional */ - HB_TAG('M','L','R',' ')}}, /* Malayalam -> Malayalam Reformed */ - {"mlq", {HB_TAG('M','L','N',' '), /* Western Maninkakan -> Malinke */ - HB_TAG('M','N','K',' ')}}, /* Western Maninkakan -> Maninka */ - {"mmr", {HB_TAG('H','M','N',' ')}}, /* Western Xiangxi Miao -> Hmong */ - {"mn", {HB_TAG('M','N','G',' ')}}, /* Mongolian [macrolanguage] */ - {"mnc", {HB_TAG('M','C','H',' ')}}, /* Manchu */ - {"mni", {HB_TAG('M','N','I',' ')}}, /* Manipuri */ - {"mnk", {HB_TAG('M','N','D',' '), /* Mandinka */ - HB_TAG('M','N','K',' ')}}, /* Mandinka -> Maninka */ - {"mnp", {HB_TAG('Z','H','S',' ')}}, /* Min Bei Chinese -> Chinese Simplified */ - {"mns", {HB_TAG('M','A','N',' ')}}, /* Mansi */ - {"mnw", {HB_TAG('M','O','N',' ')}}, /* Mon */ - {"mo", {HB_TAG('M','O','L',' ')}}, /* Moldavian (retired code) */ - {"moh", {HB_TAG('M','O','H',' ')}}, /* Mohawk */ - {"mos", {HB_TAG('M','O','S',' ')}}, /* Mossi */ - {"mpe", {HB_TAG('M','A','J',' ')}}, /* Majang */ - {"mqg", {HB_TAG('M','L','Y',' ')}}, /* Kota Bangun Kutai Malay -> Malay */ - {"mr", {HB_TAG('M','A','R',' ')}}, /* Marathi */ - {"mrh", {HB_TAG('Q','I','N',' ')}}, /* Mara Chin -> Chin */ - {"mrj", {HB_TAG('H','M','A',' ')}}, /* Western Mari -> High Mari */ - {"ms", {HB_TAG('M','L','Y',' ')}}, /* Malay [macrolanguage] */ - {"msc", {HB_TAG('M','N','K',' ')}}, /* Sankaran Maninka -> Maninka */ - {"msh", {HB_TAG('M','L','G',' ')}}, /* Masikoro Malagasy -> Malagasy */ - {"msi", {HB_TAG('M','L','Y',' ')}}, /* Sabah Malay -> Malay */ - {"mt", {HB_TAG('M','T','S',' ')}}, /* Maltese */ - {"mtr", {HB_TAG('M','A','W',' ')}}, /* Mewari -> Marwari */ - {"mui", {HB_TAG('M','L','Y',' ')}}, /* Musi -> Malay */ - {"mup", {HB_TAG('R','A','J',' ')}}, /* Malvi -> Rajasthani */ - {"muq", {HB_TAG('H','M','N',' ')}}, /* Eastern Xiangxi Miao -> Hmong */ - {"mus", {HB_TAG('M','U','S',' ')}}, /* Creek -> Muscogee */ - {"mvb", {HB_TAG('A','T','H',' ')}}, /* Mattole -> Athapaskan */ - {"mve", {HB_TAG('M','A','W',' ')}}, /* Marwari (Pakistan) */ - {"mvf", {HB_TAG('M','N','G',' ')}}, /* Peripheral Mongolian -> Mongolian */ - {"mwk", {HB_TAG('M','N','K',' ')}}, /* Kita Maninkakan -> Maninka */ - {"mwl", {HB_TAG('M','W','L',' ')}}, /* Mirandese */ - {"mwr", {HB_TAG('M','A','W',' ')}}, /* Marwari [macrolanguage] */ - {"mww", {HB_TAG('M','W','W',' ')}}, /* Hmong Daw */ - {"my", {HB_TAG('B','R','M',' ')}}, /* Burmese */ - {"mym", {HB_TAG('M','E','N',' ')}}, /* Me’en */ - {"myn", {HB_TAG('M','Y','N',' ')}}, /* Mayan [family] */ - {"myq", {HB_TAG('M','N','K',' ')}}, /* Forest Maninka (retired code) -> Maninka */ - {"myv", {HB_TAG('E','R','Z',' ')}}, /* Erzya */ - {"mzn", {HB_TAG('M','Z','N',' ')}}, /* Mazanderani */ - {"na", {HB_TAG('N','A','U',' ')}}, /* Nauru -> Nauruan */ - {"nag", {HB_TAG('N','A','G',' ')}}, /* Naga Pidgin -> Naga-Assamese */ - {"nah", {HB_TAG('N','A','H',' ')}}, /* Nahuatl [family] */ - {"nan", {HB_TAG('Z','H','S',' ')}}, /* Min Nan Chinese -> Chinese Simplified */ - {"nap", {HB_TAG('N','A','P',' ')}}, /* Neapolitan */ - {"nb", {HB_TAG('N','O','R',' ')}}, /* Norwegian Bokmål -> Norwegian */ - {"nd", {HB_TAG('N','D','B',' ')}}, /* North Ndebele -> Ndebele */ - {"ndc", {HB_TAG('N','D','C',' ')}}, /* Ndau */ - {"nds", {HB_TAG('N','D','S',' ')}}, /* Low Saxon */ - {"ne", {HB_TAG('N','E','P',' ')}}, /* Nepali [macrolanguage] */ - {"new", {HB_TAG('N','E','W',' ')}}, /* Newari */ - {"ng", {HB_TAG('N','D','G',' ')}}, /* Ndonga */ - {"nga", {HB_TAG('N','G','A',' ')}}, /* Ngbaka */ - {"ngl", {HB_TAG('L','M','W',' ')}}, /* Lomwe */ - {"ngo", {HB_TAG('S','X','T',' ')}}, /* Ngoni -> Sutu */ - {"nhd", {HB_TAG('G','U','A',' ')}}, /* Chiripá -> Guarani */ - {"niq", {HB_TAG('K','A','L',' ')}}, /* Nandi -> Kalenjin */ - {"niu", {HB_TAG('N','I','U',' ')}}, /* Niuean */ - {"niv", {HB_TAG('G','I','L',' ')}}, /* Gilyak */ - {"njz", {HB_TAG('N','I','S',' ')}}, /* Nyishi -> Nisi */ - {"nl", {HB_TAG('N','L','D',' ')}}, /* Dutch */ - {"nle", {HB_TAG('L','U','H',' ')}}, /* East Nyala -> Luyia */ - {"nn", {HB_TAG('N','Y','N',' ')}}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */ - {"no", {HB_TAG('N','O','R',' ')}}, /* Norwegian [macrolanguage] */ - {"nod", {HB_TAG('N','T','A',' ')}}, /* Northern Thai -> Northern Tai */ - {"noe", {HB_TAG('N','O','E',' ')}}, /* Nimadi */ - {"nog", {HB_TAG('N','O','G',' ')}}, /* Nogai */ - {"nov", {HB_TAG('N','O','V',' ')}}, /* Novial */ - {"npi", {HB_TAG('N','E','P',' ')}}, /* Nepali */ - {"nqo", {HB_TAG('N','K','O',' ')}}, /* N’Ko */ - {"nr", {HB_TAG('N','D','B',' ')}}, /* South Ndebele -> Ndebele */ - {"nsk", {HB_TAG('N','A','S',' ')}}, /* Naskapi */ - {"nso", {HB_TAG('N','S','O',' ')}}, /* Pedi -> Sotho, Northern */ - {"nv", {HB_TAG('N','A','V',' '), /* Navajo */ - HB_TAG('A','T','H',' ')}}, /* Navajo -> Athapaskan */ - {"ny", {HB_TAG('C','H','I',' ')}}, /* Chichewa (Chewa, Nyanja) */ - {"nyd", {HB_TAG('L','U','H',' ')}}, /* Nyore -> Luyia */ - {"nym", {HB_TAG('N','Y','M',' ')}}, /* Nyamwezi */ - {"nyn", {HB_TAG('N','K','L',' ')}}, /* Nyankole */ - {"nza", {HB_TAG('N','Z','A',' ')}}, /* Tigon Mbembe -> Mbembe Tigon */ - {"oc", {HB_TAG('O','C','I',' ')}}, /* Occitan (post 1500) */ - {"oj", {HB_TAG('O','J','B',' ')}}, /* Ojibwa [macrolanguage] -> Ojibway */ - {"ojb", {HB_TAG('O','J','B',' ')}}, /* Northwestern Ojibwa -> Ojibway */ - {"ojc", {HB_TAG('O','J','B',' ')}}, /* Central Ojibwa -> Ojibway */ - {"ojg", {HB_TAG('O','J','B',' ')}}, /* Eastern Ojibwa -> Ojibway */ - {"ojs", {HB_TAG('O','C','R',' ')}}, /* Severn Ojibwa -> Oji-Cree */ - {"ojw", {HB_TAG('O','J','B',' ')}}, /* Western Ojibwa -> Ojibway */ - {"oki", {HB_TAG('K','A','L',' ')}}, /* Okiek -> Kalenjin */ - {"okm", {HB_TAG('K','O','H',' ')}}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ - {"om", {HB_TAG('O','R','O',' ')}}, /* Oromo [macrolanguage] */ - {"or", {HB_TAG('O','R','I',' ')}}, /* Odia (formerly Oriya) [macrolanguage] */ - {"orc", {HB_TAG('O','R','O',' ')}}, /* Orma -> Oromo */ - {"orn", {HB_TAG('M','L','Y',' ')}}, /* Orang Kanaq -> Malay */ - {"ors", {HB_TAG('M','L','Y',' ')}}, /* Orang Seletar -> Malay */ - {"ory", {HB_TAG('O','R','I',' ')}}, /* Odia (formerly Oriya) */ - {"os", {HB_TAG('O','S','S',' ')}}, /* Ossetian */ - {"otw", {HB_TAG('O','J','B',' ')}}, /* Ottawa -> Ojibway */ - {"pa", {HB_TAG('P','A','N',' ')}}, /* Punjabi */ - {"pag", {HB_TAG('P','A','G',' ')}}, /* Pangasinan */ - {"pam", {HB_TAG('P','A','M',' ')}}, /* Pampanga -> Pampangan */ - {"pap", {HB_TAG('P','A','P','0')}}, /* Papiamento -> Papiamentu */ - {"pau", {HB_TAG('P','A','U',' ')}}, /* Palauan */ - {"pbt", {HB_TAG('P','A','S',' ')}}, /* Southern Pashto -> Pashto */ - {"pbu", {HB_TAG('P','A','S',' ')}}, /* Northern Pashto -> Pashto */ - {"pcc", {HB_TAG('P','C','C',' ')}}, /* Bouyei */ - {"pcd", {HB_TAG('P','C','D',' ')}}, /* Picard */ - {"pce", {HB_TAG('P','L','G',' ')}}, /* Ruching Palaung -> Palaung */ - {"pck", {HB_TAG('Q','I','N',' ')}}, /* Paite Chin -> Chin */ - {"pdc", {HB_TAG('P','D','C',' ')}}, /* Pennsylvania German */ - {"pel", {HB_TAG('M','L','Y',' ')}}, /* Pekal -> Malay */ - {"pes", {HB_TAG('F','A','R',' ')}}, /* Iranian Persian -> Persian */ - {"pga", {HB_TAG('A','R','A',' ')}}, /* Sudanese Creole Arabic -> Arabic */ - {"phk", {HB_TAG('P','H','K',' ')}}, /* Phake */ - {"pi", {HB_TAG('P','A','L',' ')}}, /* Pali */ - {"pih", {HB_TAG('P','I','H',' ')}}, /* Pitcairn-Norfolk -> Norfolk */ - {"pko", {HB_TAG('K','A','L',' ')}}, /* Pökoot -> Kalenjin */ - {"pl", {HB_TAG('P','L','K',' ')}}, /* Polish */ - {"pll", {HB_TAG('P','L','G',' ')}}, /* Shwe Palaung -> Palaung */ - {"plp", {HB_TAG('P','A','P',' ')}}, /* Palpa */ - {"plt", {HB_TAG('M','L','G',' ')}}, /* Plateau Malagasy -> Malagasy */ - {"pms", {HB_TAG('P','M','S',' ')}}, /* Piemontese */ - {"pnb", {HB_TAG('P','N','B',' ')}}, /* Western Panjabi */ - {"poh", {HB_TAG('P','O','H',' ')}}, /* Poqomchi' -> Pocomchi */ - {"pon", {HB_TAG('P','O','N',' ')}}, /* Pohnpeian */ - {"ppa", {HB_TAG('B','A','G',' ')}}, /* Pao (retired code) -> Baghelkhandi */ - {"pro", {HB_TAG('P','R','O',' ')}}, /* Old Provençal (to 1500) -> Provençal / Old Provençal */ - {"prs", {HB_TAG('D','R','I',' ')}}, /* Dari */ - {"ps", {HB_TAG('P','A','S',' ')}}, /* Pashto [macrolanguage] */ - {"pse", {HB_TAG('M','L','Y',' ')}}, /* Central Malay -> Malay */ - {"pst", {HB_TAG('P','A','S',' ')}}, /* Central Pashto -> Pashto */ - {"pt", {HB_TAG('P','T','G',' ')}}, /* Portuguese */ - {"pwo", {HB_TAG('P','W','O',' ')}}, /* Pwo Western Karen -> Western Pwo Karen */ - {"qu", {HB_TAG('Q','U','Z',' ')}}, /* Quechua [macrolanguage] */ - {"qub", {HB_TAG('Q','W','H',' ')}}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ - {"quc", {HB_TAG('Q','U','C',' ')}}, /* K’iche’ */ - {"qud", {HB_TAG('Q','V','I',' ')}}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ - {"quf", {HB_TAG('Q','U','Z',' ')}}, /* Lambayeque Quechua -> Quechua */ - {"qug", {HB_TAG('Q','V','I',' ')}}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ - {"quh", {HB_TAG('Q','U','H',' ')}}, /* South Bolivian Quechua -> Quechua (Bolivia) */ - {"quk", {HB_TAG('Q','U','Z',' ')}}, /* Chachapoyas Quechua -> Quechua */ - {"qul", {HB_TAG('Q','U','Z',' ')}}, /* North Bolivian Quechua -> Quechua */ - {"qup", {HB_TAG('Q','V','I',' ')}}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ - {"qur", {HB_TAG('Q','W','H',' ')}}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ - {"qus", {HB_TAG('Q','U','H',' ')}}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */ - {"quw", {HB_TAG('Q','V','I',' ')}}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ - {"qux", {HB_TAG('Q','W','H',' ')}}, /* Yauyos Quechua -> Quechua (Peru) */ - {"quy", {HB_TAG('Q','U','Z',' ')}}, /* Ayacucho Quechua -> Quechua */ - {"quz", {HB_TAG('Q','U','Z',' ')}}, /* Cusco Quechua -> Quechua */ - {"qva", {HB_TAG('Q','W','H',' ')}}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ - {"qvc", {HB_TAG('Q','U','Z',' ')}}, /* Cajamarca Quechua -> Quechua */ - {"qve", {HB_TAG('Q','U','Z',' ')}}, /* Eastern Apurímac Quechua -> Quechua */ - {"qvh", {HB_TAG('Q','W','H',' ')}}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ - {"qvi", {HB_TAG('Q','V','I',' ')}}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ - {"qvj", {HB_TAG('Q','V','I',' ')}}, /* Loja Highland Quichua -> Quechua (Ecuador) */ - {"qvl", {HB_TAG('Q','W','H',' ')}}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ - {"qvm", {HB_TAG('Q','W','H',' ')}}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ - {"qvn", {HB_TAG('Q','W','H',' ')}}, /* North Junín Quechua -> Quechua (Peru) */ - {"qvo", {HB_TAG('Q','V','I',' ')}}, /* Napo Lowland Quechua -> Quechua (Ecuador) */ - {"qvp", {HB_TAG('Q','W','H',' ')}}, /* Pacaraos Quechua -> Quechua (Peru) */ - {"qvs", {HB_TAG('Q','U','Z',' ')}}, /* San Martín Quechua -> Quechua */ - {"qvw", {HB_TAG('Q','W','H',' ')}}, /* Huaylla Wanca Quechua -> Quechua (Peru) */ - {"qvz", {HB_TAG('Q','V','I',' ')}}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ - {"qwa", {HB_TAG('Q','W','H',' ')}}, /* Corongo Ancash Quechua -> Quechua (Peru) */ - {"qwc", {HB_TAG('Q','U','Z',' ')}}, /* Classical Quechua -> Quechua */ - {"qwh", {HB_TAG('Q','W','H',' ')}}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ - {"qws", {HB_TAG('Q','W','H',' ')}}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ - {"qxa", {HB_TAG('Q','W','H',' ')}}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ - {"qxc", {HB_TAG('Q','W','H',' ')}}, /* Chincha Quechua -> Quechua (Peru) */ - {"qxh", {HB_TAG('Q','W','H',' ')}}, /* Panao Huánuco Quechua -> Quechua (Peru) */ - {"qxl", {HB_TAG('Q','V','I',' ')}}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */ - {"qxn", {HB_TAG('Q','W','H',' ')}}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ - {"qxo", {HB_TAG('Q','W','H',' ')}}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ - {"qxp", {HB_TAG('Q','U','Z',' ')}}, /* Puno Quechua -> Quechua */ - {"qxr", {HB_TAG('Q','V','I',' ')}}, /* Cañar Highland Quichua -> Quechua (Ecuador) */ - {"qxt", {HB_TAG('Q','W','H',' ')}}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ - {"qxu", {HB_TAG('Q','U','Z',' ')}}, /* Arequipa-La Unión Quechua -> Quechua */ - {"qxw", {HB_TAG('Q','W','H',' ')}}, /* Jauja Wanca Quechua -> Quechua (Peru) */ - {"rag", {HB_TAG('L','U','H',' ')}}, /* Logooli -> Luyia */ - {"raj", {HB_TAG('R','A','J',' ')}}, /* Rajasthani [macrolanguage] */ - {"rar", {HB_TAG('R','A','R',' ')}}, /* Rarotongan */ - {"rbb", {HB_TAG('P','L','G',' ')}}, /* Rumai Palaung -> Palaung */ - {"rbl", {HB_TAG('B','I','K',' ')}}, /* Miraya Bikol -> Bikol */ - {"rej", {HB_TAG('R','E','J',' ')}}, /* Rejang */ - {"ria", {HB_TAG('R','I','A',' ')}}, /* Riang (India) */ - {"rif", {HB_TAG('R','I','F',' ')}}, /* Tarifit */ - {"rit", {HB_TAG('R','I','T',' ')}}, /* Ritarungo */ - {"rki", {HB_TAG('A','R','K',' ')}}, /* Rakhine */ - {"rkw", {HB_TAG('R','K','W',' ')}}, /* Arakwal */ - {"rm", {HB_TAG('R','M','S',' ')}}, /* Romansh */ - {"rmc", {HB_TAG('R','O','Y',' ')}}, /* Carpathian Romani -> Romany */ - {"rmf", {HB_TAG('R','O','Y',' ')}}, /* Kalo Finnish Romani -> Romany */ - {"rml", {HB_TAG('R','O','Y',' ')}}, /* Baltic Romani -> Romany */ - {"rmn", {HB_TAG('R','O','Y',' ')}}, /* Balkan Romani -> Romany */ - {"rmo", {HB_TAG('R','O','Y',' ')}}, /* Sinte Romani -> Romany */ - {"rmw", {HB_TAG('R','O','Y',' ')}}, /* Welsh Romani -> Romany */ - {"rmy", {HB_TAG('R','M','Y',' ')}}, /* Vlax Romani */ - {"rmz", {HB_TAG('A','R','K',' ')}}, /* Marma -> Rakhine */ - {"rn", {HB_TAG('R','U','N',' ')}}, /* Rundi */ - {"rnl", {HB_TAG('H','A','L',' ')}}, /* Ranglong -> Halam (Falam Chin) */ - {"ro", {HB_TAG('R','O','M',' ')}}, /* Romanian */ - {"rom", {HB_TAG('R','O','Y',' ')}}, /* Romany [macrolanguage] */ - {"rtm", {HB_TAG('R','T','M',' ')}}, /* Rotuman */ - {"ru", {HB_TAG('R','U','S',' ')}}, /* Russian */ - {"rue", {HB_TAG('R','S','Y',' ')}}, /* Rusyn */ - {"rup", {HB_TAG('R','U','P',' ')}}, /* Aromanian */ - {"rw", {HB_TAG('R','U','A',' ')}}, /* Kinyarwanda */ - {"rwr", {HB_TAG('M','A','W',' ')}}, /* Marwari (India) */ - {"sa", {HB_TAG('S','A','N',' ')}}, /* Sanskrit */ - {"sah", {HB_TAG('Y','A','K',' ')}}, /* Yakut -> Sakha */ - {"sam", {HB_TAG('P','A','A',' ')}}, /* Samaritan Aramaic -> Palestinian Aramaic */ - {"sas", {HB_TAG('S','A','S',' ')}}, /* Sasak */ - {"sat", {HB_TAG('S','A','T',' ')}}, /* Santali */ - {"sc", {HB_TAG('S','R','D',' ')}}, /* Sardinian [macrolanguage] */ - {"sck", {HB_TAG('S','A','D',' ')}}, /* Sadri */ - {"scn", {HB_TAG('S','C','N',' ')}}, /* Sicilian */ - {"sco", {HB_TAG('S','C','O',' ')}}, /* Scots */ - {"scs", {HB_TAG('S','C','S',' '), /* North Slavey */ - HB_TAG('S','L','A',' '), /* North Slavey -> Slavey */ - HB_TAG('A','T','H',' ')}}, /* North Slavey -> Athapaskan */ - {"sd", {HB_TAG('S','N','D',' ')}}, /* Sindhi */ - {"sdc", {HB_TAG('S','R','D',' ')}}, /* Sassarese Sardinian -> Sardinian */ - {"sdh", {HB_TAG('K','U','R',' ')}}, /* Southern Kurdish -> Kurdish */ - {"sdn", {HB_TAG('S','R','D',' ')}}, /* Gallurese Sardinian -> Sardinian */ - {"se", {HB_TAG('N','S','M',' ')}}, /* Northern Sami */ - {"seh", {HB_TAG('S','N','A',' ')}}, /* Sena */ - {"sek", {HB_TAG('A','T','H',' ')}}, /* Sekani -> Athapaskan */ - {"sel", {HB_TAG('S','E','L',' ')}}, /* Selkup */ - {"sez", {HB_TAG('Q','I','N',' ')}}, /* Senthang Chin -> Chin */ - {"sfm", {HB_TAG('H','M','N',' ')}}, /* Small Flowery Miao -> Hmong */ - {"sg", {HB_TAG('S','G','O',' ')}}, /* Sango */ - {"sga", {HB_TAG('S','G','A',' ')}}, /* Old Irish (to 900) */ - {"sgc", {HB_TAG('K','A','L',' ')}}, /* Kipsigis -> Kalenjin */ - {"sgs", {HB_TAG('S','G','S',' ')}}, /* Samogitian */ - {"sgw", {HB_TAG('C','H','G',' '), /* Sebat Bet Gurage -> Chaha Gurage */ - HB_TAG('S','G','W',' ')}}, /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */ - {"shi", {HB_TAG('S','H','I',' ')}}, /* Tachelhit */ - {"shn", {HB_TAG('S','H','N',' ')}}, /* Shan */ - {"shu", {HB_TAG('A','R','A',' ')}}, /* Chadian Arabic -> Arabic */ - {"si", {HB_TAG('S','N','H',' ')}}, /* Sinhala (Sinhalese) */ - {"sid", {HB_TAG('S','I','D',' ')}}, /* Sidamo */ - {"sjd", {HB_TAG('K','S','M',' ')}}, /* Kildin Sami */ - {"sjo", {HB_TAG('S','I','B',' ')}}, /* Xibe -> Sibe */ - {"sk", {HB_TAG('S','K','Y',' ')}}, /* Slovak */ - {"skg", {HB_TAG('M','L','G',' ')}}, /* Sakalava Malagasy -> Malagasy */ - {"skr", {HB_TAG('S','R','K',' ')}}, /* Saraiki */ - {"sl", {HB_TAG('S','L','V',' ')}}, /* Slovenian */ - {"sm", {HB_TAG('S','M','O',' ')}}, /* Samoan */ - {"sma", {HB_TAG('S','S','M',' ')}}, /* Southern Sami */ - {"smj", {HB_TAG('L','S','M',' ')}}, /* Lule Sami */ - {"smn", {HB_TAG('I','S','M',' ')}}, /* Inari Sami */ - {"sms", {HB_TAG('S','K','S',' ')}}, /* Skolt Sami */ - {"sn", {HB_TAG('S','N','A','0')}}, /* Shona */ - {"snk", {HB_TAG('S','N','K',' ')}}, /* Soninke */ - {"so", {HB_TAG('S','M','L',' ')}}, /* Somali */ - {"sop", {HB_TAG('S','O','P',' ')}}, /* Songe */ - {"spv", {HB_TAG('O','R','I',' ')}}, /* Sambalpuri -> Odia (formerly Oriya) */ - {"spy", {HB_TAG('K','A','L',' ')}}, /* Sabaot -> Kalenjin */ - {"sq", {HB_TAG('S','Q','I',' ')}}, /* Albanian [macrolanguage] */ - {"sr", {HB_TAG('S','R','B',' ')}}, /* Serbian */ - {"src", {HB_TAG('S','R','D',' ')}}, /* Logudorese Sardinian -> Sardinian */ - {"sro", {HB_TAG('S','R','D',' ')}}, /* Campidanese Sardinian -> Sardinian */ - {"srr", {HB_TAG('S','R','R',' ')}}, /* Serer */ - {"srs", {HB_TAG('A','T','H',' ')}}, /* Sarsi -> Athapaskan */ - {"ss", {HB_TAG('S','W','Z',' ')}}, /* Swati */ - {"ssh", {HB_TAG('A','R','A',' ')}}, /* Shihhi Arabic -> Arabic */ - {"st", {HB_TAG('S','O','T',' ')}}, /* Southern Sotho -> Sotho, Southern */ - {"stq", {HB_TAG('S','T','Q',' ')}}, /* Saterfriesisch -> Saterland Frisian */ - {"stv", {HB_TAG('S','I','G',' ')}}, /* Silt'e -> Silte Gurage */ - {"su", {HB_TAG('S','U','N',' ')}}, /* Sundanese */ - {"suk", {HB_TAG('S','U','K',' ')}}, /* Sukuma */ - {"suq", {HB_TAG('S','U','R',' ')}}, /* Suri */ - {"sv", {HB_TAG('S','V','E',' ')}}, /* Swedish */ - {"sva", {HB_TAG('S','V','A',' ')}}, /* Svan */ - {"sw", {HB_TAG('S','W','K',' ')}}, /* Swahili [macrolanguage] */ - {"swb", {HB_TAG('C','M','R',' ')}}, /* Maore Comorian -> Comorian */ - {"swc", {HB_TAG('S','W','K',' ')}}, /* Congo Swahili -> Swahili */ - {"swh", {HB_TAG('S','W','K',' ')}}, /* Swahili */ - {"swv", {HB_TAG('M','A','W',' ')}}, /* Shekhawati -> Marwari */ - {"sxu", {HB_TAG('S','X','U',' ')}}, /* Upper Saxon */ - {"syc", {HB_TAG('S','Y','R',' ')}}, /* Classical Syriac -> Syriac */ - {"syl", {HB_TAG('S','Y','L',' ')}}, /* Sylheti */ - {"syr", {HB_TAG('S','Y','R',' ')}}, /* Syriac [macrolanguage] */ - {"szl", {HB_TAG('S','Z','L',' ')}}, /* Silesian */ - {"ta", {HB_TAG('T','A','M',' ')}}, /* Tamil */ - {"taa", {HB_TAG('A','T','H',' ')}}, /* Lower Tanana -> Athapaskan */ - {"tab", {HB_TAG('T','A','B',' ')}}, /* Tabassaran -> Tabasaran */ - {"taq", {HB_TAG('T','M','H',' ')}}, /* Tamasheq -> Tamashek */ - {"tau", {HB_TAG('A','T','H',' ')}}, /* Upper Tanana -> Athapaskan */ - {"tcb", {HB_TAG('A','T','H',' ')}}, /* Tanacross -> Athapaskan */ - {"tce", {HB_TAG('A','T','H',' ')}}, /* Southern Tutchone -> Athapaskan */ - {"tcp", {HB_TAG('Q','I','N',' ')}}, /* Tawr Chin -> Chin */ - {"tcy", {HB_TAG('T','U','L',' ')}}, /* Tulu -> Tumbuka */ - {"tcz", {HB_TAG('Q','I','N',' ')}}, /* Thado Chin -> Chin */ - {"tdd", {HB_TAG('T','D','D',' ')}}, /* Tai Nüa -> Dehong Dai */ - {"tdx", {HB_TAG('M','L','G',' ')}}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ - {"te", {HB_TAG('T','E','L',' ')}}, /* Telugu */ - {"tec", {HB_TAG('K','A','L',' ')}}, /* Terik -> Kalenjin */ - {"tem", {HB_TAG('T','M','N',' ')}}, /* Timne -> Temne */ - {"tet", {HB_TAG('T','E','T',' ')}}, /* Tetum */ - {"tfn", {HB_TAG('A','T','H',' ')}}, /* Tanaina -> Athapaskan */ - {"tg", {HB_TAG('T','A','J',' ')}}, /* Tajik -> Tajiki */ - {"tgj", {HB_TAG('N','I','S',' ')}}, /* Tagin -> Nisi */ - {"tgx", {HB_TAG('A','T','H',' ')}}, /* Tagish -> Athapaskan */ - {"th", {HB_TAG('T','H','A',' ')}}, /* Thai */ - {"tht", {HB_TAG('A','T','H',' ')}}, /* Tahltan -> Athapaskan */ - {"thv", {HB_TAG('T','M','H',' ')}}, /* Tahaggart Tamahaq -> Tamashek */ - {"thz", {HB_TAG('T','M','H',' ')}}, /* Tayart Tamajeq -> Tamashek */ - {"ti", {HB_TAG('T','G','Y',' ')}}, /* Tigrinya */ - {"tig", {HB_TAG('T','G','R',' ')}}, /* Tigre */ - {"tiv", {HB_TAG('T','I','V',' ')}}, /* Tiv */ - {"tk", {HB_TAG('T','K','M',' ')}}, /* Turkmen */ - {"tkg", {HB_TAG('M','L','G',' ')}}, /* Tesaka Malagasy -> Malagasy */ - {"tl", {HB_TAG('T','G','L',' ')}}, /* Tagalog */ - {"tmh", {HB_TAG('T','M','H',' ')}}, /* Tamashek [macrolanguage] */ - {"tmw", {HB_TAG('M','L','Y',' ')}}, /* Temuan -> Malay */ - {"tn", {HB_TAG('T','N','A',' ')}}, /* Tswana */ - {"tnf", {HB_TAG('D','R','I',' ')}}, /* Tangshewi (retired code) -> Dari */ - {"to", {HB_TAG('T','G','N',' ')}}, /* Tonga (Tonga Islands) -> Tongan */ - {"tod", {HB_TAG('T','O','D','0')}}, /* Toma */ - {"toi", {HB_TAG('T','N','G',' ')}}, /* Tonga (Zambia) */ - {"tol", {HB_TAG('A','T','H',' ')}}, /* Tolowa -> Athapaskan */ - {"tpi", {HB_TAG('T','P','I',' ')}}, /* Tok Pisin */ - {"tr", {HB_TAG('T','R','K',' ')}}, /* Turkish */ - {"tru", {HB_TAG('T','U','A',' '), /* Turoyo -> Turoyo Aramaic */ - HB_TAG('S','Y','R',' ')}}, /* Turoyo -> Syriac */ - {"ts", {HB_TAG('T','S','G',' ')}}, /* Tsonga */ - {"tsj", {HB_TAG('T','S','J',' ')}}, /* Tshangla */ - {"tt", {HB_TAG('T','A','T',' ')}}, /* Tatar */ - {"ttm", {HB_TAG('A','T','H',' ')}}, /* Northern Tutchone -> Athapaskan */ - {"ttq", {HB_TAG('T','M','H',' ')}}, /* Tawallammat Tamajaq -> Tamashek */ - {"tum", {HB_TAG('T','U','M',' ')}}, /* Tumbuka -> Tulu */ - {"tuu", {HB_TAG('A','T','H',' ')}}, /* Tututni -> Athapaskan */ - {"tuy", {HB_TAG('K','A','L',' ')}}, /* Tugen -> Kalenjin */ - {"tvl", {HB_TAG('T','V','L',' ')}}, /* Tuvalu */ - {"tw", {HB_TAG('T','W','I',' '), /* Twi */ - HB_TAG('A','K','A',' ')}}, /* Twi -> Akan */ - {"txc", {HB_TAG('A','T','H',' ')}}, /* Tsetsaut -> Athapaskan */ - {"txy", {HB_TAG('M','L','G',' ')}}, /* Tanosy Malagasy -> Malagasy */ - {"ty", {HB_TAG('T','H','T',' ')}}, /* Tahitian */ - {"tyv", {HB_TAG('T','U','V',' ')}}, /* Tuvinian -> Tuvin */ - {"tyz", {HB_TAG('T','Y','Z',' ')}}, /* Tày */ - {"tzm", {HB_TAG('T','Z','M',' ')}}, /* Central Atlas Tamazight -> Tamazight */ - {"tzo", {HB_TAG('T','Z','O',' ')}}, /* Tzotzil */ - {"ubl", {HB_TAG('B','I','K',' ')}}, /* Buhi'non Bikol -> Bikol */ - {"udm", {HB_TAG('U','D','M',' ')}}, /* Udmurt */ - {"ug", {HB_TAG('U','Y','G',' ')}}, /* Uyghur */ - {"uk", {HB_TAG('U','K','R',' ')}}, /* Ukrainian */ - {"umb", {HB_TAG('U','M','B',' ')}}, /* Umbundu */ - {"unr", {HB_TAG('M','U','N',' ')}}, /* Mundari */ - {"ur", {HB_TAG('U','R','D',' ')}}, /* Urdu */ - {"urk", {HB_TAG('M','L','Y',' ')}}, /* Urak Lawoi' -> Malay */ - {"uz", {HB_TAG('U','Z','B',' ')}}, /* Uzbek [macrolanguage] */ - {"uzn", {HB_TAG('U','Z','B',' ')}}, /* Northern Uzbek -> Uzbek */ - {"uzs", {HB_TAG('U','Z','B',' ')}}, /* Southern Uzbek -> Uzbek */ - {"ve", {HB_TAG('V','E','N',' ')}}, /* Venda */ - {"vec", {HB_TAG('V','E','C',' ')}}, /* Venetian */ - {"vi", {HB_TAG('V','I','T',' ')}}, /* Vietnamese */ - {"vkk", {HB_TAG('M','L','Y',' ')}}, /* Kaur -> Malay */ - {"vkt", {HB_TAG('M','L','Y',' ')}}, /* Tenggarong Kutai Malay -> Malay */ - {"vls", {HB_TAG('F','L','E',' ')}}, /* Vlaams -> Dutch (Flemish) */ - {"vmw", {HB_TAG('M','A','K',' ')}}, /* Makhuwa */ - {"vo", {HB_TAG('V','O','L',' ')}}, /* Volapük */ - {"vro", {HB_TAG('V','R','O',' ')}}, /* Võro */ - {"wa", {HB_TAG('W','L','N',' ')}}, /* Walloon */ - {"war", {HB_TAG('W','A','R',' ')}}, /* Waray (Philippines) -> Waray-Waray */ - {"wbm", {HB_TAG('W','A',' ',' ')}}, /* Wa */ - {"wbr", {HB_TAG('W','A','G',' ')}}, /* Wagdi */ - {"wlc", {HB_TAG('C','M','R',' ')}}, /* Mwali Comorian -> Comorian */ - {"wle", {HB_TAG('S','I','G',' ')}}, /* Wolane -> Silte Gurage */ - {"wlk", {HB_TAG('A','T','H',' ')}}, /* Wailaki -> Athapaskan */ - {"wni", {HB_TAG('C','M','R',' ')}}, /* Ndzwani Comorian -> Comorian */ - {"wo", {HB_TAG('W','L','F',' ')}}, /* Wolof */ - {"wry", {HB_TAG('M','A','W',' ')}}, /* Merwari -> Marwari */ - {"wsg", {HB_TAG('G','O','N',' ')}}, /* Adilabad Gondi -> Gondi */ - {"wtm", {HB_TAG('W','T','M',' ')}}, /* Mewati */ - {"wuu", {HB_TAG('Z','H','S',' ')}}, /* Wu Chinese -> Chinese Simplified */ - {"xal", {HB_TAG('K','L','M',' '), /* Kalmyk */ - HB_TAG('T','O','D',' ')}}, /* Kalmyk -> Todo */ - {"xan", {HB_TAG('S','E','K',' ')}}, /* Xamtanga -> Sekota */ - {"xh", {HB_TAG('X','H','S',' ')}}, /* Xhosa */ - {"xjb", {HB_TAG('X','J','B',' ')}}, /* Minjungbal -> Minjangbal */ - {"xkf", {HB_TAG('X','K','F',' ')}}, /* Khengkha */ - {"xmm", {HB_TAG('M','L','Y',' ')}}, /* Manado Malay -> Malay */ - {"xmv", {HB_TAG('M','L','G',' ')}}, /* Antankarana Malagasy -> Malagasy */ - {"xmw", {HB_TAG('M','L','G',' ')}}, /* Tsimihety Malagasy -> Malagasy */ - {"xnr", {HB_TAG('D','G','R',' ')}}, /* Kangri -> Dogri */ - {"xog", {HB_TAG('X','O','G',' ')}}, /* Soga */ - {"xpe", {HB_TAG('X','P','E',' ')}}, /* Liberia Kpelle -> Kpelle (Liberia) */ - {"xsl", {HB_TAG('S','S','L',' '), /* South Slavey */ - HB_TAG('S','L','A',' '), /* South Slavey -> Slavey */ - HB_TAG('A','T','H',' ')}}, /* South Slavey -> Athapaskan */ - {"xst", {HB_TAG('S','I','G',' ')}}, /* Silt'e (retired code) -> Silte Gurage */ - {"xwo", {HB_TAG('T','O','D',' ')}}, /* Written Oirat -> Todo */ - {"yao", {HB_TAG('Y','A','O',' ')}}, /* Yao */ - {"yap", {HB_TAG('Y','A','P',' ')}}, /* Yapese */ - {"ybd", {HB_TAG('A','R','K',' ')}}, /* Yangbye (retired code) -> Rakhine */ - {"ydd", {HB_TAG('J','I','I',' ')}}, /* Eastern Yiddish -> Yiddish */ - {"yi", {HB_TAG('J','I','I',' ')}}, /* Yiddish [macrolanguage] */ - {"yih", {HB_TAG('J','I','I',' ')}}, /* Western Yiddish -> Yiddish */ - {"yo", {HB_TAG('Y','B','A',' ')}}, /* Yoruba */ - {"yos", {HB_TAG('Q','I','N',' ')}}, /* Yos (retired code) -> Chin */ - {"yrk", {HB_TAG('T','N','E',' '), /* Nenets -> Tundra Nenets */ - HB_TAG('F','N','E',' ')}}, /* Nenets -> Forest Nenets */ - {"yue", {HB_TAG('Z','H','H',' ')}}, /* Yue Chinese -> Chinese, Hong Kong SAR */ - {"za", {HB_TAG('Z','H','A',' ')}}, /* Zhuang [macrolanguage] */ - {"zch", {HB_TAG('Z','H','A',' ')}}, /* Central Hongshuihe Zhuang -> Zhuang */ - {"zdj", {HB_TAG('C','M','R',' ')}}, /* Ngazidja Comorian -> Comorian */ - {"zea", {HB_TAG('Z','E','A',' ')}}, /* Zeeuws -> Zealandic */ - {"zeh", {HB_TAG('Z','H','A',' ')}}, /* Eastern Hongshuihe Zhuang -> Zhuang */ - {"zgb", {HB_TAG('Z','H','A',' ')}}, /* Guibei Zhuang -> Zhuang */ - {"zgh", {HB_TAG('Z','G','H',' ')}}, /* Standard Moroccan Tamazight */ - {"zgm", {HB_TAG('Z','H','A',' ')}}, /* Minz Zhuang -> Zhuang */ - {"zgn", {HB_TAG('Z','H','A',' ')}}, /* Guibian Zhuang -> Zhuang */ - {"zh", {HB_TAG('Z','H','S',' ')}}, /* Chinese [macrolanguage] -> Chinese Simplified */ - {"zhd", {HB_TAG('Z','H','A',' ')}}, /* Dai Zhuang -> Zhuang */ - {"zhn", {HB_TAG('Z','H','A',' ')}}, /* Nong Zhuang -> Zhuang */ - {"zlj", {HB_TAG('Z','H','A',' ')}}, /* Liujiang Zhuang -> Zhuang */ - {"zlm", {HB_TAG('M','L','Y',' ')}}, /* Malay */ - {"zln", {HB_TAG('Z','H','A',' ')}}, /* Lianshan Zhuang -> Zhuang */ - {"zlq", {HB_TAG('Z','H','A',' ')}}, /* Liuqian Zhuang -> Zhuang */ - {"zmi", {HB_TAG('M','L','Y',' ')}}, /* Negeri Sembilan Malay -> Malay */ - {"zne", {HB_TAG('Z','N','D',' ')}}, /* Zande */ - {"zom", {HB_TAG('Q','I','N',' ')}}, /* Zou -> Chin */ - {"zqe", {HB_TAG('Z','H','A',' ')}}, /* Qiubei Zhuang -> Zhuang */ - {"zsm", {HB_TAG('M','L','Y',' ')}}, /* Standard Malay -> Malay */ - {"zu", {HB_TAG('Z','U','L',' ')}}, /* Zulu */ - {"zum", {HB_TAG('L','R','C',' ')}}, /* Kumzari -> Luri */ - {"zyb", {HB_TAG('Z','H','A',' ')}}, /* Yongbei Zhuang -> Zhuang */ - {"zyg", {HB_TAG('Z','H','A',' ')}}, /* Yang Zhuang -> Zhuang */ - {"zyj", {HB_TAG('Z','H','A',' ')}}, /* Youjiang Zhuang -> Zhuang */ - {"zyn", {HB_TAG('Z','H','A',' ')}}, /* Yongnan Zhuang -> Zhuang */ - {"zza", {HB_TAG('Z','Z','A',' ')}}, /* Zazaki [macrolanguage] */ - {"zzj", {HB_TAG('Z','H','A',' ')}}, /* Zuojiang Zhuang -> Zhuang */ + {"aa", HB_TAG('A','F','R',' ')}, /* Afar */ + {"aae", HB_TAG('S','Q','I',' ')}, /* Arbëreshë Albanian -> Albanian */ + {"aao", HB_TAG('A','R','A',' ')}, /* Algerian Saharan Arabic -> Arabic */ + {"aat", HB_TAG('S','Q','I',' ')}, /* Arvanitika Albanian -> Albanian */ + {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */ + {"abh", HB_TAG('A','R','A',' ')}, /* Tajiki Arabic -> Arabic */ + {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */ + {"abv", HB_TAG('A','R','A',' ')}, /* Baharna Arabic -> Arabic */ + {"acf", HB_TAG('F','A','N',' ')}, /* Saint Lucian Creole French -> French Antillean */ + {"ach", HB_TAG('A','C','H',' ')}, /* Acoli -> Acholi */ + {"acm", HB_TAG('A','R','A',' ')}, /* Mesopotamian Arabic -> Arabic */ + {"acq", HB_TAG('A','R','A',' ')}, /* Ta'izzi-Adeni Arabic -> Arabic */ + {"acr", HB_TAG('A','C','R',' ')}, /* Achi */ + {"acw", HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */ + {"acx", HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */ + {"acy", HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */ + {"ada", HB_TAG('D','N','G',' ')}, /* Adangme -> Dangme */ + {"adf", HB_TAG('A','R','A',' ')}, /* Dhofari Arabic -> Arabic */ + {"adp", HB_TAG('D','Z','N',' ')}, /* Adap (retired code) -> Dzongkha */ + {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */ + {"aeb", HB_TAG('A','R','A',' ')}, /* Tunisian Arabic -> Arabic */ + {"aec", HB_TAG('A','R','A',' ')}, /* Saidi Arabic -> Arabic */ + {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */ + {"afb", HB_TAG('A','R','A',' ')}, /* Gulf Arabic -> Arabic */ + {"ahg", HB_TAG('A','G','W',' ')}, /* Qimant -> Agaw */ + {"aht", HB_TAG('A','T','H',' ')}, /* Ahtena -> Athapaskan */ + {"aii", HB_TAG('S','W','A',' ')}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ + {"aii", HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */ + {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */ + {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */ + {"ajp", HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */ + {"ak", HB_TAG('A','K','A',' ')}, /* Akan [macrolanguage] */ + {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] -> Twi */ + {"aln", HB_TAG('S','Q','I',' ')}, /* Gheg Albanian -> Albanian */ + {"als", HB_TAG('S','Q','I',' ')}, /* Tosk Albanian -> Albanian */ + {"alt", HB_TAG('A','L','T',' ')}, /* Southern Altai -> Altai */ + {"am", HB_TAG('A','M','H',' ')}, /* Amharic */ + {"amf", HB_TAG('H','B','N',' ')}, /* Hamer-Banna -> Hammer-Banna */ + {"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic -> Syriac */ + {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */ + {"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) -> Anglo-Saxon */ + {"apc", HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */ + {"apd", HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */ + {"apj", HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */ + {"apk", HB_TAG('A','T','H',' ')}, /* Kiowa Apache -> Athapaskan */ + {"apl", HB_TAG('A','T','H',' ')}, /* Lipan Apache -> Athapaskan */ + {"apm", HB_TAG('A','T','H',' ')}, /* Mescalero-Chiricahua Apache -> Athapaskan */ + {"apw", HB_TAG('A','T','H',' ')}, /* Western Apache -> Athapaskan */ + {"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */ + {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic -> Arabic */ + {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */ + {"arq", HB_TAG('A','R','A',' ')}, /* Algerian Arabic -> Arabic */ + {"ars", HB_TAG('A','R','A',' ')}, /* Najdi Arabic -> Arabic */ + {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic -> Moroccan */ + {"arz", HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */ + {"as", HB_TAG('A','S','M',' ')}, /* Assamese */ + {"ast", HB_TAG('A','S','T',' ')}, /* Asturian */ + {"ath", HB_TAG('A','T','H',' ')}, /* Athapascan [family] -> Athapaskan */ + {"atj", HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */ + {"atv", HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */ + {"auz", HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ + {"av", HB_TAG('A','V','R',' ')}, /* Avaric -> Avar */ + {"avl", HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ + {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */ + {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ + {"ayc", HB_TAG('A','Y','M',' ')}, /* Southern Aymara -> Aymara */ + {"ayh", HB_TAG('A','R','A',' ')}, /* Hadrami Arabic -> Arabic */ + {"ayl", HB_TAG('A','R','A',' ')}, /* Libyan Arabic -> Arabic */ + {"ayn", HB_TAG('A','R','A',' ')}, /* Sanaani Arabic -> Arabic */ + {"ayp", HB_TAG('A','R','A',' ')}, /* North Mesopotamian Arabic -> Arabic */ + {"ayr", HB_TAG('A','Y','M',' ')}, /* Central Aymara -> Aymara */ + {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ + {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani -> Torki */ + {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani -> Azerbaijani */ + {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */ + {"bad", HB_TAG('B','A','D','0')}, /* Banda [family] */ + {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */ + {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */ + {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */ + {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */ + {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */ + {"bbz", HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic -> Arabic */ + {"bcc", HB_TAG('B','L','I',' ')}, /* Southern Balochi -> Baluchi */ + {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé -> Baulé */ + {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */ + {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ + {"bcr", HB_TAG('A','T','H',' ')}, /* Babine -> Athapaskan */ + {"bdy", HB_TAG('B','D','Y',' ')}, /* Bandjalang */ + {"be", HB_TAG('B','E','L',' ')}, /* Belarusian -> Belarussian */ + {"bea", HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */ + {"beb", HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */ + {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ + {"ber", HB_TAG('B','B','R',' ')}, /* Berber [family] */ + {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ + {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ + {"bfu", HB_TAG('L','A','H',' ')}, /* Gahri -> Lahuli */ + {"bfy", HB_TAG('B','A','G',' ')}, /* Bagheli -> Baghelkhandi */ + {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */ + {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */ + {"bgn", HB_TAG('B','L','I',' ')}, /* Western Balochi -> Baluchi */ + {"bgp", HB_TAG('B','L','I',' ')}, /* Eastern Balochi -> Baluchi */ + {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */ + {"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin -> Chin */ + {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */ + {"bhi", HB_TAG('B','H','I',' ')}, /* Bhilali -> Bhili */ + {"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) -> Bikol */ + {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */ + {"bhr", HB_TAG('M','L','G',' ')}, /* Bara Malagasy -> Malagasy */ + {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */ + {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */ + {"bin", HB_TAG('E','D','O',' ')}, /* Edo */ + {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */ + {"bjn", HB_TAG('M','L','Y',' ')}, /* Banjar -> Malay */ + {"bjq", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */ + {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja -> Balante */ + {"bla", HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */ + {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */ + {"blk", HB_TAG('B','L','K',' ')}, /* Pa’o Karen */ + {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol -> Bikol */ + {"bm", HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ + {"bmm", HB_TAG('M','L','G',' ')}, /* Northern Betsimisaraka Malagasy -> Malagasy */ + {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */ + {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */ + {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya -> Bishnupriya Manipuri */ + {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari -> Luri */ + {"br", HB_TAG('B','R','E',' ')}, /* Breton */ + {"bra", HB_TAG('B','R','I',' ')}, /* Braj -> Braj Bhasha */ + {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */ + {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */ + {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */ + {"bsk", HB_TAG('B','S','K',' ')}, /* Burushaski */ + {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) (retired code) */ + {"btj", HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */ + {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */ + {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */ + {"bug", HB_TAG('B','U','G',' ')}, /* Buginese -> Bugis */ + {"bum", HB_TAG('B','T','I',' ')}, /* Bulu (Cameroon) -> Beti */ + {"bve", HB_TAG('M','L','Y',' ')}, /* Berau Malay -> Malay */ + {"bvu", HB_TAG('M','L','Y',' ')}, /* Bukit Malay -> Malay */ + {"bxk", HB_TAG('L','U','H',' ')}, /* Bukusu -> Luyia */ + {"bxp", HB_TAG('B','T','I',' ')}, /* Bebil -> Beti */ + {"bxr", HB_TAG('R','B','U',' ')}, /* Russia Buriat -> Russian Buriat */ + {"byn", HB_TAG('B','I','L',' ')}, /* Bilin -> Bilen */ + {"byv", HB_TAG('B','Y','V',' ')}, /* Medumba */ + {"bzc", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy -> Malagasy */ + {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */ + {"caf", HB_TAG('C','R','R',' ')}, /* Southern Carrier -> Carrier */ + {"caf", HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */ + {"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */ + {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */ + {"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */ + {"cco", HB_TAG('C','C','H','N')}, /* Comaltepec Chinantec -> Chinantec */ + {"ccq", HB_TAG('A','R','K',' ')}, /* Chaungtha (retired code) -> Rakhine */ + {"cdo", HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese Simplified */ + {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */ + {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */ + {"cfm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) */ + {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */ + {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */ + {"chj", HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */ + {"chk", HB_TAG('C','H','K','0')}, /* Chuukese */ + {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */ + {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */ + {"chp", HB_TAG('S','A','Y',' ')}, /* Chipewyan -> Sayisi */ + {"chp", HB_TAG('A','T','H',' ')}, /* Chipewyan -> Athapaskan */ + {"chq", HB_TAG('C','C','H','N')}, /* Quiotepec Chinantec -> Chinantec */ + {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */ + {"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */ + {"chz", HB_TAG('C','C','H','N')}, /* Ozumacín Chinantec -> Chinantec */ + {"ciw", HB_TAG('O','J','B',' ')}, /* Chippewa -> Ojibway */ + {"cja", HB_TAG('C','J','A',' ')}, /* Western Cham */ + {"cjm", HB_TAG('C','J','M',' ')}, /* Eastern Cham */ + {"cjy", HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese Simplified */ + {"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin (retired code) -> Chin */ + {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish -> Kurdish */ + {"ckt", HB_TAG('C','H','K',' ')}, /* Chukot -> Chukchi */ + {"clc", HB_TAG('A','T','H',' ')}, /* Chilcotin -> Athapaskan */ + {"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic -> Syriac */ + {"cle", HB_TAG('C','C','H','N')}, /* Lealao Chinantec -> Chinantec */ + {"cmn", HB_TAG('Z','H','S',' ')}, /* Mandarin Chinese -> Chinese Simplified */ + {"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin -> Chin */ + {"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin -> Chin */ + {"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin -> Chin */ + {"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin -> Chin */ + {"cnl", HB_TAG('C','C','H','N')}, /* Lalana Chinantec -> Chinantec */ + {"cnt", HB_TAG('C','C','H','N')}, /* Tepetotutla Chinantec -> Chinantec */ + {"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */ + {"co", HB_TAG('C','O','S',' ')}, /* Corsican */ + {"coa", HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */ + {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */ + {"coq", HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */ + {"cpa", HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */ + {"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [family] -> Creoles */ + {"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [family] -> Creoles */ + {"cpp", HB_TAG('C','P','P',' ')}, /* Portuguese-based creoles and pidgins [family] -> Creoles */ + {"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese Simplified */ + {"cqd", HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */ + {"cqu", HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ + {"cr", HB_TAG('C','R','E',' ')}, /* Cree [macrolanguage] */ + {"cr", HB_TAG('Y','C','R',' ')}, /* Cree [macrolanguage] -> Y-Cree */ + {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */ + {"crj", HB_TAG('E','C','R',' ')}, /* Southern East Cree -> Eastern Cree */ + {"crk", HB_TAG('W','C','R',' ')}, /* Plains Cree -> West-Cree */ + {"crl", HB_TAG('E','C','R',' ')}, /* Northern East Cree -> Eastern Cree */ + {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */ + {"crm", HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */ + {"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [family] -> Creoles */ + {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */ + {"crx", HB_TAG('A','T','H',' ')}, /* Carrier -> Athapaskan */ + {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */ + {"csa", HB_TAG('C','C','H','N')}, /* Chiltepec Chinantec -> Chinantec */ + {"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */ + {"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin -> Chin */ + {"cso", HB_TAG('C','C','H','N')}, /* Sochiapam Chinantec -> Chinantec */ + {"csw", HB_TAG('N','C','R',' ')}, /* Swampy Cree -> N-Cree */ + {"csw", HB_TAG('N','H','C',' ')}, /* Swampy Cree -> Norway House Cree */ + {"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin -> Chin */ + {"ctc", HB_TAG('A','T','H',' ')}, /* Chetco -> Athapaskan */ + {"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin -> Chin */ + {"cte", HB_TAG('C','C','H','N')}, /* Tepinapa Chinantec -> Chinantec */ + {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */ + {"ctl", HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ + {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ + {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavonic */ + {"cuc", HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */ + {"cuk", HB_TAG('C','U','K',' ')}, /* San Blas Kuna */ + {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */ + {"cvn", HB_TAG('C','C','H','N')}, /* Valle Nacional Chinantec -> Chinantec */ + {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */ + {"cwd", HB_TAG('T','C','R',' ')}, /* Woods Cree -> TH-Cree */ + {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */ + {"czh", HB_TAG('Z','H','S',' ')}, /* Huizhou Chinese -> Chinese Simplified */ + {"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese Simplified */ + {"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */ + {"da", HB_TAG('D','A','N',' ')}, /* Danish */ + {"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */ + {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */ + {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */ + {"dax", HB_TAG('D','A','X',' ')}, /* Dayi */ + {"de", HB_TAG('D','E','U',' ')}, /* German */ + {"den", HB_TAG('S','L','A',' ')}, /* Slave (Athapascan) [macrolanguage] -> Slavey */ + {"den", HB_TAG('A','T','H',' ')}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ + {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */ + {"dgr", HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */ + {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */ + {"dhg", HB_TAG('D','H','G',' ')}, /* Dhangu */ + {"dib", HB_TAG('D','N','K',' ')}, /* South Central Dinka -> Dinka */ + {"dik", HB_TAG('D','N','K',' ')}, /* Southwestern Dinka -> Dinka */ + {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ + {"dip", HB_TAG('D','N','K',' ')}, /* Northeastern Dinka -> Dinka */ + {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */ + {"diw", HB_TAG('D','N','K',' ')}, /* Northwestern Dinka -> Dinka */ + {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */ + {"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */ + {"dks", HB_TAG('D','N','K',' ')}, /* Southeastern Dinka -> Dinka */ + {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */ + {"dnj", HB_TAG('D','N','J',' ')}, /* Dan */ + {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */ + {"drh", HB_TAG('M','N','G',' ')}, /* Darkhat (retired code) -> Mongolian */ + {"drw", HB_TAG('D','R','I',' ')}, /* Darwazi (retired code) -> Dari */ + {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ + {"dty", HB_TAG('N','E','P',' ')}, /* Dotyali -> Nepali */ + {"duj", HB_TAG('D','U','J',' ')}, /* Dhuwal (retired code) */ + {"dup", HB_TAG('M','L','Y',' ')}, /* Duano -> Malay */ + {"dv", HB_TAG('D','I','V',' ')}, /* Divehi (Dhivehi, Maldivian) */ + {"dv", HB_TAG('D','H','V',' ')}, /* Divehi (Dhivehi, Maldivian) (deprecated) */ + {"dwu", HB_TAG('D','U','J',' ')}, /* Dhuwal */ + {"dwy", HB_TAG('D','U','J',' ')}, /* Dhuwaya -> Dhuwal */ + {"dyu", HB_TAG('J','U','L',' ')}, /* Dyula -> Jula */ + {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */ + {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */ + {"efi", HB_TAG('E','F','I',' ')}, /* Efik */ + {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian -> Estonian */ + {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) -> Greek */ + {"emk", HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */ + {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan -> Maninka */ + {"en", HB_TAG('E','N','G',' ')}, /* English */ + {"enb", HB_TAG('K','A','L',' ')}, /* Markweeta -> Kalenjin */ + {"enf", HB_TAG('F','N','E',' ')}, /* Forest Enets -> Forest Nenets */ + {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Enets -> Tundra Nenets */ + {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */ + {"es", HB_TAG('E','S','P',' ')}, /* Spanish */ + {"esg", HB_TAG('G','O','N',' ')}, /* Aheri Gondi -> Gondi */ + {"esi", HB_TAG('I','P','K',' ')}, /* North Alaskan Inupiatun -> Inupiat */ + {"esk", HB_TAG('I','P','K',' ')}, /* Northwest Alaska Inupiatun -> Inupiat */ + {"esu", HB_TAG('E','S','U',' ')}, /* Central Yupik */ + {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */ + {"eto", HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */ + {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */ + {"eve", HB_TAG('E','V','N',' ')}, /* Even */ + {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */ + {"ewo", HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */ + {"eyo", HB_TAG('K','A','L',' ')}, /* Keiyo -> Kalenjin */ + {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */ + {"fan", HB_TAG('F','A','N','0')}, /* Fang (Equatorial Guinea) */ + {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */ + {"fbl", HB_TAG('B','I','K',' ')}, /* West Albay Bikol -> Bikol */ + {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */ + {"ffm", HB_TAG('F','U','L',' ')}, /* Maasina Fulfulde -> Fulah */ + {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */ + {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */ + {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */ + {"flm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) (retired code) */ + {"flm", HB_TAG('Q','I','N',' ')}, /* Falam Chin (retired code) -> Chin */ + {"fmp", HB_TAG('F','M','P',' ')}, /* Fe’fe’ */ + {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */ + {"fon", HB_TAG('F','O','N',' ')}, /* Fon */ + {"fr", HB_TAG('F','R','A',' ')}, /* French */ + {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */ + {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan */ + {"fub", HB_TAG('F','U','L',' ')}, /* Adamawa Fulfulde -> Fulah */ + {"fuc", HB_TAG('F','U','L',' ')}, /* Pulaar -> Fulah */ + {"fue", HB_TAG('F','U','L',' ')}, /* Borgu Fulfulde -> Fulah */ + {"fuf", HB_TAG('F','T','A',' ')}, /* Pular -> Futa */ + {"fuh", HB_TAG('F','U','L',' ')}, /* Western Niger Fulfulde -> Fulah */ + {"fui", HB_TAG('F','U','L',' ')}, /* Bagirmi Fulfulde -> Fulah */ + {"fuq", HB_TAG('F','U','L',' ')}, /* Central-Eastern Niger Fulfulde -> Fulah */ + {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */ + {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ + {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ + {"ga", HB_TAG('I','R','I',' ')}, /* Irish */ + {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */ + {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */ + {"gan", HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese Simplified */ + {"gax", HB_TAG('O','R','O',' ')}, /* Borana-Arsi-Guji Oromo -> Oromo */ + {"gaz", HB_TAG('O','R','O',' ')}, /* West Central Oromo -> Oromo */ + {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */ + {"gce", HB_TAG('A','T','H',' ')}, /* Galice -> Athapaskan */ + {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ + {"gda", HB_TAG('R','A','J',' ')}, /* Gade Lohar -> Rajasthani */ + {"gez", HB_TAG('G','E','Z',' ')}, /* Geez */ + {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */ + {"gih", HB_TAG('G','I','H',' ')}, /* Githabul */ + {"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */ + {"gju", HB_TAG('R','A','J',' ')}, /* Gujari -> Rajasthani */ + {"gkp", HB_TAG('G','K','P',' ')}, /* Guinea Kpelle -> Kpelle (Guinea) */ + {"gl", HB_TAG('G','A','L',' ')}, /* Galician */ + {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */ + {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */ + {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ + {"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */ + {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi -> Gondi */ + {"gnw", HB_TAG('G','U','A',' ')}, /* Western Bolivian Guaraní -> Guarani */ + {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */ + {"gom", HB_TAG('K','O','K',' ')}, /* Goan Konkani -> Konkani */ + {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */ + {"grt", HB_TAG('G','R','O',' ')}, /* Garo */ + {"gru", HB_TAG('S','O','G',' ')}, /* Kistane -> Sodo Gurage */ + {"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */ + {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */ + {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */ + {"guf", HB_TAG('G','U','F',' ')}, /* Gupapuyngu */ + {"gug", HB_TAG('G','U','A',' ')}, /* Paraguayan Guaraní -> Guarani */ + {"gui", HB_TAG('G','U','A',' ')}, /* Eastern Bolivian Guaraní -> Guarani */ + {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */ + {"guk", HB_TAG('G','U','K',' ')}, /* Gumuz (SIL fonts) */ + {"gun", HB_TAG('G','U','A',' ')}, /* Mbyá Guaraní -> Guarani */ + {"guz", HB_TAG('G','U','Z',' ')}, /* Gusii */ + {"gv", HB_TAG('M','N','X',' ')}, /* Manx */ + {"gwi", HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ + {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ + {"haa", HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ + {"hae", HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ + {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese Simplified */ + {"har", HB_TAG('H','R','I',' ')}, /* Harari */ + {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */ + {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ + {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ + {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ + {"hea", HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */ + {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ + {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */ + {"hji", HB_TAG('M','L','Y',' ')}, /* Haji -> Malay */ + {"hlt", HB_TAG('Q','I','N',' ')}, /* Matu Chin -> Chin */ + {"hma", HB_TAG('H','M','N',' ')}, /* Southern Mashan Hmong -> Hmong */ + {"hmc", HB_TAG('H','M','N',' ')}, /* Central Huishui Hmong -> Hmong */ + {"hmd", HB_TAG('H','M','N',' ')}, /* Large Flowery Miao -> Hmong */ + {"hme", HB_TAG('H','M','N',' ')}, /* Eastern Huishui Hmong -> Hmong */ + {"hmg", HB_TAG('H','M','N',' ')}, /* Southwestern Guiyang Hmong -> Hmong */ + {"hmh", HB_TAG('H','M','N',' ')}, /* Southwestern Huishui Hmong -> Hmong */ + {"hmi", HB_TAG('H','M','N',' ')}, /* Northern Huishui Hmong -> Hmong */ + {"hmj", HB_TAG('H','M','N',' ')}, /* Ge -> Hmong */ + {"hml", HB_TAG('H','M','N',' ')}, /* Luopohe Hmong -> Hmong */ + {"hmm", HB_TAG('H','M','N',' ')}, /* Central Mashan Hmong -> Hmong */ + {"hmn", HB_TAG('H','M','N',' ')}, /* Hmong [macrolanguage] */ + {"hmp", HB_TAG('H','M','N',' ')}, /* Northern Mashan Hmong -> Hmong */ + {"hmq", HB_TAG('H','M','N',' ')}, /* Eastern Qiandong Miao -> Hmong */ + {"hms", HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */ + {"hmw", HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */ + {"hmy", HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */ + {"hmz", HB_TAG('H','M','N',' ')}, /* Hmong Shua -> Hmong */ + {"hnd", HB_TAG('H','N','D',' ')}, /* Southern Hindko -> Hindko */ + {"hne", HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ + {"hnj", HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ + {"hno", HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ + {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */ + {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */ + {"hoi", HB_TAG('A','T','H',' ')}, /* Holikachuk -> Athapaskan */ + {"hoj", HB_TAG('H','A','R',' ')}, /* Hadothi -> Harauti */ + {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */ + {"hrm", HB_TAG('H','M','N',' ')}, /* Horned Miao -> Hmong */ + {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */ + {"hsn", HB_TAG('Z','H','S',' ')}, /* Xiang Chinese -> Chinese Simplified */ + {"ht", HB_TAG('H','A','I',' ')}, /* Haitian (Haitian Creole) */ + {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */ + {"huj", HB_TAG('H','M','N',' ')}, /* Northern Guiyang Hmong -> Hmong */ + {"hup", HB_TAG('A','T','H',' ')}, /* Hupa -> Athapaskan */ + {"hy", HB_TAG('H','Y','E','0')}, /* Armenian -> Armenian East */ + {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */ + {"hyw", HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */ + {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ + {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */ + {"iba", HB_TAG('I','B','A',' ')}, /* Iban */ + {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */ + {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */ + {"ida", HB_TAG('L','U','H',' ')}, /* Idakho-Isukha-Tiriki -> Luyia */ + {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue */ + {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */ + {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */ + {"ii", HB_TAG('Y','I','M',' ')}, /* Sichuan Yi -> Yi Modern */ + {"ijc", HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */ + {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */ + {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */ + {"ike", HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */ + {"ikt", HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */ + {"ilo", HB_TAG('I','L','O',' ')}, /* Iloko -> Ilokano */ + {"in", HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */ + {"ing", HB_TAG('A','T','H',' ')}, /* Degexit'an -> Athapaskan */ + {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */ + {"io", HB_TAG('I','D','O',' ')}, /* Ido */ + {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */ + {"it", HB_TAG('I','T','A',' ')}, /* Italian */ + {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */ + {"iw", HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */ + {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */ + {"jak", HB_TAG('M','L','Y',' ')}, /* Jakun -> Malay */ + {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English -> Jamaican Creole */ + {"jax", HB_TAG('M','L','Y',' ')}, /* Jambi Malay -> Malay */ + {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */ + {"jct", HB_TAG('J','C','T',' ')}, /* Krymchak */ + {"ji", HB_TAG('J','I','I',' ')}, /* Yiddish (retired code) */ + {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */ + {"jw", HB_TAG('J','A','V',' ')}, /* Javanese (retired code) */ + {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */ + {"kaa", HB_TAG('K','R','K',' ')}, /* Kara-Kalpak -> Karakalpak */ + {"kab", HB_TAG('K','A','B','0')}, /* Kabyle */ + {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ + {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */ + {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */ + {"kby", HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */ + {"kca", HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ + {"kca", HB_TAG('K','H','S',' ')}, /* Khanty -> Khanty-Shurishkar */ + {"kca", HB_TAG('K','H','V',' ')}, /* Khanty -> Khanty-Vakhi */ + {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */ + {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */ + {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */ + {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */ + {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */ + {"kex", HB_TAG('K','K','N',' ')}, /* Kukna -> Kokni */ + {"kfa", HB_TAG('K','O','D',' ')}, /* Kodava -> Kodagu */ + {"kfr", HB_TAG('K','A','C',' ')}, /* Kachhi -> Kachchi */ + {"kfx", HB_TAG('K','U','L',' ')}, /* Kullu Pahari -> Kulvi */ + {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */ + {"kg", HB_TAG('K','O','N','0')}, /* Kongo [macrolanguage] */ + {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */ + {"khb", HB_TAG('X','B','D',' ')}, /* Lü */ + {"khk", HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */ + {"kht", HB_TAG('K','H','N',' ')}, /* Khamti -> Khamti Shan (Microsoft fonts) */ + {"kht", HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */ + {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */ + {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu (Gikuyu) */ + {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */ + {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama */ + {"kjd", HB_TAG('K','J','D',' ')}, /* Southern Kiwai */ + {"kjh", HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */ + {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ + {"kjz", HB_TAG('K','J','Z',' ')}, /* Bumthangkha */ + {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */ + {"kkz", HB_TAG('A','T','H',' ')}, /* Kaska -> Athapaskan */ + {"kl", HB_TAG('G','R','N',' ')}, /* Greenlandic */ + {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin [macrolanguage] */ + {"km", HB_TAG('K','H','M',' ')}, /* Khmer */ + {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */ + {"kmr", HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */ + {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */ + {"kmz", HB_TAG('K','M','Z',' ')}, /* Khorasani Turkish -> Khorasani Turkic */ + {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */ + {"knc", HB_TAG('K','N','R',' ')}, /* Central Kanuri -> Kanuri */ + {"kng", HB_TAG('K','O','N','0')}, /* Koongo -> Kongo */ + {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */ + {"ko", HB_TAG('K','O','R',' ')}, /* Korean */ + {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ + {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */ + {"kos", HB_TAG('K','O','S',' ')}, /* Kosraean */ + {"koy", HB_TAG('A','T','H',' ')}, /* Koyukon -> Athapaskan */ + {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ + {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ + {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */ + {"kqs", HB_TAG('K','I','S',' ')}, /* Northern Kissi -> Kisii */ + {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */ + {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */ + {"krc", HB_TAG('K','A','R',' ')}, /* Karachay-Balkar -> Karachay */ + {"krc", HB_TAG('B','A','L',' ')}, /* Karachay-Balkar -> Balkar */ + {"kri", HB_TAG('K','R','I',' ')}, /* Krio */ + {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */ + {"krt", HB_TAG('K','N','R',' ')}, /* Tumari Kanuri -> Kanuri */ + {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */ + {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */ + {"ksh", HB_TAG('K','S','H','0')}, /* Kölsch -> Ripuarian */ + {"kss", HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */ + {"ksw", HB_TAG('K','S','W',' ')}, /* S’gaw Karen */ + {"ktb", HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */ + {"ktu", HB_TAG('K','O','N',' ')}, /* Kituba (Democratic Republic of Congo) -> Kikongo */ + {"ktw", HB_TAG('A','T','H',' ')}, /* Kato -> Athapaskan */ + {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */ + {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */ + {"kuu", HB_TAG('A','T','H',' ')}, /* Upper Kuskokwim -> Athapaskan */ + {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */ + {"kvb", HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */ + {"kvr", HB_TAG('M','L','Y',' ')}, /* Kerinci -> Malay */ + {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */ + {"kwy", HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ + {"kxc", HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ + {"kxd", HB_TAG('M','L','Y',' ')}, /* Brunei -> Malay */ + {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */ + {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz (Kyrgyz) */ + {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */ + {"la", HB_TAG('L','A','T',' ')}, /* Latin */ + {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */ + {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */ + {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */ + {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */ + {"lbl", HB_TAG('B','I','K',' ')}, /* Libon Bikol -> Bikol */ + {"lce", HB_TAG('M','L','Y',' ')}, /* Loncong -> Malay */ + {"lcf", HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */ + {"ldi", HB_TAG('K','O','N','0')}, /* Laari -> Kongo */ + {"lez", HB_TAG('L','E','Z',' ')}, /* Lezghian -> Lezgi */ + {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */ + {"li", HB_TAG('L','I','M',' ')}, /* Limburgish */ + {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */ + {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */ + {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */ + {"liw", HB_TAG('M','L','Y',' ')}, /* Col -> Malay */ + {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api -> Lampung */ + {"lkb", HB_TAG('L','U','H',' ')}, /* Kabras -> Luyia */ + {"lki", HB_TAG('L','K','I',' ')}, /* Laki */ + {"lko", HB_TAG('L','U','H',' ')}, /* Khayo -> Luyia */ + {"lks", HB_TAG('L','U','H',' ')}, /* Kisa -> Luyia */ + {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */ + {"lmn", HB_TAG('L','A','M',' ')}, /* Lambadi -> Lambani */ + {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */ + {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */ + {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ + {"lom", HB_TAG('L','O','M',' ')}, /* Loma (Liberia) */ + {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri -> Luri */ + {"lri", HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */ + {"lrm", HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */ + {"lsm", HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */ + {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */ + {"ltg", HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */ + {"lto", HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ + {"lts", HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ + {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */ + {"lua", HB_TAG('L','U','A',' ')}, /* Luba-Lulua */ + {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */ + {"lus", HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ + {"luy", HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ + {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ + {"lv", HB_TAG('L','V','I',' ')}, /* Latvian [macrolanguage] */ + {"lvs", HB_TAG('L','V','I',' ')}, /* Standard Latvian -> Latvian */ + {"lwg", HB_TAG('L','U','H',' ')}, /* Wanga -> Luyia */ + {"lzh", HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese Traditional */ + {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */ + {"mad", HB_TAG('M','A','D',' ')}, /* Madurese -> Madura */ + {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */ + {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */ + {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */ + {"mam", HB_TAG('M','A','M',' ')}, /* Mam */ + {"man", HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */ + {"max", HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */ + {"mbo", HB_TAG('M','B','O',' ')}, /* Mbo (Cameroon) */ + {"mct", HB_TAG('B','T','I',' ')}, /* Mengisa -> Beti */ + {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */ + {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */ + {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */ + {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ + {"meo", HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */ + {"mer", HB_TAG('M','E','R',' ')}, /* Meru */ + {"mfa", HB_TAG('M','F','A',' ')}, /* Pattani Malay */ + {"mfb", HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */ + {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */ + {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */ + {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */ + {"mhr", HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */ + {"mhv", HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */ + {"mi", HB_TAG('M','R','I',' ')}, /* Maori */ + {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */ + {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */ + {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka -> Maninka */ + {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */ + {"ml", HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */ + {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */ + {"mlq", HB_TAG('M','L','N',' ')}, /* Western Maninkakan -> Malinke */ + {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan -> Maninka */ + {"mmr", HB_TAG('H','M','N',' ')}, /* Western Xiangxi Miao -> Hmong */ + {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ + {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */ + {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */ + {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */ + {"mnk", HB_TAG('M','N','K',' ')}, /* Mandinka -> Maninka */ + {"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese Simplified */ + {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */ + {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */ + {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ + {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */ + {"mos", HB_TAG('M','O','S',' ')}, /* Mossi */ + {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */ + {"mqg", HB_TAG('M','L','Y',' ')}, /* Kota Bangun Kutai Malay -> Malay */ + {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */ + {"mrh", HB_TAG('Q','I','N',' ')}, /* Mara Chin -> Chin */ + {"mrj", HB_TAG('H','M','A',' ')}, /* Western Mari -> High Mari */ + {"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */ + {"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka -> Maninka */ + {"msh", HB_TAG('M','L','G',' ')}, /* Masikoro Malagasy -> Malagasy */ + {"msi", HB_TAG('M','L','Y',' ')}, /* Sabah Malay -> Malay */ + {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */ + {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari -> Marwari */ + {"mui", HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */ + {"mup", HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */ + {"muq", HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */ + {"mus", HB_TAG('M','U','S',' ')}, /* Creek -> Muscogee */ + {"mvb", HB_TAG('A','T','H',' ')}, /* Mattole -> Athapaskan */ + {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */ + {"mvf", HB_TAG('M','N','G',' ')}, /* Peripheral Mongolian -> Mongolian */ + {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan -> Maninka */ + {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */ + {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */ + {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */ + {"my", HB_TAG('B','R','M',' ')}, /* Burmese */ + {"mym", HB_TAG('M','E','N',' ')}, /* Me’en */ + {"myn", HB_TAG('M','Y','N',' ')}, /* Mayan [family] */ + {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */ + {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */ + {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */ + {"na", HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */ + {"nag", HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */ + {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */ + {"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese Simplified */ + {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */ + {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål -> Norwegian */ + {"nd", HB_TAG('N','D','B',' ')}, /* North Ndebele -> Ndebele */ + {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */ + {"nds", HB_TAG('N','D','S',' ')}, /* Low Saxon */ + {"ne", HB_TAG('N','E','P',' ')}, /* Nepali [macrolanguage] */ + {"new", HB_TAG('N','E','W',' ')}, /* Newari */ + {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */ + {"nga", HB_TAG('N','G','A',' ')}, /* Ngbaka */ + {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ + {"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni -> Sutu */ + {"nhd", HB_TAG('G','U','A',' ')}, /* Chiripá -> Guarani */ + {"niq", HB_TAG('K','A','L',' ')}, /* Nandi -> Kalenjin */ + {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */ + {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */ + {"njz", HB_TAG('N','I','S',' ')}, /* Nyishi -> Nisi */ + {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */ + {"nle", HB_TAG('L','U','H',' ')}, /* East Nyala -> Luyia */ + {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */ + {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */ + {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */ + {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */ + {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */ + {"nov", HB_TAG('N','O','V',' ')}, /* Novial */ + {"npi", HB_TAG('N','E','P',' ')}, /* Nepali */ + {"nqo", HB_TAG('N','K','O',' ')}, /* N’Ko */ + {"nr", HB_TAG('N','D','B',' ')}, /* South Ndebele -> Ndebele */ + {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ + {"nso", HB_TAG('N','S','O',' ')}, /* Pedi -> Sotho, Northern */ + {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */ + {"nv", HB_TAG('A','T','H',' ')}, /* Navajo -> Athapaskan */ + {"ny", HB_TAG('C','H','I',' ')}, /* Chichewa (Chewa, Nyanja) */ + {"nyd", HB_TAG('L','U','H',' ')}, /* Nyore -> Luyia */ + {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */ + {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */ + {"nza", HB_TAG('N','Z','A',' ')}, /* Tigon Mbembe -> Mbembe Tigon */ + {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ + {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */ + {"ojb", HB_TAG('O','J','B',' ')}, /* Northwestern Ojibwa -> Ojibway */ + {"ojc", HB_TAG('O','J','B',' ')}, /* Central Ojibwa -> Ojibway */ + {"ojg", HB_TAG('O','J','B',' ')}, /* Eastern Ojibwa -> Ojibway */ + {"ojs", HB_TAG('O','C','R',' ')}, /* Severn Ojibwa -> Oji-Cree */ + {"ojw", HB_TAG('O','J','B',' ')}, /* Western Ojibwa -> Ojibway */ + {"oki", HB_TAG('K','A','L',' ')}, /* Okiek -> Kalenjin */ + {"okm", HB_TAG('K','O','H',' ')}, /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */ + {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ + {"or", HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) [macrolanguage] */ + {"orc", HB_TAG('O','R','O',' ')}, /* Orma -> Oromo */ + {"orn", HB_TAG('M','L','Y',' ')}, /* Orang Kanaq -> Malay */ + {"ors", HB_TAG('M','L','Y',' ')}, /* Orang Seletar -> Malay */ + {"ory", HB_TAG('O','R','I',' ')}, /* Odia (formerly Oriya) */ + {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */ + {"otw", HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ + {"pa", HB_TAG('P','A','N',' ')}, /* Punjabi */ + {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */ + {"pam", HB_TAG('P','A','M',' ')}, /* Pampanga -> Pampangan */ + {"pap", HB_TAG('P','A','P','0')}, /* Papiamento -> Papiamentu */ + {"pau", HB_TAG('P','A','U',' ')}, /* Palauan */ + {"pbt", HB_TAG('P','A','S',' ')}, /* Southern Pashto -> Pashto */ + {"pbu", HB_TAG('P','A','S',' ')}, /* Northern Pashto -> Pashto */ + {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */ + {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */ + {"pce", HB_TAG('P','L','G',' ')}, /* Ruching Palaung -> Palaung */ + {"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin -> Chin */ + {"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */ + {"pel", HB_TAG('M','L','Y',' ')}, /* Pekal -> Malay */ + {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian -> Persian */ + {"pga", HB_TAG('A','R','A',' ')}, /* Sudanese Creole Arabic -> Arabic */ + {"phk", HB_TAG('P','H','K',' ')}, /* Phake */ + {"pi", HB_TAG('P','A','L',' ')}, /* Pali */ + {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk -> Norfolk */ + {"pko", HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */ + {"pl", HB_TAG('P','L','K',' ')}, /* Polish */ + {"pll", HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */ + {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */ + {"plt", HB_TAG('M','L','G',' ')}, /* Plateau Malagasy -> Malagasy */ + {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */ + {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */ + {"poh", HB_TAG('P','O','H',' ')}, /* Poqomchi' -> Pocomchi */ + {"pon", HB_TAG('P','O','N',' ')}, /* Pohnpeian */ + {"ppa", HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */ + {"pro", HB_TAG('P','R','O',' ')}, /* Old Provençal (to 1500) -> Provençal / Old Provençal */ + {"prs", HB_TAG('D','R','I',' ')}, /* Dari */ + {"ps", HB_TAG('P','A','S',' ')}, /* Pashto [macrolanguage] */ + {"pse", HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */ + {"pst", HB_TAG('P','A','S',' ')}, /* Central Pashto -> Pashto */ + {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */ + {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen -> Western Pwo Karen */ + {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */ + {"qub", HB_TAG('Q','W','H',' ')}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ + {"quc", HB_TAG('Q','U','C',' ')}, /* K’iche’ */ + {"qud", HB_TAG('Q','V','I',' ')}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ + {"quf", HB_TAG('Q','U','Z',' ')}, /* Lambayeque Quechua -> Quechua */ + {"qug", HB_TAG('Q','V','I',' ')}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ + {"quh", HB_TAG('Q','U','H',' ')}, /* South Bolivian Quechua -> Quechua (Bolivia) */ + {"quk", HB_TAG('Q','U','Z',' ')}, /* Chachapoyas Quechua -> Quechua */ + {"qul", HB_TAG('Q','U','Z',' ')}, /* North Bolivian Quechua -> Quechua */ + {"qup", HB_TAG('Q','V','I',' ')}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ + {"qur", HB_TAG('Q','W','H',' ')}, /* Yanahuanca Pasco Quechua -> Quechua (Peru) */ + {"qus", HB_TAG('Q','U','H',' ')}, /* Santiago del Estero Quichua -> Quechua (Bolivia) */ + {"quw", HB_TAG('Q','V','I',' ')}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ + {"qux", HB_TAG('Q','W','H',' ')}, /* Yauyos Quechua -> Quechua (Peru) */ + {"quy", HB_TAG('Q','U','Z',' ')}, /* Ayacucho Quechua -> Quechua */ + {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua -> Quechua */ + {"qva", HB_TAG('Q','W','H',' ')}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ + {"qvc", HB_TAG('Q','U','Z',' ')}, /* Cajamarca Quechua -> Quechua */ + {"qve", HB_TAG('Q','U','Z',' ')}, /* Eastern Apurímac Quechua -> Quechua */ + {"qvh", HB_TAG('Q','W','H',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ + {"qvi", HB_TAG('Q','V','I',' ')}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ + {"qvj", HB_TAG('Q','V','I',' ')}, /* Loja Highland Quichua -> Quechua (Ecuador) */ + {"qvl", HB_TAG('Q','W','H',' ')}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ + {"qvm", HB_TAG('Q','W','H',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ + {"qvn", HB_TAG('Q','W','H',' ')}, /* North Junín Quechua -> Quechua (Peru) */ + {"qvo", HB_TAG('Q','V','I',' ')}, /* Napo Lowland Quechua -> Quechua (Ecuador) */ + {"qvp", HB_TAG('Q','W','H',' ')}, /* Pacaraos Quechua -> Quechua (Peru) */ + {"qvs", HB_TAG('Q','U','Z',' ')}, /* San Martín Quechua -> Quechua */ + {"qvw", HB_TAG('Q','W','H',' ')}, /* Huaylla Wanca Quechua -> Quechua (Peru) */ + {"qvz", HB_TAG('Q','V','I',' ')}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ + {"qwa", HB_TAG('Q','W','H',' ')}, /* Corongo Ancash Quechua -> Quechua (Peru) */ + {"qwc", HB_TAG('Q','U','Z',' ')}, /* Classical Quechua -> Quechua */ + {"qwh", HB_TAG('Q','W','H',' ')}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ + {"qws", HB_TAG('Q','W','H',' ')}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ + {"qxa", HB_TAG('Q','W','H',' ')}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ + {"qxc", HB_TAG('Q','W','H',' ')}, /* Chincha Quechua -> Quechua (Peru) */ + {"qxh", HB_TAG('Q','W','H',' ')}, /* Panao Huánuco Quechua -> Quechua (Peru) */ + {"qxl", HB_TAG('Q','V','I',' ')}, /* Salasaca Highland Quichua -> Quechua (Ecuador) */ + {"qxn", HB_TAG('Q','W','H',' ')}, /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */ + {"qxo", HB_TAG('Q','W','H',' ')}, /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */ + {"qxp", HB_TAG('Q','U','Z',' ')}, /* Puno Quechua -> Quechua */ + {"qxr", HB_TAG('Q','V','I',' ')}, /* Cañar Highland Quichua -> Quechua (Ecuador) */ + {"qxt", HB_TAG('Q','W','H',' ')}, /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */ + {"qxu", HB_TAG('Q','U','Z',' ')}, /* Arequipa-La Unión Quechua -> Quechua */ + {"qxw", HB_TAG('Q','W','H',' ')}, /* Jauja Wanca Quechua -> Quechua (Peru) */ + {"rag", HB_TAG('L','U','H',' ')}, /* Logooli -> Luyia */ + {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */ + {"rar", HB_TAG('R','A','R',' ')}, /* Rarotongan */ + {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung -> Palaung */ + {"rbl", HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */ + {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */ + {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */ + {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */ + {"rit", HB_TAG('R','I','T',' ')}, /* Ritarungo */ + {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */ + {"rkw", HB_TAG('R','K','W',' ')}, /* Arakwal */ + {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */ + {"rmc", HB_TAG('R','O','Y',' ')}, /* Carpathian Romani -> Romany */ + {"rmf", HB_TAG('R','O','Y',' ')}, /* Kalo Finnish Romani -> Romany */ + {"rml", HB_TAG('R','O','Y',' ')}, /* Baltic Romani -> Romany */ + {"rmn", HB_TAG('R','O','Y',' ')}, /* Balkan Romani -> Romany */ + {"rmo", HB_TAG('R','O','Y',' ')}, /* Sinte Romani -> Romany */ + {"rmw", HB_TAG('R','O','Y',' ')}, /* Welsh Romani -> Romany */ + {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ + {"rmz", HB_TAG('A','R','K',' ')}, /* Marma -> Rakhine */ + {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */ + {"rnl", HB_TAG('H','A','L',' ')}, /* Ranglong -> Halam (Falam Chin) */ + {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */ + {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ + {"rtm", HB_TAG('R','T','M',' ')}, /* Rotuman */ + {"ru", HB_TAG('R','U','S',' ')}, /* Russian */ + {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */ + {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian */ + {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ + {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */ + {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */ + {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut -> Sakha */ + {"sam", HB_TAG('P','A','A',' ')}, /* Samaritan Aramaic -> Palestinian Aramaic */ + {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */ + {"sat", HB_TAG('S','A','T',' ')}, /* Santali */ + {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ + {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ + {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */ + {"sco", HB_TAG('S','C','O',' ')}, /* Scots */ + {"scs", HB_TAG('S','C','S',' ')}, /* North Slavey */ + {"scs", HB_TAG('S','L','A',' ')}, /* North Slavey -> Slavey */ + {"scs", HB_TAG('A','T','H',' ')}, /* North Slavey -> Athapaskan */ + {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */ + {"sdc", HB_TAG('S','R','D',' ')}, /* Sassarese Sardinian -> Sardinian */ + {"sdh", HB_TAG('K','U','R',' ')}, /* Southern Kurdish -> Kurdish */ + {"sdn", HB_TAG('S','R','D',' ')}, /* Gallurese Sardinian -> Sardinian */ + {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */ + {"seh", HB_TAG('S','N','A',' ')}, /* Sena */ + {"sek", HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ + {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */ + {"sez", HB_TAG('Q','I','N',' ')}, /* Senthang Chin -> Chin */ + {"sfm", HB_TAG('H','M','N',' ')}, /* Small Flowery Miao -> Hmong */ + {"sg", HB_TAG('S','G','O',' ')}, /* Sango */ + {"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */ + {"sgc", HB_TAG('K','A','L',' ')}, /* Kipsigis -> Kalenjin */ + {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */ + {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */ + {"sgw", HB_TAG('S','G','W',' ')}, /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */ + {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */ + {"shn", HB_TAG('S','H','N',' ')}, /* Shan */ + {"shu", HB_TAG('A','R','A',' ')}, /* Chadian Arabic -> Arabic */ + {"si", HB_TAG('S','N','H',' ')}, /* Sinhala (Sinhalese) */ + {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */ + {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */ + {"sjo", HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ + {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */ + {"skg", HB_TAG('M','L','G',' ')}, /* Sakalava Malagasy -> Malagasy */ + {"skr", HB_TAG('S','R','K',' ')}, /* Saraiki */ + {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */ + {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */ + {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */ + {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */ + {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */ + {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */ + {"sn", HB_TAG('S','N','A','0')}, /* Shona */ + {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */ + {"so", HB_TAG('S','M','L',' ')}, /* Somali */ + {"sop", HB_TAG('S','O','P',' ')}, /* Songe */ + {"spv", HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ + {"spy", HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ + {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */ + {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */ + {"src", HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ + {"sro", HB_TAG('S','R','D',' ')}, /* Campidanese Sardinian -> Sardinian */ + {"srr", HB_TAG('S','R','R',' ')}, /* Serer */ + {"srs", HB_TAG('A','T','H',' ')}, /* Sarsi -> Athapaskan */ + {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */ + {"ssh", HB_TAG('A','R','A',' ')}, /* Shihhi Arabic -> Arabic */ + {"st", HB_TAG('S','O','T',' ')}, /* Southern Sotho -> Sotho, Southern */ + {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch -> Saterland Frisian */ + {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */ + {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */ + {"suk", HB_TAG('S','U','K',' ')}, /* Sukuma */ + {"suq", HB_TAG('S','U','R',' ')}, /* Suri */ + {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */ + {"sva", HB_TAG('S','V','A',' ')}, /* Svan */ + {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */ + {"swb", HB_TAG('C','M','R',' ')}, /* Maore Comorian -> Comorian */ + {"swc", HB_TAG('S','W','K',' ')}, /* Congo Swahili -> Swahili */ + {"swh", HB_TAG('S','W','K',' ')}, /* Swahili */ + {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati -> Marwari */ + {"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */ + {"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac -> Syriac */ + {"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */ + {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */ + {"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */ + {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */ + {"taa", HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */ + {"tab", HB_TAG('T','A','B',' ')}, /* Tabassaran -> Tabasaran */ + {"taq", HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */ + {"tau", HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */ + {"tcb", HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */ + {"tce", HB_TAG('A','T','H',' ')}, /* Southern Tutchone -> Athapaskan */ + {"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin -> Chin */ + {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu -> Tumbuka */ + {"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ + {"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa -> Dehong Dai */ + {"tdx", HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ + {"te", HB_TAG('T','E','L',' ')}, /* Telugu */ + {"tec", HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */ + {"tem", HB_TAG('T','M','N',' ')}, /* Timne -> Temne */ + {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */ + {"tfn", HB_TAG('A','T','H',' ')}, /* Tanaina -> Athapaskan */ + {"tg", HB_TAG('T','A','J',' ')}, /* Tajik -> Tajiki */ + {"tgj", HB_TAG('N','I','S',' ')}, /* Tagin -> Nisi */ + {"tgx", HB_TAG('A','T','H',' ')}, /* Tagish -> Athapaskan */ + {"th", HB_TAG('T','H','A',' ')}, /* Thai */ + {"tht", HB_TAG('A','T','H',' ')}, /* Tahltan -> Athapaskan */ + {"thv", HB_TAG('T','M','H',' ')}, /* Tahaggart Tamahaq -> Tamashek */ + {"thz", HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */ + {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */ + {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ + {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */ + {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ + {"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ + {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ + {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ + {"tmw", HB_TAG('M','L','Y',' ')}, /* Temuan -> Malay */ + {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */ + {"tnf", HB_TAG('D','R','I',' ')}, /* Tangshewi (retired code) -> Dari */ + {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) -> Tongan */ + {"tod", HB_TAG('T','O','D','0')}, /* Toma */ + {"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */ + {"tol", HB_TAG('A','T','H',' ')}, /* Tolowa -> Athapaskan */ + {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */ + {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */ + {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */ + {"tru", HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */ + {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */ + {"tsj", HB_TAG('T','S','J',' ')}, /* Tshangla */ + {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */ + {"ttm", HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */ + {"ttq", HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ + {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka -> Tulu */ + {"tuu", HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ + {"tuy", HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ + {"tvl", HB_TAG('T','V','L',' ')}, /* Tuvalu */ + {"tw", HB_TAG('T','W','I',' ')}, /* Twi */ + {"tw", HB_TAG('A','K','A',' ')}, /* Twi -> Akan */ + {"txc", HB_TAG('A','T','H',' ')}, /* Tsetsaut -> Athapaskan */ + {"txy", HB_TAG('M','L','G',' ')}, /* Tanosy Malagasy -> Malagasy */ + {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */ + {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvinian -> Tuvin */ + {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */ + {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight -> Tamazight */ + {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */ + {"ubl", HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */ + {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */ + {"ug", HB_TAG('U','Y','G',' ')}, /* Uyghur */ + {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */ + {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */ + {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */ + {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */ + {"urk", HB_TAG('M','L','Y',' ')}, /* Urak Lawoi' -> Malay */ + {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */ + {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek -> Uzbek */ + {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek -> Uzbek */ + {"ve", HB_TAG('V','E','N',' ')}, /* Venda */ + {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */ + {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */ + {"vkk", HB_TAG('M','L','Y',' ')}, /* Kaur -> Malay */ + {"vkt", HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */ + {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ + {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */ + {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */ + {"vro", HB_TAG('V','R','O',' ')}, /* Võro */ + {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */ + {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) -> Waray-Waray */ + {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ + {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ + {"wlc", HB_TAG('C','M','R',' ')}, /* Mwali Comorian -> Comorian */ + {"wle", HB_TAG('S','I','G',' ')}, /* Wolane -> Silte Gurage */ + {"wlk", HB_TAG('A','T','H',' ')}, /* Wailaki -> Athapaskan */ + {"wni", HB_TAG('C','M','R',' ')}, /* Ndzwani Comorian -> Comorian */ + {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */ + {"wry", HB_TAG('M','A','W',' ')}, /* Merwari -> Marwari */ + {"wsg", HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */ + {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */ + {"wuu", HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese Simplified */ + {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */ + {"xal", HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */ + {"xan", HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */ + {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */ + {"xjb", HB_TAG('X','J','B',' ')}, /* Minjungbal -> Minjangbal */ + {"xkf", HB_TAG('X','K','F',' ')}, /* Khengkha */ + {"xmm", HB_TAG('M','L','Y',' ')}, /* Manado Malay -> Malay */ + {"xmv", HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */ + {"xmw", HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */ + {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri */ + {"xog", HB_TAG('X','O','G',' ')}, /* Soga */ + {"xpe", HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */ + {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */ + {"xsl", HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */ + {"xsl", HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */ + {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */ + {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */ + {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */ + {"yap", HB_TAG('Y','A','P',' ')}, /* Yapese */ + {"ybd", HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ + {"ydd", HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ + {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ + {"yih", HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ + {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */ + {"yos", HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */ + {"yrk", HB_TAG('T','N','E',' ')}, /* Nenets -> Tundra Nenets */ + {"yrk", HB_TAG('F','N','E',' ')}, /* Nenets -> Forest Nenets */ + {"yue", HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Hong Kong SAR */ + {"za", HB_TAG('Z','H','A',' ')}, /* Zhuang [macrolanguage] */ + {"zch", HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ + {"zdj", HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ + {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws -> Zealandic */ + {"zeh", HB_TAG('Z','H','A',' ')}, /* Eastern Hongshuihe Zhuang -> Zhuang */ + {"zgb", HB_TAG('Z','H','A',' ')}, /* Guibei Zhuang -> Zhuang */ + {"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Moroccan Tamazight */ + {"zgm", HB_TAG('Z','H','A',' ')}, /* Minz Zhuang -> Zhuang */ + {"zgn", HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */ + {"zh", HB_TAG('Z','H','S',' ')}, /* Chinese [macrolanguage] -> Chinese Simplified */ + {"zhd", HB_TAG('Z','H','A',' ')}, /* Dai Zhuang -> Zhuang */ + {"zhn", HB_TAG('Z','H','A',' ')}, /* Nong Zhuang -> Zhuang */ + {"zlj", HB_TAG('Z','H','A',' ')}, /* Liujiang Zhuang -> Zhuang */ + {"zlm", HB_TAG('M','L','Y',' ')}, /* Malay */ + {"zln", HB_TAG('Z','H','A',' ')}, /* Lianshan Zhuang -> Zhuang */ + {"zlq", HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */ + {"zmi", HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */ + {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */ + {"zom", HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */ + {"zqe", HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */ + {"zsm", HB_TAG('M','L','Y',' ')}, /* Standard Malay -> Malay */ + {"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */ + {"zum", HB_TAG('L','R','C',' ')}, /* Kumzari -> Luri */ + {"zyb", HB_TAG('Z','H','A',' ')}, /* Yongbei Zhuang -> Zhuang */ + {"zyg", HB_TAG('Z','H','A',' ')}, /* Yang Zhuang -> Zhuang */ + {"zyj", HB_TAG('Z','H','A',' ')}, /* Youjiang Zhuang -> Zhuang */ + {"zyn", HB_TAG('Z','H','A',' ')}, /* Yongnan Zhuang -> Zhuang */ + {"zza", HB_TAG('Z','Z','A',' ')}, /* Zazaki [macrolanguage] */ + {"zzj", HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */ }; -static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == 3u, ""); - /** * hb_ot_tags_from_complex_language: * @lang_str: a BCP 47 language tag to convert. diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 751ccab0b..c8a57c472 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -198,7 +198,7 @@ lang_matches (const char *lang_str, const char *spec) struct LangTag { char language[4]; - hb_tag_t tags[HB_OT_MAX_TAGS_PER_LANGUAGE]; + hb_tag_t tag; int cmp (const char *a) const { @@ -246,6 +246,7 @@ hb_ot_tags_from_language (const char *lang_str, hb_tag_t *tags) { const char *s; + unsigned int tag_idx; /* Check for matches of multiple subtags. */ if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags)) @@ -254,7 +255,6 @@ hb_ot_tags_from_language (const char *lang_str, /* Find a language matching in the first component. */ s = strchr (lang_str, '-'); { - const LangTag *lang_tag; if (s && limit - lang_str >= 6) { const char *extlang_end = strchr (s + 1, '-'); @@ -263,12 +263,18 @@ hb_ot_tags_from_language (const char *lang_str, ISALPHA (s[1])) lang_str = s + 1; } - lang_tag = hb_sorted_array (ot_languages).bsearch (lang_str); - if (lang_tag) + if (hb_sorted_array (ot_languages).bfind (lang_str, &tag_idx)) { unsigned int i; - for (i = 0; i < *count && lang_tag->tags[i] != HB_TAG_NONE; i++) - tags[i] = lang_tag->tags[i]; + while (tag_idx != 0 && + 0 == strcmp (ot_languages[tag_idx].language, ot_languages[tag_idx - 1].language)) + tag_idx--; + for (i = 0; + i < *count && + tag_idx + i < ARRAY_LENGTH (ot_languages) && + 0 == strcmp (ot_languages[tag_idx + i].language, ot_languages[tag_idx].language); + i++) + tags[i] = ot_languages[tag_idx + i].tag; *count = i; return; } @@ -417,7 +423,7 @@ hb_ot_tag_to_language (hb_tag_t tag) } for (i = 0; i < ARRAY_LENGTH (ot_languages); i++) - if (ot_languages[i].tags[0] == tag) + if (ot_languages[i].tag == tag) return hb_language_from_string (ot_languages[i].language, -1); /* Else return a custom language in the form of "x-hbotABCD" */ @@ -506,7 +512,7 @@ test_langs_sorted () for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++) { int c = ot_languages[i].cmp (&ot_languages[i - 1]); - if (c >= 0) + if (c > 0) { fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n", i, ot_languages[i-1].language, c, ot_languages[i].language); From 54ece299bcb3436763cc4f3b6b0ca11de8133b28 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 16:45:53 -0400 Subject: [PATCH 032/336] Use type aliasing for meta-functions, ie. those returning a type --- src/hb-algs.hh | 3 ++- src/hb-array.hh | 6 +++--- src/hb-atomic.hh | 2 +- src/hb-blob.hh | 2 +- src/hb-common.cc | 2 +- src/hb-ft.cc | 2 +- src/hb-iter.hh | 2 +- src/hb-meta.hh | 12 ++++++------ src/hb-null.hh | 6 +++--- 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 6981d06ae..3d7badb32 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -42,7 +42,8 @@ struct //{ return hb_deref_pointer (v).hash (); } /* Instead, the following ugly soution: */ template + hb_enable_if (!hb_is_integer (hb_remove_const >) && + !hb_is_pointer (T))> uint32_t operator () (T&& v) const { return v.hash (); } template diff --git a/src/hb-array.hh b/src/hb-array.hh index d42e086bd..74b6757b2 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -47,13 +47,13 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> hb_iter_with_fallback_t, Type&> (), arrayZ (o.arrayZ), length (o.length) {} template - hb_array_t (const hb_array_t &o) : arrayZ (o.arrayZ), length (o.length) {} + hb_array_t (const hb_array_t > &o) : arrayZ (o.arrayZ), length (o.length) {} hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} template - hb_array_t& operator = (const hb_array_t &o) + hb_array_t& operator = (const hb_array_t > &o) { arrayZ = o.arrayZ; length = o.length; return *this; } hb_array_t& operator = (const hb_array_t &o) { arrayZ = o.arrayZ; length = o.length; return *this; } @@ -214,7 +214,7 @@ struct hb_sorted_array_t : hb_sorted_array_t () : hb_array_t () {} hb_sorted_array_t (const hb_array_t &o) : hb_array_t (o) {} template - hb_sorted_array_t (const hb_sorted_array_t &o) : hb_array_t (o) {} + hb_sorted_array_t (const hb_sorted_array_t > &o) : hb_array_t (o) {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t (array_, length_) {} template hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index a2ce8f28d..8307a549d 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -283,7 +283,7 @@ struct hb_atomic_int_t template struct hb_atomic_ptr_t { - typedef hb_remove_pointer (P) T; + typedef hb_remove_pointer

T; void init (T* v_ = nullptr) { set_relaxed (v_); } 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 3a30efe55..cff492fa0 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -81,7 +81,7 @@ struct hb_blob_t template struct hb_blob_ptr_t { - typedef hb_remove_pointer (P) T; + typedef hb_remove_pointer

T; hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {} hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; } diff --git a/src/hb-common.cc b/src/hb-common.cc index ab93bf427..356c2bf17 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -783,7 +783,7 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv) static void free_static_C_locale (); #endif -static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t, hb_C_locale_lazy_loader_t> { static HB_LOCALE_T create () diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 48434dc8c..f8dab8bc1 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 (); #endif -static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t, hb_ft_library_lazy_loader_t> { static FT_Library create () diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 7e7673326..38d477027 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -78,7 +78,7 @@ struct hb_iter_t * it will be returning pointer to temporary rvalue. */ template - hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } + hb_remove_reference* operator -> () const { return hb_addressof (**thiz()); } item_t operator * () const { return thiz()->__item__ (); } item_t operator * () { return thiz()->__item__ (); } item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 83b0ad6b3..a5edd0372 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -56,15 +56,15 @@ template static inline T hb_declval (); template struct hb_match_const { typedef T type; enum { value = false }; }; template struct hb_match_const { typedef T type; enum { value = true }; }; -#define hb_remove_const(T) typename hb_match_const::type +template using hb_remove_const = typename hb_match_const::type; #define hb_is_const(T) hb_match_const::value template struct hb_match_reference { typedef T type; enum { value = false }; }; template struct hb_match_reference { typedef T type; enum { value = true }; }; -#define hb_remove_reference(T) typename hb_match_reference::type +template using hb_remove_reference = typename hb_match_reference::type; #define hb_is_reference(T) hb_match_reference::value template struct hb_match_pointer { typedef T type; enum { value = false }; }; template struct hb_match_pointer { typedef T type; enum { value = true }; }; -#define hb_remove_pointer(T) typename hb_match_pointer::type +template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value struct @@ -79,12 +79,12 @@ struct /* std::move and std::forward */ template -static hb_remove_reference (T)&& hb_move (T&& t) { return (hb_remove_reference (T)&&) (t); } +static hb_remove_reference&& hb_move (T&& t) { return (hb_remove_reference&&) (t); } template -static T&& hb_forward (hb_remove_reference (T)& t) { return (T&&) t; } +static T&& hb_forward (hb_remove_reference& t) { return (T&&) t; } template -static T&& hb_forward (hb_remove_reference (T)&& t) { return (T&&) t; } +static T&& hb_forward (hb_remove_reference&& t) { return (T&&) t; } /* Void! For when we need a expression-type of void. */ diff --git a/src/hb-null.hh b/src/hb-null.hh index 6d4a68360..1e20a47e9 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -95,7 +95,7 @@ struct Null { template struct NullHelper { - typedef hb_remove_const (hb_remove_reference (QType)) Type; + typedef hb_remove_const > Type; static const Type & get_null () { return Null::get_null (); } }; #define Null(Type) NullHelper::get_null () @@ -148,7 +148,7 @@ static inline Type& Crap () { template struct CrapHelper { - typedef hb_remove_const (hb_remove_reference (QType)) Type; + typedef hb_remove_const > Type; static Type & get_crap () { return Crap (); } }; #define Crap(Type) CrapHelper::get_crap () @@ -171,7 +171,7 @@ struct CrapOrNullHelper { template struct hb_nonnull_ptr_t { - typedef hb_remove_pointer (P) T; + typedef hb_remove_pointer

T; hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {} T * operator = (T *v_) { return v = v_; } From 973717175d46d62471772318bb0b607070c53ec7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 16:50:07 -0400 Subject: [PATCH 033/336] Fix priorities --- src/hb-algs.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 3d7badb32..ab1caa031 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -78,15 +78,15 @@ struct /* Pointer-to-member-function. */ template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a ()) + impl (Appl&& a, Val &&v, hb_priority<5>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a ()) template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a ()) + impl (Appl&& a, Val &&v, hb_priority<4>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a ()) /* Pointer-to-member. */ template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a) + impl (Appl&& a, Val &&v, hb_priority<3>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a) template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a) + impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a) /* Operator(). */ template auto @@ -141,7 +141,7 @@ struct impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward (v))) template auto - impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR ( + impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ( hb_invoke (hb_forward (f), hb_forward (v)) ) From 75fd845a4abccc2596f0e1fe2294f936199e61f3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 17:22:29 -0400 Subject: [PATCH 034/336] Move around --- src/hb-algs.hh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index ab1caa031..485c139b9 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -34,6 +34,18 @@ #include "hb-null.hh" +struct +{ + template T + operator () (const T& v) const { return v; } +} HB_FUNCOBJ (hb_identity); + +struct +{ + template bool + operator () (const T& v) const { return bool (v); } +} HB_FUNCOBJ (hb_bool); + struct { /* Don't know how to set priority of following. Doesn't work right now. */ @@ -59,19 +71,6 @@ struct } } HB_FUNCOBJ (hb_hash); -struct -{ - template T - operator () (const T& v) const { return v; } -} HB_FUNCOBJ (hb_identity); - -struct -{ - template bool - operator () (const T& v) const { return bool (v); } -} HB_FUNCOBJ (hb_bool); - - struct { private: From c918a6706fa759696569ad6dcaae03fed76306bc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 17:28:18 -0400 Subject: [PATCH 035/336] Properly prioritize hb_hash() --- src/hb-algs.hh | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 485c139b9..c21d8634e 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -48,27 +48,22 @@ struct struct { - /* Don't know how to set priority of following. Doesn't work right now. */ - //template - //uint32_t operator () (const T& v) const - //{ return hb_deref_pointer (v).hash (); } - /* Instead, the following ugly soution: */ - template >) && - !hb_is_pointer (T))> - uint32_t operator () (T&& v) const { return v.hash (); } - - template - uint32_t operator () (const T *v) const - { return operator() (*v); } + private: + template auto + impl (const T& v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_deref_pointer (v).hash ()) template - uint32_t operator () (T v) const - { + hb_enable_if (hb_is_integer (T))> auto + impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + ( /* Knuth's multiplicative method: */ - return (uint32_t) v * 2654435761u; - } + (uint32_t) v * 2654435761u + ) + + public: + + template auto + operator () (const T& v) const HB_AUTO_RETURN_EXPR ((uint32_t) impl (v, hb_prioritize)) } HB_FUNCOBJ (hb_hash); struct @@ -96,7 +91,8 @@ struct public: template auto - operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR ( + operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR + ( impl (hb_forward (a), hb_forward (v), hb_prioritize) @@ -114,7 +110,8 @@ struct impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v)) template auto - impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ( + impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + ( hb_invoke (hb_forward (p), hb_forward (v)) ) @@ -122,7 +119,8 @@ struct public: template auto - operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR ( + operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR + ( (bool) impl (hb_forward (p), hb_forward (v), hb_prioritize) @@ -140,7 +138,8 @@ struct impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward (v))) template auto - impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ( + impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + ( hb_invoke (hb_forward (f), hb_forward (v)) ) @@ -148,7 +147,8 @@ struct public: template auto - operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR ( + operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR + ( impl (hb_forward (f), hb_forward (v), hb_prioritize) From fe30fcd228ff95be1f169f580b30184c8511d1c3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 17:34:06 -0400 Subject: [PATCH 036/336] Use hb_deref_pointer() to reduce number of overloads --- src/hb-algs.hh | 27 ++++++++++----------------- src/hb-meta.hh | 36 +++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index c21d8634e..6b80a61f9 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -72,21 +72,18 @@ struct /* Pointer-to-member-function. */ template auto - impl (Appl&& a, Val &&v, hb_priority<5>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a ()) - template auto - impl (Appl&& a, Val &&v, hb_priority<4>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a ()) + impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR + (hb_forward (hb_deref_pointer (v)).*a ()) /* Pointer-to-member. */ template auto - impl (Appl&& a, Val &&v, hb_priority<3>) const HB_AUTO_RETURN_EXPR (hb_forward (v).*a) - template auto - impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (hb_forward (v)->*a) + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR + (hb_forward (hb_deref_pointer (v)).*a) /* Operator(). */ template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward (v))) - template auto - impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ((*a) (hb_forward (v))) + impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + (hb_deref_pointer (a) (hb_forward (v))) public: @@ -104,10 +101,8 @@ struct private: template auto - impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v)) - - template auto - impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v)) + impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR + (hb_deref_pointer (p).has (v)) template auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR @@ -132,10 +127,8 @@ struct private: template auto - impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f->get (hb_forward (v))) - - template auto - impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward (v))) + impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR + (hb_deref_pointer (f).get (hb_forward (v))) template auto impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR diff --git a/src/hb-meta.hh b/src/hb-meta.hh index a5edd0372..5698250fc 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -34,6 +34,15 @@ * C++ template meta-programming & fundamentals used with them. */ +/* Function overloading SFINAE and priority. */ + +#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); } +#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt { (E); } + +template struct hb_priority : hb_priority {}; +template <> struct hb_priority<0> {}; +#define hb_prioritize hb_priority<16> () + #define HB_FUNCOBJ(x) static_const x HB_UNUSED struct @@ -67,14 +76,6 @@ template struct hb_match_pointer { typedef T type; enum { valu template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value -struct -{ - template - T operator () (T v) const { return v; } - template - T& operator () (T *v) const { return *v; } -} HB_FUNCOBJ (hb_deref_pointer); - /* std::move and std::forward */ @@ -86,6 +87,16 @@ static T&& hb_forward (hb_remove_reference& t) { return (T&&) t; } template static T&& hb_forward (hb_remove_reference&& t) { return (T&&) t; } +struct +{ + template auto + operator () (T&& v) const HB_AUTO_RETURN_EXPR (hb_forward (v)) + + template auto + operator () (T *v) const HB_AUTO_RETURN_EXPR (*v) + +} HB_FUNCOBJ (hb_deref_pointer); + /* Void! For when we need a expression-type of void. */ struct hb_void_t { typedef void value; }; @@ -140,14 +151,5 @@ template <> struct hb_is_integer { enum { value = true }; }; template <> struct hb_is_integer { enum { value = true }; }; #define hb_is_integer(T) hb_is_integer::value -/* Function overloading SFINAE and priority. */ - -#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); } -#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt { (E); } - -template struct hb_priority : hb_priority {}; -template <> struct hb_priority<0> {}; -#define hb_prioritize hb_priority<16> () - #endif /* HB_META_HH */ From 0241a40f2aff43aba045fb7de4a2c3e5f1e9626a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 18:26:30 -0400 Subject: [PATCH 037/336] Use auto return type for hb_first/hb_second --- src/hb-algs.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 6b80a61f9..a7e3aaa37 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -169,14 +169,14 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t (a, b); } struct { - template decltype (hb_declval (Pair).first) - operator () (const Pair& pair) const { return pair.first; } + template auto + operator () (const Pair& pair) const HB_AUTO_RETURN_EXPR (pair.first) } HB_FUNCOBJ (hb_first); struct { - template decltype (hb_declval (Pair).second) - operator () (const Pair& pair) const { return pair.second; } + template auto + operator () (const Pair& pair) const HB_AUTO_RETURN_EXPR (pair.second) } HB_FUNCOBJ (hb_second); struct From da293b0e59a0d6c47e9b3a7807115a168a0a5c94 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 18:27:25 -0400 Subject: [PATCH 038/336] Use HB_AUTO_RETURN_EXPR in hb_min/max --- src/hb-algs.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index a7e3aaa37..b1c928246 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -181,13 +181,13 @@ struct struct { - template T - operator () (const T& a, const T2& b) const { return a <= b ? a : b; } + template auto + operator () (const T& a, const T2& b) const HB_AUTO_RETURN_EXPR (a <= b ? a : b) } HB_FUNCOBJ (hb_min); struct { - template T - operator () (const T& a, const T2& b) const { return a >= b ? a : b; } + template auto + operator () (const T& a, const T2& b) const HB_AUTO_RETURN_EXPR (a >= b ? a : b) } HB_FUNCOBJ (hb_max); From 5b33427f2c4d596a12f05ffebebfd68655fd63eb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 18:28:17 -0400 Subject: [PATCH 039/336] Rename HB_AUTO_RETURN_EXPR to HB_AUTO_RETURN --- src/hb-algs.hh | 34 +++++++++++++++++----------------- src/hb-meta.hh | 8 ++++---- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index b1c928246..232467e49 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -50,11 +50,11 @@ struct { private: template auto - impl (const T& v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (hb_deref_pointer (v).hash ()) + impl (const T& v, hb_priority<1>) const HB_AUTO_RETURN (hb_deref_pointer (v).hash ()) template auto - impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN ( /* Knuth's multiplicative method: */ (uint32_t) v * 2654435761u @@ -63,7 +63,7 @@ struct public: template auto - operator () (const T& v) const HB_AUTO_RETURN_EXPR ((uint32_t) impl (v, hb_prioritize)) + operator () (const T& v) const HB_AUTO_RETURN ((uint32_t) impl (v, hb_prioritize)) } HB_FUNCOBJ (hb_hash); struct @@ -72,23 +72,23 @@ struct /* Pointer-to-member-function. */ template auto - impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR + impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN (hb_forward (hb_deref_pointer (v)).*a ()) /* Pointer-to-member. */ template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR + impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN (hb_forward (hb_deref_pointer (v)).*a) /* Operator(). */ template auto - impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN (hb_deref_pointer (a) (hb_forward (v))) public: template auto - operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN_EXPR + operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN ( impl (hb_forward (a), hb_forward (v), @@ -101,11 +101,11 @@ struct private: template auto - impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR + impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN (hb_deref_pointer (p).has (v)) template auto - impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN ( hb_invoke (hb_forward (p), hb_forward (v)) @@ -114,7 +114,7 @@ struct public: template auto - operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR + operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN ( (bool) impl (hb_forward (p), hb_forward (v), @@ -127,11 +127,11 @@ struct private: template auto - impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR + impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN (hb_deref_pointer (f).get (hb_forward (v))) template auto - impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR + impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN ( hb_invoke (hb_forward (f), hb_forward (v)) @@ -140,7 +140,7 @@ struct public: template auto - operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR + operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN ( impl (hb_forward (f), hb_forward (v), @@ -170,24 +170,24 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t (a, b); } struct { template auto - operator () (const Pair& pair) const HB_AUTO_RETURN_EXPR (pair.first) + operator () (const Pair& pair) const HB_AUTO_RETURN (pair.first) } HB_FUNCOBJ (hb_first); struct { template auto - operator () (const Pair& pair) const HB_AUTO_RETURN_EXPR (pair.second) + operator () (const Pair& pair) const HB_AUTO_RETURN (pair.second) } HB_FUNCOBJ (hb_second); struct { template auto - operator () (const T& a, const T2& b) const HB_AUTO_RETURN_EXPR (a <= b ? a : b) + operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a <= b ? a : b) } HB_FUNCOBJ (hb_min); struct { template auto - operator () (const T& a, const T2& b) const HB_AUTO_RETURN_EXPR (a >= b ? a : b) + operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a >= b ? a : b) } HB_FUNCOBJ (hb_max); diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 5698250fc..4a141ce92 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -36,8 +36,8 @@ /* Function overloading SFINAE and priority. */ -#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); } -#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt { (E); } +#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); } +#define HB_VOID_RETURN(E) -> hb_void_tt { (E); } template struct hb_priority : hb_priority {}; template <> struct hb_priority<0> {}; @@ -90,10 +90,10 @@ static T&& hb_forward (hb_remove_reference&& t) { return (T&&) t; } struct { template auto - operator () (T&& v) const HB_AUTO_RETURN_EXPR (hb_forward (v)) + operator () (T&& v) const HB_AUTO_RETURN (hb_forward (v)) template auto - operator () (T *v) const HB_AUTO_RETURN_EXPR (*v) + operator () (T *v) const HB_AUTO_RETURN (*v) } HB_FUNCOBJ (hb_deref_pointer); From 6916b77863cd5ce492a274eb85f196f2152fbb96 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 18:33:51 -0400 Subject: [PATCH 040/336] One more auto return type --- src/hb-iter.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 38d477027..a4ffbd6f0 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -258,8 +258,8 @@ struct hb_is_iterator_of { enum { template -static inline decltype (hb_declval (Rhs) (hb_declval (Lhs))) -operator | (Lhs lhs, const Rhs &rhs) { return rhs (lhs); } +static inline auto +operator | (Lhs lhs, const Rhs &rhs) HB_AUTO_RETURN (rhs (lhs)) /* hb_map(), hb_filter(), hb_reduce() */ From 5daeff3e68e4e202effb152f52702a044c09f386 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Wed, 17 Apr 2019 09:11:44 -0400 Subject: [PATCH 041/336] Fix "hb_script_" doc typo --- src/hb-common.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index 356c2bf17..60d16c8a4 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -488,7 +488,7 @@ hb_script_from_string (const char *str, int len) /** * hb_script_to_iso15924_tag: - * @script: an #hb_script_ to convert. + * @script: an #hb_script_t to convert. * * See hb_script_from_iso15924_tag(). * From 6745a600bfec13b3f5468b3d31bab7d82b1e61ce Mon Sep 17 00:00:00 2001 From: David Corbett Date: Tue, 16 Apr 2019 17:29:34 -0400 Subject: [PATCH 042/336] Comment out ot_languages where fallback suffices --- src/gen-tag-table.py | 15 +- src/hb-ot-tag-table.hh | 443 +++++++++++++++++++++-------------------- src/hb-ot-tag.cc | 19 +- test/api/test-ot-tag.c | 5 +- 4 files changed, 255 insertions(+), 227 deletions(-) diff --git a/src/gen-tag-table.py b/src/gen-tag-table.py index 1e225c4bd..49f5b30bb 100755 --- a/src/gen-tag-table.py +++ b/src/gen-tag-table.py @@ -895,11 +895,18 @@ def language_name_intersection (a, b): def get_matching_language_name (intersection, candidates): return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c)))) +def same_tag (bcp_47_tag, ot_tags): + return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower () + for language, tags in sorted (ot.from_bcp_47.items ()): if language == '' or '-' in language: continue + commented_out = same_tag (language, tags) for i, tag in enumerate (tags, start=1): - print (' {\"%s\",\t%s},\t/* ' % (language, hb_tag (tag)), end='') + print ('%s{\"%s\",\t%s},' % ('/*' if commented_out else ' ', language, hb_tag (tag)), end='') + if commented_out: + print ('*/', end='') + print ('\t/* ', end='') bcp_47_name = bcp_47.names.get (language, '') bcp_47_name_candidates = bcp_47_name.split ('\n') intersection = language_name_intersection (bcp_47_name, ot.names[tag]) @@ -1040,7 +1047,8 @@ print (' * @tag: A language tag.') print (' *') print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to') print (' * many language tags) and the best tag is not the alphabetically first, or if') -print (' * the best tag consists of multiple subtags.') +print (' * the best tag consists of multiple subtags, or if the best tag does not appear') +print (' * in #ot_languages.') print (' *') print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,') print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.') @@ -1091,7 +1099,8 @@ def verify_disambiguation_dict (): '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag)) elif ot_tag not in disambiguation: disambiguation[ot_tag] = macrolanguages[0] - if disambiguation[ot_tag] == sorted (primary_tags)[0] and '-' not in disambiguation[ot_tag]: + different_primary_tags = sorted (t for t in primary_tags if not same_tag (t, ot.from_bcp_47.get (t))) + if different_primary_tags and disambiguation[ot_tag] == different_primary_tags[0] and '-' not in disambiguation[ot_tag]: del disambiguation[ot_tag] for ot_tag in disambiguation.keys (): expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag) diff --git a/src/hb-ot-tag-table.hh b/src/hb-ot-tag-table.hh index c7717a347..d8fcd2fdb 100644 --- a/src/hb-ot-tag-table.hh +++ b/src/hb-ot-tag-table.hh @@ -23,17 +23,17 @@ static const LangTag ot_languages[] = { {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */ {"abv", HB_TAG('A','R','A',' ')}, /* Baharna Arabic -> Arabic */ {"acf", HB_TAG('F','A','N',' ')}, /* Saint Lucian Creole French -> French Antillean */ - {"ach", HB_TAG('A','C','H',' ')}, /* Acoli -> Acholi */ +/*{"ach", HB_TAG('A','C','H',' ')},*/ /* Acoli -> Acholi */ {"acm", HB_TAG('A','R','A',' ')}, /* Mesopotamian Arabic -> Arabic */ {"acq", HB_TAG('A','R','A',' ')}, /* Ta'izzi-Adeni Arabic -> Arabic */ - {"acr", HB_TAG('A','C','R',' ')}, /* Achi */ +/*{"acr", HB_TAG('A','C','R',' ')},*/ /* Achi */ {"acw", HB_TAG('A','R','A',' ')}, /* Hijazi Arabic -> Arabic */ {"acx", HB_TAG('A','R','A',' ')}, /* Omani Arabic -> Arabic */ {"acy", HB_TAG('A','R','A',' ')}, /* Cypriot Arabic -> Arabic */ {"ada", HB_TAG('D','N','G',' ')}, /* Adangme -> Dangme */ {"adf", HB_TAG('A','R','A',' ')}, /* Dhofari Arabic -> Arabic */ {"adp", HB_TAG('D','Z','N',' ')}, /* Adap (retired code) -> Dzongkha */ - {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */ +/*{"ady", HB_TAG('A','D','Y',' ')},*/ /* Adyghe */ {"aeb", HB_TAG('A','R','A',' ')}, /* Tunisian Arabic -> Arabic */ {"aec", HB_TAG('A','R','A',' ')}, /* Saidi Arabic -> Arabic */ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */ @@ -42,19 +42,19 @@ static const LangTag ot_languages[] = { {"aht", HB_TAG('A','T','H',' ')}, /* Ahtena -> Athapaskan */ {"aii", HB_TAG('S','W','A',' ')}, /* Assyrian Neo-Aramaic -> Swadaya Aramaic */ {"aii", HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */ - {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */ +/*{"aio", HB_TAG('A','I','O',' ')},*/ /* Aiton */ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */ {"ajp", HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */ {"ak", HB_TAG('A','K','A',' ')}, /* Akan [macrolanguage] */ {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] -> Twi */ {"aln", HB_TAG('S','Q','I',' ')}, /* Gheg Albanian -> Albanian */ {"als", HB_TAG('S','Q','I',' ')}, /* Tosk Albanian -> Albanian */ - {"alt", HB_TAG('A','L','T',' ')}, /* Southern Altai -> Altai */ +/*{"alt", HB_TAG('A','L','T',' ')},*/ /* Southern Altai -> Altai */ {"am", HB_TAG('A','M','H',' ')}, /* Amharic */ {"amf", HB_TAG('H','B','N',' ')}, /* Hamer-Banna -> Hammer-Banna */ {"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic -> Syriac */ {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */ - {"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) -> Anglo-Saxon */ +/*{"ang", HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */ {"apc", HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */ {"apd", HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */ {"apj", HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */ @@ -70,14 +70,14 @@ static const LangTag ot_languages[] = { {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic -> Moroccan */ {"arz", HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */ {"as", HB_TAG('A','S','M',' ')}, /* Assamese */ - {"ast", HB_TAG('A','S','T',' ')}, /* Asturian */ - {"ath", HB_TAG('A','T','H',' ')}, /* Athapascan [family] -> Athapaskan */ +/*{"ast", HB_TAG('A','S','T',' ')},*/ /* Asturian */ +/*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [family] -> Athapaskan */ {"atj", HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */ {"atv", HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */ {"auz", HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ {"av", HB_TAG('A','V','R',' ')}, /* Avaric -> Avar */ {"avl", HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ - {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */ +/*{"awa", HB_TAG('A','W','A',' ')},*/ /* Awadhi */ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ {"ayc", HB_TAG('A','Y','M',' ')}, /* Southern Aymara -> Aymara */ {"ayh", HB_TAG('A','R','A',' ')}, /* Hadrami Arabic -> Arabic */ @@ -86,70 +86,70 @@ static const LangTag ot_languages[] = { {"ayp", HB_TAG('A','R','A',' ')}, /* North Mesopotamian Arabic -> Arabic */ {"ayr", HB_TAG('A','Y','M',' ')}, /* Central Aymara -> Aymara */ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */ - {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani -> Torki */ +/*{"azb", HB_TAG('A','Z','B',' ')},*/ /* South Azerbaijani -> Torki */ {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani -> Azerbaijani */ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */ {"bad", HB_TAG('B','A','D','0')}, /* Banda [family] */ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */ - {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */ - {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */ - {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */ +/*{"ban", HB_TAG('B','A','N',' ')},*/ /* Balinese */ +/*{"bar", HB_TAG('B','A','R',' ')},*/ /* Bavarian */ +/*{"bbc", HB_TAG('B','B','C',' ')},*/ /* Batak Toba */ {"bbz", HB_TAG('A','R','A',' ')}, /* Babalia Creole Arabic -> Arabic */ {"bcc", HB_TAG('B','L','I',' ')}, /* Southern Balochi -> Baluchi */ {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé -> Baulé */ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol -> Bikol */ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ {"bcr", HB_TAG('A','T','H',' ')}, /* Babine -> Athapaskan */ - {"bdy", HB_TAG('B','D','Y',' ')}, /* Bandjalang */ +/*{"bdy", HB_TAG('B','D','Y',' ')},*/ /* Bandjalang */ {"be", HB_TAG('B','E','L',' ')}, /* Belarusian -> Belarussian */ {"bea", HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */ {"beb", HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */ - {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ +/*{"bem", HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */ {"ber", HB_TAG('B','B','R',' ')}, /* Berber [family] */ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ {"bfu", HB_TAG('L','A','H',' ')}, /* Gahri -> Lahuli */ {"bfy", HB_TAG('B','A','G',' ')}, /* Bagheli -> Baghelkhandi */ {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */ - {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */ +/*{"bgc", HB_TAG('B','G','C',' ')},*/ /* Haryanvi */ {"bgn", HB_TAG('B','L','I',' ')}, /* Western Balochi -> Baluchi */ {"bgp", HB_TAG('B','L','I',' ')}, /* Eastern Balochi -> Baluchi */ - {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */ +/*{"bgq", HB_TAG('B','G','Q',' ')},*/ /* Bagri */ {"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin -> Chin */ {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */ - {"bhi", HB_TAG('B','H','I',' ')}, /* Bhilali -> Bhili */ +/*{"bhi", HB_TAG('B','H','I',' ')},*/ /* Bhilali -> Bhili */ {"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) -> Bikol */ - {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */ +/*{"bho", HB_TAG('B','H','O',' ')},*/ /* Bhojpuri */ {"bhr", HB_TAG('M','L','G',' ')}, /* Bara Malagasy -> Malagasy */ {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */ - {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */ +/*{"bik", HB_TAG('B','I','K',' ')},*/ /* Bikol [macrolanguage] */ {"bin", HB_TAG('E','D','O',' ')}, /* Edo */ - {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */ +/*{"bjj", HB_TAG('B','J','J',' ')},*/ /* Kanauji */ {"bjn", HB_TAG('M','L','Y',' ')}, /* Banjar -> Malay */ {"bjq", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */ {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja -> Balante */ {"bla", HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */ - {"blk", HB_TAG('B','L','K',' ')}, /* Pa’o Karen */ +/*{"blk", HB_TAG('B','L','K',' ')},*/ /* Pa’o Karen */ {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol -> Bikol */ {"bm", HB_TAG('B','M','B',' ')}, /* Bambara (Bamanankan) */ {"bmm", HB_TAG('M','L','G',' ')}, /* Northern Betsimisaraka Malagasy -> Malagasy */ {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */ {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */ - {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya -> Bishnupriya Manipuri */ +/*{"bpy", HB_TAG('B','P','Y',' ')},*/ /* Bishnupriya -> Bishnupriya Manipuri */ {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari -> Luri */ {"br", HB_TAG('B','R','E',' ')}, /* Breton */ {"bra", HB_TAG('B','R','I',' ')}, /* Braj -> Braj Bhasha */ - {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */ - {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */ +/*{"brh", HB_TAG('B','R','H',' ')},*/ /* Brahui */ +/*{"brx", HB_TAG('B','R','X',' ')},*/ /* Bodo (India) */ {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */ - {"bsk", HB_TAG('B','S','K',' ')}, /* Burushaski */ +/*{"bsk", HB_TAG('B','S','K',' ')},*/ /* Burushaski */ {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) (retired code) */ {"btj", HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */ {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */ - {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */ - {"bug", HB_TAG('B','U','G',' ')}, /* Buginese -> Bugis */ +/*{"bts", HB_TAG('B','T','S',' ')},*/ /* Batak Simalungun */ +/*{"bug", HB_TAG('B','U','G',' ')},*/ /* Buginese -> Bugis */ {"bum", HB_TAG('B','T','I',' ')}, /* Bulu (Cameroon) -> Beti */ {"bve", HB_TAG('M','L','Y',' ')}, /* Berau Malay -> Malay */ {"bvu", HB_TAG('M','L','Y',' ')}, /* Bukit Malay -> Malay */ @@ -157,35 +157,35 @@ static const LangTag ot_languages[] = { {"bxp", HB_TAG('B','T','I',' ')}, /* Bebil -> Beti */ {"bxr", HB_TAG('R','B','U',' ')}, /* Russia Buriat -> Russian Buriat */ {"byn", HB_TAG('B','I','L',' ')}, /* Bilin -> Bilen */ - {"byv", HB_TAG('B','Y','V',' ')}, /* Medumba */ +/*{"byv", HB_TAG('B','Y','V',' ')},*/ /* Medumba */ {"bzc", HB_TAG('M','L','G',' ')}, /* Southern Betsimisaraka Malagasy -> Malagasy */ {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */ {"caf", HB_TAG('C','R','R',' ')}, /* Southern Carrier -> Carrier */ {"caf", HB_TAG('A','T','H',' ')}, /* Southern Carrier -> Athapaskan */ - {"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */ - {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano -> Zamboanga Chavacano */ +/*{"cak", HB_TAG('C','A','K',' ')},*/ /* Kaqchikel */ +/*{"cbk", HB_TAG('C','B','K',' ')},*/ /* Chavacano -> Zamboanga Chavacano */ {"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin -> Chin */ {"cco", HB_TAG('C','C','H','N')}, /* Comaltepec Chinantec -> Chinantec */ {"ccq", HB_TAG('A','R','K',' ')}, /* Chaungtha (retired code) -> Rakhine */ {"cdo", HB_TAG('Z','H','S',' ')}, /* Min Dong Chinese -> Chinese Simplified */ {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */ - {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */ +/*{"ceb", HB_TAG('C','E','B',' ')},*/ /* Cebuano */ {"cfm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) */ - {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */ +/*{"cgg", HB_TAG('C','G','G',' ')},*/ /* Chiga */ {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */ {"chj", HB_TAG('C','C','H','N')}, /* Ojitlán Chinantec -> Chinantec */ {"chk", HB_TAG('C','H','K','0')}, /* Chuukese */ - {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */ +/*{"cho", HB_TAG('C','H','O',' ')},*/ /* Choctaw */ {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */ {"chp", HB_TAG('S','A','Y',' ')}, /* Chipewyan -> Sayisi */ {"chp", HB_TAG('A','T','H',' ')}, /* Chipewyan -> Athapaskan */ {"chq", HB_TAG('C','C','H','N')}, /* Quiotepec Chinantec -> Chinantec */ - {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */ - {"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */ +/*{"chr", HB_TAG('C','H','R',' ')},*/ /* Cherokee */ +/*{"chy", HB_TAG('C','H','Y',' ')},*/ /* Cheyenne */ {"chz", HB_TAG('C','C','H','N')}, /* Ozumacín Chinantec -> Chinantec */ {"ciw", HB_TAG('O','J','B',' ')}, /* Chippewa -> Ojibway */ - {"cja", HB_TAG('C','J','A',' ')}, /* Western Cham */ - {"cjm", HB_TAG('C','J','M',' ')}, /* Eastern Cham */ +/*{"cja", HB_TAG('C','J','A',' ')},*/ /* Western Cham */ +/*{"cjm", HB_TAG('C','J','M',' ')},*/ /* Eastern Cham */ {"cjy", HB_TAG('Z','H','S',' ')}, /* Jinyu Chinese -> Chinese Simplified */ {"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin (retired code) -> Chin */ {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish -> Kurdish */ @@ -203,12 +203,12 @@ static const LangTag ot_languages[] = { {"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin -> Chin */ {"co", HB_TAG('C','O','S',' ')}, /* Corsican */ {"coa", HB_TAG('M','L','Y',' ')}, /* Cocos Islands Malay -> Malay */ - {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */ +/*{"cop", HB_TAG('C','O','P',' ')},*/ /* Coptic */ {"coq", HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */ {"cpa", HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */ {"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [family] -> Creoles */ {"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [family] -> Creoles */ - {"cpp", HB_TAG('C','P','P',' ')}, /* Portuguese-based creoles and pidgins [family] -> Creoles */ +/*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [family] -> Creoles */ {"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese Simplified */ {"cqd", HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */ {"cqu", HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */ @@ -225,7 +225,7 @@ static const LangTag ot_languages[] = { {"crx", HB_TAG('A','T','H',' ')}, /* Carrier -> Athapaskan */ {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */ {"csa", HB_TAG('C','C','H','N')}, /* Chiltepec Chinantec -> Chinantec */ - {"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */ +/*{"csb", HB_TAG('C','S','B',' ')},*/ /* Kashubian */ {"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin -> Chin */ {"cso", HB_TAG('C','C','H','N')}, /* Sochiapam Chinantec -> Chinantec */ {"csw", HB_TAG('N','C','R',' ')}, /* Swampy Cree -> N-Cree */ @@ -234,12 +234,12 @@ static const LangTag ot_languages[] = { {"ctc", HB_TAG('A','T','H',' ')}, /* Chetco -> Athapaskan */ {"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin -> Chin */ {"cte", HB_TAG('C','C','H','N')}, /* Tepinapa Chinantec -> Chinantec */ - {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */ +/*{"ctg", HB_TAG('C','T','G',' ')},*/ /* Chittagonian */ {"ctl", HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavonic */ {"cuc", HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */ - {"cuk", HB_TAG('C','U','K',' ')}, /* San Blas Kuna */ +/*{"cuk", HB_TAG('C','U','K',' ')},*/ /* San Blas Kuna */ {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */ {"cvn", HB_TAG('C','C','H','N')}, /* Valle Nacional Chinantec -> Chinantec */ {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */ @@ -251,32 +251,32 @@ static const LangTag ot_languages[] = { {"da", HB_TAG('D','A','N',' ')}, /* Danish */ {"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */ {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */ - {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */ - {"dax", HB_TAG('D','A','X',' ')}, /* Dayi */ +/*{"dar", HB_TAG('D','A','R',' ')},*/ /* Dargwa */ +/*{"dax", HB_TAG('D','A','X',' ')},*/ /* Dayi */ {"de", HB_TAG('D','E','U',' ')}, /* German */ {"den", HB_TAG('S','L','A',' ')}, /* Slave (Athapascan) [macrolanguage] -> Slavey */ {"den", HB_TAG('A','T','H',' ')}, /* Slave (Athapascan) [macrolanguage] -> Athapaskan */ - {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */ +/*{"dgo", HB_TAG('D','G','O',' ')},*/ /* Dogri */ {"dgr", HB_TAG('A','T','H',' ')}, /* Dogrib -> Athapaskan */ {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari -> Marwari */ - {"dhg", HB_TAG('D','H','G',' ')}, /* Dhangu */ +/*{"dhg", HB_TAG('D','H','G',' ')},*/ /* Dhangu */ {"dib", HB_TAG('D','N','K',' ')}, /* South Central Dinka -> Dinka */ {"dik", HB_TAG('D','N','K',' ')}, /* Southwestern Dinka -> Dinka */ {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ {"dip", HB_TAG('D','N','K',' ')}, /* Northeastern Dinka -> Dinka */ - {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */ +/*{"diq", HB_TAG('D','I','Q',' ')},*/ /* Dimli */ {"diw", HB_TAG('D','N','K',' ')}, /* Northwestern Dinka -> Dinka */ {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */ {"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */ {"dks", HB_TAG('D','N','K',' ')}, /* Southeastern Dinka -> Dinka */ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */ - {"dnj", HB_TAG('D','N','J',' ')}, /* Dan */ +/*{"dnj", HB_TAG('D','N','J',' ')},*/ /* Dan */ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */ {"drh", HB_TAG('M','N','G',' ')}, /* Darkhat (retired code) -> Mongolian */ {"drw", HB_TAG('D','R','I',' ')}, /* Darwazi (retired code) -> Dari */ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ {"dty", HB_TAG('N','E','P',' ')}, /* Dotyali -> Nepali */ - {"duj", HB_TAG('D','U','J',' ')}, /* Dhuwal (retired code) */ +/*{"duj", HB_TAG('D','U','J',' ')},*/ /* Dhuwal (retired code) */ {"dup", HB_TAG('M','L','Y',' ')}, /* Duano -> Malay */ {"dv", HB_TAG('D','I','V',' ')}, /* Divehi (Dhivehi, Maldivian) */ {"dv", HB_TAG('D','H','V',' ')}, /* Divehi (Dhivehi, Maldivian) (deprecated) */ @@ -285,7 +285,7 @@ static const LangTag ot_languages[] = { {"dyu", HB_TAG('J','U','L',' ')}, /* Dyula -> Jula */ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */ {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */ - {"efi", HB_TAG('E','F','I',' ')}, /* Efik */ +/*{"efi", HB_TAG('E','F','I',' ')},*/ /* Efik */ {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian -> Estonian */ {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) -> Greek */ {"emk", HB_TAG('E','M','K',' ')}, /* Eastern Maninkakan */ @@ -299,7 +299,7 @@ static const LangTag ot_languages[] = { {"esg", HB_TAG('G','O','N',' ')}, /* Aheri Gondi -> Gondi */ {"esi", HB_TAG('I','P','K',' ')}, /* North Alaskan Inupiatun -> Inupiat */ {"esk", HB_TAG('I','P','K',' ')}, /* Northwest Alaska Inupiatun -> Inupiat */ - {"esu", HB_TAG('E','S','U',' ')}, /* Central Yupik */ +/*{"esu", HB_TAG('E','S','U',' ')},*/ /* Central Yupik */ {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */ {"eto", HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */ @@ -309,7 +309,7 @@ static const LangTag ot_languages[] = { {"eyo", HB_TAG('K','A','L',' ')}, /* Keiyo -> Kalenjin */ {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */ {"fan", HB_TAG('F','A','N','0')}, /* Fang (Equatorial Guinea) */ - {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */ +/*{"fat", HB_TAG('F','A','T',' ')},*/ /* Fanti */ {"fbl", HB_TAG('B','I','K',' ')}, /* West Albay Bikol -> Bikol */ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */ {"ffm", HB_TAG('F','U','L',' ')}, /* Maasina Fulfulde -> Fulah */ @@ -318,12 +318,12 @@ static const LangTag ot_languages[] = { {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */ {"flm", HB_TAG('H','A','L',' ')}, /* Halam (Falam Chin) (retired code) */ {"flm", HB_TAG('Q','I','N',' ')}, /* Falam Chin (retired code) -> Chin */ - {"fmp", HB_TAG('F','M','P',' ')}, /* Fe’fe’ */ +/*{"fmp", HB_TAG('F','M','P',' ')},*/ /* Fe’fe’ */ {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */ - {"fon", HB_TAG('F','O','N',' ')}, /* Fon */ +/*{"fon", HB_TAG('F','O','N',' ')},*/ /* Fon */ {"fr", HB_TAG('F','R','A',' ')}, /* French */ - {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */ - {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan */ +/*{"frc", HB_TAG('F','R','C',' ')},*/ /* Cajun French */ +/*{"frp", HB_TAG('F','R','P',' ')},*/ /* Arpitan */ {"fub", HB_TAG('F','U','L',' ')}, /* Adamawa Fulfulde -> Fulah */ {"fuc", HB_TAG('F','U','L',' ')}, /* Pulaar -> Fulah */ {"fue", HB_TAG('F','U','L',' ')}, /* Borgu Fulfulde -> Fulah */ @@ -332,11 +332,11 @@ static const LangTag ot_languages[] = { {"fui", HB_TAG('F','U','L',' ')}, /* Bagirmi Fulfulde -> Fulah */ {"fuq", HB_TAG('F','U','L',' ')}, /* Central-Eastern Niger Fulfulde -> Fulah */ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */ - {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ +/*{"fuv", HB_TAG('F','U','V',' ')},*/ /* Nigerian Fulfulde */ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian -> Frisian */ {"ga", HB_TAG('I','R','I',' ')}, /* Irish */ {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */ - {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */ +/*{"gag", HB_TAG('G','A','G',' ')},*/ /* Gagauz */ {"gan", HB_TAG('Z','H','S',' ')}, /* Gan Chinese -> Chinese Simplified */ {"gax", HB_TAG('O','R','O',' ')}, /* Borana-Arsi-Guji Oromo -> Oromo */ {"gaz", HB_TAG('O','R','O',' ')}, /* West Central Oromo -> Oromo */ @@ -344,34 +344,34 @@ static const LangTag ot_languages[] = { {"gce", HB_TAG('A','T','H',' ')}, /* Galice -> Athapaskan */ {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic (Gaelic) */ {"gda", HB_TAG('R','A','J',' ')}, /* Gade Lohar -> Rajasthani */ - {"gez", HB_TAG('G','E','Z',' ')}, /* Geez */ +/*{"gez", HB_TAG('G','E','Z',' ')},*/ /* Geez */ {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi (retired code) -> Gondi */ - {"gih", HB_TAG('G','I','H',' ')}, /* Githabul */ +/*{"gih", HB_TAG('G','I','H',' ')},*/ /* Githabul */ {"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */ {"gju", HB_TAG('R','A','J',' ')}, /* Gujari -> Rajasthani */ - {"gkp", HB_TAG('G','K','P',' ')}, /* Guinea Kpelle -> Kpelle (Guinea) */ +/*{"gkp", HB_TAG('G','K','P',' ')},*/ /* Guinea Kpelle -> Kpelle (Guinea) */ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */ - {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */ +/*{"glk", HB_TAG('G','L','K',' ')},*/ /* Gilaki */ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ - {"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */ +/*{"gnn", HB_TAG('G','N','N',' ')},*/ /* Gumatj */ {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi -> Gondi */ {"gnw", HB_TAG('G','U','A',' ')}, /* Western Bolivian Guaraní -> Guarani */ - {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */ +/*{"gog", HB_TAG('G','O','G',' ')},*/ /* Gogo */ {"gom", HB_TAG('K','O','K',' ')}, /* Goan Konkani -> Konkani */ - {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */ +/*{"gon", HB_TAG('G','O','N',' ')},*/ /* Gondi [macrolanguage] */ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */ {"gru", HB_TAG('S','O','G',' ')}, /* Kistane -> Sodo Gurage */ {"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */ - {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */ - {"guf", HB_TAG('G','U','F',' ')}, /* Gupapuyngu */ +/*{"guc", HB_TAG('G','U','C',' ')},*/ /* Wayuu */ +/*{"guf", HB_TAG('G','U','F',' ')},*/ /* Gupapuyngu */ {"gug", HB_TAG('G','U','A',' ')}, /* Paraguayan Guaraní -> Guarani */ {"gui", HB_TAG('G','U','A',' ')}, /* Eastern Bolivian Guaraní -> Guarani */ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */ {"guk", HB_TAG('G','U','K',' ')}, /* Gumuz (SIL fonts) */ {"gun", HB_TAG('G','U','A',' ')}, /* Mbyá Guaraní -> Guarani */ - {"guz", HB_TAG('G','U','Z',' ')}, /* Gusii */ +/*{"guz", HB_TAG('G','U','Z',' ')},*/ /* Gusii */ {"gv", HB_TAG('M','N','X',' ')}, /* Manx */ {"gwi", HB_TAG('A','T','H',' ')}, /* Gwichʼin -> Athapaskan */ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ @@ -379,13 +379,13 @@ static const LangTag ot_languages[] = { {"hae", HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese Simplified */ {"har", HB_TAG('H','R','I',' ')}, /* Harari */ - {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */ - {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ - {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ +/*{"haw", HB_TAG('H','A','W',' ')},*/ /* Hawaiian */ +/*{"hay", HB_TAG('H','A','Y',' ')},*/ /* Haya */ +/*{"haz", HB_TAG('H','A','Z',' ')},*/ /* Hazaragi */ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ {"hea", HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ - {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */ +/*{"hil", HB_TAG('H','I','L',' ')},*/ /* Hiligaynon */ {"hji", HB_TAG('M','L','Y',' ')}, /* Haji -> Malay */ {"hlt", HB_TAG('Q','I','N',' ')}, /* Matu Chin -> Chin */ {"hma", HB_TAG('H','M','N',' ')}, /* Southern Mashan Hmong -> Hmong */ @@ -398,14 +398,14 @@ static const LangTag ot_languages[] = { {"hmj", HB_TAG('H','M','N',' ')}, /* Ge -> Hmong */ {"hml", HB_TAG('H','M','N',' ')}, /* Luopohe Hmong -> Hmong */ {"hmm", HB_TAG('H','M','N',' ')}, /* Central Mashan Hmong -> Hmong */ - {"hmn", HB_TAG('H','M','N',' ')}, /* Hmong [macrolanguage] */ +/*{"hmn", HB_TAG('H','M','N',' ')},*/ /* Hmong [macrolanguage] */ {"hmp", HB_TAG('H','M','N',' ')}, /* Northern Mashan Hmong -> Hmong */ {"hmq", HB_TAG('H','M','N',' ')}, /* Eastern Qiandong Miao -> Hmong */ {"hms", HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */ {"hmw", HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */ {"hmy", HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */ {"hmz", HB_TAG('H','M','N',' ')}, /* Hmong Shua -> Hmong */ - {"hnd", HB_TAG('H','N','D',' ')}, /* Southern Hindko -> Hindko */ +/*{"hnd", HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */ {"hne", HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ {"hnj", HB_TAG('H','M','N',' ')}, /* Hmong Njua -> Hmong */ {"hno", HB_TAG('H','N','D',' ')}, /* Northern Hindko -> Hindko */ @@ -426,8 +426,8 @@ static const LangTag ot_languages[] = { {"hyw", HB_TAG('H','Y','E',' ')}, /* Western Armenian -> Armenian */ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */ - {"iba", HB_TAG('I','B','A',' ')}, /* Iban */ - {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */ +/*{"iba", HB_TAG('I','B','A',' ')},*/ /* Iban */ +/*{"ibb", HB_TAG('I','B','B',' ')},*/ /* Ibibio */ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */ {"ida", HB_TAG('L','U','H',' ')}, /* Idakho-Isukha-Tiriki -> Luyia */ {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue */ @@ -435,11 +435,11 @@ static const LangTag ot_languages[] = { {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */ {"ii", HB_TAG('Y','I','M',' ')}, /* Sichuan Yi -> Yi Modern */ {"ijc", HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */ - {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */ +/*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [family] */ {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */ {"ike", HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */ {"ikt", HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */ - {"ilo", HB_TAG('I','L','O',' ')}, /* Iloko -> Ilokano */ +/*{"ilo", HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */ {"in", HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */ {"ing", HB_TAG('A','T','H',' ')}, /* Degexit'an -> Athapaskan */ {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */ @@ -450,10 +450,10 @@ static const LangTag ot_languages[] = { {"iw", HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */ {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */ {"jak", HB_TAG('M','L','Y',' ')}, /* Jakun -> Malay */ - {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English -> Jamaican Creole */ +/*{"jam", HB_TAG('J','A','M',' ')},*/ /* Jamaican Creole English -> Jamaican Creole */ {"jax", HB_TAG('M','L','Y',' ')}, /* Jambi Malay -> Malay */ - {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */ - {"jct", HB_TAG('J','C','T',' ')}, /* Krymchak */ +/*{"jbo", HB_TAG('J','B','O',' ')},*/ /* Lojban */ +/*{"jct", HB_TAG('J','C','T',' ')},*/ /* Krymchak */ {"ji", HB_TAG('J','I','I',' ')}, /* Yiddish (retired code) */ {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */ {"jw", HB_TAG('J','A','V',' ')}, /* Javanese (retired code) */ @@ -467,11 +467,11 @@ static const LangTag ot_languages[] = { {"kca", HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ {"kca", HB_TAG('K','H','S',' ')}, /* Khanty -> Khanty-Shurishkar */ {"kca", HB_TAG('K','H','V',' ')}, /* Khanty -> Khanty-Vakhi */ - {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */ +/*{"kde", HB_TAG('K','D','E',' ')},*/ /* Makonde */ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */ - {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */ - {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */ +/*{"kea", HB_TAG('K','E','A',' ')},*/ /* Kabuverdianu (Crioulo) */ +/*{"kek", HB_TAG('K','E','K',' ')},*/ /* Kekchi */ {"kex", HB_TAG('K','K','N',' ')}, /* Kukna -> Kokni */ {"kfa", HB_TAG('K','O','D',' ')}, /* Kodava -> Kodagu */ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachhi -> Kachchi */ @@ -483,14 +483,14 @@ static const LangTag ot_languages[] = { {"khk", HB_TAG('M','N','G',' ')}, /* Halh Mongolian -> Mongolian */ {"kht", HB_TAG('K','H','N',' ')}, /* Khamti -> Khamti Shan (Microsoft fonts) */ {"kht", HB_TAG('K','H','T',' ')}, /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */ - {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */ +/*{"khw", HB_TAG('K','H','W',' ')},*/ /* Khowar */ {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu (Gikuyu) */ - {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */ +/*{"kiu", HB_TAG('K','I','U',' ')},*/ /* Kirmanjki */ {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama */ - {"kjd", HB_TAG('K','J','D',' ')}, /* Southern Kiwai */ +/*{"kjd", HB_TAG('K','J','D',' ')},*/ /* Southern Kiwai */ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakas -> Khakass */ - {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen -> Eastern Pwo Karen */ - {"kjz", HB_TAG('K','J','Z',' ')}, /* Bumthangkha */ +/*{"kjp", HB_TAG('K','J','P',' ')},*/ /* Pwo Eastern Karen -> Eastern Pwo Karen */ +/*{"kjz", HB_TAG('K','J','Z',' ')},*/ /* Bumthangkha */ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */ {"kkz", HB_TAG('A','T','H',' ')}, /* Kaska -> Athapaskan */ {"kl", HB_TAG('G','R','N',' ')}, /* Greenlandic */ @@ -499,15 +499,15 @@ static const LangTag ot_languages[] = { {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu -> Mbundu */ {"kmr", HB_TAG('K','U','R',' ')}, /* Northern Kurdish -> Kurdish */ {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */ - {"kmz", HB_TAG('K','M','Z',' ')}, /* Khorasani Turkish -> Khorasani Turkic */ +/*{"kmz", HB_TAG('K','M','Z',' ')},*/ /* Khorasani Turkish -> Khorasani Turkic */ {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */ {"knc", HB_TAG('K','N','R',' ')}, /* Central Kanuri -> Kanuri */ {"kng", HB_TAG('K','O','N','0')}, /* Koongo -> Kongo */ {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */ {"ko", HB_TAG('K','O','R',' ')}, /* Korean */ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ - {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */ - {"kos", HB_TAG('K','O','S',' ')}, /* Kosraean */ +/*{"kok", HB_TAG('K','O','K',' ')},*/ /* Konkani [macrolanguage] */ +/*{"kos", HB_TAG('K','O','S',' ')},*/ /* Kosraean */ {"koy", HB_TAG('A','T','H',' ')}, /* Koyukon -> Athapaskan */ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ @@ -517,19 +517,19 @@ static const LangTag ot_languages[] = { {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */ {"krc", HB_TAG('K','A','R',' ')}, /* Karachay-Balkar -> Karachay */ {"krc", HB_TAG('B','A','L',' ')}, /* Karachay-Balkar -> Balkar */ - {"kri", HB_TAG('K','R','I',' ')}, /* Krio */ - {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */ +/*{"kri", HB_TAG('K','R','I',' ')},*/ /* Krio */ +/*{"krl", HB_TAG('K','R','L',' ')},*/ /* Karelian */ {"krt", HB_TAG('K','N','R',' ')}, /* Tumari Kanuri -> Kanuri */ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */ {"ksh", HB_TAG('K','S','H','0')}, /* Kölsch -> Ripuarian */ {"kss", HB_TAG('K','I','S',' ')}, /* Southern Kisi -> Kisii */ - {"ksw", HB_TAG('K','S','W',' ')}, /* S’gaw Karen */ +/*{"ksw", HB_TAG('K','S','W',' ')},*/ /* S’gaw Karen */ {"ktb", HB_TAG('K','E','B',' ')}, /* Kambaata -> Kebena */ {"ktu", HB_TAG('K','O','N',' ')}, /* Kituba (Democratic Republic of Congo) -> Kikongo */ {"ktw", HB_TAG('A','T','H',' ')}, /* Kato -> Athapaskan */ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */ - {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */ +/*{"kum", HB_TAG('K','U','M',' ')},*/ /* Kumyk */ {"kuu", HB_TAG('A','T','H',' ')}, /* Upper Kuskokwim -> Athapaskan */ {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */ {"kvb", HB_TAG('M','L','Y',' ')}, /* Kubu -> Malay */ @@ -540,7 +540,7 @@ static const LangTag ot_languages[] = { {"kxd", HB_TAG('M','L','Y',' ')}, /* Brunei -> Malay */ {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz (Kyrgyz) */ - {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */ +/*{"kyu", HB_TAG('K','Y','U',' ')},*/ /* Western Kayah */ {"la", HB_TAG('L','A','T',' ')}, /* Latin */ {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */ {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */ @@ -550,25 +550,25 @@ static const LangTag ot_languages[] = { {"lce", HB_TAG('M','L','Y',' ')}, /* Loncong -> Malay */ {"lcf", HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */ {"ldi", HB_TAG('K','O','N','0')}, /* Laari -> Kongo */ - {"lez", HB_TAG('L','E','Z',' ')}, /* Lezghian -> Lezgi */ +/*{"lez", HB_TAG('L','E','Z',' ')},*/ /* Lezghian -> Lezgi */ {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */ {"li", HB_TAG('L','I','M',' ')}, /* Limburgish */ {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */ - {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */ - {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */ +/*{"lij", HB_TAG('L','I','J',' ')},*/ /* Ligurian */ +/*{"lis", HB_TAG('L','I','S',' ')},*/ /* Lisu */ {"liw", HB_TAG('M','L','Y',' ')}, /* Col -> Malay */ - {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api -> Lampung */ +/*{"ljp", HB_TAG('L','J','P',' ')},*/ /* Lampung Api -> Lampung */ {"lkb", HB_TAG('L','U','H',' ')}, /* Kabras -> Luyia */ - {"lki", HB_TAG('L','K','I',' ')}, /* Laki */ +/*{"lki", HB_TAG('L','K','I',' ')},*/ /* Laki */ {"lko", HB_TAG('L','U','H',' ')}, /* Khayo -> Luyia */ {"lks", HB_TAG('L','U','H',' ')}, /* Kisa -> Luyia */ {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */ {"lmn", HB_TAG('L','A','M',' ')}, /* Lambadi -> Lambani */ - {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */ +/*{"lmo", HB_TAG('L','M','O',' ')},*/ /* Lombard */ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ - {"lom", HB_TAG('L','O','M',' ')}, /* Loma (Liberia) */ - {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri -> Luri */ +/*{"lom", HB_TAG('L','O','M',' ')},*/ /* Loma (Liberia) */ +/*{"lrc", HB_TAG('L','R','C',' ')},*/ /* Northern Luri -> Luri */ {"lri", HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */ {"lrm", HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */ {"lsm", HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */ @@ -577,8 +577,8 @@ static const LangTag ot_languages[] = { {"lto", HB_TAG('L','U','H',' ')}, /* Tsotso -> Luyia */ {"lts", HB_TAG('L','U','H',' ')}, /* Tachoni -> Luyia */ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */ - {"lua", HB_TAG('L','U','A',' ')}, /* Luba-Lulua */ - {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */ +/*{"lua", HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ +/*{"luo", HB_TAG('L','U','O',' ')},*/ /* Luo (Kenya and Tanzania) */ {"lus", HB_TAG('M','I','Z',' ')}, /* Lushai -> Mizo */ {"luy", HB_TAG('L','U','H',' ')}, /* Luyia [macrolanguage] */ {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri -> Luri */ @@ -587,33 +587,33 @@ static const LangTag ot_languages[] = { {"lwg", HB_TAG('L','U','H',' ')}, /* Wanga -> Luyia */ {"lzh", HB_TAG('Z','H','T',' ')}, /* Literary Chinese -> Chinese Traditional */ {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */ - {"mad", HB_TAG('M','A','D',' ')}, /* Madurese -> Madura */ - {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */ +/*{"mad", HB_TAG('M','A','D',' ')},*/ /* Madurese -> Madura */ +/*{"mag", HB_TAG('M','A','G',' ')},*/ /* Magahi */ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */ {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */ - {"mam", HB_TAG('M','A','M',' ')}, /* Mam */ +/*{"mam", HB_TAG('M','A','M',' ')},*/ /* Mam */ {"man", HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */ {"max", HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */ - {"mbo", HB_TAG('M','B','O',' ')}, /* Mbo (Cameroon) */ +/*{"mbo", HB_TAG('M','B','O',' ')},*/ /* Mbo (Cameroon) */ {"mct", HB_TAG('B','T','I',' ')}, /* Mengisa -> Beti */ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */ - {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */ +/*{"mdr", HB_TAG('M','D','R',' ')},*/ /* Mandar */ {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */ {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */ {"meo", HB_TAG('M','L','Y',' ')}, /* Kedah Malay -> Malay */ - {"mer", HB_TAG('M','E','R',' ')}, /* Meru */ - {"mfa", HB_TAG('M','F','A',' ')}, /* Pattani Malay */ +/*{"mer", HB_TAG('M','E','R',' ')},*/ /* Meru */ +/*{"mfa", HB_TAG('M','F','A',' ')},*/ /* Pattani Malay */ {"mfb", HB_TAG('M','L','Y',' ')}, /* Bangka -> Malay */ - {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */ +/*{"mfe", HB_TAG('M','F','E',' ')},*/ /* Morisyen */ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */ {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */ {"mhr", HB_TAG('L','M','A',' ')}, /* Eastern Mari -> Low Mari */ {"mhv", HB_TAG('A','R','K',' ')}, /* Arakanese (retired code) -> Rakhine */ {"mi", HB_TAG('M','R','I',' ')}, /* Maori */ - {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */ +/*{"min", HB_TAG('M','I','N',' ')},*/ /* Minangkabau */ {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */ {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka -> Maninka */ - {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */ +/*{"mkw", HB_TAG('M','K','W',' ')},*/ /* Kituba (Congo) */ {"ml", HB_TAG('M','A','L',' ')}, /* Malayalam -> Malayalam Traditional */ {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam -> Malayalam Reformed */ {"mlq", HB_TAG('M','L','N',' ')}, /* Western Maninkakan -> Malinke */ @@ -621,15 +621,15 @@ static const LangTag ot_languages[] = { {"mmr", HB_TAG('H','M','N',' ')}, /* Western Xiangxi Miao -> Hmong */ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */ {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */ - {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */ +/*{"mni", HB_TAG('M','N','I',' ')},*/ /* Manipuri */ {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */ {"mnk", HB_TAG('M','N','K',' ')}, /* Mandinka -> Maninka */ {"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese Simplified */ {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */ {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ - {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */ - {"mos", HB_TAG('M','O','S',' ')}, /* Mossi */ +/*{"moh", HB_TAG('M','O','H',' ')},*/ /* Mohawk */ +/*{"mos", HB_TAG('M','O','S',' ')},*/ /* Mossi */ {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */ {"mqg", HB_TAG('M','L','Y',' ')}, /* Kota Bangun Kutai Malay -> Malay */ {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */ @@ -644,38 +644,38 @@ static const LangTag ot_languages[] = { {"mui", HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */ {"mup", HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */ {"muq", HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */ - {"mus", HB_TAG('M','U','S',' ')}, /* Creek -> Muscogee */ +/*{"mus", HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */ {"mvb", HB_TAG('A','T','H',' ')}, /* Mattole -> Athapaskan */ {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */ {"mvf", HB_TAG('M','N','G',' ')}, /* Peripheral Mongolian -> Mongolian */ {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan -> Maninka */ - {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */ +/*{"mwl", HB_TAG('M','W','L',' ')},*/ /* Mirandese */ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */ - {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */ +/*{"mww", HB_TAG('M','W','W',' ')},*/ /* Hmong Daw */ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */ {"mym", HB_TAG('M','E','N',' ')}, /* Me’en */ - {"myn", HB_TAG('M','Y','N',' ')}, /* Mayan [family] */ +/*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [family] */ {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */ - {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */ +/*{"mzn", HB_TAG('M','Z','N',' ')},*/ /* Mazanderani */ {"na", HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */ - {"nag", HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */ - {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */ +/*{"nag", HB_TAG('N','A','G',' ')},*/ /* Naga Pidgin -> Naga-Assamese */ +/*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [family] */ {"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese Simplified */ - {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */ +/*{"nap", HB_TAG('N','A','P',' ')},*/ /* Neapolitan */ {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål -> Norwegian */ {"nd", HB_TAG('N','D','B',' ')}, /* North Ndebele -> Ndebele */ - {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */ - {"nds", HB_TAG('N','D','S',' ')}, /* Low Saxon */ +/*{"ndc", HB_TAG('N','D','C',' ')},*/ /* Ndau */ +/*{"nds", HB_TAG('N','D','S',' ')},*/ /* Low Saxon */ {"ne", HB_TAG('N','E','P',' ')}, /* Nepali [macrolanguage] */ - {"new", HB_TAG('N','E','W',' ')}, /* Newari */ +/*{"new", HB_TAG('N','E','W',' ')},*/ /* Newari */ {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */ - {"nga", HB_TAG('N','G','A',' ')}, /* Ngbaka */ +/*{"nga", HB_TAG('N','G','A',' ')},*/ /* Ngbaka */ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ {"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni -> Sutu */ {"nhd", HB_TAG('G','U','A',' ')}, /* Chiripá -> Guarani */ {"niq", HB_TAG('K','A','L',' ')}, /* Nandi -> Kalenjin */ - {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */ +/*{"niu", HB_TAG('N','I','U',' ')},*/ /* Niuean */ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */ {"njz", HB_TAG('N','I','S',' ')}, /* Nyishi -> Nisi */ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */ @@ -683,24 +683,24 @@ static const LangTag ot_languages[] = { {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai -> Northern Tai */ - {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */ - {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */ - {"nov", HB_TAG('N','O','V',' ')}, /* Novial */ +/*{"noe", HB_TAG('N','O','E',' ')},*/ /* Nimadi */ +/*{"nog", HB_TAG('N','O','G',' ')},*/ /* Nogai */ +/*{"nov", HB_TAG('N','O','V',' ')},*/ /* Novial */ {"npi", HB_TAG('N','E','P',' ')}, /* Nepali */ {"nqo", HB_TAG('N','K','O',' ')}, /* N’Ko */ {"nr", HB_TAG('N','D','B',' ')}, /* South Ndebele -> Ndebele */ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ - {"nso", HB_TAG('N','S','O',' ')}, /* Pedi -> Sotho, Northern */ +/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Pedi -> Sotho, Northern */ {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */ {"nv", HB_TAG('A','T','H',' ')}, /* Navajo -> Athapaskan */ {"ny", HB_TAG('C','H','I',' ')}, /* Chichewa (Chewa, Nyanja) */ {"nyd", HB_TAG('L','U','H',' ')}, /* Nyore -> Luyia */ - {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */ +/*{"nym", HB_TAG('N','Y','M',' ')},*/ /* Nyamwezi */ {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */ - {"nza", HB_TAG('N','Z','A',' ')}, /* Tigon Mbembe -> Mbembe Tigon */ +/*{"nza", HB_TAG('N','Z','A',' ')},*/ /* Tigon Mbembe -> Mbembe Tigon */ {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] -> Ojibway */ - {"ojb", HB_TAG('O','J','B',' ')}, /* Northwestern Ojibwa -> Ojibway */ +/*{"ojb", HB_TAG('O','J','B',' ')},*/ /* Northwestern Ojibwa -> Ojibway */ {"ojc", HB_TAG('O','J','B',' ')}, /* Central Ojibwa -> Ojibway */ {"ojg", HB_TAG('O','J','B',' ')}, /* Eastern Ojibwa -> Ojibway */ {"ojs", HB_TAG('O','C','R',' ')}, /* Severn Ojibwa -> Oji-Cree */ @@ -716,47 +716,47 @@ static const LangTag ot_languages[] = { {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */ {"otw", HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */ {"pa", HB_TAG('P','A','N',' ')}, /* Punjabi */ - {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */ - {"pam", HB_TAG('P','A','M',' ')}, /* Pampanga -> Pampangan */ +/*{"pag", HB_TAG('P','A','G',' ')},*/ /* Pangasinan */ +/*{"pam", HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */ {"pap", HB_TAG('P','A','P','0')}, /* Papiamento -> Papiamentu */ - {"pau", HB_TAG('P','A','U',' ')}, /* Palauan */ +/*{"pau", HB_TAG('P','A','U',' ')},*/ /* Palauan */ {"pbt", HB_TAG('P','A','S',' ')}, /* Southern Pashto -> Pashto */ {"pbu", HB_TAG('P','A','S',' ')}, /* Northern Pashto -> Pashto */ - {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */ - {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */ +/*{"pcc", HB_TAG('P','C','C',' ')},*/ /* Bouyei */ +/*{"pcd", HB_TAG('P','C','D',' ')},*/ /* Picard */ {"pce", HB_TAG('P','L','G',' ')}, /* Ruching Palaung -> Palaung */ {"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin -> Chin */ - {"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */ +/*{"pdc", HB_TAG('P','D','C',' ')},*/ /* Pennsylvania German */ {"pel", HB_TAG('M','L','Y',' ')}, /* Pekal -> Malay */ {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian -> Persian */ {"pga", HB_TAG('A','R','A',' ')}, /* Sudanese Creole Arabic -> Arabic */ - {"phk", HB_TAG('P','H','K',' ')}, /* Phake */ +/*{"phk", HB_TAG('P','H','K',' ')},*/ /* Phake */ {"pi", HB_TAG('P','A','L',' ')}, /* Pali */ - {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk -> Norfolk */ +/*{"pih", HB_TAG('P','I','H',' ')},*/ /* Pitcairn-Norfolk -> Norfolk */ {"pko", HB_TAG('K','A','L',' ')}, /* Pökoot -> Kalenjin */ {"pl", HB_TAG('P','L','K',' ')}, /* Polish */ {"pll", HB_TAG('P','L','G',' ')}, /* Shwe Palaung -> Palaung */ {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */ {"plt", HB_TAG('M','L','G',' ')}, /* Plateau Malagasy -> Malagasy */ - {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */ - {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */ - {"poh", HB_TAG('P','O','H',' ')}, /* Poqomchi' -> Pocomchi */ - {"pon", HB_TAG('P','O','N',' ')}, /* Pohnpeian */ +/*{"pms", HB_TAG('P','M','S',' ')},*/ /* Piemontese */ +/*{"pnb", HB_TAG('P','N','B',' ')},*/ /* Western Panjabi */ +/*{"poh", HB_TAG('P','O','H',' ')},*/ /* Poqomchi' -> Pocomchi */ +/*{"pon", HB_TAG('P','O','N',' ')},*/ /* Pohnpeian */ {"ppa", HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */ - {"pro", HB_TAG('P','R','O',' ')}, /* Old Provençal (to 1500) -> Provençal / Old Provençal */ +/*{"pro", HB_TAG('P','R','O',' ')},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */ {"prs", HB_TAG('D','R','I',' ')}, /* Dari */ {"ps", HB_TAG('P','A','S',' ')}, /* Pashto [macrolanguage] */ {"pse", HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */ {"pst", HB_TAG('P','A','S',' ')}, /* Central Pashto -> Pashto */ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */ - {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen -> Western Pwo Karen */ +/*{"pwo", HB_TAG('P','W','O',' ')},*/ /* Pwo Western Karen -> Western Pwo Karen */ {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */ {"qub", HB_TAG('Q','W','H',' ')}, /* Huallaga Huánuco Quechua -> Quechua (Peru) */ - {"quc", HB_TAG('Q','U','C',' ')}, /* K’iche’ */ +/*{"quc", HB_TAG('Q','U','C',' ')},*/ /* K’iche’ */ {"qud", HB_TAG('Q','V','I',' ')}, /* Calderón Highland Quichua -> Quechua (Ecuador) */ {"quf", HB_TAG('Q','U','Z',' ')}, /* Lambayeque Quechua -> Quechua */ {"qug", HB_TAG('Q','V','I',' ')}, /* Chimborazo Highland Quichua -> Quechua (Ecuador) */ - {"quh", HB_TAG('Q','U','H',' ')}, /* South Bolivian Quechua -> Quechua (Bolivia) */ +/*{"quh", HB_TAG('Q','U','H',' ')},*/ /* South Bolivian Quechua -> Quechua (Bolivia) */ {"quk", HB_TAG('Q','U','Z',' ')}, /* Chachapoyas Quechua -> Quechua */ {"qul", HB_TAG('Q','U','Z',' ')}, /* North Bolivian Quechua -> Quechua */ {"qup", HB_TAG('Q','V','I',' ')}, /* Southern Pastaza Quechua -> Quechua (Ecuador) */ @@ -765,12 +765,12 @@ static const LangTag ot_languages[] = { {"quw", HB_TAG('Q','V','I',' ')}, /* Tena Lowland Quichua -> Quechua (Ecuador) */ {"qux", HB_TAG('Q','W','H',' ')}, /* Yauyos Quechua -> Quechua (Peru) */ {"quy", HB_TAG('Q','U','Z',' ')}, /* Ayacucho Quechua -> Quechua */ - {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua -> Quechua */ +/*{"quz", HB_TAG('Q','U','Z',' ')},*/ /* Cusco Quechua -> Quechua */ {"qva", HB_TAG('Q','W','H',' ')}, /* Ambo-Pasco Quechua -> Quechua (Peru) */ {"qvc", HB_TAG('Q','U','Z',' ')}, /* Cajamarca Quechua -> Quechua */ {"qve", HB_TAG('Q','U','Z',' ')}, /* Eastern Apurímac Quechua -> Quechua */ {"qvh", HB_TAG('Q','W','H',' ')}, /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */ - {"qvi", HB_TAG('Q','V','I',' ')}, /* Imbabura Highland Quichua -> Quechua (Ecuador) */ +/*{"qvi", HB_TAG('Q','V','I',' ')},*/ /* Imbabura Highland Quichua -> Quechua (Ecuador) */ {"qvj", HB_TAG('Q','V','I',' ')}, /* Loja Highland Quichua -> Quechua (Ecuador) */ {"qvl", HB_TAG('Q','W','H',' ')}, /* Cajatambo North Lima Quechua -> Quechua (Peru) */ {"qvm", HB_TAG('Q','W','H',' ')}, /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */ @@ -782,7 +782,7 @@ static const LangTag ot_languages[] = { {"qvz", HB_TAG('Q','V','I',' ')}, /* Northern Pastaza Quichua -> Quechua (Ecuador) */ {"qwa", HB_TAG('Q','W','H',' ')}, /* Corongo Ancash Quechua -> Quechua (Peru) */ {"qwc", HB_TAG('Q','U','Z',' ')}, /* Classical Quechua -> Quechua */ - {"qwh", HB_TAG('Q','W','H',' ')}, /* Huaylas Ancash Quechua -> Quechua (Peru) */ +/*{"qwh", HB_TAG('Q','W','H',' ')},*/ /* Huaylas Ancash Quechua -> Quechua (Peru) */ {"qws", HB_TAG('Q','W','H',' ')}, /* Sihuas Ancash Quechua -> Quechua (Peru) */ {"qxa", HB_TAG('Q','W','H',' ')}, /* Chiquián Ancash Quechua -> Quechua (Peru) */ {"qxc", HB_TAG('Q','W','H',' ')}, /* Chincha Quechua -> Quechua (Peru) */ @@ -796,16 +796,16 @@ static const LangTag ot_languages[] = { {"qxu", HB_TAG('Q','U','Z',' ')}, /* Arequipa-La Unión Quechua -> Quechua */ {"qxw", HB_TAG('Q','W','H',' ')}, /* Jauja Wanca Quechua -> Quechua (Peru) */ {"rag", HB_TAG('L','U','H',' ')}, /* Logooli -> Luyia */ - {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */ - {"rar", HB_TAG('R','A','R',' ')}, /* Rarotongan */ +/*{"raj", HB_TAG('R','A','J',' ')},*/ /* Rajasthani [macrolanguage] */ +/*{"rar", HB_TAG('R','A','R',' ')},*/ /* Rarotongan */ {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung -> Palaung */ {"rbl", HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */ - {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */ - {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */ - {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */ - {"rit", HB_TAG('R','I','T',' ')}, /* Ritarungo */ +/*{"rej", HB_TAG('R','E','J',' ')},*/ /* Rejang */ +/*{"ria", HB_TAG('R','I','A',' ')},*/ /* Riang (India) */ +/*{"rif", HB_TAG('R','I','F',' ')},*/ /* Tarifit */ +/*{"rit", HB_TAG('R','I','T',' ')},*/ /* Ritarungo */ {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */ - {"rkw", HB_TAG('R','K','W',' ')}, /* Arakwal */ +/*{"rkw", HB_TAG('R','K','W',' ')},*/ /* Arakwal */ {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */ {"rmc", HB_TAG('R','O','Y',' ')}, /* Carpathian Romani -> Romany */ {"rmf", HB_TAG('R','O','Y',' ')}, /* Kalo Finnish Romani -> Romany */ @@ -813,27 +813,27 @@ static const LangTag ot_languages[] = { {"rmn", HB_TAG('R','O','Y',' ')}, /* Balkan Romani -> Romany */ {"rmo", HB_TAG('R','O','Y',' ')}, /* Sinte Romani -> Romany */ {"rmw", HB_TAG('R','O','Y',' ')}, /* Welsh Romani -> Romany */ - {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ +/*{"rmy", HB_TAG('R','M','Y',' ')},*/ /* Vlax Romani */ {"rmz", HB_TAG('A','R','K',' ')}, /* Marma -> Rakhine */ {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */ {"rnl", HB_TAG('H','A','L',' ')}, /* Ranglong -> Halam (Falam Chin) */ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ - {"rtm", HB_TAG('R','T','M',' ')}, /* Rotuman */ +/*{"rtm", HB_TAG('R','T','M',' ')},*/ /* Rotuman */ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */ - {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian */ +/*{"rup", HB_TAG('R','U','P',' ')},*/ /* Aromanian */ {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */ {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut -> Sakha */ {"sam", HB_TAG('P','A','A',' ')}, /* Samaritan Aramaic -> Palestinian Aramaic */ - {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */ - {"sat", HB_TAG('S','A','T',' ')}, /* Santali */ +/*{"sas", HB_TAG('S','A','S',' ')},*/ /* Sasak */ +/*{"sat", HB_TAG('S','A','T',' ')},*/ /* Santali */ {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ - {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */ - {"sco", HB_TAG('S','C','O',' ')}, /* Scots */ +/*{"scn", HB_TAG('S','C','N',' ')},*/ /* Sicilian */ +/*{"sco", HB_TAG('S','C','O',' ')},*/ /* Scots */ {"scs", HB_TAG('S','C','S',' ')}, /* North Slavey */ {"scs", HB_TAG('S','L','A',' ')}, /* North Slavey -> Slavey */ {"scs", HB_TAG('A','T','H',' ')}, /* North Slavey -> Athapaskan */ @@ -844,20 +844,20 @@ static const LangTag ot_languages[] = { {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */ {"seh", HB_TAG('S','N','A',' ')}, /* Sena */ {"sek", HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ - {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */ +/*{"sel", HB_TAG('S','E','L',' ')},*/ /* Selkup */ {"sez", HB_TAG('Q','I','N',' ')}, /* Senthang Chin -> Chin */ {"sfm", HB_TAG('H','M','N',' ')}, /* Small Flowery Miao -> Hmong */ {"sg", HB_TAG('S','G','O',' ')}, /* Sango */ - {"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */ +/*{"sga", HB_TAG('S','G','A',' ')},*/ /* Old Irish (to 900) */ {"sgc", HB_TAG('K','A','L',' ')}, /* Kipsigis -> Kalenjin */ - {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */ +/*{"sgs", HB_TAG('S','G','S',' ')},*/ /* Samogitian */ {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */ {"sgw", HB_TAG('S','G','W',' ')}, /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */ - {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */ - {"shn", HB_TAG('S','H','N',' ')}, /* Shan */ +/*{"shi", HB_TAG('S','H','I',' ')},*/ /* Tachelhit */ +/*{"shn", HB_TAG('S','H','N',' ')},*/ /* Shan */ {"shu", HB_TAG('A','R','A',' ')}, /* Chadian Arabic -> Arabic */ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala (Sinhalese) */ - {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */ +/*{"sid", HB_TAG('S','I','D',' ')},*/ /* Sidamo */ {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */ {"sjo", HB_TAG('S','I','B',' ')}, /* Xibe -> Sibe */ {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */ @@ -870,40 +870,40 @@ static const LangTag ot_languages[] = { {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */ {"sn", HB_TAG('S','N','A','0')}, /* Shona */ - {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */ +/*{"snk", HB_TAG('S','N','K',' ')},*/ /* Soninke */ {"so", HB_TAG('S','M','L',' ')}, /* Somali */ - {"sop", HB_TAG('S','O','P',' ')}, /* Songe */ +/*{"sop", HB_TAG('S','O','P',' ')},*/ /* Songe */ {"spv", HB_TAG('O','R','I',' ')}, /* Sambalpuri -> Odia (formerly Oriya) */ {"spy", HB_TAG('K','A','L',' ')}, /* Sabaot -> Kalenjin */ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */ {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */ {"src", HB_TAG('S','R','D',' ')}, /* Logudorese Sardinian -> Sardinian */ {"sro", HB_TAG('S','R','D',' ')}, /* Campidanese Sardinian -> Sardinian */ - {"srr", HB_TAG('S','R','R',' ')}, /* Serer */ +/*{"srr", HB_TAG('S','R','R',' ')},*/ /* Serer */ {"srs", HB_TAG('A','T','H',' ')}, /* Sarsi -> Athapaskan */ {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */ {"ssh", HB_TAG('A','R','A',' ')}, /* Shihhi Arabic -> Arabic */ {"st", HB_TAG('S','O','T',' ')}, /* Southern Sotho -> Sotho, Southern */ - {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch -> Saterland Frisian */ +/*{"stq", HB_TAG('S','T','Q',' ')},*/ /* Saterfriesisch -> Saterland Frisian */ {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e -> Silte Gurage */ {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */ - {"suk", HB_TAG('S','U','K',' ')}, /* Sukuma */ +/*{"suk", HB_TAG('S','U','K',' ')},*/ /* Sukuma */ {"suq", HB_TAG('S','U','R',' ')}, /* Suri */ {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */ - {"sva", HB_TAG('S','V','A',' ')}, /* Svan */ +/*{"sva", HB_TAG('S','V','A',' ')},*/ /* Svan */ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */ {"swb", HB_TAG('C','M','R',' ')}, /* Maore Comorian -> Comorian */ {"swc", HB_TAG('S','W','K',' ')}, /* Congo Swahili -> Swahili */ {"swh", HB_TAG('S','W','K',' ')}, /* Swahili */ {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati -> Marwari */ - {"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */ +/*{"sxu", HB_TAG('S','X','U',' ')},*/ /* Upper Saxon */ {"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac -> Syriac */ - {"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */ - {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */ - {"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */ +/*{"syl", HB_TAG('S','Y','L',' ')},*/ /* Sylheti */ +/*{"syr", HB_TAG('S','Y','R',' ')},*/ /* Syriac [macrolanguage] */ +/*{"szl", HB_TAG('S','Z','L',' ')},*/ /* Silesian */ {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */ {"taa", HB_TAG('A','T','H',' ')}, /* Lower Tanana -> Athapaskan */ - {"tab", HB_TAG('T','A','B',' ')}, /* Tabassaran -> Tabasaran */ +/*{"tab", HB_TAG('T','A','B',' ')},*/ /* Tabassaran -> Tabasaran */ {"taq", HB_TAG('T','M','H',' ')}, /* Tamasheq -> Tamashek */ {"tau", HB_TAG('A','T','H',' ')}, /* Upper Tanana -> Athapaskan */ {"tcb", HB_TAG('A','T','H',' ')}, /* Tanacross -> Athapaskan */ @@ -911,12 +911,12 @@ static const LangTag ot_languages[] = { {"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin -> Chin */ {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu -> Tumbuka */ {"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ - {"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa -> Dehong Dai */ +/*{"tdd", HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */ {"tdx", HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ {"te", HB_TAG('T','E','L',' ')}, /* Telugu */ {"tec", HB_TAG('K','A','L',' ')}, /* Terik -> Kalenjin */ {"tem", HB_TAG('T','M','N',' ')}, /* Timne -> Temne */ - {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */ +/*{"tet", HB_TAG('T','E','T',' ')},*/ /* Tetum */ {"tfn", HB_TAG('A','T','H',' ')}, /* Tanaina -> Athapaskan */ {"tg", HB_TAG('T','A','J',' ')}, /* Tajik -> Tajiki */ {"tgj", HB_TAG('N','I','S',' ')}, /* Tagin -> Nisi */ @@ -927,11 +927,11 @@ static const LangTag ot_languages[] = { {"thz", HB_TAG('T','M','H',' ')}, /* Tayart Tamajeq -> Tamashek */ {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ - {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */ +/*{"tiv", HB_TAG('T','I','V',' ')},*/ /* Tiv */ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ {"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ - {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ +/*{"tmh", HB_TAG('T','M','H',' ')},*/ /* Tamashek [macrolanguage] */ {"tmw", HB_TAG('M','L','Y',' ')}, /* Temuan -> Malay */ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */ {"tnf", HB_TAG('D','R','I',' ')}, /* Tangshewi (retired code) -> Dari */ @@ -939,33 +939,33 @@ static const LangTag ot_languages[] = { {"tod", HB_TAG('T','O','D','0')}, /* Toma */ {"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */ {"tol", HB_TAG('A','T','H',' ')}, /* Tolowa -> Athapaskan */ - {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */ +/*{"tpi", HB_TAG('T','P','I',' ')},*/ /* Tok Pisin */ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */ {"tru", HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */ - {"tsj", HB_TAG('T','S','J',' ')}, /* Tshangla */ +/*{"tsj", HB_TAG('T','S','J',' ')},*/ /* Tshangla */ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */ {"ttm", HB_TAG('A','T','H',' ')}, /* Northern Tutchone -> Athapaskan */ {"ttq", HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ - {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka -> Tulu */ +/*{"tum", HB_TAG('T','U','M',' ')},*/ /* Tumbuka -> Tulu */ {"tuu", HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ {"tuy", HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ - {"tvl", HB_TAG('T','V','L',' ')}, /* Tuvalu */ +/*{"tvl", HB_TAG('T','V','L',' ')},*/ /* Tuvalu */ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */ {"tw", HB_TAG('A','K','A',' ')}, /* Twi -> Akan */ {"txc", HB_TAG('A','T','H',' ')}, /* Tsetsaut -> Athapaskan */ {"txy", HB_TAG('M','L','G',' ')}, /* Tanosy Malagasy -> Malagasy */ {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvinian -> Tuvin */ - {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */ - {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight -> Tamazight */ - {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */ +/*{"tyz", HB_TAG('T','Y','Z',' ')},*/ /* Tày */ +/*{"tzm", HB_TAG('T','Z','M',' ')},*/ /* Central Atlas Tamazight -> Tamazight */ +/*{"tzo", HB_TAG('T','Z','O',' ')},*/ /* Tzotzil */ {"ubl", HB_TAG('B','I','K',' ')}, /* Buhi'non Bikol -> Bikol */ - {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */ +/*{"udm", HB_TAG('U','D','M',' ')},*/ /* Udmurt */ {"ug", HB_TAG('U','Y','G',' ')}, /* Uyghur */ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */ - {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */ +/*{"umb", HB_TAG('U','M','B',' ')},*/ /* Umbundu */ {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */ {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */ {"urk", HB_TAG('M','L','Y',' ')}, /* Urak Lawoi' -> Malay */ @@ -973,16 +973,16 @@ static const LangTag ot_languages[] = { {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek -> Uzbek */ {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek -> Uzbek */ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */ - {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */ +/*{"vec", HB_TAG('V','E','C',' ')},*/ /* Venetian */ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */ {"vkk", HB_TAG('M','L','Y',' ')}, /* Kaur -> Malay */ {"vkt", HB_TAG('M','L','Y',' ')}, /* Tenggarong Kutai Malay -> Malay */ {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams -> Dutch (Flemish) */ {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */ {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */ - {"vro", HB_TAG('V','R','O',' ')}, /* Võro */ +/*{"vro", HB_TAG('V','R','O',' ')},*/ /* Võro */ {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */ - {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) -> Waray-Waray */ +/*{"war", HB_TAG('W','A','R',' ')},*/ /* Waray (Philippines) -> Waray-Waray */ {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ {"wlc", HB_TAG('C','M','R',' ')}, /* Mwali Comorian -> Comorian */ @@ -992,27 +992,27 @@ static const LangTag ot_languages[] = { {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */ {"wry", HB_TAG('M','A','W',' ')}, /* Merwari -> Marwari */ {"wsg", HB_TAG('G','O','N',' ')}, /* Adilabad Gondi -> Gondi */ - {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */ +/*{"wtm", HB_TAG('W','T','M',' ')},*/ /* Mewati */ {"wuu", HB_TAG('Z','H','S',' ')}, /* Wu Chinese -> Chinese Simplified */ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */ {"xal", HB_TAG('T','O','D',' ')}, /* Kalmyk -> Todo */ {"xan", HB_TAG('S','E','K',' ')}, /* Xamtanga -> Sekota */ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */ - {"xjb", HB_TAG('X','J','B',' ')}, /* Minjungbal -> Minjangbal */ - {"xkf", HB_TAG('X','K','F',' ')}, /* Khengkha */ +/*{"xjb", HB_TAG('X','J','B',' ')},*/ /* Minjungbal -> Minjangbal */ +/*{"xkf", HB_TAG('X','K','F',' ')},*/ /* Khengkha */ {"xmm", HB_TAG('M','L','Y',' ')}, /* Manado Malay -> Malay */ {"xmv", HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */ {"xmw", HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */ {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri */ - {"xog", HB_TAG('X','O','G',' ')}, /* Soga */ - {"xpe", HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */ +/*{"xog", HB_TAG('X','O','G',' ')},*/ /* Soga */ +/*{"xpe", HB_TAG('X','P','E',' ')},*/ /* Liberia Kpelle -> Kpelle (Liberia) */ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */ {"xsl", HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */ {"xsl", HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */ - {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */ - {"yap", HB_TAG('Y','A','P',' ')}, /* Yapese */ +/*{"yao", HB_TAG('Y','A','O',' ')},*/ /* Yao */ +/*{"yap", HB_TAG('Y','A','P',' ')},*/ /* Yapese */ {"ybd", HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ {"ydd", HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ @@ -1025,10 +1025,10 @@ static const LangTag ot_languages[] = { {"za", HB_TAG('Z','H','A',' ')}, /* Zhuang [macrolanguage] */ {"zch", HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ {"zdj", HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ - {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws -> Zealandic */ +/*{"zea", HB_TAG('Z','E','A',' ')},*/ /* Zeeuws -> Zealandic */ {"zeh", HB_TAG('Z','H','A',' ')}, /* Eastern Hongshuihe Zhuang -> Zhuang */ {"zgb", HB_TAG('Z','H','A',' ')}, /* Guibei Zhuang -> Zhuang */ - {"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Moroccan Tamazight */ +/*{"zgh", HB_TAG('Z','G','H',' ')},*/ /* Standard Moroccan Tamazight */ {"zgm", HB_TAG('Z','H','A',' ')}, /* Minz Zhuang -> Zhuang */ {"zgn", HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */ {"zh", HB_TAG('Z','H','S',' ')}, /* Chinese [macrolanguage] -> Chinese Simplified */ @@ -1049,7 +1049,7 @@ static const LangTag ot_languages[] = { {"zyg", HB_TAG('Z','H','A',' ')}, /* Yang Zhuang -> Zhuang */ {"zyj", HB_TAG('Z','H','A',' ')}, /* Youjiang Zhuang -> Zhuang */ {"zyn", HB_TAG('Z','H','A',' ')}, /* Yongnan Zhuang -> Zhuang */ - {"zza", HB_TAG('Z','Z','A',' ')}, /* Zazaki [macrolanguage] */ +/*{"zza", HB_TAG('Z','Z','A',' ')},*/ /* Zazaki [macrolanguage] */ {"zzj", HB_TAG('Z','H','A',' ')}, /* Zuojiang Zhuang -> Zhuang */ }; @@ -1932,7 +1932,8 @@ hb_ot_tags_from_complex_language (const char *lang_str, * * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to * many language tags) and the best tag is not the alphabetically first, or if - * the best tag consists of multiple subtags. + * the best tag consists of multiple subtags, or if the best tag does not appear + * in #ot_languages. * * Return value: The #hb_language_t corresponding to the BCP 47 language tag, * or #HB_LANGUAGE_INVALID if @tag is not ambiguous. @@ -1942,6 +1943,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) { switch (tag) { + case HB_TAG('A','L','T',' '): /* Altai */ + return hb_language_from_string ("alt", -1); /* Southern Altai */ case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ return hb_language_from_string ("und-fonnapa", -1); /* Undetermined; North American Phonetic Alphabet */ case HB_TAG('A','R','A',' '): /* Arabic */ @@ -1960,8 +1963,6 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("din", -1); /* Dinka */ case HB_TAG('D','R','I',' '): /* Dari */ return hb_language_from_string ("prs", -1); /* Dari */ - case HB_TAG('D','U','J',' '): /* Dhuwal */ - return hb_language_from_string ("dwu", -1); /* Dhuwal */ case HB_TAG('D','Z','N',' '): /* Dzongkha */ return hb_language_from_string ("dz", -1); /* Dzongkha */ case HB_TAG('E','T','I',' '): /* Estonian */ @@ -1970,6 +1971,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("gon", -1); /* Gondi */ case HB_TAG('H','M','N',' '): /* Hmong */ return hb_language_from_string ("hmn", -1); /* Hmong */ + case HB_TAG('H','N','D',' '): /* Hindko */ + return hb_language_from_string ("hnd", -1); /* Southern Hindko */ case HB_TAG('I','J','O',' '): /* Ijo */ return hb_language_from_string ("ijo", -1); /* Ijo */ case HB_TAG('I','N','U',' '): /* Inuktitut */ diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index c8a57c472..c57c688d4 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -426,17 +426,30 @@ hb_ot_tag_to_language (hb_tag_t tag) if (ot_languages[i].tag == tag) return hb_language_from_string (ot_languages[i].language, -1); - /* Else return a custom language in the form of "x-hbotABCD" */ + /* If it's three letters long, assume it's ISO 639-3 and lower-case and use it + * (if it's not a registered tag, calling hb_ot_tag_from_language on the + * result might not return the same tag as the original tag). + * Else return a custom language in the form of "x-hbotABCD". */ { - unsigned char buf[11] = "x-hbot"; + char buf[11] = "x-hbot"; + char *str = buf; buf[6] = tag >> 24; buf[7] = (tag >> 16) & 0xFF; buf[8] = (tag >> 8) & 0xFF; buf[9] = tag & 0xFF; if (buf[9] == 0x20) + { buf[9] = '\0'; + if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8])) + { + buf[6] = TOLOWER (buf[6]); + buf[7] = TOLOWER (buf[7]); + buf[8] = TOLOWER (buf[8]); + str += 6; + } + } buf[10] = '\0'; - return hb_language_from_string ((char *) buf, -1); + return hb_language_from_string (str, -1); } } diff --git a/test/api/test-ot-tag.c b/test/api/test-ot-tag.c index 60231afe9..66c69caf7 100644 --- a/test/api/test-ot-tag.c +++ b/test/api/test-ot-tag.c @@ -281,6 +281,8 @@ test_ot_tag_language (void) g_assert_cmphex (HB_TAG_CHAR4 ("dflt"), ==, HB_OT_TAG_DEFAULT_LANGUAGE); test_language_two_way ("dflt", NULL); + test_language_two_way ("ALT", "alt"); + test_language_two_way ("ARA", "ar"); test_language_two_way ("AZE", "az"); @@ -353,7 +355,8 @@ test_ot_tag_language (void) test_tag_from_language ("ZHS", "zh"); /* Chinese */ test_tag_from_language ("ZHS", "zh-xx"); - test_language_two_way ("ABC", "x-hbotabc"); + test_language_two_way ("ABC", "abc"); + test_language_two_way ("ABCD", "x-hbotabcd"); test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc"); test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc"); test_tag_from_language ("ABCD", "asdf-asdf-wer-x-hbotabcd"); From c67a0d581fcc50df5563c23060b4fcd9dac4c87c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 10:20:02 -0400 Subject: [PATCH 043/336] Add HB_RETURN --- src/hb-algs.hh | 13 ++++++------- src/hb-meta.hh | 34 ++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 232467e49..93677435b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -50,7 +50,7 @@ struct { private: template auto - impl (const T& v, hb_priority<1>) const HB_AUTO_RETURN (hb_deref_pointer (v).hash ()) + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref_pointer (v).hash ()) template auto @@ -63,7 +63,7 @@ struct public: template auto - operator () (const T& v) const HB_AUTO_RETURN ((uint32_t) impl (v, hb_prioritize)) + operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize)) } HB_FUNCOBJ (hb_hash); struct @@ -114,11 +114,10 @@ struct public: template auto - operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN - ( - (bool) impl (hb_forward (p), - hb_forward (v), - hb_prioritize) + operator () (Pred&& p, Val &&v) const HB_RETURN (bool, + impl (hb_forward (p), + hb_forward (v), + hb_prioritize) ) } HB_FUNCOBJ (hb_has); diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 4a141ce92..0dcf79320 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -34,8 +34,27 @@ * C++ template meta-programming & fundamentals used with them. */ +/* Void! For when we need a expression-type of void. */ +struct hb_void_t { typedef void value; }; + +/* Void meta-function ala std::void_t + * https://en.cppreference.com/w/cpp/types/void_t */ +template struct _hb_void_tt { typedef void type; }; +template using hb_void_tt = typename _hb_void_tt::type; + +template struct _hb_head_tt { typedef Head type; }; +template using hb_head_tt = typename _hb_head_tt::type; + +/* Bool! For when we need to evaluate type-dependent expressions + * in a template argument. */ +template struct hb_bool_tt { enum { value = b }; }; +typedef hb_bool_tt hb_true_t; +typedef hb_bool_tt hb_false_t; + + /* Function overloading SFINAE and priority. */ +#define HB_RETURN(Ret, E) -> hb_head_tt { return (E); } #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); } #define HB_VOID_RETURN(E) -> hb_void_tt { (E); } @@ -45,6 +64,7 @@ template <> struct hb_priority<0> {}; #define HB_FUNCOBJ(x) static_const x HB_UNUSED + struct { template @@ -98,20 +118,6 @@ struct } HB_FUNCOBJ (hb_deref_pointer); -/* Void! For when we need a expression-type of void. */ -struct hb_void_t { typedef void value; }; - -/* Void meta-function ala std::void_t - * https://en.cppreference.com/w/cpp/types/void_t */ -template struct _hb_void_tt { typedef void type; }; -template using hb_void_tt = typename _hb_void_tt::type; - -/* Bool! For when we need to evaluate type-dependent expressions - * in a template argument. */ -template struct hb_bool_tt { enum { value = b }; }; -typedef hb_bool_tt hb_true_t; -typedef hb_bool_tt hb_false_t; - template struct hb_enable_if {}; template struct hb_enable_if { typedef T type; }; #define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr From efbba7ad26dda5930f5d1bd5292304835432f504 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 11:00:08 -0400 Subject: [PATCH 044/336] [serializer] Add copy() Calls obj.copy() or obj.operator=() in that order. --- src/hb-serialize.hh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 0d908bd13..a8fd8d32e 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -358,6 +358,24 @@ struct hb_serialize_context_t memcpy (ret, &obj, size); return ret; } + + template auto + _copy (const Type &obj, hb_priority<1>) const HB_RETURN (Type *, obj.copy (this)) + + template auto + _copy (const Type &obj, hb_priority<0>) const -> decltype (&(obj = obj)) + { + Type *ret = this->allocate_size (sizeof (Type)); + if (unlikely (!ret)) return nullptr; + *ret = obj; + return ret; + } + + /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data + * instead of memcpy(). */ + template + Type *copy (const Type &obj) { return _copy (obj, hb_prioritize); } + template hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } From db0c9a1485ae6ca7ca9af38a43504f1ae4ea09c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 17:58:13 -0400 Subject: [PATCH 045/336] [subset] Assert offsets are zero during relocation If they're not, it's a bug in our subsetting logic somewhere. So check. --- src/hb-serialize.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index a8fd8d32e..971359f40 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -294,12 +294,14 @@ struct hb_serialize_context_t if (link.is_wide) { auto &off = * ((BEInt *) (parent.head + link.position)); + assert (0 == off); off = offset; propagate_error (off == offset); } else { auto &off = * ((BEInt *) (parent.head + link.position)); + assert (0 == off); off = offset; propagate_error (off == offset); } From 693d91cd49fda3e728b59e6885bea8d7b01958ef Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 17:59:39 -0400 Subject: [PATCH 046/336] [serialize] Fix offset calculation --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 971359f40..311eacfe4 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -272,7 +272,7 @@ struct hb_serialize_context_t auto& link = *current->links.push (); link.is_wide = sizeof (T) == 4; - link.position = (const char *) &ofs - (const char *) base; + link.position = (const char *) &ofs - current->head; link.bias = (const char *) base - current->head; link.objidx = objidx; } From 91d958acc08cb99ddd3b656922e13497b9d1595d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 18 Apr 2019 10:04:10 -0400 Subject: [PATCH 047/336] [array] Simplify copy assignment/constructor To fix bogus MSVC warnings: c:\projects\harfbuzz\src\hb-array.hh(189): warning C4521: 'hb_array_t': multiple copy constructors specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj] c:\projects\harfbuzz\src\hb-array.hh(189): warning C4522: 'hb_array_t': multiple assignment operators specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj] --- src/hb-array.hh | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 74b6757b2..ee34dd54d 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -43,20 +43,29 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> * Constructors. */ hb_array_t () : arrayZ (nullptr), length (0) {} - hb_array_t (const hb_array_t &o) : - hb_iter_with_fallback_t, Type&> (), - arrayZ (o.arrayZ), length (o.length) {} - template - hb_array_t (const hb_array_t > &o) : arrayZ (o.arrayZ), length (o.length) {} - hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} - template - hb_array_t& operator = (const hb_array_t > &o) - { arrayZ = o.arrayZ; length = o.length; return *this; } - hb_array_t& operator = (const hb_array_t &o) + template , U) || + hb_is_same (Type, hb_remove_reference) || + hb_is_same (hb_remove_const, hb_remove_reference) + )> + hb_array_t (const hb_array_t &o) : + hb_iter_with_fallback_t, Type&> (), + arrayZ (o.arrayZ), length (o.length) {} + template , U) || + hb_is_same (Type, hb_remove_reference) || + hb_is_same (hb_remove_const, hb_remove_reference) + )> + hb_array_t& operator = (const hb_array_t &o) { arrayZ = o.arrayZ; length = o.length; return *this; } + /* * Iterator implementation. */ From 518e6e07f29d9bb7e532313fb0af6177d8022ea5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 18 Apr 2019 12:21:25 -0400 Subject: [PATCH 048/336] Minor --- src/hb-ot-map.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index ef0bcc716..b943d8493 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -219,7 +219,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, continue; /* Feature disabled, or not enough bits. */ - hb_bool_t found = false; + bool found = false; unsigned int feature_index[2]; for (unsigned int table_index = 0; table_index < 2; table_index++) { From dd4c37529bcecee33d43015a852a3fcf9e978b7f Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 10:38:57 -0700 Subject: [PATCH 049/336] silence MVC warnings --- src/hb-cff-interp-common.hh | 2 +- src/hb-ot-cff1-table.cc | 4 ++-- src/hb-ot-cff2-table.cc | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh index 78ef997b1..c5157c783 100644 --- a/src/hb-cff-interp-common.hh +++ b/src/hb-cff-interp-common.hh @@ -691,7 +691,7 @@ struct opset_t case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1: case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3: - env.argStack.push_int ((int16_t)(-(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108)); + env.argStack.push_int ((-(int16_t)(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108)); env.str_ref.inc (); break; diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 8773c05a2..f62b80e3c 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -165,8 +165,8 @@ struct bounds_t { void init () { - min.set_int (0x7FFFFFFF, 0x7FFFFFFF); - max.set_int (-0x80000000, -0x80000000); + min.set_int ((1<<31)-1, (1<<31)-1); + max.set_int (-(1<<31), -(1<<31)); } void update (const point_t &pt) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 7daa53656..11619d779 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -34,10 +34,10 @@ struct extents_param_t void init () { path_open = false; - min_x.set_int (0x7FFFFFFF); - min_y.set_int (0x7FFFFFFF); - max_x.set_int (-0x80000000); - max_y.set_int (-0x80000000); + min_x.set_int ((1<<31)-1); + min_y.set_int ((1<<31)-1); + max_x.set_int (-(1<<31)); + max_y.set_int (-(1<<31)); } void start_path () { path_open = true; } From 705dde57fe7bd5aafe93f284db2aa809aad932dc Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 11:32:10 -0700 Subject: [PATCH 050/336] silence MVC warnings 2nd attempt --- src/hb-ot-cff1-table.cc | 4 ++-- src/hb-ot-cff2-table.cc | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index f62b80e3c..3b5e5947b 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -165,8 +165,8 @@ struct bounds_t { void init () { - min.set_int ((1<<31)-1, (1<<31)-1); - max.set_int (-(1<<31), -(1<<31)); + min.set_int (2147483647, 2147483647); + max.set_int (-2147483648, -2147483648); } void update (const point_t &pt) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 11619d779..0f8a16df8 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -34,10 +34,10 @@ struct extents_param_t void init () { path_open = false; - min_x.set_int ((1<<31)-1); - min_y.set_int ((1<<31)-1); - max_x.set_int (-(1<<31)); - max_y.set_int (-(1<<31)); + min_x.set_int (2147483647); + min_y.set_int (2147483647); + max_x.set_int (-2147483648); + max_y.set_int (-2147483648); } void start_path () { path_open = true; } From 63a2108480cca2d9c1a2f61d6642d70496f1a5e3 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 13:54:58 -0700 Subject: [PATCH 051/336] silence MVC warnings 3rd attempt --- src/hb-ot-cff1-table.cc | 5 +++-- src/hb-ot-cff2-table.cc | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 3b5e5947b..5132801bf 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -26,6 +26,7 @@ #include "hb-ot-cff1-table.hh" #include "hb-cff1-interp-cs.hh" +#include using namespace CFF; @@ -165,8 +166,8 @@ struct bounds_t { void init () { - min.set_int (2147483647, 2147483647); - max.set_int (-2147483648, -2147483648); + min.set_int (INT_MAX, INT_MAX); + max.set_int (INT_MIN, INT_MIN); } void update (const point_t &pt) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 0f8a16df8..15cdbaa85 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -26,6 +26,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-cff2-interp-cs.hh" +#include using namespace CFF; @@ -34,10 +35,10 @@ struct extents_param_t void init () { path_open = false; - min_x.set_int (2147483647); - min_y.set_int (2147483647); - max_x.set_int (-2147483648); - max_y.set_int (-2147483648); + min_x.set_int (INT_MAX); + min_y.set_int (INT_MAX); + max_x.set_int (INT_MIN); + max_y.set_int (INT_MIN); } void start_path () { path_open = true; } From ba0386060d92dffcde2d14f9e523a46ea8713de2 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 14:53:35 -0700 Subject: [PATCH 052/336] fix oss-fuzz issue 14345 --- src/hb-ot-cff1-table.hh | 3 ++- ...-minimized-hb-subset-fuzzer-5923632099885056 | Bin 0 -> 25847 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 7fbda905e..51cc84694 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -110,7 +110,8 @@ struct Encoding1 { { if (glyph <= ranges[i].nLeft) { - return (hb_codepoint_t)ranges[i].first + glyph; + hb_codepoint_t code = (hb_codepoint_t)ranges[i].first + glyph; + return (likely (code < 0x100)? code: CFF_UNDEF_CODE); } glyph -= (ranges[i].nLeft + 1); } diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 new file mode 100644 index 0000000000000000000000000000000000000000..0a3c6df0ee0073d24d708bbc70d4d8acbba3a354 GIT binary patch literal 25847 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 Date: Thu, 18 Apr 2019 15:17:10 -0700 Subject: [PATCH 053/336] add spaces --- src/hb-ot-cff1-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 51cc84694..f7ec00c34 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -110,8 +110,8 @@ struct Encoding1 { { if (glyph <= ranges[i].nLeft) { - hb_codepoint_t code = (hb_codepoint_t)ranges[i].first + glyph; - return (likely (code < 0x100)? code: CFF_UNDEF_CODE); + hb_codepoint_t code = (hb_codepoint_t) ranges[i].first + glyph; + return (likely (code < 0x100) ? code: CFF_UNDEF_CODE); } glyph -= (ranges[i].nLeft + 1); } From 42f4bd6b801f96fc33a365db8ab6390e74cef05a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 18 Apr 2019 19:04:59 -0400 Subject: [PATCH 054/336] Minor warning fix again --- src/hb-ot-map.cc | 20 ++++++++++---------- test/api/test-ot-face.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index b943d8493..846414c9b 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -226,21 +226,21 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, if (required_feature_tag[table_index] == info->tag) required_feature_stage[table_index] = info->stage[table_index]; - found |= hb_ot_layout_language_find_feature (face, - table_tags[table_index], - script_index[table_index], - language_index[table_index], - info->tag, - &feature_index[table_index]); + found |= (bool) hb_ot_layout_language_find_feature (face, + table_tags[table_index], + script_index[table_index], + language_index[table_index], + info->tag, + &feature_index[table_index]); } if (!found && (info->flags & F_GLOBAL_SEARCH)) { for (unsigned int table_index = 0; table_index < 2; table_index++) { - found |= hb_ot_layout_table_find_feature (face, - table_tags[table_index], - info->tag, - &feature_index[table_index]); + found |= (bool) hb_ot_layout_table_find_feature (face, + table_tags[table_index], + info->tag, + &feature_index[table_index]); } } if (!found && !(info->flags & F_HAS_FALLBACK)) diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c index 9ebcb4e2b..12ac666a4 100644 --- a/test/api/test-ot-face.c +++ b/test/api/test-ot-face.c @@ -111,7 +111,7 @@ test_ot_face_empty (void) } static void -test_ot_var_axis_on_zero_named_instance () +test_ot_var_axis_on_zero_named_instance (void) { hb_face_t *face = hb_test_open_font_file ("fonts/Zycon.ttf"); g_assert (hb_ot_var_get_axis_count (face)); From 694cb1beeefe1c54b2e613d2d566a21e248a2c9c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 19 Apr 2019 07:51:04 -0700 Subject: [PATCH 055/336] Add harfbuzzjs build configuration (#1636) --- CMakeLists.txt | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f64f96d1c..b3133942b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,10 @@ if (HB_CHECK) endif () endif () +# https://github.com/harfbuzz/harfbuzzjs/ +# emcmake cmake -Bwasmbuild -H. -GNinja -DHB_HARFBUZZJS=1 && ninja -Cwasmbuild +option(HB_HARFBUZZJS "Enable our opinionated harfbuzzjs related build optimization" OFF) + include_directories(AFTER ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src @@ -295,6 +299,16 @@ if (HB_HAVE_GRAPHITE2) mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY) endif () +if (HB_HARFBUZZJS) + # we won't need multithread support in harfbuzzjs + add_definitions(-DHB_NO_MT) + + add_definitions(-DHB_NO_OPTIONS -DHB_NO_OT_FONT_CFF -DHB_NO_NAME_TABLE_AAT + -DHB_NO_OT_FONT_BITMAP -DHB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK + -DHB_NO_OT_SHAPE_FALLBACK -DHB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK + -DHB_NO_OT_LAYOUT_BLACKLIST -DHB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS) +endif () + if (HB_BUILTIN_UCDN) include_directories(src/hb-ucdn) add_definitions(-DHAVE_UCDN) @@ -538,6 +552,27 @@ endif () add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) +if (HB_HARFBUZZJS) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s MODULARIZE=1 \ + -s NO_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 -s STRICT=1 \ + -Oz --closure 1") + + # add_definitions("-DHB_EXTERN=__attribute__((used))") + # Alternatively, only the needed calls + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s \"EXPORTED_FUNCTIONS=['_hb_version_string', \ + '_malloc', '_hb_blob_create', '_hb_face_create', '_hb_font_create', \ + '_hb_buffer_create', '_hb_buffer_add_utf8', '_hb_buffer_guess_segment_properties', \ + '_hb_buffer_set_direction', '_hb_shape', '_hb_buffer_serialize_glyphs', \ + '_hb_buffer_get_length', '_hb_buffer_serialize_glyphs', '_hb_buffer_destroy', \ + '_hb_font_destroy', '_hb_face_destroy', '_hb_blob_destroy', '_hb_blob_get_length', \ + '_hb_direction_from_string', '_free']\"") + + # Trick emscripten to create js/wasm from a library + add_executable(harfbuzzjs /dev/null) + + target_link_libraries(harfbuzzjs harfbuzz) +endif () + ## Define harfbuzz-subset library if (HB_BUILD_SUBSET) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) From a464cbeecea73aeaa03c262f49fed8584057d9bb Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 19 Apr 2019 12:14:09 -0700 Subject: [PATCH 056/336] Revert "Add harfbuzzjs build configuration (#1636)" (#1675) This reverts commit 694cb1beeefe1c54b2e613d2d566a21e248a2c9c. --- CMakeLists.txt | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3133942b..f64f96d1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,10 +85,6 @@ if (HB_CHECK) endif () endif () -# https://github.com/harfbuzz/harfbuzzjs/ -# emcmake cmake -Bwasmbuild -H. -GNinja -DHB_HARFBUZZJS=1 && ninja -Cwasmbuild -option(HB_HARFBUZZJS "Enable our opinionated harfbuzzjs related build optimization" OFF) - include_directories(AFTER ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src @@ -299,16 +295,6 @@ if (HB_HAVE_GRAPHITE2) mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY) endif () -if (HB_HARFBUZZJS) - # we won't need multithread support in harfbuzzjs - add_definitions(-DHB_NO_MT) - - add_definitions(-DHB_NO_OPTIONS -DHB_NO_OT_FONT_CFF -DHB_NO_NAME_TABLE_AAT - -DHB_NO_OT_FONT_BITMAP -DHB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK - -DHB_NO_OT_SHAPE_FALLBACK -DHB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK - -DHB_NO_OT_LAYOUT_BLACKLIST -DHB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS) -endif () - if (HB_BUILTIN_UCDN) include_directories(src/hb-ucdn) add_definitions(-DHAVE_UCDN) @@ -552,27 +538,6 @@ endif () add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) -if (HB_HARFBUZZJS) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s MODULARIZE=1 \ - -s NO_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 -s STRICT=1 \ - -Oz --closure 1") - - # add_definitions("-DHB_EXTERN=__attribute__((used))") - # Alternatively, only the needed calls - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s \"EXPORTED_FUNCTIONS=['_hb_version_string', \ - '_malloc', '_hb_blob_create', '_hb_face_create', '_hb_font_create', \ - '_hb_buffer_create', '_hb_buffer_add_utf8', '_hb_buffer_guess_segment_properties', \ - '_hb_buffer_set_direction', '_hb_shape', '_hb_buffer_serialize_glyphs', \ - '_hb_buffer_get_length', '_hb_buffer_serialize_glyphs', '_hb_buffer_destroy', \ - '_hb_font_destroy', '_hb_face_destroy', '_hb_blob_destroy', '_hb_blob_get_length', \ - '_hb_direction_from_string', '_free']\"") - - # Trick emscripten to create js/wasm from a library - add_executable(harfbuzzjs /dev/null) - - target_link_libraries(harfbuzzjs harfbuzz) -endif () - ## Define harfbuzz-subset library if (HB_BUILD_SUBSET) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) From 8ed7655be89c658219ab702e34a79734ba0efb73 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 21 Apr 2019 12:25:19 -0400 Subject: [PATCH 057/336] Update AUTHORS / COPYING --- AUTHORS | 3 +++ COPYING | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 0763761bb..83c0c66f9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,11 +1,14 @@ Behdad Esfahbod +David Corbett David Turner Ebrahim Byagowi +Garret Rieger Jonathan Kew Khaled Hosny Lars Knoll Martin Hosken Owen Taylor +Roderick Sheeter Roozbeh Pournader Simon Hausmann Werner Lemberg diff --git a/COPYING b/COPYING index 9d1056f40..0278e60a5 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,8 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. For parts of HarfBuzz that are licensed under different licenses see individual files names COPYING in subdirectories where applicable. -Copyright © 2010,2011,2012 Google, Inc. +Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019 Google, Inc. +Copyright © 2019 Facebook, Inc. Copyright © 2012 Mozilla Foundation Copyright © 2011 Codethink Limited Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies) From ecac94ca763e80d217ba5db429745e8882b38464 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 21 Apr 2019 12:27:32 -0400 Subject: [PATCH 058/336] [docs] Remove fdo repo Has not been updated. --- docs/harfbuzz-docs.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index f4ad134ea..e48d17593 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -20,11 +20,7 @@ The canonical source-code tree is available at - github.com/harfbuzz/harfbuzz - and is also available at - cgit.freedesktop.org/harfbuzz. + github.com/harfbuzz/harfbuzz. See for release tarballs. From 9bab398462fa598047f34fd6d23e07a91305b1b3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:16:35 -0400 Subject: [PATCH 059/336] Simplify propagate_error() --- src/hb-serialize.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 311eacfe4..612a26a1e 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -120,12 +120,12 @@ struct hb_serialize_context_t this->packed.push (nullptr); } - bool propagate_error (bool e) - { return this->successful = this->successful && e; } - template bool propagate_error (const T &obj) - { return this->successful = this->successful && !obj.in_error (); } - template bool propagate_error (const T *obj) - { return this->successful = this->successful && !obj->in_error (); } + bool propagate_error (bool success) + { return this->successful = this->successful && success; } + + template bool propagate_error (T &&obj) + { return propagate_error (!hb_deref_pointer (obj).in_error ()); } + template bool propagate_error (T1 &&o1, T2 &&o2) { return propagate_error (o1) && propagate_error (o2); } template From 24da1d08603a7fe262ae88d687986efc0343956f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:20:25 -0400 Subject: [PATCH 060/336] Use variadic template args for propagate_error() Let's see if bots happy. Not sure where else we can use these. Mm. Maybe in hb_invoke(). --- src/hb-serialize.hh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 612a26a1e..12b615349 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -126,11 +126,8 @@ struct hb_serialize_context_t template bool propagate_error (T &&obj) { return propagate_error (!hb_deref_pointer (obj).in_error ()); } - template bool propagate_error (T1 &&o1, T2 &&o2) - { return propagate_error (o1) && propagate_error (o2); } - template - bool propagate_error (T1 &&o1, T2 &&o2, T3 &&o3) - { return propagate_error (o1) && propagate_error (o2, o3); } + template bool propagate_error (T1 &&o1, Ts &&...os) + { return propagate_error (o1) && propagate_error (os...); } /* To be called around main operation. */ template From ae8da4b61b4cc3b55242b85fe7c63393d65bd6cf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:25:11 -0400 Subject: [PATCH 061/336] Minor --- src/hb-iter.hh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a4ffbd6f0..46d6c406b 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -209,13 +209,16 @@ template struct hb_is_iterable { private: + template - static auto test (int) -> decltype (hb_declval (U).iter (), hb_true_t ()); + static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_t ()); + template - static hb_false_t test (...); + static hb_false_t impl (hb_priority<0>); public: - enum { value = decltype (test (0))::value }; + + enum { value = decltype (impl (hb_prioritize))::value }; }; #define hb_is_iterable(Iterable) hb_is_iterable::value From 9c724e48a2f5d61c31c79f0b4660f08e5d07db10 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:37:10 -0400 Subject: [PATCH 062/336] [serializer] Add err_propagaged_error() --- src/hb-serialize.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 12b615349..b831ea626 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -121,7 +121,7 @@ struct hb_serialize_context_t } bool propagate_error (bool success) - { return this->successful = this->successful && success; } + { return this->successful && (success || (err_propagated_error (), false)); } template bool propagate_error (T &&obj) { return propagate_error (!hb_deref_pointer (obj).in_error ()); } @@ -322,8 +322,11 @@ struct hb_serialize_context_t return ret; } + /* Following two functions exist to allow setting breakpoint on. */ void err_ran_out_of_room () { this->ran_out_of_room = true; } + void + err_propagated_error () { this->successful = false; } template Type *allocate_size (unsigned int size) From c862a532df0bc3ce0b47f3fde9bf1dd300ff8bee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 17:32:19 -0400 Subject: [PATCH 063/336] Add variadic arguments to hb_invoke() --- src/hb-algs.hh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 93677435b..779d3b70f 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -71,28 +71,28 @@ struct private: /* Pointer-to-member-function. */ - template auto - impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v)).*a ()) + template auto + impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN + (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs...))) /* Pointer-to-member. */ template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN + impl (Appl&& a, hb_priority<1>, Val &&v) const HB_AUTO_RETURN (hb_forward (hb_deref_pointer (v)).*a) /* Operator(). */ - template auto - impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN - (hb_deref_pointer (a) (hb_forward (v))) + template auto + impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN + (hb_deref_pointer (a) (hb_forward (vs...))) public: - template auto - operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN + template auto + operator () (Appl&& a, Vals &&...vs) const HB_AUTO_RETURN ( impl (hb_forward (a), - hb_forward (v), - hb_prioritize) + hb_prioritize, + hb_forward (vs...)) ) } HB_FUNCOBJ (hb_invoke); From 25dd88efc6521b972babe1067c0de1b9d4f5dbe5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 17:45:23 -0400 Subject: [PATCH 064/336] Err, fix hb_invoke() variadic --- src/hb-algs.hh | 6 +++--- src/test-iter.cc | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 779d3b70f..e54c6b434 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,7 +73,7 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs...))) + (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs)...)) /* Pointer-to-member. */ template auto @@ -83,7 +83,7 @@ struct /* Operator(). */ template auto impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (a) (hb_forward (vs...))) + (hb_deref_pointer (a) (hb_forward (vs)...)) public: @@ -92,7 +92,7 @@ struct ( impl (hb_forward (a), hb_prioritize, - hb_forward (vs...)) + hb_forward (vs)...) ) } HB_FUNCOBJ (hb_invoke); diff --git a/src/test-iter.cc b/src/test-iter.cc index 675bbe397..93a48526d 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -181,7 +181,7 @@ main (int argc, char **argv) ; /* The result should be something like 0->10, 1->11, ..., 9->19 */ assert (hb_map_get (result, 9) == 19); - + unsigned int temp3 = 0; + hb_iter(src) | hb_map([&] (int i) -> int { return ++temp3; }) @@ -197,5 +197,8 @@ main (int argc, char **argv) long vl; s >> vl; + if (0) + hb_invoke (main, 0, nullptr); + return 0; } From 7c218351ab45c41e48147b2196393357f7b551d4 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 23 Apr 2019 12:40:29 +0430 Subject: [PATCH 065/336] .editorconfig, minor still doesn't work with vscode --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 499147351..4850f2bf6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ insert_final_newline = true [*.{c,cc,h,hh}] tab_width = 8 indent_size = 2 -indent_style = space +indent_style = tab # should be space [*.{py,sh}] indent_style = tab From 64ca2ffa4c88b961dcbd9d06be8ac7dd80ad8182 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 23 Apr 2019 01:10:46 -0700 Subject: [PATCH 066/336] Fix clang's -Wmain complain (#1678) --- src/test-iter.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 93a48526d..cf1e6d670 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -99,6 +99,12 @@ test_iterable (const Iterable &lst = Null(Iterable)) test_iterator (lst.iter ()); } +static char * +test_func (int a, char **b) +{ + return b[a]; +} + int main (int argc, char **argv) { @@ -198,7 +204,7 @@ main (int argc, char **argv) s >> vl; if (0) - hb_invoke (main, 0, nullptr); + hb_invoke (test_func, 0, nullptr); return 0; } From 98c54cdef8b0615a95382bdba4ecd008789f8c9e Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 23 Apr 2019 17:48:42 +0100 Subject: [PATCH 067/336] Usermanual: add chapter on object model. --- docs/harfbuzz-docs.xml | 1 + docs/usermanual-object-model.xml | 249 +++++++++++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100644 docs/usermanual-object-model.xml diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index f4ad134ea..63863350e 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -37,6 +37,7 @@ + diff --git a/docs/usermanual-object-model.xml b/docs/usermanual-object-model.xml new file mode 100644 index 000000000..f0b76ce91 --- /dev/null +++ b/docs/usermanual-object-model.xml @@ -0,0 +1,249 @@ + + + +]> + + The HarfBuzz object model +

+ An overview of data types in HarfBuzz + + HarfBuzz features two kinds of data types: non-opaque, + pass-by-value types and opaque, heap-allocated types. This kind + of separation is common in C libraries that have to provide + API/ABI compatibility (almost) indefinitely. + + + Value types: The non-opaque, pass-by-value + types include integer types, enums, and small structs. Exposing + a struct in the public API makes it impossible to expand the + struct in the future. As such, exposing structs is reserved for + cases where it’s extremely inefficient to do otherwise. + + + In HarfBuzz, several structs, like hb_glyph_info_t and + hb_glyph_position_t, fall into that efficiency-sensitive + category and are non-opaque. + + + For all non-opaque structs where future extensibility may be + necessary, reserved members are included to hold space for + possible future members. As such, it’s important to provide + equal(), and hash() + methods for such structs, allowing users of the API do + effectively deal with the type without having to + adapt their code to future changes. + + + Important value types provided by HarfBuzz include the structs + for working with Unicode code points, glyphs, and tags for font + tables and features, as well as the enums for many Unicode and + OpenType properties. + +
+ +
+ Objects in HarfBuzz + + Object types: Opaque struct types are used + for what HarfBuzz loosely calls "objects." This doesn’t have + much to do with the terminology from object-oriented programming + (OOP), although some of the concepts are similar. + + + In HarfBuzz, all object types provide certain + lifecycle-management APIs. Objects are reference-counted, and + constructed with various create() methods, referenced via + reference() and dereferenced using + destroy(). + + + For example, + the hb_buffer_t object has + hb_buffer_create() as its constructor, + hb_buffer_reference() to reference, and + hb_buffer_destroy() to dereference. + + + After construction, each object's properties are accessible only + through the setter and getter functions described in the API + Reference manual. + + + Key object types provided by HarfBuzz include: + + + + + blobs, which act as low-level wrappers around binary + data. Blobs are typically used to hold the contents of a + binary font file. + + + + + faces, which represent typefaces from a + font file, but without specific parameters (such as size) set. + + + + + fonts, which represent instances of a + face will all of their parameters specified. + + + + + buffers, which hold Unicode code points + for characters (before shaping) and the shaped glyph output + (after shaping). + + + + + shape plans, which store the settings + that HarfBuzz will use when shaping a particular text segment. + + + + +
+ + + +
+ Object lifecycle management + + Each object type in HarfBuzz provides a + create() method. Some object types provide + additional variants of create() to handle + special cases or to speed up common tasks; those variants are + documented in the API reference. For example, + hb_blob_create_from_file() constructs a new + blob directly from the contents of a file. + + + Client programs can increase the reference count on an object by + calling its reference() method. Whenever a + client program is finished with an object, it should call its + corresponding destroy() method. The destroy + method will decrease the reference count on the object and, + whenever the reference count reaches zero, it will also destroy + the object and free all of the associated memory. + + + All of HarfBuzz's object-lifecycle-management APIs are + thread-safe, even when the object as a whole is not thread-safe . + It is also permissible to reference() or to + destroy() the NULL + value. + + + Some objects are thread-safe after they have been constructed + and set up. The general pattern is to + create() the object, make a few + set_*() calls to set up the + object, and then use it without further modification. + + + To ensure that such an object is not modified, client programs + can explicitly mark an object as immutable. HarfBuzz provides + make_immutable() methods to mark an object + as immutable and is_immutable() methods to + test whether or not an object is immutable. Attempts to use + setter functions on immutable objects will fail; see the API + Reference manual for specifics. + + + Note also that there are no "make mutable" methods. If client + programs need to alter an object previously marked as immutable, + they will need to make a duplicate of the original. + + + Finally, object constructors (and, indeed, as much of the API as + possible) will never return NULL. Instead, + if there is an allocation error, each constructor will + return an “empty” object singleton. + + + These empty-object singletons are inert and safe (although + typically useless) to pass around. This design choice avoids + having to check for NULL pointers all + throughout the code. + + + In addition, this “empty” object singleton can also be accessed + using the get_empty() method of the object + type in question. + +
+ + +
+ User data + + To better integrate with client programs, HarfBuzz's objects + offer a "user data" mechanism that can be used to attach + arbitrary data to the object. User-data attachment can be + useful for tying the lifecycles of various pieces of data + together, or for creating language bindings. + + + Each object type has a set_user_data() + method and a get_user_data() method. The + set_user_data() methods take a client-provided + key and a pointer, + user_data, pointing to the data itself. Once + the key-data pair has been attached to the object, the + get_user_data() method can be called with + the key, returning the user_data pointer. + + + The set_user_data() methods also support an + optional destroy callback. Client programs + can set the destroy callback and receive + notification from HarfBuzz whenever the object is destructed. + + + Finally, each set_user_data() method allows + the client program to set a replace Boolean + indicating whether or not the user_data + associated with a key ought to be replaceable. + +
+ + + +
+ Blobs + + While most of HarfBuzz's object types are specific to the + shaping process, blobs are somewhat + different. + + + Blobs are an abstraction desgined to negotiate lifecycle and + permissions for raw pieces of data. For example, when you load + the raw font data into memory and want to pass it to HarfBuzz, + you do so in a hb_blob_t wrapper. + + + This allows you to take advantage of HarffBuzz's + reference-counting and destroy + callbacks. If you allocated the memory for the data using + malloc(), you would create the blob using + + + hb_blob_create (data, length, HB_MEMORY_MODE_WRITABLE, NULL, free) + + + That way, HarfBuzz will call free() on the + allocated memory whenever the blob drops its last reference and + is deconstructed. Consequently, the user code can stop worrying + about freeing memory and let the reference-counting machinery + take care of that. + +
+ + From aa6692cb0079bbe1e003f211a321e8fe6a18ea94 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 23 Apr 2019 17:56:44 +0100 Subject: [PATCH 068/336] Usermanual: update Makefile SGML list. Again. --- docs/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Makefile.am b/docs/Makefile.am index 9b54b40e1..7020273df 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -76,6 +76,7 @@ content_files= \ usermanual-install-harfbuzz.xml \ usermanual-getting-started.xml \ usermanual-shaping-concepts.xml \ + usermanual-object-model.xml \ usermanual-buffers-language-script-and-direction.xml \ usermanual-fonts-and-faces.xml \ usermanual-clusters.xml \ From 20f3134789f65b10f301c4635c9f80c2dda0fb97 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2019 12:58:52 -0400 Subject: [PATCH 069/336] Use variadic templates in OffsetTo<> and various ArrayOf<>s --- src/hb-open-type.hh | 145 +++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 96 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 23f7511b1..f4e7cd6d0 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -284,8 +284,8 @@ struct OffsetTo : Offset return * (Type *) Offset::serialize (c, base); } - template - bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base) + template + bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts ...ds) { *this = 0; if (has_null && &src == &Null (T)) @@ -295,7 +295,7 @@ struct OffsetTo : Offset s->push (); - bool ret = src.subset (c); + bool ret = src.subset (c, ds...); if (ret || !has_null) s->add_link (*this, s->pop_pack (), base); @@ -314,39 +314,13 @@ struct OffsetTo : Offset return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && (this->is_null () || - StructAtOffset (base, *this).sanitize (c) || - neuter (c))); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const - { - TRACE_SANITIZE (this); - return_trace (sanitize_shallow (c, base) && - (this->is_null () || - StructAtOffset (base, *this).sanitize (c, d1) || - neuter (c))); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const - { - TRACE_SANITIZE (this); - return_trace (sanitize_shallow (c, base) && - (this->is_null () || - StructAtOffset (base, *this).sanitize (c, d1, d2) || - neuter (c))); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const - { - TRACE_SANITIZE (this); - return_trace (sanitize_shallow (c, base) && - (this->is_null () || - StructAtOffset (base, *this).sanitize (c, d1, d2, d3) || + StructAtOffset (base, *this).sanitize (c, ds...) || neuter (c))); } @@ -430,29 +404,26 @@ struct UnsizedArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && arrayZ[0].sanitize (c)); + if (false) + { + arrayZ[0].sanitize (c); + Type v; + v = arrayZ[0]; + } return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } @@ -492,17 +463,12 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf return this+*p; } - - bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + template + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts ...ds) const { TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf::sanitize (c, count, this))); - } - template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const - { - TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf::sanitize (c, count, this, user_data))); + return_trace ((UnsizedOffsetArrayOf + ::sanitize (c, count, this, ds...))); } }; @@ -622,24 +588,14 @@ struct ArrayOf return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } @@ -706,16 +662,11 @@ struct OffsetListOf : OffsetArrayOf return_trace (true); } - bool sanitize (hb_sanitize_context_t *c) const + template + bool sanitize (hb_sanitize_context_t *c, Ts ...ds) const { TRACE_SANITIZE (this); - return_trace (OffsetArrayOf::sanitize (c, this)); - } - template - bool sanitize (hb_sanitize_context_t *c, T user_data) const - { - TRACE_SANITIZE (this); - return_trace (OffsetArrayOf::sanitize (c, this, user_data)); + return_trace (OffsetArrayOf::sanitize (c, this, ds...)); } }; @@ -763,10 +714,16 @@ struct HeadlessArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && arrayZ[0].sanitize (c)); + if (false) + { + arrayZ[0].sanitize (c); + Type v; + v = arrayZ[0]; + } return_trace (true); } @@ -807,14 +764,14 @@ struct ArrayOfM1 unsigned int get_size () const { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } @@ -999,31 +956,27 @@ struct VarSizedBinSearchArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && StructAtOffset (&bytesZ, 0).sanitize (c)); + if (false) + { + (*this)[0].sanitize (c); + Type v; + v = (*this)[0]; + } return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = get_length (); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base, user_data))) + if (unlikely (!(*this)[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } From 441cca235477a5399af214c9ac85320d4de69f0b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2019 23:49:21 -0400 Subject: [PATCH 070/336] Use hb_forward() when forwarding parameter pack --- src/hb-open-type.hh | 32 ++++++++++++++++---------------- src/hb-serialize.hh | 3 ++- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index f4e7cd6d0..d165f475f 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -285,7 +285,7 @@ struct OffsetTo : Offset } template - bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts ...ds) + bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts &&...ds) { *this = 0; if (has_null && &src == &Null (T)) @@ -295,7 +295,7 @@ struct OffsetTo : Offset s->push (); - bool ret = src.subset (c, ds...); + bool ret = src.subset (c, hb_forward (ds)...); if (ret || !has_null) s->add_link (*this, s->pop_pack (), base); @@ -315,12 +315,12 @@ struct OffsetTo : Offset } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && (this->is_null () || - StructAtOffset (base, *this).sanitize (c, ds...) || + StructAtOffset (base, *this).sanitize (c, hb_forward (ds)...) || neuter (c))); } @@ -418,12 +418,12 @@ struct UnsizedArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) + if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -464,11 +464,11 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts &&...ds) const { TRACE_SANITIZE (this); return_trace ((UnsizedOffsetArrayOf - ::sanitize (c, count, this, ds...))); + ::sanitize (c, count, this, hb_forward (ds)...))); } }; @@ -589,13 +589,13 @@ struct ArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) + if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -663,10 +663,10 @@ struct OffsetListOf : OffsetArrayOf } template - bool sanitize (hb_sanitize_context_t *c, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); - return_trace (OffsetArrayOf::sanitize (c, this, ds...)); + return_trace (OffsetArrayOf::sanitize (c, this, hb_forward (ds)...)); } }; @@ -765,13 +765,13 @@ struct ArrayOfM1 { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) + if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -970,13 +970,13 @@ struct VarSizedBinSearchArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base, ds...))) + if (unlikely (!(*this)[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index b831ea626..cab444e26 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -127,7 +127,8 @@ struct hb_serialize_context_t { return propagate_error (!hb_deref_pointer (obj).in_error ()); } template bool propagate_error (T1 &&o1, Ts &&...os) - { return propagate_error (o1) && propagate_error (os...); } + { return propagate_error (hb_forward (o1)) && + propagate_error (hb_forward (os)...); } /* To be called around main operation. */ template From 175bdad8bff5b0e9732ab1fb97617a9293680fd4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2019 23:57:11 -0400 Subject: [PATCH 071/336] One more variadic parameter pack use --- src/hb-aat-layout-common.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 2508276c2..7c74d7938 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -153,13 +153,13 @@ struct LookupSegmentArray first <= last && valuesZ.sanitize (c, base, last - first + 1)); } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T2 user_data) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && first <= last && - valuesZ.sanitize (c, base, last - first + 1, user_data)); + valuesZ.sanitize (c, base, last - first + 1, hb_forward (ds)...)); } GlyphID last; /* Last GlyphID in this segment */ From 3ad20c38ade76aca8aed024014977ecb5f2b636e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:09:00 -0400 Subject: [PATCH 072/336] [serialize] Fix a few overflow TODO items --- src/hb-open-type.hh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index d165f475f..56c87b385 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -182,7 +182,8 @@ struct Offset : Type void *serialize (hb_serialize_context_t *c, const void *base) { void *t = c->start_embed (); - *this = (char *) t - (char *) base; /* TODO(serialize) Overflow? */ + unsigned int offset = (char *) t - (char *) base; + c->propagate_error ((*this = offset) == offset); return t; } @@ -548,7 +549,7 @@ struct ArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - len = items_len; /* TODO(serialize) Overflow? */ + c->propagate_error ((len = items_len) == items_len); if (unlikely (!c->extend (*this))) return_trace (false); return_trace (true); } @@ -698,7 +699,7 @@ struct HeadlessArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - lenP1 = items.length + 1; /* TODO(serialize) Overflow? */ + c->propagate_error ((lenP1 = items.length + 1) == items.length + 1); if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items.length; i++) arrayZ[i] = items[i]; From 27377a7e287dd39e3f7caad5c1e0691ae381ccf8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:22:14 -0400 Subject: [PATCH 073/336] Rely on variadic parameter pack more --- 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 56c87b385..d8cd3edb2 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -419,12 +419,12 @@ struct UnsizedArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -590,13 +590,13 @@ struct ArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -766,13 +766,13 @@ struct ArrayOfM1 { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -971,13 +971,13 @@ struct VarSizedBinSearchArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!(*this)[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } From 12017db0bfe62e7777e1ab6ba5b14729dcd4c351 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:24:38 -0400 Subject: [PATCH 074/336] Move test code around --- src/test-algs.cc | 8 ++++++++ src/test-iter.cc | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/test-algs.cc b/src/test-algs.cc index 42a9538dc..8ec93f009 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -28,6 +28,12 @@ #include "hb-algs.hh" +static char * +test_func (int a, char **b) +{ + return b ? b[a] : nullptr; +} + int main (int argc, char **argv) { @@ -46,5 +52,7 @@ main (int argc, char **argv) q.second = 4; assert (i == 4); + hb_invoke (test_func, 0, nullptr); + return 0; } diff --git a/src/test-iter.cc b/src/test-iter.cc index cf1e6d670..9ce8b0ca2 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -99,12 +99,6 @@ test_iterable (const Iterable &lst = Null(Iterable)) test_iterator (lst.iter ()); } -static char * -test_func (int a, char **b) -{ - return b[a]; -} - int main (int argc, char **argv) { @@ -203,8 +197,5 @@ main (int argc, char **argv) long vl; s >> vl; - if (0) - hb_invoke (test_func, 0, nullptr); - return 0; } From 11ab889a8d743304c8ec17920e209a514f46739d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:55:24 -0400 Subject: [PATCH 075/336] Rename a few test programs --- src/Makefile.am | 24 +++++++++---------- ...ize-params.cc => test-gpos-size-params.cc} | 0 ...itute.cc => test-gsub-would-substitute.cc} | 0 src/{test-name-table.cc => test-ot-name.cc} | 0 4 files changed, 12 insertions(+), 12 deletions(-) rename src/{test-size-params.cc => test-gpos-size-params.cc} (100%) rename src/{test-would-substitute.cc => test-gsub-would-substitute.cc} (100%) rename src/{test-name-table.cc => test-ot-name.cc} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 66a3b3177..9b5512f20 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -310,9 +310,9 @@ noinst_PROGRAMS = \ main \ test \ test-buffer-serialize \ - test-name-table \ - test-size-params \ - test-would-substitute \ + test-ot-name \ + test-gpos-size-params \ + test-gsub-would-substitute \ $(NULL) bin_PROGRAMS = @@ -328,17 +328,17 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) -test_name_table_SOURCES = test-name-table.cc -test_name_table_CPPFLAGS = $(HBCFLAGS) -test_name_table_LDADD = libharfbuzz.la $(HBLIBS) +test_ot_name_SOURCES = test-ot-name.cc +test_ot_name_CPPFLAGS = $(HBCFLAGS) +test_ot_name_LDADD = libharfbuzz.la $(HBLIBS) -test_size_params_SOURCES = test-size-params.cc -test_size_params_CPPFLAGS = $(HBCFLAGS) -test_size_params_LDADD = libharfbuzz.la $(HBLIBS) +test_gpos_size_params_SOURCES = test-gpos-size-params.cc +test_gpos_size_params_CPPFLAGS = $(HBCFLAGS) +test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS) -test_would_substitute_SOURCES = test-would-substitute.cc -test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) -test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) +test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc +test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) +test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) if HAVE_FREETYPE if HAVE_CAIRO_FT diff --git a/src/test-size-params.cc b/src/test-gpos-size-params.cc similarity index 100% rename from src/test-size-params.cc rename to src/test-gpos-size-params.cc diff --git a/src/test-would-substitute.cc b/src/test-gsub-would-substitute.cc similarity index 100% rename from src/test-would-substitute.cc rename to src/test-gsub-would-substitute.cc diff --git a/src/test-name-table.cc b/src/test-ot-name.cc similarity index 100% rename from src/test-name-table.cc rename to src/test-ot-name.cc From 00a00bc1f23c681d64fbd4df33582ec0165e337a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:01:30 -0400 Subject: [PATCH 076/336] Fix two TODOs --- src/hb-ot-layout-gsub-table.hh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index e664e06f4..a08f21fb7 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -90,7 +90,7 @@ struct SingleSubstFormat1 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); - deltaGlyphID = delta; /* TODO(serialize) overflow? */ + c->propagate_error ((deltaGlyphID = delta) == delta); return_trace (true); } @@ -231,15 +231,14 @@ struct SingleSubst { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 2; - int delta = 0; + unsigned format = 2; + unsigned delta = 0; if (glyphs.length) { format = 1; - /* TODO(serialize) check for wrap-around */ - delta = substitutes[0] - glyphs[0]; + delta = (unsigned) (substitutes[0] - glyphs[0]) & 0xFFFF; for (unsigned int i = 1; i < glyphs.length; i++) - if (delta != (int) (substitutes[i] - glyphs[i])) { + if (delta != ((unsigned) (substitutes[i] - glyphs[i]) & 0xFFFF)) { format = 2; break; } From 915b9ea5f48d56df21419761477b2d4ba2843b54 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:07:19 -0400 Subject: [PATCH 077/336] [serialize] Add c->check_assign() To check for assignment overflows. --- src/hb-open-type.hh | 7 +++---- src/hb-ot-layout-gsub-table.hh | 2 +- src/hb-serialize.hh | 20 +++++++++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index d8cd3edb2..b232fdbc1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -182,8 +182,7 @@ struct Offset : Type void *serialize (hb_serialize_context_t *c, const void *base) { void *t = c->start_embed (); - unsigned int offset = (char *) t - (char *) base; - c->propagate_error ((*this = offset) == offset); + c->check_assign (*this, (char *) t - (char *) base); return t; } @@ -549,7 +548,7 @@ struct ArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - c->propagate_error ((len = items_len) == items_len); + c->check_assign (len, items_len); if (unlikely (!c->extend (*this))) return_trace (false); return_trace (true); } @@ -699,7 +698,7 @@ struct HeadlessArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - c->propagate_error ((lenP1 = items.length + 1) == items.length + 1); + c->check_assign (lenP1, items.length + 1); if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items.length; i++) arrayZ[i] = items[i]; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index a08f21fb7..8574eb5c8 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -90,7 +90,7 @@ struct SingleSubstFormat1 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); - c->propagate_error ((deltaGlyphID = delta) == delta); + c->check_assign (deltaGlyphID, delta); return_trace (true); } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index cab444e26..7e2d2f7b9 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -120,11 +120,19 @@ struct hb_serialize_context_t this->packed.push (nullptr); } - bool propagate_error (bool success) + bool check_success (bool success) { return this->successful && (success || (err_propagated_error (), false)); } + template + bool check_equal (T1 &&v1, T2 &&v2) + { return check_success (v1 == v2); } + + template + bool check_assign (T1 &v1, T2 &&v2) + { return check_equal (v1 = v2, v2); } + template bool propagate_error (T &&obj) - { return propagate_error (!hb_deref_pointer (obj).in_error ()); } + { return check_success (!hb_deref_pointer (obj).in_error ()); } template bool propagate_error (T1 &&o1, Ts &&...os) { return propagate_error (hb_forward (o1)) && @@ -170,7 +178,7 @@ struct hb_serialize_context_t { object_t *obj = object_pool.alloc (); if (unlikely (!obj)) - propagate_error (false); + check_success (false); else { obj->head = head; @@ -293,15 +301,13 @@ struct hb_serialize_context_t { auto &off = * ((BEInt *) (parent.head + link.position)); assert (0 == off); - off = offset; - propagate_error (off == offset); + check_assign (off, offset); } else { auto &off = * ((BEInt *) (parent.head + link.position)); assert (0 == off); - off = offset; - propagate_error (off == offset); + check_assign (off, offset); } } } From 085793d6cd35a1590a66712f39260030367490db Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:15:59 -0400 Subject: [PATCH 078/336] Remove wrong TODOs --- src/hb-ot-layout-gsubgpos.hh | 2 +- src/hb-ot-shape-complex-indic.cc | 1 - src/hb-ot-shape-complex-khmer.cc | 4 ++-- src/hb-ot-shape-complex-myanmar.cc | 3 ++- src/hb-ot-shape-complex-use.cc | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 2e9165be2..840c142ab 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -286,7 +286,7 @@ struct hb_ot_apply_context_t : }; may_match_t may_match (const hb_glyph_info_t &info, - const HBUINT16 *glyph_data) const + const HBUINT16 *glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 1fd8fc670..6d46fe33c 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -1008,7 +1008,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ginfo.cluster = buffer->cur().cluster; ginfo.mask = buffer->cur().mask; ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && buffer->successful && diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 5746651d6..4c8847762 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -368,7 +368,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -407,7 +408,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ginfo.cluster = buffer->cur().cluster; ginfo.mask = buffer->cur().mask; ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && buffer->successful && diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 70ab972c6..b1f6b65ef 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -301,7 +301,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index eecde6e85..ec4d4aa7e 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -526,7 +526,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -560,7 +561,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ginfo.cluster = buffer->cur().cluster; ginfo.mask = buffer->cur().mask; ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && buffer->successful && From 6cc9707c9c0885a3133b7844f615cdcdaeccec18 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:22:06 -0400 Subject: [PATCH 079/336] [serialize] Rename --- src/hb-serialize.hh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 7e2d2f7b9..7566881a8 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -121,7 +121,7 @@ struct hb_serialize_context_t } bool check_success (bool success) - { return this->successful && (success || (err_propagated_error (), false)); } + { return this->successful && (success || (err_other_error (), false)); } template bool check_equal (T1 &&v1, T2 &&v2) @@ -330,10 +330,8 @@ struct hb_serialize_context_t } /* Following two functions exist to allow setting breakpoint on. */ - void - err_ran_out_of_room () { this->ran_out_of_room = true; } - void - err_propagated_error () { this->successful = false; } + void err_ran_out_of_room () { this->ran_out_of_room = true; } + void err_other_error () { this->successful = false; } template Type *allocate_size (unsigned int size) From 42526d1697e2449fa23741f84721dcf2ce688af7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:24:33 -0400 Subject: [PATCH 080/336] [serialize] Fix SingleSubstFormat1 failure --- src/hb-ot-layout-gsub-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 8574eb5c8..10c35e32c 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -85,7 +85,7 @@ struct SingleSubstFormat1 bool serialize (hb_serialize_context_t *c, hb_sorted_array_t glyphs, - int delta) + unsigned delta) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -127,8 +127,8 @@ struct SingleSubstFormat1 OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBINT16 deltaGlyphID; /* Add to original GlyphID to get - * substitute GlyphID */ + HBUINT16 deltaGlyphID; /* Add to original GlyphID to get + * substitute GlyphID, modulo 0x10000 */ public: DEFINE_SIZE_STATIC (6); }; From 8f79a5750e8982f9ab73c0dc6a8534dffef74610 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:32:49 -0400 Subject: [PATCH 081/336] [algs] Add more hb_forward<>()'s --- src/hb-algs.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index e54c6b434..3f627c108 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,17 +73,17 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs)...)) + (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) /* Pointer-to-member. */ template auto impl (Appl&& a, hb_priority<1>, Val &&v) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v)).*a) + ((hb_deref_pointer (hb_forward (v))).*hb_forward (a)) /* Operator(). */ template auto impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (a) (hb_forward (vs)...)) + (hb_deref_pointer (hb_forward (a)) (hb_forward (vs)...)) public: @@ -102,7 +102,7 @@ struct template auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref_pointer (p).has (v)) + (hb_deref_pointer (hb_forward (p)).has (v)) template auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN @@ -127,7 +127,7 @@ struct template auto impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref_pointer (f).get (hb_forward (v))) + (hb_deref_pointer (hb_forward (f)).get (hb_forward (v))) template auto impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN From 0268db11965d022883d5ef2ef828c0635165b7bd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:43:40 -0400 Subject: [PATCH 082/336] [map] Use hb_invoke() with pointer-to-method --- src/hb-algs.hh | 5 ++++- src/hb-map.hh | 4 ++-- src/test-algs.cc | 8 ++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 3f627c108..c3467800b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,7 +73,7 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) + ((hb_deref_pointer (hb_forward (v1)).*hb_forward (a)) (hb_forward (vs)...)) /* Pointer-to-member. */ template auto @@ -86,6 +86,9 @@ struct (hb_deref_pointer (hb_forward (a)) (hb_forward (vs)...)) public: + template auto + impl2 (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN + (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) template auto operator () (Appl&& a, Vals &&...vs) const HB_AUTO_RETURN diff --git a/src/hb-map.hh b/src/hb-map.hh index b99fb8f4b..9ffa83a8a 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -122,7 +122,7 @@ struct hb_hashmap_t return false; } + hb_iter (new_items, new_size) - | hb_apply ([] (item_t &_) { _.clear (); }) /* TODO make pointer-to-methods invokable. */ + | hb_apply (&item_t::clear) ; unsigned int old_size = mask + 1; @@ -193,7 +193,7 @@ struct hb_hashmap_t return; if (items) + hb_iter (items, mask + 1) - | hb_apply ([] (item_t &_) { _.clear (); }) /* TODO make pointer-to-methods invokable. */ + | hb_apply (&item_t::clear) ; population = occupancy = 0; diff --git a/src/test-algs.cc b/src/test-algs.cc index 8ec93f009..163a79ad3 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -34,6 +34,11 @@ test_func (int a, char **b) return b ? b[a] : nullptr; } +struct A +{ + void a () {} +}; + int main (int argc, char **argv) { @@ -54,5 +59,8 @@ main (int argc, char **argv) hb_invoke (test_func, 0, nullptr); + A a; + hb_invoke (&A::a, a); + return 0; } From 4c6136e976af4f7332f703f5a7625505ffc296b6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:44:24 -0400 Subject: [PATCH 083/336] [mutex] Remove TODO --- src/hb-mutex.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-mutex.hh b/src/hb-mutex.hh index 35f1fded1..a760e7317 100644 --- a/src/hb-mutex.hh +++ b/src/hb-mutex.hh @@ -127,8 +127,6 @@ typedef int hb_mutex_impl_t; struct hb_mutex_t { - /* TODO Add tracing. */ - hb_mutex_impl_t m; void init () { hb_mutex_impl_init (&m); } From 22da12318a3e9fd9955f24fd0092de1a4a1a940d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:53:16 -0400 Subject: [PATCH 084/336] [map] Fix TODO --- src/hb-map.hh | 6 ++---- src/hb-meta.hh | 6 ++++++ src/hb-ot-cff1-table.cc | 1 - src/hb-ot-cff2-table.cc | 1 - src/hb.hh | 3 +-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 9ffa83a8a..bbb1bef5d 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -34,11 +34,9 @@ * hb_hashmap_t */ -/* TODO if K/V is signed integer, -1 is not a good default. - * Don't know how to get to -MAX using bit work. */ template + K kINVALID = hb_is_pointer (K) ? 0 : hb_is_signed (K) ? hb_int_min (K) : (K) -1, + V vINVALID = hb_is_pointer (V) ? 0 : hb_is_signed (V) ? hb_int_min (V) : (V) -1> struct hb_hashmap_t { HB_DELETE_COPY_ASSIGN (hb_hashmap_t); diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 0dcf79320..bb67b03a8 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -138,6 +138,12 @@ template <> struct hb_is_signed { enum { value = false }; }; template <> struct hb_is_signed { enum { value = false }; }; #define hb_is_signed(T) hb_is_signed::value +template struct hb_int_min { static constexpr T value = 0; }; +template <> struct hb_int_min { static constexpr char value = CHAR_MIN; }; +template <> struct hb_int_min { static constexpr int value = INT_MIN; }; +template <> struct hb_int_min { static constexpr long value = LONG_MIN; }; +#define hb_int_min(T) hb_int_min::value + template struct hb_signedness_int; template <> struct hb_signedness_int { typedef unsigned int value; }; template <> struct hb_signedness_int { typedef signed int value; }; diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 5132801bf..1d97e5444 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -26,7 +26,6 @@ #include "hb-ot-cff1-table.hh" #include "hb-cff1-interp-cs.hh" -#include using namespace CFF; diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 15cdbaa85..d2463d785 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -26,7 +26,6 @@ #include "hb-ot-cff2-table.hh" #include "hb-cff2-interp-cs.hh" -#include using namespace CFF; diff --git a/src/hb.hh b/src/hb.hh index ee35c4dd9..0336ed568 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -167,8 +167,7 @@ #include "hb-aat.h" #define HB_AAT_H_IN -#include "hb-aat.h" - +#include #include #include #include From 714307cc437f375f128e17e5ab01eba0c57aaf01 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:56:12 -0400 Subject: [PATCH 085/336] [iter] Remove fixed TODO --- src/hb-iter.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 46d6c406b..2cab2dcd1 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -129,8 +129,6 @@ struct hb_iter_t #define hb_iter_t(Iterable) decltype (hb_declval (Iterable).iter ()) -/* TODO Change to function-object. */ - template struct hb_array_t; struct @@ -225,7 +223,6 @@ struct hb_is_iterable /* TODO Add hb_is_iterable_of(). * TODO Add random_access / sorted variants. */ - /* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ template From 59a8fa53533b10b9c25458d9ba2d68b7b01c3ff0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 12:19:13 -0400 Subject: [PATCH 086/336] [iter] Add tests for casting to hb_iter_t<> base class for hb_sorted_array_t<> Something's phishy about hb_sorted_array_t<>. Can't get it work nicely with change I'm making. Ugh.. --- src/test-iter.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 9ce8b0ca2..3de340145 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -91,7 +91,7 @@ test_iterator (Iter it) } template + hb_enable_if (hb_is_iterable (Iterable))> static void test_iterable (const Iterable &lst = Null(Iterable)) { @@ -127,6 +127,11 @@ main (int argc, char **argv) hb_set_t st; test_iterable (st); hb_sorted_array_t sa; + (void) static_cast, hb_sorted_array_t::item_t>&> (sa); + (void) static_cast, hb_sorted_array_t::__item_t__>&> (sa); + (void) static_cast, int&>&>(sa); + (void) static_cast>&>(sa); + (void) static_cast, int&>&> (sa); test_iterable (sa); test_iterable > (); From 0ca358f21a2a6e86a3d5c145a70bb84ab6e2db32 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 16:36:29 -0400 Subject: [PATCH 087/336] Try fixing cmake build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f64f96d1c..4ef0a2f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -844,7 +844,7 @@ endif () if (HB_BUILD_TESTS) ## src/ executables - foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) + foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges test-ot-name) set (prog_name ${prog}) if (${prog_name} STREQUAL "test") # test can not be used as a valid executable name on cmake, lets special case it From f2d20dd9d3b52f434f5fe9dbef82bd95eb499edf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 15:08:27 -0700 Subject: [PATCH 088/336] [THANKS] Add Ivan Kuckir https://github.com/harfbuzz/harfbuzz/issues/1633#issuecomment-485764140 --- THANKS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/THANKS b/THANKS index 940cfde5c..88cb7e9ea 100644 --- a/THANKS +++ b/THANKS @@ -1,6 +1,6 @@ Bradley Grainger -Khaled Hosny Kenichi Ishibashi +Ivan Kuckir Ryan Lortie Jeff Muizelaar suzuki toshiya From c69f02784ac53a7fd13eee559559b38d8224ef59 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 16:31:37 -0700 Subject: [PATCH 089/336] Fix sign-compare error on 32-bit systems --- src/hb-open-type.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index b232fdbc1..041b9843f 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -182,7 +182,7 @@ struct Offset : Type void *serialize (hb_serialize_context_t *c, const void *base) { void *t = c->start_embed (); - c->check_assign (*this, (char *) t - (char *) base); + c->check_assign (*this, (unsigned) ((char *) t - (char *) base)); return t; } From 3fc066314ac19005ea8157a6541412cfd24abbc2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 16:41:57 -0700 Subject: [PATCH 090/336] Another try at fixing cmake build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ef0a2f79..a8d12c163 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -844,7 +844,7 @@ endif () if (HB_BUILD_TESTS) ## src/ executables - foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges test-ot-name) + foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) set (prog_name ${prog}) if (${prog_name} STREQUAL "test") # test can not be used as a valid executable name on cmake, lets special case it From 474f3587cd18fdaf86b2068647fa03b107557d8c Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Fri, 26 Apr 2019 10:12:38 -0700 Subject: [PATCH 091/336] copy retain_gids from input to plan --- src/hb-subset-plan.cc | 1 + src/hb-subset-plan.hh | 1 + 2 files changed, 2 insertions(+) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 8b7231494..6e32ed774 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -204,6 +204,7 @@ hb_subset_plan_create (hb_face_t *face, plan->drop_hints = input->drop_hints; plan->drop_layout = input->drop_layout; plan->desubroutinize = input->desubroutinize; + plan->retain_gids = input->retain_gids; plan->unicodes = hb_set_create(); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 56726d4d0..afaeff4e8 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -42,6 +42,7 @@ struct hb_subset_plan_t bool drop_hints : 1; bool drop_layout : 1; bool desubroutinize : 1; + bool retain_gids : 1; // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; From 52bb0346d319c322f117567a096fafa1bc804e26 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 12:52:28 -0700 Subject: [PATCH 092/336] [meta] Add hb_decay<> --- src/hb-meta.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index bb67b03a8..73f965f86 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -96,6 +96,8 @@ template struct hb_match_pointer { typedef T type; enum { valu template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value +template using hb_decay = hb_remove_const>; + /* std::move and std::forward */ From 8ecae793aa79056a312d3c8518106cfeca42390e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 12:57:56 -0700 Subject: [PATCH 093/336] [meta] Add hb_is_cr_convertible_to() --- src/hb-meta.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 73f965f86..005420364 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -98,6 +98,11 @@ template using hb_remove_pointer = typename hb_match_pointer::ty template using hb_decay = hb_remove_const>; +#define hb_is_cr_convertible_to(A, B) ( \ + hb_is_same (hb_decay, hb_decay) && \ + hb_is_const (A) <= hb_is_const (B) && \ + hb_is_reference (A) >= hb_is_reference (B)) + /* std::move and std::forward */ From b2758c360cc08d7a0334aae11845d0c5d50c46af Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 12:58:06 -0700 Subject: [PATCH 094/336] [array] Use hb_is_cr_convertible_to() --- src/hb-array.hh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index ee34dd54d..7a781bea3 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -47,22 +47,12 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} template , U) || - hb_is_same (Type, hb_remove_reference) || - hb_is_same (hb_remove_const, hb_remove_reference) - )> + hb_enable_if (hb_is_cr_convertible_to(U, Type))> hb_array_t (const hb_array_t &o) : hb_iter_with_fallback_t, Type&> (), arrayZ (o.arrayZ), length (o.length) {} template , U) || - hb_is_same (Type, hb_remove_reference) || - hb_is_same (hb_remove_const, hb_remove_reference) - )> + hb_enable_if (hb_is_cr_convertible_to(U, Type))> hb_array_t& operator = (const hb_array_t &o) { arrayZ = o.arrayZ; length = o.length; return *this; } From c51f15ddfcae8578483693b761b81ceaebf05f2a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 13:03:41 -0700 Subject: [PATCH 095/336] [array] Adjust hb_sorted_array_t copy constructor/assignment to match hb_array_t --- src/hb-array.hh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 7a781bea3..b4619ee9a 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -211,12 +211,19 @@ struct hb_sorted_array_t : static constexpr bool is_sorted_iterator = true; hb_sorted_array_t () : hb_array_t () {} - hb_sorted_array_t (const hb_array_t &o) : hb_array_t (o) {} - template - hb_sorted_array_t (const hb_sorted_array_t > &o) : hb_array_t (o) {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t (array_, length_) {} template hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} + template + hb_sorted_array_t (const hb_array_t &o) : + hb_iter_t, Type&> (), + hb_array_t (o) {} + template + hb_sorted_array_t& operator = (const hb_array_t &o) + { hb_array_t (*this) = o; return *this; } + 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)); } hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const From 73c82f2301a52cf2111296b34691bc898a7a6363 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 13:16:48 -0700 Subject: [PATCH 096/336] [iter] Fix hb_is_iterator_of() to actually check item type --- src/hb-iter.hh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2cab2dcd1..f0947282d 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -225,19 +225,17 @@ struct hb_is_iterable /* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ -template -struct _hb_is_iterator_of -{ - char operator () (...) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - static_assert (sizeof (char) != sizeof (int), ""); -}; +template +static inline char _hb_is_iterator_of (hb_priority<0>, const void *) { return 0; } +template +static inline int _hb_is_iterator_of (hb_priority<2>, hb_iter_t *) { return 0; } + template struct hb_is_iterator_of { enum { - value = sizeof (int) == sizeof (hb_declval (_hb_is_iterator_of) (hb_declval (Iter*))) }; }; + value = sizeof (int) == sizeof (_hb_is_iterator_of (hb_prioritize, hb_declval (Iter*))) }; }; #define hb_is_iterator_of(Iter, Item) hb_is_iterator_of::value #define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) From 3a7f5bdd18314676425ec811199767a5f8e65a40 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 14:40:01 -0700 Subject: [PATCH 097/336] Rewrite hb_is_signed() --- src/hb-meta.hh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 005420364..c3efe48a6 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -134,15 +134,17 @@ template struct hb_is_same : hb_true_t {}; #define hb_is_same(T, T2) hb_is_same::value template struct hb_is_signed; -/* https://github.com/harfbuzz/harfbuzz/issues/1535 */ -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = CHAR_MIN < 0 }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; #define hb_is_signed(T) hb_is_signed::value template struct hb_int_min { static constexpr T value = 0; }; From 408c1daeb4ff86d2204ed1bdd059513357ada392 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Fri, 29 Mar 2019 10:34:32 -0700 Subject: [PATCH 098/336] [subset] subset name table step 1, write out table unmodified, use accelerator to access string --- src/hb-ot-name-table.hh | 53 +++++++++++++++++++++++++++++++++++++++++ src/hb-subset.cc | 4 ++++ 2 files changed, 57 insertions(+) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index fca509149..bacd5a8e6 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -158,6 +158,59 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } + size_t get_subsetted_size(const name *source_name, hb_subset_plan_t *plan, hb_set_t *name_record_ids_to_retain) const + { + size_t result = min_size; + result += count * NameRecord::static_size; + + hb_face_t *face = plan->source; + accelerator_t acc; + acc.init (face); + + for(unsigned int i = 0; iadd(i); + } + } + + acc.fini(); + + return result; + } + + void serialize(void *dest, const void *source, size_t dest_size) const + { + memcpy(dest, source, dest_size); + } + + bool subset(hb_subset_plan_t *plan) const + { + hb_set_t *name_record_ids_to_retain = hb_set_create(); + size_t dest_size = get_subsetted_size(this, plan, name_record_ids_to_retain); + name *dest = (name *) malloc (dest_size); + if(unlikely (!dest)) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for name subset output.", + (unsigned long) dest_size); + return false; + } + + serialize(dest, this, dest_size); + hb_set_destroy(name_record_ids_to_retain); + + hb_blob_t *name_prime_blob = hb_blob_create((const char *) dest, + dest_size, + HB_MEMORY_MODE_READONLY, + dest, + free); + bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); + hb_blob_destroy (name_prime_blob); + + return result; + } bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-subset.cc b/src/hb-subset.cc index bccb98d62..333e7d484 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -43,6 +43,7 @@ #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" +#include "hb-ot-name-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" @@ -158,6 +159,9 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_hdmx: result = _subset (plan); break; + case HB_OT_TAG_name: + result = _subset (plan); + break; case HB_OT_TAG_head: // TODO that won't work well if there is no glyf DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf"); From 2637a81615c80443911a603cbd161ade525c79f1 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 2 Apr 2019 13:38:27 -0700 Subject: [PATCH 099/336] [subset] subset name table step 2, add implementation for collecting subset elements and serialize method --- src/hb-ot-name-table.hh | 131 +++++++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 22 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index bacd5a8e6..a387e6e38 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -95,6 +95,28 @@ struct NameRecord return UNSUPPORTED; } + bool serialize (hb_serialize_context_t *c, const NameRecord& origin_namerecord, unsigned int *new_offset) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->allocate_size (NameRecord::static_size))) + { + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for NameRecord: %d.", + NameRecord::static_size); + return_trace (false); + } + + this->platformID.set (origin_namerecord.platformID); + this->encodingID.set (origin_namerecord.encodingID); + this->languageID.set (origin_namerecord.languageID); + this->nameID.set (origin_namerecord.nameID); + this->length.set (origin_namerecord.length); + this->offset.set (*new_offset); + *new_offset += origin_namerecord.length; + + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -158,59 +180,124 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } - size_t get_subsetted_size(const name *source_name, hb_subset_plan_t *plan, hb_set_t *name_record_ids_to_retain) const + size_t get_subsetted_size (const name *source_name, + const hb_subset_plan_t *plan, + hb_vector_t& name_record_idx_to_retain) const { size_t result = min_size; - result += count * NameRecord::static_size; hb_face_t *face = plan->source; accelerator_t acc; acc.init (face); - for(unsigned int i = 0; iadd(i); - } + if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25) + continue; + result += acc.get_name (i).get_size (); + name_record_idx_to_retain.push (i); } - acc.fini(); + acc.fini (); + + result += name_record_idx_to_retain.length * NameRecord::static_size; return result; } - void serialize(void *dest, const void *source, size_t dest_size) const + bool serialize (hb_serialize_context_t *c, + const name *source_name, + const hb_subset_plan_t *plan, + const hb_vector_t& name_record_idx_to_retain) { - memcpy(dest, source, dest_size); + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + this->format.set (source_name->format); + this->count.set (name_record_idx_to_retain.length); + this->stringOffset.set (min_size + name_record_idx_to_retain.length * NameRecord::static_size); + + //write new NameRecord + unsigned int new_offset = 0; + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + if (unlikely (idx >= source_name->count)) + { + DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); + return_trace (false); + } + + const NameRecord &namerec = source_name->nameRecordZ[idx]; + + if (!c->start_embed ()->serialize (c, namerec, &new_offset)) + return_trace (false); + } + + hb_face_t *face = plan->source; + accelerator_t acc; + acc.init (face); + + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + unsigned int size = acc.get_name (idx).get_size (); + char *new_pos = c->allocate_size (size); + + if (unlikely (new_pos == nullptr)) + { + acc.fini (); + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %d.", + size); + return_trace (false); + } + + unsigned int origin_offset = source_name->stringOffset + source_name->nameRecordZ[idx].offset; + + memcpy (new_pos, source_name + origin_offset, size); + } + + acc.fini (); + + return_trace (true); } - bool subset(hb_subset_plan_t *plan) const + bool subset (hb_subset_plan_t *plan) const { - hb_set_t *name_record_ids_to_retain = hb_set_create(); - size_t dest_size = get_subsetted_size(this, plan, name_record_ids_to_retain); + hb_vector_t name_record_idx_to_retain; + + size_t dest_size = get_subsetted_size (this, plan, name_record_idx_to_retain); name *dest = (name *) malloc (dest_size); if(unlikely (!dest)) { - DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for name subset output.", + DEBUG_MSG (SUBSET, nullptr, "Unable to alloc %lu for name subset output.", (unsigned long) dest_size); return false; } - serialize(dest, this, dest_size); - hb_set_destroy(name_record_ids_to_retain); + hb_serialize_context_t c (dest, dest_size); + name *name_prime = c.start_serialize (); + if (!name_prime || !name_prime->serialize (&c, this, plan, name_record_idx_to_retain)) + { + free (dest); + DEBUG_MSG (SUBSET, nullptr, "Failed to serialize write new name."); + c.end_serialize (); + return false; + } + c.end_serialize (); - hb_blob_t *name_prime_blob = hb_blob_create((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); + hb_blob_t *name_prime_blob = hb_blob_create ((const char *) dest, + dest_size, + HB_MEMORY_MODE_READONLY, + dest, + free); bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); hb_blob_destroy (name_prime_blob); return result; } + bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); From e501ea143d1e63974903cdb41932c50f4222ff4e Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Fri, 5 Apr 2019 10:05:55 -0700 Subject: [PATCH 100/336] [subset] Subset name table step 3, add --nameids option to guide the selection of which name records to keep in the subset method. --- src/hb-ot-name-table.hh | 28 ++++++++++++++----------- src/hb-subset-input.cc | 8 ++++++++ src/hb-subset-input.hh | 3 ++- src/hb-subset-plan.cc | 10 +++++---- src/hb-subset-plan.hh | 3 +++ src/hb-subset.h | 3 +++ util/hb-subset.cc | 1 + util/options.cc | 45 +++++++++++++++++++++++++++++++++++++++++ util/options.hh | 8 ++++++++ 9 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index a387e6e38..cdb8dba54 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -106,12 +106,12 @@ struct NameRecord return_trace (false); } - this->platformID.set (origin_namerecord.platformID); - this->encodingID.set (origin_namerecord.encodingID); - this->languageID.set (origin_namerecord.languageID); - this->nameID.set (origin_namerecord.nameID); - this->length.set (origin_namerecord.length); - this->offset.set (*new_offset); + this->platformID = origin_namerecord.platformID; + this->encodingID = origin_namerecord.encodingID; + this->languageID = origin_namerecord.languageID; + this->nameID = origin_namerecord.nameID; + this->length = origin_namerecord.length; + this->offset = *new_offset; *new_offset += origin_namerecord.length; return_trace (true); @@ -194,6 +194,9 @@ struct name { if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25) continue; + if (!hb_set_is_empty (plan->name_ids) && + !hb_set_has (plan->name_ids, source_name->nameRecordZ[i].nameID)) + continue; result += acc.get_name (i).get_size (); name_record_idx_to_retain.push (i); } @@ -214,9 +217,9 @@ struct name if (unlikely (!c->extend_min ((*this)))) return_trace (false); - this->format.set (source_name->format); - this->count.set (name_record_idx_to_retain.length); - this->stringOffset.set (min_size + name_record_idx_to_retain.length * NameRecord::static_size); + this->format = source_name->format; + this->count = name_record_idx_to_retain.length; + this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; //write new NameRecord unsigned int new_offset = 0; @@ -253,9 +256,10 @@ struct name return_trace (false); } - unsigned int origin_offset = source_name->stringOffset + source_name->nameRecordZ[idx].offset; - - memcpy (new_pos, source_name + origin_offset, size); + const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; + unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; + + memcpy (new_pos, source_string_pool + name_record_offset, size); } acc.fini (); diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc index 4d203b545..b3b27d427 100644 --- a/src/hb-subset-input.cc +++ b/src/hb-subset-input.cc @@ -44,6 +44,7 @@ hb_subset_input_create_or_fail () input->unicodes = hb_set_create (); input->glyphs = hb_set_create (); + input->name_ids = hb_set_create (); input->drop_hints = false; input->drop_layout = true; input->desubroutinize = false; @@ -81,6 +82,7 @@ hb_subset_input_destroy (hb_subset_input_t *subset_input) hb_set_destroy (subset_input->unicodes); hb_set_destroy (subset_input->glyphs); + hb_set_destroy (subset_input->name_ids); free (subset_input); } @@ -109,6 +111,12 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input) return subset_input->glyphs; } +HB_EXTERN hb_set_t * +hb_subset_input_nameid_set (hb_subset_input_t *subset_input) +{ + return subset_input->name_ids; +} + HB_EXTERN void hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, hb_bool_t drop_hints) diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh index 04d6e121b..d01fecee0 100644 --- a/src/hb-subset-input.hh +++ b/src/hb-subset-input.hh @@ -40,6 +40,7 @@ struct hb_subset_input_t hb_set_t *unicodes; hb_set_t *glyphs; + hb_set_t *name_ids; bool drop_hints : 1; bool drop_layout : 1; @@ -49,7 +50,7 @@ struct hb_subset_input_t * * features * lookups - * nameIDs + * name_ids * ... */ }; diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 6e32ed774..fe636b190 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -205,12 +205,13 @@ hb_subset_plan_create (hb_face_t *face, plan->drop_layout = input->drop_layout; plan->desubroutinize = input->desubroutinize; plan->retain_gids = input->retain_gids; - plan->unicodes = hb_set_create(); + plan->unicodes = hb_set_create (); + plan->name_ids = hb_set_reference (input->name_ids); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); - plan->codepoint_to_glyph = hb_map_create(); - plan->glyph_map = hb_map_create(); - plan->reverse_glyph_map = hb_map_create(); + plan->codepoint_to_glyph = hb_map_create (); + plan->glyph_map = hb_map_create (); + plan->reverse_glyph_map = hb_map_create (); plan->_glyphset = _populate_gids_to_retain (face, input->unicodes, input->glyphs, @@ -239,6 +240,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (!hb_object_destroy (plan)) return; hb_set_destroy (plan->unicodes); + hb_set_destroy (plan->name_ids); hb_face_destroy (plan->source); hb_face_destroy (plan->dest); hb_map_destroy (plan->codepoint_to_glyph); diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index afaeff4e8..abbab5e22 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -47,6 +47,9 @@ struct hb_subset_plan_t // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; + //name_ids we would like to retain + hb_set_t *name_ids; + // The glyph subset hb_map_t *codepoint_to_glyph; diff --git a/src/hb-subset.h b/src/hb-subset.h index 657709ec8..50345061c 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -54,6 +54,9 @@ hb_subset_input_unicode_set (hb_subset_input_t *subset_input); HB_EXTERN hb_set_t * hb_subset_input_glyph_set (hb_subset_input_t *subset_input); +HB_EXTERN hb_set_t * +hb_subset_input_nameid_set (hb_subset_input_t *subset_input); + HB_EXTERN void hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, hb_bool_t drop_hints); diff --git a/util/hb-subset.cc b/util/hb-subset.cc index 33e584b75..682ca4c34 100644 --- a/util/hb-subset.cc +++ b/util/hb-subset.cc @@ -93,6 +93,7 @@ struct subset_consumer_t hb_subset_input_set_drop_hints (input, subset_options.drop_hints); hb_subset_input_set_retain_gids (input, subset_options.retain_gids); hb_subset_input_set_desubroutinize (input, subset_options.desubroutinize); + hb_set_set (hb_subset_input_nameid_set (input), subset_options.name_ids); hb_face_t *face = hb_font_get_face (font); diff --git a/util/options.cc b/util/options.cc index c5a4f0f0b..a9b3fc77e 100644 --- a/util/options.cc +++ b/util/options.cc @@ -971,6 +971,49 @@ format_options_t::serialize_buffer_of_glyphs (hb_buffer_t *buffer, g_string_append_c (gs, '\n'); } +static gboolean +parse_nameids (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + subset_options_t *subset_opts = (subset_options_t *) data; + + hb_set_t *name_ids = hb_set_create (); + char *s = (char *) arg; + char *p; + + while (s && *s) + { + while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t\v\f\r ", *s)) + s++; + if (!*s) + break; + + errno = 0; + hb_codepoint_t u = strtoul (s, &p, 10); + if (errno || s == p) + { + hb_set_destroy (name_ids); + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Failed parsing nameID values at: '%s'", s); + return false; + } + + hb_set_add (name_ids, u); + + s = p; + } + + hb_set_t *prev = subset_opts->name_ids; + subset_opts->name_ids = hb_set_reference (name_ids); + hb_set_destroy (prev); + hb_set_destroy (name_ids); + + return true; +} + + void subset_options_t::add_options (option_parser_t *parser) { @@ -980,6 +1023,7 @@ subset_options_t::add_options (option_parser_t *parser) {"no-hinting", 0, 0, G_OPTION_ARG_NONE, &this->drop_hints, "Whether to drop hints", nullptr}, {"retain-gids", 0, 0, G_OPTION_ARG_NONE, &this->retain_gids, "If set don't renumber glyph ids in the subset.", nullptr}, {"desubroutinize", 0, 0, G_OPTION_ARG_NONE, &this->desubroutinize, "Remove CFF/CFF2 use of subroutines", nullptr}, + {"name-IDs", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_nameids, "Subset specified nameids", "list of int numbers"}, {nullptr} }; @@ -989,3 +1033,4 @@ subset_options_t::add_options (option_parser_t *parser) "Options subsetting", this); } + diff --git a/util/options.hh b/util/options.hh index 84139f55c..2691e2269 100644 --- a/util/options.hh +++ b/util/options.hh @@ -677,16 +677,24 @@ struct subset_options_t : option_group_t drop_hints = false; retain_gids = false; desubroutinize = false; + name_ids = hb_set_create (); add_options (parser); } + virtual ~subset_options_t () + { + hb_set_destroy (name_ids); + } + + void add_options (option_parser_t *parser); hb_bool_t keep_layout; hb_bool_t drop_hints; hb_bool_t retain_gids; hb_bool_t desubroutinize; + hb_set_t *name_ids; }; /* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */ From 6faac8df83bb59f08e5d329e76435ba438b2ea54 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Wed, 10 Apr 2019 16:38:35 -0700 Subject: [PATCH 101/336] [subset] Subsetting Name Table Step 4 Add unit test and integration test --- test/api/Makefile.am | 2 + test/api/fonts/nameID.expected.ttf | Bin 0 -> 170696 bytes test/api/fonts/nameID.origin.ttf | Bin 0 -> 170976 bytes test/api/hb-subset-test.h | 9 +++ test/api/test-subset-nameids.c | 58 ++++++++++++++++++ .../Roboto-Regular.abc.name-ids.61,62,63.ttf | Bin 0 -> 2168 bytes .../Roboto-Regular.abc.name-ids.61,63.ttf | Bin 0 -> 1988 bytes .../basics/Roboto-Regular.abc.name-ids.61.ttf | Bin 0 -> 1792 bytes .../basics/Roboto-Regular.abc.name-ids.62.ttf | Bin 0 -> 1740 bytes .../basics/Roboto-Regular.abc.name-ids.63.ttf | Bin 0 -> 1716 bytes test/subset/data/profiles/name-ids.txt | 1 + test/subset/data/tests/basics.tests | 1 + 12 files changed, 71 insertions(+) create mode 100644 test/api/fonts/nameID.expected.ttf create mode 100644 test/api/fonts/nameID.origin.ttf create mode 100644 test/api/test-subset-nameids.c create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,63.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.63.ttf create mode 100644 test/subset/data/profiles/name-ids.txt diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 67d66e16d..9d7b3198c 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -52,6 +52,7 @@ TEST_PROGS = \ test-subset-cff2 \ test-unicode \ test-version \ + test-subset-nameids \ $(NULL) test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la @@ -64,6 +65,7 @@ test_subset_post_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_vmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cff1_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cff2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la +test_subset_nameids_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_unicode_CPPFLAGS = \ $(AM_CPPFLAGS) \ diff --git a/test/api/fonts/nameID.expected.ttf b/test/api/fonts/nameID.expected.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ccd4b8bcd26816e7ffcd6afa58306373bc0534d9 GIT binary patch literal 170696 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%0Dkep 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 literal 0 HcmV?d00001 diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h index 3e759a8a9..8f32aee67 100644 --- a/test/api/hb-subset-test.h +++ b/test/api/hb-subset-test.h @@ -65,6 +65,15 @@ hb_subset_test_create_input_from_glyphs (const hb_set_t *glyphs) return input; } +static inline hb_subset_input_t * +hb_subset_test_create_input_from_nameids (const hb_set_t *name_ids) +{ + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t * input_name_ids = hb_subset_input_nameid_set (input); + hb_set_union (input_name_ids, name_ids); + return input; +} + static inline hb_face_t * hb_subset_test_create_subset (hb_face_t *source, hb_subset_input_t *input) diff --git a/test/api/test-subset-nameids.c b/test/api/test-subset-nameids.c new file mode 100644 index 000000000..0057a7b75 --- /dev/null +++ b/test/api/test-subset-nameids.c @@ -0,0 +1,58 @@ +/* + * 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. + * + * Google Author(s): Garret Rieger + */ + +#include "hb-test.h" +#include "hb-subset-test.h" + +static void +test_subset_nameids (void) +{ + hb_face_t *face_origin = hb_test_open_font_file ("fonts/nameID.origin.ttf"); + hb_face_t *face_expected = hb_test_open_font_file ("fonts/nameID.expected.ttf"); + + hb_set_t *name_ids = hb_set_create(); + hb_face_t *face_subset; + hb_set_add (name_ids, 0); + hb_set_add (name_ids, 9); + face_subset = hb_subset_test_create_subset (face_origin, hb_subset_test_create_input_from_nameids (name_ids)); + hb_set_destroy (name_ids); + + hb_subset_test_check (face_expected, face_subset, HB_TAG ('n','a','m','e')); + + hb_face_destroy (face_subset); + hb_face_destroy (face_origin); + hb_face_destroy (face_expected); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_subset_nameids); + + return hb_test_run(); +} diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf new file mode 100644 index 0000000000000000000000000000000000000000..12d92081b31eda6deaf2aa8b62e69c0535dfe225 GIT binary patch literal 2168 zcmZuydu&rx82`?_x9x3Lw%b`&*oEzu%ib*;+o&)Xm~k866vj5>cHyzo?nPEsSO=4c zqP%8#OcY}TL1Ks^8ab`#HipR(LE{5_fpI39nD7T05-_462(8~~J0`}{+~4_r-~G;a ze&0Dg=K=wMG}s0_1eP`ymj*kYO9kL>ptr^A_XI#D*8zkU}d;G23py>~s-->*0pt~m+^MeohW9)rkV{71zw%eZp=!2+tF>v6IUE_ZfmOvKd z!&4DkL7^pm9<@nS`5GwHXw+6Lhi#ej-Ekry5z>)d^ZM+n$@JS7+qTDW6$ZHm5vSouQwsmb+YKr5QGh z)iyb&)b-#TRhewf;PWNZv+p0fK*+DBgB!fN&h(t$G;&GEji#)4O+65OH>fo1`e4u7 zBg;KKzJ<$P(MFC(Q(xAkea(x0{&dA!+y>YiyCx`lfK-?YZISd$naN9+D33LZ#qmnb zSe$vhY#s?eUbY^Io|UZ=c~-W`%sOh8!s!#`P+kh#CTPiQV&&8sc?Q)|W^pO$mONIV z!IDu{>JpSIqZb0klfwZL`epdV=LhSTpWbl8Ua#(FJG$bR<_iS492riYFEn$=E99EwuYSxrfclX4D93hhqHJCs_==hQZ6 zs#^&up~b$CQmb@$d{oGZ_xPeU>6Hp%Ba0sHt|kEfkVNSiv|Sy`K*e_^+et-ws@Xnjx~S9#dhb+GXZY z?W!FWx~rYk=%{PdYEYsbC7K*Gzs5;Z9JByCvm=~G`jt?lHe7}K{ zEmIZ6D*Zzeu3OT_s+{DYRsBN>G;84ksFsJJfWKOeesd9pB8U))DG82r{lf`WfH%4U3rOr+WI-nBiL7Dp41?lK5{xWm(9K|g!6^nY2HBaUmyPIU zBYN40-bh*&8_VE2gX}DfTf<<0!B-4o3>IWza5sZu1>?FA*uf}-Blz_WK_6VgFWnMo zhTYHtPe3_W31=Y!`{5i$S)(mr>Cd$6=%~<0i>A_cl8Gc z0{iduz7HUZ0Nlj^?`RMtcnH_$aNRU8{8WF-dRf5u9*;+Th4&C>{Vm;>3DzUtjR8{=1(8=oV1VCg33uza{)EZh?F#g{Py| zvT}3QI%bubas?PPY0O$_i&%5ldlEoIAZDciAOHkW-YVjzs4?M~u@bjOGC7uBq1nH; z-S$MYj8-BQV*4Nim=UB}aYj#m} z{lj&tl5NQmO6BzDKRWXj$NltiXs>VT!szAk`Kw}a%((5OdNlSyNa>jR9LAYpqESW?L( znF&{zEHew)h;?bHY7Hr@$>7yOFxRDotHp^vP&B{ZcT75`8^65ghuB}C>&HI*O*$vd z3>`jk{NP0Qj8>sIxS=Y=pDZOS;E|l-UPUFKJFcric?C%?d<*?VnW9bZAWe&7V_VxsaDf+m zdWZq^ryb`(0q!&vhz&Z1KtcXw$C5!O>hMQsP>$wGw8Th09laYwJgtCFLBu>y%<(wl zgpZ$zpI%f?w-ge!Jlf5so|Jnd9Owu^00q2BBxClW`73X&Q1f zuGh(U2jj}^P9`{%W+oIhcWA0d2`k}E{;<-l40`=cEJ}D>=nH!)6$YK!5ZW%y&Ribb zV%X>LG&q?^G`It+!yY8qogzS=NLAi>iJk=@&Jk)@O#6C)K7on7-V}q$ES9##}ZAo^Y7>IyKeKCc|M{7&~}?7ygasIQVbE z_0I%8fu=cbvK^_=sdgJBRJ&?Ng&wz)862&hS`$jNqr`LvD{XQzql1;9GdUt9+_Vzz z)Xux`9s1@ZnC{ZfL#c2x=&>;s#VXTtGCsFdj=EgtV6N#o1-i9J8Mtldp-i~x#=NP5 zK?OuPnXllYW)AJFxuL4aCWBM~vs}v~tL+vHXL+qDhtyb-5H7x|-^X6D;ZDy{+|mlrtXmZ%Njfu1CYZ zM#?R-$R>lHqKwAsl9gtPGF`Q0d5OJp`=d!!fd7tZ*g*2VMK|PfqtPBR&ylIjZvX%Q literal 0 HcmV?d00001 diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a699eea0bced6d31e273e28487cb5292da5bc78b GIT binary patch literal 1792 zcmZuyZERCj7=F*ax3{0H?d(?Ah3#H08{68_xs3{Qks8}ETx4aNaPOjQW!(p4b%k{> z4eI>DtAq$B+F$jX#WHAd$rQ)8I!U#+eubt?%irpvKeO=e*Bz z-uJ!lIrp4XAOPToIp87F+aGStPCV}d;0~iYJd#dkKq5aQzm8lRIhd6L?^;g-h~3Bs z#xmpSLw^px55PwO$i?yGbOvm24~{S6xNCg!$+4aDzimMK7Cy@psr0PfA~-PLcWiuO zG?}`!@0+KPuS6c1K*4d|au&IUeBDGkJ8S&`E+bDMw@prsBmupVdl1BQayG-Y@^*ap z4dn6@$@D0<;P@SfP9fivnVQZP(~v@bg^gzpjAqV`-TVSTzT6h5t#|4zi1CjYoHLRTiCZB*qdUp3$8aXk0YnJ)?X@#F0Nkt64)KRtNiiqKGS?mDHOD14BW`;L6_%6k_c zO-`q_?s!AH@OGi%b1SZckRJx<4SOF9I9aeEF}g|!6a@Sh-J>!xa6l+ZaMtf z)ggE1AF#@XBEY2^UiLlVD(PFkDc!zmZ?R1ywPS)(<6ni8FbHWDZ=EdQUb1hyDHR^J zx0G|6ZVWl#g(KuOtO6`2Ep7P9IAfq>YOO&kHixLq z%+RmVs6;_G43@87Qx!UA7?OcA_?s{Nn=cahuMqvGfGZGRBy$N&g`KKMOi&e7!3y3#9x0 z4T=xV1y1YU)L63kzK7cDtC=S3exx(7idmLOaP2BLv&8+6ceP5)vYt5fScl3i+cV>d z%{9!j55yx4r7Vtv!#$BTOmn`F+HU%}uH}u9PNuE!d0cjpSrwhF>sNc3<&L&DttrKN z5)YbH0p2WDoPhb=@>^=ibbg4zvkbyDB%AMLFvZ|FgAW-L8PwH~85S|aB4${`Ox|6~ zVj29(psp7Eh8P@Y@D+n1gDth_JjEa^qu&$)I~dJy8vjKMn1w5N<8FsRco~LaC$w{& za1ruw3@)LUuP_Wg?oE(+1)M?$_=Kb2!Sm`9S3(te2fX4EREXE`CNdj`H#44A!Hy@9 wokG**@WygMA56g>e6slT!6=Nw3{2vwJb+%MR@}$#{{LwNuNE6{c+TB_0gD%;od5s; literal 0 HcmV?d00001 diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf new file mode 100644 index 0000000000000000000000000000000000000000..52706dc90320133d24a0a6c3109b9d1ef1bf8ec7 GIT binary patch literal 1740 zcmZuyUu;ul6hGg+x3|4rVQsC*c46F08DsR8&ao^o7pbuw;3BKrH1`r^>(>3l)mFB_ zG(i^?o!1Fse8Lb64~F0aUmKEb22B%r&WwaHG?=W_xS9q+Kt3nN`j&XPN!;^1E*? zCZ4=_>^;GEyZGJ7qcW^~_EzzS;)>&wE9Z;G`71ah+B*SGz#8ZWN14$~(1hzJS2?X$ z*)QmSw&C2^KyBwAQ0GD;z~!61Z6vR<-dlInm8(jNYYM4?3Cc}efRuC;7AW31S;Re7 z_TEv8k0~wH+!Z%M0YvF__6}A7j#G~9IOK+k6u*H{N>@!;iJ*G!wcR~EyCDigFeF0} zVAOd^01em~a*#S49EpafvoZ?_&kv4K=44xk8f7Di=L$MOLT?PjAK8aWr3#kLRBOgr zV59Ryt?Ywxh;$A{H&+s7j(a)PDK0gZC3cM1Rz%~_XHFpYn>vqL>OFPDvO2Xj zyfw^Sl?;6*kE$Fj+opVdW>DvIwyoMYgTHv;-+YO|e+|)p8gK>TOKdKIsZa!Ul?*{W zsAGjzEX)<7yU&bci8_|(Hu#o!nAaG*8HLBlHL-ck?lYI8xL?CdE|~8(mtl)|BWtNV zh{bC2OI}>Js*Ps3%HYxYB@OnQxn_u|%g`*|h@ssR;t+y7^9muB_c6ppUq?%$>IGK_ z7TKPMw&?*>7X@?AjxA+P?0vMYaShp|1CMux>PU068yo9tNt2&{rmIyY&3W?3(;Y$5 zTrZ6!cGi=o^vBybm$SGJ4|cb&CtJ;{seKhc&$YZg+)1`o0k21qNn737+O*C`T5Ytg zd3`z7n|P#B73BRjPMknx-}1Za*;Iaj;AMhHJ)6$=5M&5W5L_TA5p1YuGZZmH5i=Aq zldo-{Sc2aOHZ-8$0Ko}@uLw#6yBg3rLlDu>FN1&=0k*U++;=KuqMN|*x?GQIsRZP|&}DgcC5v<@ZHi43Uh4(hj28_DBYEwJdi1mL)jdSE0o znm+OS(EI4W3&5_8CZ;nW!y^FBMfAHzCtn=7^I_c$|&yjy@IFY(P z@$E~P`z7k|7#hkxc3eTf8}-()bavKt4GO3w)biw1G64g~fL%v$rW3Onp-og!zl&Ns znn(`|%VocyD~@_sW@@>x zwHr9Z4DM-BbDo+#W=Y5>U6acmE`H5D9_}N|ZTQ>O`e;L2`0a0Y_f-pflIP_m$MH{({!uXks7f#L| zJiM4=dV%8lov;cp;<_M!2J9UQ zkUAV3g@#|Dy$T7x6a0^oCfjCYRE=i*exMU1jK)O#kv&-~+E~22)-!!U6mO4G4ALY% zj6<-SD{&*o*jaOh72n{m*X9&)@JNWWpr*yfqnr(exDe!QyB^|VQ0wAiLsy^SH#JMM z4x}utOB+k1xYSUZ(J^e9EgFY@V;ph7(0RmEAJSpd>7 z#2vwIjf;(O<5`2xMO7Y&nyRjAFXyF$Og zBPs{evZ!9a;n(?`WvLdf;4fYHw_aiJUqj@d2Hb(z3Y&{#DV+SeN(R5~*Rex08sbW@ zyWfami#oPg7UbJvAzmKj%{aM(xh6KRS^dV<2)?i6iVX7u##PuR-pZIN_hYl#{E7$n zZOuljTo>e#`4tTg8o6eOs#l>|ycI>eJHR0TdFBxUEbnEA%ifOG2Gs*{0G8SQCwAyQ zq|1V_f7iAW6Z@WOZ>T1lbmW=Nz$RjjaB$0}N@C6z4tKSw#9VKkIMm@MCciQo-(5pY z8Hj}&OI6B_4|RuY$yREgHs6A<((l4wqmKESQDw@Rsa>gK!Fl;5ld)I^i1R;VjTS z>suWHpKuX0QHOG=1ANjM@Zfp%IXA+3_8xeh1*mY|#GA+-0@TrIl@vUQbP8=Q;Em;m nKA3{%@yX)T2g5K5GcXAWIEGQBQJkRr`hNz)t3?I@&w1saJT{N3 literal 0 HcmV?d00001 diff --git a/test/subset/data/profiles/name-ids.txt b/test/subset/data/profiles/name-ids.txt new file mode 100644 index 000000000..db42c09a4 --- /dev/null +++ b/test/subset/data/profiles/name-ids.txt @@ -0,0 +1 @@ +--name-IDs=0,1,2 diff --git a/test/subset/data/tests/basics.tests b/test/subset/data/tests/basics.tests index 4fc3f4eba..794510d87 100644 --- a/test/subset/data/tests/basics.tests +++ b/test/subset/data/tests/basics.tests @@ -6,6 +6,7 @@ default.txt drop-hints.txt drop-hints-retain-gids.txt retain-gids.txt +name-ids.txt SUBSETS: abc From 9ad14f56b6cf2a345104b3a897b52a1f4c0f33a5 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 16 Apr 2019 11:20:58 -0700 Subject: [PATCH 102/336] [subset] update name table subsetting with new serializer --- src/hb-ot-name-table.hh | 156 +++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 66 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index cdb8dba54..fde808c19 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -95,28 +95,6 @@ struct NameRecord return UNSUPPORTED; } - bool serialize (hb_serialize_context_t *c, const NameRecord& origin_namerecord, unsigned int *new_offset) - { - TRACE_SERIALIZE (this); - - if (unlikely (!c->allocate_size (NameRecord::static_size))) - { - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for NameRecord: %d.", - NameRecord::static_size); - return_trace (false); - } - - this->platformID = origin_namerecord.platformID; - this->encodingID = origin_namerecord.encodingID; - this->languageID = origin_namerecord.languageID; - this->nameID = origin_namerecord.nameID; - this->length = origin_namerecord.length; - this->offset = *new_offset; - *new_offset += origin_namerecord.length; - - return_trace (true); - } - bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -208,6 +186,88 @@ struct name return result; } + bool serialize_name_record (hb_serialize_context_t *c, + const name *source_name, + const hb_vector_t& name_record_idx_to_retain) + { + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + if (unlikely (idx >= source_name->count)) + { + DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); + return false; + } + + c->push (); + if (!c->embed (source_name->nameRecordZ[idx])) + return false; + } + + return true; + } + + bool serialize_strings (hb_serialize_context_t *c, + const name *source_name, + const hb_subset_plan_t *plan, + const hb_vector_t& name_record_idx_to_retain) + { + hb_face_t *face = plan->source; + accelerator_t acc; + acc.init (face); + + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + unsigned int size = acc.get_name (idx).get_size (); + + c->push (); + char *new_pos = c->allocate_size (size); + + if (unlikely (new_pos == nullptr)) + { + acc.fini (); + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %u.", + size); + return false; + } + + const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; + unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; + + memcpy (new_pos, source_string_pool + name_record_offset, size); + } + + acc.fini (); + return true; + } + + bool pack_record_and_strings (name *dest_name_unpacked, + hb_serialize_context_t *c, + unsigned length) + { + hb_hashmap_t id_str_idx_map; + for (int i = length-1; i >= 0; i--) + { + unsigned objidx = c->pop_pack (); + id_str_idx_map.set ((unsigned)i, objidx); + } + + const void *base = & (dest_name_unpacked->nameRecordZ[length]); + for (int i = length-1; i >= 0; i--) + { + unsigned str_idx = id_str_idx_map.get ((unsigned)i); + NameRecord& namerecord = dest_name_unpacked->nameRecordZ[i]; + c->add_link (namerecord.offset, str_idx, base); + c->pop_pack (); + } + + if (c->in_error ()) + return false; + + return true; + } + bool serialize (hb_serialize_context_t *c, const name *source_name, const hb_subset_plan_t *plan, @@ -221,48 +281,15 @@ struct name this->count = name_record_idx_to_retain.length; this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; - //write new NameRecord - unsigned int new_offset = 0; - for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) - { - unsigned int idx = name_record_idx_to_retain[i]; - if (unlikely (idx >= source_name->count)) - { - DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); - return_trace (false); - } - const NameRecord &namerec = source_name->nameRecordZ[idx]; + if (!serialize_name_record (c, source_name, name_record_idx_to_retain)) + return_trace (false); - if (!c->start_embed ()->serialize (c, namerec, &new_offset)) - return_trace (false); - } + if (!serialize_strings (c, source_name, plan, name_record_idx_to_retain)) + return_trace (false); - hb_face_t *face = plan->source; - accelerator_t acc; - acc.init (face); - - for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) - { - unsigned int idx = name_record_idx_to_retain[i]; - unsigned int size = acc.get_name (idx).get_size (); - char *new_pos = c->allocate_size (size); - - if (unlikely (new_pos == nullptr)) - { - acc.fini (); - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %d.", - size); - return_trace (false); - } - - const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; - unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; - - memcpy (new_pos, source_string_pool + name_record_offset, size); - } - - acc.fini (); + if (!pack_record_and_strings (this, c, name_record_idx_to_retain.length)) + return_trace (false); return_trace (true); } @@ -289,13 +316,10 @@ struct name c.end_serialize (); return false; } + c.end_serialize (); - hb_blob_t *name_prime_blob = hb_blob_create ((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); + hb_blob_t *name_prime_blob = c.copy_blob (); bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); hb_blob_destroy (name_prime_blob); From 1ca4b5c77012ed586413f39e730b03bf965e1305 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 22 Apr 2019 11:31:23 -0700 Subject: [PATCH 103/336] [subset] Add unit test for str de-dup Also move the implementation of some methods from the .cc to the .hh --- src/Makefile.sources | 1 - src/hb-aat-layout.cc | 8 - src/hb-aat-layout.hh | 9 +- src/hb-ot-name-language.cc | 457 ------------------------- src/hb-ot-name-language.hh | 432 ++++++++++++++++++++++- test/api/fonts/nameID.dup.expected.ttf | Bin 0 -> 2340 bytes test/api/fonts/nameID.dup.origin.ttf | Bin 0 -> 170680 bytes test/api/test-subset-nameids.c | 21 ++ 8 files changed, 456 insertions(+), 472 deletions(-) delete mode 100644 src/hb-ot-name-language.cc create mode 100644 test/api/fonts/nameID.dup.expected.ttf create mode 100644 test/api/fonts/nameID.dup.origin.ttf diff --git a/src/Makefile.sources b/src/Makefile.sources index 17956c59d..803d229ac 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -84,7 +84,6 @@ HB_BASE_sources = \ hb-ot-math-table.hh \ hb-ot-math.cc \ hb-ot-maxp-table.hh \ - hb-ot-name-language.cc \ hb-ot-name-language.hh \ hb-ot-name-table.hh \ hb-ot-name.cc \ diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 5168a9c85..1966ded32 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -311,14 +311,6 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, trak.apply (&c); } - -hb_language_t -_hb_aat_language_get (hb_face_t *face, - unsigned int i) -{ - return face->table.ltag->get_language (i); -} - /** * hb_aat_layout_get_feature_types: * @face: a face object diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 6340924bf..1ed009e12 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -30,6 +30,7 @@ #include "hb.hh" #include "hb-ot-shape.hh" +#include "hb-aat-ltag-table.hh" struct hb_aat_feature_mapping_t @@ -77,9 +78,13 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL hb_language_t + +inline hb_language_t _hb_aat_language_get (hb_face_t *face, - unsigned int i); + unsigned int i) +{ + return face->table.ltag->get_language (i); +} #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/hb-ot-name-language.cc b/src/hb-ot-name-language.cc deleted file mode 100644 index 0e37e0acb..000000000 --- a/src/hb-ot-name-language.cc +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb-ot-name-language.hh" - -/* Following two tables were generated by joining FreeType, FontConfig, - * and OpenType specification language lists, then filled in missing - * entries using: - * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings - */ - -struct hb_ot_language_map_t -{ - static int cmp (const void *key, const void *item) - { - unsigned int a = * (unsigned int *) key; - unsigned int b = ((const hb_ot_language_map_t *) item)->code; - return a < b ? -1 : a > b ? +1 : 0; - } - - uint16_t code; - char lang[6]; -}; - -static const hb_ot_language_map_t -hb_ms_language_map[] = -{ - {0x0001, "ar"}, /* ??? */ - {0x0004, "zh"}, /* ??? */ - {0x0009, "en"}, /* ??? */ - {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ - {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ - {0x0403, "ca"}, /* Catalan (Catalan) */ - {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ - {0x0405, "cs"}, /* Czech (Czech Republic) */ - {0x0406, "da"}, /* Danish (Denmark) */ - {0x0407, "de"}, /* German (Germany) */ - {0x0408, "el"}, /* Greek (Greece) */ - {0x0409, "en"}, /* English (United States) */ - {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ - {0x040B, "fi"}, /* Finnish (Finland) */ - {0x040C, "fr"}, /* French (France) */ - {0x040D, "he"}, /* Hebrew (Israel) */ - {0x040E, "hu"}, /* Hungarian (Hungary) */ - {0x040F, "is"}, /* Icelandic (Iceland) */ - {0x0410, "it"}, /* Italian (Italy) */ - {0x0411, "ja"}, /* Japanese (Japan) */ - {0x0412, "ko"}, /* Korean (Korea) */ - {0x0413, "nl"}, /* Dutch (Netherlands) */ - {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ - {0x0415, "pl"}, /* Polish (Poland) */ - {0x0416, "pt"}, /* Portuguese (Brazil) */ - {0x0417, "rm"}, /* Romansh (Switzerland) */ - {0x0418, "ro"}, /* Romanian (Romania) */ - {0x0419, "ru"}, /* Russian (Russia) */ - {0x041A, "hr"}, /* Croatian (Croatia) */ - {0x041B, "sk"}, /* Slovak (Slovakia) */ - {0x041C, "sq"}, /* Albanian (Albania) */ - {0x041D, "sv"}, /* Swedish (Sweden) */ - {0x041E, "th"}, /* Thai (Thailand) */ - {0x041F, "tr"}, /* Turkish (Turkey) */ - {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ - {0x0421, "id"}, /* Indonesian (Indonesia) */ - {0x0422, "uk"}, /* Ukrainian (Ukraine) */ - {0x0423, "be"}, /* Belarusian (Belarus) */ - {0x0424, "sl"}, /* Slovenian (Slovenia) */ - {0x0425, "et"}, /* Estonian (Estonia) */ - {0x0426, "lv"}, /* Latvian (Latvia) */ - {0x0427, "lt"}, /* Lithuanian (Lithuania) */ - {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ - {0x0429, "fa"}, /* Persian (Iran) */ - {0x042A, "vi"}, /* Vietnamese (Vietnam) */ - {0x042B, "hy"}, /* Armenian (Armenia) */ - {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ - {0x042D, "eu"}, /* Basque (Basque) */ - {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ - {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ - {0x0430, "st"}, /* ??? */ - {0x0431, "ts"}, /* ??? */ - {0x0432, "tn"}, /* Setswana (South Africa) */ - {0x0433, "ven"}, /* ??? */ - {0x0434, "xh"}, /* isiXhosa (South Africa) */ - {0x0435, "zu"}, /* isiZulu (South Africa) */ - {0x0436, "af"}, /* Afrikaans (South Africa) */ - {0x0437, "ka"}, /* Georgian (Georgia) */ - {0x0438, "fo"}, /* Faroese (Faroe Islands) */ - {0x0439, "hi"}, /* Hindi (India) */ - {0x043A, "mt"}, /* Maltese (Malta) */ - {0x043B, "se"}, /* Sami (Northern) (Norway) */ - {0x043C, "ga"}, /* ??? */ - {0x043D, "yi"}, /* ??? */ - {0x043E, "ms"}, /* Malay (Malaysia) */ - {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ - {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ - {0x0441, "sw"}, /* Kiswahili (Kenya) */ - {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ - {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ - {0x0444, "tt"}, /* Tatar (Russia) */ - {0x0445, "bn"}, /* Bengali (India) */ - {0x0446, "pa"}, /* Punjabi (India) */ - {0x0447, "gu"}, /* Gujarati (India) */ - {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ - {0x0449, "ta"}, /* Tamil (India) */ - {0x044A, "te"}, /* Telugu (India) */ - {0x044B, "kn"}, /* Kannada (India) */ - {0x044C, "ml"}, /* Malayalam (India) */ - {0x044D, "as"}, /* Assamese (India) */ - {0x044E, "mr"}, /* Marathi (India) */ - {0x044F, "sa"}, /* Sanskrit (India) */ - {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ - {0x0451, "bo"}, /* Tibetan (PRC) */ - {0x0452, "cy"}, /* Welsh (United Kingdom) */ - {0x0453, "km"}, /* Khmer (Cambodia) */ - {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ - {0x0455, "my"}, /* ??? */ - {0x0456, "gl"}, /* Galician (Galician) */ - {0x0457, "kok"}, /* Konkani (India) */ - {0x0458, "mni"}, /* ??? */ - {0x0459, "sd"}, /* ??? */ - {0x045A, "syr"}, /* Syriac (Syria) */ - {0x045B, "si"}, /* Sinhala (Sri Lanka) */ - {0x045C, "chr"}, /* ??? */ - {0x045D, "iu"}, /* Inuktitut (Canada) */ - {0x045E, "am"}, /* Amharic (Ethiopia) */ - {0x0460, "ks"}, /* ??? */ - {0x0461, "ne"}, /* Nepali (Nepal) */ - {0x0462, "fy"}, /* Frisian (Netherlands) */ - {0x0463, "ps"}, /* Pashto (Afghanistan) */ - {0x0464, "phi"}, /* Filipino (Philippines) */ - {0x0465, "div"}, /* Divehi (Maldives) */ - {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ - {0x046A, "yo"}, /* Yoruba (Nigeria) */ - {0x046B, "quz"}, /* Quechua (Bolivia) */ - {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ - {0x046D, "ba"}, /* Bashkir (Russia) */ - {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ - {0x046F, "kl"}, /* Greenlandic (Greenland) */ - {0x0470, "ibo"}, /* Igbo (Nigeria) */ - {0x0471, "kau"}, /* ??? */ - {0x0472, "om"}, /* ??? */ - {0x0473, "ti"}, /* ??? */ - {0x0474, "gn"}, /* ??? */ - {0x0475, "haw"}, /* ??? */ - {0x0476, "la"}, /* ??? */ - {0x0477, "so"}, /* ??? */ - {0x0478, "ii"}, /* Yi (PRC) */ - {0x0479, "pap"}, /* ??? */ - {0x047A, "arn"}, /* Mapudungun (Chile) */ - {0x047C, "moh"}, /* Mohawk (Mohawk) */ - {0x047E, "br"}, /* Breton (France) */ - {0x0480, "ug"}, /* Uighur (PRC) */ - {0x0481, "mi"}, /* Maori (New Zealand) */ - {0x0482, "oc"}, /* Occitan (France) */ - {0x0483, "co"}, /* Corsican (France) */ - {0x0484, "gsw"}, /* Alsatian (France) */ - {0x0485, "sah"}, /* Yakut (Russia) */ - {0x0486, "qut"}, /* K'iche (Guatemala) */ - {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ - {0x0488, "wo"}, /* Wolof (Senegal) */ - {0x048C, "fa"}, /* Dari (Afghanistan) */ - {0x0801, "ar"}, /* Arabic (Iraq) */ - {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ - {0x0807, "de"}, /* German (Switzerland) */ - {0x0809, "en"}, /* English (United Kingdom) */ - {0x080A, "es"}, /* Spanish (Mexico) */ - {0x080C, "fr"}, /* French (Belgium) */ - {0x0810, "it"}, /* Italian (Switzerland) */ - {0x0812, "ko"}, /* ??? */ - {0x0813, "nl"}, /* Dutch (Belgium) */ - {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ - {0x0816, "pt"}, /* Portuguese (Portugal) */ - {0x0818, "mo"}, /* ??? */ - {0x0819, "ru"}, /* ??? */ - {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ - {0x081D, "sv"}, /* Sweden (Finland) */ - {0x0820, "ur"}, /* ??? */ - {0x0827, "lt"}, /* ??? */ - {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ - {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ -//{0x083B, ""}, /* Sami (Northern) (Sweden) */ - {0x083C, "gd"}, /* Irish (Ireland) */ - {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ - {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ - {0x0845, "bn"}, /* Bengali (Bangladesh) */ - {0x0846, "ar"}, /* ??? */ - {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ - {0x0851, "dz"}, /* ??? */ - {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ - {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ - {0x0861, "ne"}, /* ??? */ -//{0x086B, ""}, /* Quechua (Ecuador) */ - {0x0873, "ti"}, /* ??? */ - {0x0C01, "ar"}, /* Arabic (Egypt) */ - {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ - {0x0C07, "de"}, /* German (Austria) */ - {0x0C09, "en"}, /* English (Australia) */ - {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ - {0x0C0C, "fr"}, /* French (Canada) */ - {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ - {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ -//{0x0C6B, ""}, /* Quechua (Peru) */ - {0x1001, "ar"}, /* Arabic (Libya) */ - {0x1004, "zh-sg"}, /* Chinese (Singapore) */ - {0x1007, "de"}, /* German (Luxembourg) */ - {0x1009, "en"}, /* English (Canada) */ - {0x100A, "es"}, /* Spanish (Guatemala) */ - {0x100C, "fr"}, /* French (Switzerland) */ - {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ - {0x103B, "smj"}, /* Sami (Lule) (Norway) */ - {0x1401, "ar"}, /* Arabic (Algeria) */ -//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ - {0x1407, "de"}, /* German (Liechtenstein) */ - {0x1409, "en"}, /* English (New Zealand) */ - {0x140A, "es"}, /* Spanish (Costa Rica) */ - {0x140C, "fr"}, /* French (Luxembourg) */ - {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ -//{0x143B, ""}, /* Sami (Lule) (Sweden) */ - {0x1801, "ar"}, /* Arabic (Morocco) */ - {0x1809, "en"}, /* English (Ireland) */ - {0x180A, "es"}, /* Spanish (Panama) */ - {0x180C, "fr"}, /* French (Principality of Monaco) */ -//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ - {0x183B, "sma"}, /* Sami (Southern) (Norway) */ - {0x1C01, "ar"}, /* Arabic (Tunisia) */ - {0x1C09, "en"}, /* English (South Africa) */ - {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ - {0x1C0C, "fr"}, /* ??? */ -//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ -//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ - {0x2001, "ar"}, /* Arabic (Oman) */ - {0x2009, "en"}, /* English (Jamaica) */ - {0x200A, "es"}, /* Spanish (Venezuela) */ - {0x200C, "fr"}, /* ??? */ - {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ - {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ - {0x2401, "ar"}, /* Arabic (Yemen) */ - {0x2409, "en"}, /* English (Caribbean) */ - {0x240A, "es"}, /* Spanish (Colombia) */ - {0x240C, "fr"}, /* ??? */ - {0x243B, "smn"}, /* Sami (Inari) (Finland) */ - {0x2801, "ar"}, /* Arabic (Syria) */ - {0x2809, "en"}, /* English (Belize) */ - {0x280A, "es"}, /* Spanish (Peru) */ - {0x280C, "fr"}, /* ??? */ - {0x2C01, "ar"}, /* Arabic (Jordan) */ - {0x2C09, "en"}, /* English (Trinidad and Tobago) */ - {0x2C0A, "es"}, /* Spanish (Argentina) */ - {0x2C0C, "fr"}, /* ??? */ - {0x3001, "ar"}, /* Arabic (Lebanon) */ - {0x3009, "en"}, /* English (Zimbabwe) */ - {0x300A, "es"}, /* Spanish (Ecuador) */ - {0x300C, "fr"}, /* ??? */ - {0x3401, "ar"}, /* Arabic (Kuwait) */ - {0x3409, "en"}, /* English (Republic of the Philippines) */ - {0x340A, "es"}, /* Spanish (Chile) */ - {0x340C, "fr"}, /* ??? */ - {0x3801, "ar"}, /* Arabic (U.A.E.) */ - {0x380A, "es"}, /* Spanish (Uruguay) */ - {0x380C, "fr"}, /* ??? */ - {0x3C01, "ar"}, /* Arabic (Bahrain) */ - {0x3C09, "en"}, /* ??? */ - {0x3C0A, "es"}, /* Spanish (Paraguay) */ - {0x3C0C, "fr"}, /* ??? */ - {0x4001, "ar"}, /* Arabic (Qatar) */ - {0x4009, "en"}, /* English (India) */ - {0x400A, "es"}, /* Spanish (Bolivia) */ - {0x4409, "en"}, /* English (Malaysia) */ - {0x440A, "es"}, /* Spanish (El Salvador) */ - {0x4809, "en"}, /* English (Singapore) */ - {0x480A, "es"}, /* Spanish (Honduras) */ - {0x4C0A, "es"}, /* Spanish (Nicaragua) */ - {0x500A, "es"}, /* Spanish (Puerto Rico) */ - {0x540A, "es"}, /* Spanish (United States) */ - {0xE40A, "es"}, /* ??? */ - {0xE40C, "fr"}, /* ??? */ -}; - -static const hb_ot_language_map_t -hb_mac_language_map[] = -{ - { 0, "en"}, /* English */ - { 1, "fr"}, /* French */ - { 2, "de"}, /* German */ - { 3, "it"}, /* Italian */ - { 4, "nl"}, /* Dutch */ - { 5, "sv"}, /* Swedish */ - { 6, "es"}, /* Spanish */ - { 7, "da"}, /* Danish */ - { 8, "pt"}, /* Portuguese */ - { 9, "no"}, /* Norwegian */ - { 10, "he"}, /* Hebrew */ - { 11, "ja"}, /* Japanese */ - { 12, "ar"}, /* Arabic */ - { 13, "fi"}, /* Finnish */ - { 14, "el"}, /* Greek */ - { 15, "is"}, /* Icelandic */ - { 16, "mt"}, /* Maltese */ - { 17, "tr"}, /* Turkish */ - { 18, "hr"}, /* Croatian */ - { 19, "zh-tw"}, /* Chinese (Traditional) */ - { 20, "ur"}, /* Urdu */ - { 21, "hi"}, /* Hindi */ - { 22, "th"}, /* Thai */ - { 23, "ko"}, /* Korean */ - { 24, "lt"}, /* Lithuanian */ - { 25, "pl"}, /* Polish */ - { 26, "hu"}, /* Hungarian */ - { 27, "et"}, /* Estonian */ - { 28, "lv"}, /* Latvian */ -//{ 29, ""}, /* Sami */ - { 30, "fo"}, /* Faroese */ - { 31, "fa"}, /* Farsi/Persian */ - { 32, "ru"}, /* Russian */ - { 33, "zh-cn"}, /* Chinese (Simplified) */ - { 34, "nl"}, /* Flemish */ - { 35, "ga"}, /* Irish Gaelic */ - { 36, "sq"}, /* Albanian */ - { 37, "ro"}, /* Romanian */ - { 38, "cs"}, /* Czech */ - { 39, "sk"}, /* Slovak */ - { 40, "sl"}, /* Slovenian */ - { 41, "yi"}, /* Yiddish */ - { 42, "sr"}, /* Serbian */ - { 43, "mk"}, /* Macedonian */ - { 44, "bg"}, /* Bulgarian */ - { 45, "uk"}, /* Ukrainian */ - { 46, "be"}, /* Byelorussian */ - { 47, "uz"}, /* Uzbek */ - { 48, "kk"}, /* Kazakh */ - { 49, "az"}, /* Azerbaijani (Cyrillic script) */ - { 50, "az"}, /* Azerbaijani (Arabic script) */ - { 51, "hy"}, /* Armenian */ - { 52, "ka"}, /* Georgian */ - { 53, "mo"}, /* Moldavian */ - { 54, "ky"}, /* Kirghiz */ - { 55, "tg"}, /* Tajiki */ - { 56, "tk"}, /* Turkmen */ - { 57, "mn"}, /* Mongolian (Mongolian script) */ - { 58, "mn"}, /* Mongolian (Cyrillic script) */ - { 59, "ps"}, /* Pashto */ - { 60, "ku"}, /* Kurdish */ - { 61, "ks"}, /* Kashmiri */ - { 62, "sd"}, /* Sindhi */ - { 63, "bo"}, /* Tibetan */ - { 64, "ne"}, /* Nepali */ - { 65, "sa"}, /* Sanskrit */ - { 66, "mr"}, /* Marathi */ - { 67, "bn"}, /* Bengali */ - { 68, "as"}, /* Assamese */ - { 69, "gu"}, /* Gujarati */ - { 70, "pa"}, /* Punjabi */ - { 71, "or"}, /* Oriya */ - { 72, "ml"}, /* Malayalam */ - { 73, "kn"}, /* Kannada */ - { 74, "ta"}, /* Tamil */ - { 75, "te"}, /* Telugu */ - { 76, "si"}, /* Sinhalese */ - { 77, "my"}, /* Burmese */ - { 78, "km"}, /* Khmer */ - { 79, "lo"}, /* Lao */ - { 80, "vi"}, /* Vietnamese */ - { 81, "id"}, /* Indonesian */ - { 82, "tl"}, /* Tagalog */ - { 83, "ms"}, /* Malay (Roman script) */ - { 84, "ms"}, /* Malay (Arabic script) */ - { 85, "am"}, /* Amharic */ - { 86, "ti"}, /* Tigrinya */ - { 87, "om"}, /* Galla */ - { 88, "so"}, /* Somali */ - { 89, "sw"}, /* Swahili */ - { 90, "rw"}, /* Kinyarwanda/Ruanda */ - { 91, "rn"}, /* Rundi */ - { 92, "ny"}, /* Nyanja/Chewa */ - { 93, "mg"}, /* Malagasy */ - { 94, "eo"}, /* Esperanto */ - {128, "cy"}, /* Welsh */ - {129, "eu"}, /* Basque */ - {130, "ca"}, /* Catalan */ - {131, "la"}, /* Latin */ - {132, "qu"}, /* Quechua */ - {133, "gn"}, /* Guarani */ - {134, "ay"}, /* Aymara */ - {135, "tt"}, /* Tatar */ - {136, "ug"}, /* Uighur */ - {137, "dz"}, /* Dzongkha */ - {138, "jw"}, /* Javanese (Roman script) */ - {139, "su"}, /* Sundanese (Roman script) */ - {140, "gl"}, /* Galician */ - {141, "af"}, /* Afrikaans */ - {142, "br"}, /* Breton */ - {143, "iu"}, /* Inuktitut */ - {144, "gd"}, /* Scottish Gaelic */ - {145, "gv"}, /* Manx Gaelic */ - {146, "ga"}, /* Irish Gaelic (with dot above) */ - {147, "to"}, /* Tongan */ - {148, "el"}, /* Greek (polytonic) */ - {149, "ik"}, /* Greenlandic */ - {150, "az"}, /* Azerbaijani (Roman script) */ -}; - - -static hb_language_t -_hb_ot_name_language_for (unsigned int code, - const hb_ot_language_map_t *array, - unsigned int len) -{ - const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) - hb_bsearch (&code, - array, - len, - sizeof (array[0]), - hb_ot_language_map_t::cmp); - - if (entry) - return hb_language_from_string (entry->lang, -1); - - return HB_LANGUAGE_INVALID; -} - -hb_language_t -_hb_ot_name_language_for_ms_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_ms_language_map, - ARRAY_LENGTH (hb_ms_language_map)); -} - -hb_language_t -_hb_ot_name_language_for_mac_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_mac_language_map, - ARRAY_LENGTH (hb_mac_language_map)); -} diff --git a/src/hb-ot-name-language.hh b/src/hb-ot-name-language.hh index 903076c0d..a5449764c 100644 --- a/src/hb-ot-name-language.hh +++ b/src/hb-ot-name-language.hh @@ -29,12 +29,436 @@ #include "hb.hh" +/* Following two tables were generated by joining FreeType, FontConfig, + * and OpenType specification language lists, then filled in missing + * entries using: + * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings + */ -HB_INTERNAL hb_language_t -_hb_ot_name_language_for_ms_code (unsigned int code); +struct hb_ot_language_map_t +{ + static int cmp (const void *key, const void *item) + { + unsigned int a = * (unsigned int *) key; + unsigned int b = ((const hb_ot_language_map_t *) item)->code; + return a < b ? -1 : a > b ? +1 : 0; + } -HB_INTERNAL hb_language_t -_hb_ot_name_language_for_mac_code (unsigned int code); + uint16_t code; + char lang[6]; +}; + + +static const hb_ot_language_map_t +hb_ms_language_map[] = +{ + {0x0001, "ar"}, /* ??? */ + {0x0004, "zh"}, /* ??? */ + {0x0009, "en"}, /* ??? */ + {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ + {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ + {0x0403, "ca"}, /* Catalan (Catalan) */ + {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ + {0x0405, "cs"}, /* Czech (Czech Republic) */ + {0x0406, "da"}, /* Danish (Denmark) */ + {0x0407, "de"}, /* German (Germany) */ + {0x0408, "el"}, /* Greek (Greece) */ + {0x0409, "en"}, /* English (United States) */ + {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ + {0x040B, "fi"}, /* Finnish (Finland) */ + {0x040C, "fr"}, /* French (France) */ + {0x040D, "he"}, /* Hebrew (Israel) */ + {0x040E, "hu"}, /* Hungarian (Hungary) */ + {0x040F, "is"}, /* Icelandic (Iceland) */ + {0x0410, "it"}, /* Italian (Italy) */ + {0x0411, "ja"}, /* Japanese (Japan) */ + {0x0412, "ko"}, /* Korean (Korea) */ + {0x0413, "nl"}, /* Dutch (Netherlands) */ + {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ + {0x0415, "pl"}, /* Polish (Poland) */ + {0x0416, "pt"}, /* Portuguese (Brazil) */ + {0x0417, "rm"}, /* Romansh (Switzerland) */ + {0x0418, "ro"}, /* Romanian (Romania) */ + {0x0419, "ru"}, /* Russian (Russia) */ + {0x041A, "hr"}, /* Croatian (Croatia) */ + {0x041B, "sk"}, /* Slovak (Slovakia) */ + {0x041C, "sq"}, /* Albanian (Albania) */ + {0x041D, "sv"}, /* Swedish (Sweden) */ + {0x041E, "th"}, /* Thai (Thailand) */ + {0x041F, "tr"}, /* Turkish (Turkey) */ + {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ + {0x0421, "id"}, /* Indonesian (Indonesia) */ + {0x0422, "uk"}, /* Ukrainian (Ukraine) */ + {0x0423, "be"}, /* Belarusian (Belarus) */ + {0x0424, "sl"}, /* Slovenian (Slovenia) */ + {0x0425, "et"}, /* Estonian (Estonia) */ + {0x0426, "lv"}, /* Latvian (Latvia) */ + {0x0427, "lt"}, /* Lithuanian (Lithuania) */ + {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ + {0x0429, "fa"}, /* Persian (Iran) */ + {0x042A, "vi"}, /* Vietnamese (Vietnam) */ + {0x042B, "hy"}, /* Armenian (Armenia) */ + {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ + {0x042D, "eu"}, /* Basque (Basque) */ + {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ + {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ + {0x0430, "st"}, /* ??? */ + {0x0431, "ts"}, /* ??? */ + {0x0432, "tn"}, /* Setswana (South Africa) */ + {0x0433, "ven"}, /* ??? */ + {0x0434, "xh"}, /* isiXhosa (South Africa) */ + {0x0435, "zu"}, /* isiZulu (South Africa) */ + {0x0436, "af"}, /* Afrikaans (South Africa) */ + {0x0437, "ka"}, /* Georgian (Georgia) */ + {0x0438, "fo"}, /* Faroese (Faroe Islands) */ + {0x0439, "hi"}, /* Hindi (India) */ + {0x043A, "mt"}, /* Maltese (Malta) */ + {0x043B, "se"}, /* Sami (Northern) (Norway) */ + {0x043C, "ga"}, /* ??? */ + {0x043D, "yi"}, /* ??? */ + {0x043E, "ms"}, /* Malay (Malaysia) */ + {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ + {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ + {0x0441, "sw"}, /* Kiswahili (Kenya) */ + {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ + {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ + {0x0444, "tt"}, /* Tatar (Russia) */ + {0x0445, "bn"}, /* Bengali (India) */ + {0x0446, "pa"}, /* Punjabi (India) */ + {0x0447, "gu"}, /* Gujarati (India) */ + {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ + {0x0449, "ta"}, /* Tamil (India) */ + {0x044A, "te"}, /* Telugu (India) */ + {0x044B, "kn"}, /* Kannada (India) */ + {0x044C, "ml"}, /* Malayalam (India) */ + {0x044D, "as"}, /* Assamese (India) */ + {0x044E, "mr"}, /* Marathi (India) */ + {0x044F, "sa"}, /* Sanskrit (India) */ + {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ + {0x0451, "bo"}, /* Tibetan (PRC) */ + {0x0452, "cy"}, /* Welsh (United Kingdom) */ + {0x0453, "km"}, /* Khmer (Cambodia) */ + {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ + {0x0455, "my"}, /* ??? */ + {0x0456, "gl"}, /* Galician (Galician) */ + {0x0457, "kok"}, /* Konkani (India) */ + {0x0458, "mni"}, /* ??? */ + {0x0459, "sd"}, /* ??? */ + {0x045A, "syr"}, /* Syriac (Syria) */ + {0x045B, "si"}, /* Sinhala (Sri Lanka) */ + {0x045C, "chr"}, /* ??? */ + {0x045D, "iu"}, /* Inuktitut (Canada) */ + {0x045E, "am"}, /* Amharic (Ethiopia) */ + {0x0460, "ks"}, /* ??? */ + {0x0461, "ne"}, /* Nepali (Nepal) */ + {0x0462, "fy"}, /* Frisian (Netherlands) */ + {0x0463, "ps"}, /* Pashto (Afghanistan) */ + {0x0464, "phi"}, /* Filipino (Philippines) */ + {0x0465, "div"}, /* Divehi (Maldives) */ + {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ + {0x046A, "yo"}, /* Yoruba (Nigeria) */ + {0x046B, "quz"}, /* Quechua (Bolivia) */ + {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ + {0x046D, "ba"}, /* Bashkir (Russia) */ + {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ + {0x046F, "kl"}, /* Greenlandic (Greenland) */ + {0x0470, "ibo"}, /* Igbo (Nigeria) */ + {0x0471, "kau"}, /* ??? */ + {0x0472, "om"}, /* ??? */ + {0x0473, "ti"}, /* ??? */ + {0x0474, "gn"}, /* ??? */ + {0x0475, "haw"}, /* ??? */ + {0x0476, "la"}, /* ??? */ + {0x0477, "so"}, /* ??? */ + {0x0478, "ii"}, /* Yi (PRC) */ + {0x0479, "pap"}, /* ??? */ + {0x047A, "arn"}, /* Mapudungun (Chile) */ + {0x047C, "moh"}, /* Mohawk (Mohawk) */ + {0x047E, "br"}, /* Breton (France) */ + {0x0480, "ug"}, /* Uighur (PRC) */ + {0x0481, "mi"}, /* Maori (New Zealand) */ + {0x0482, "oc"}, /* Occitan (France) */ + {0x0483, "co"}, /* Corsican (France) */ + {0x0484, "gsw"}, /* Alsatian (France) */ + {0x0485, "sah"}, /* Yakut (Russia) */ + {0x0486, "qut"}, /* K'iche (Guatemala) */ + {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ + {0x0488, "wo"}, /* Wolof (Senegal) */ + {0x048C, "fa"}, /* Dari (Afghanistan) */ + {0x0801, "ar"}, /* Arabic (Iraq) */ + {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ + {0x0807, "de"}, /* German (Switzerland) */ + {0x0809, "en"}, /* English (United Kingdom) */ + {0x080A, "es"}, /* Spanish (Mexico) */ + {0x080C, "fr"}, /* French (Belgium) */ + {0x0810, "it"}, /* Italian (Switzerland) */ + {0x0812, "ko"}, /* ??? */ + {0x0813, "nl"}, /* Dutch (Belgium) */ + {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ + {0x0816, "pt"}, /* Portuguese (Portugal) */ + {0x0818, "mo"}, /* ??? */ + {0x0819, "ru"}, /* ??? */ + {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ + {0x081D, "sv"}, /* Sweden (Finland) */ + {0x0820, "ur"}, /* ??? */ + {0x0827, "lt"}, /* ??? */ + {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ + {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ +//{0x083B, ""}, /* Sami (Northern) (Sweden) */ + {0x083C, "gd"}, /* Irish (Ireland) */ + {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ + {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ + {0x0845, "bn"}, /* Bengali (Bangladesh) */ + {0x0846, "ar"}, /* ??? */ + {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ + {0x0851, "dz"}, /* ??? */ + {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ + {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ + {0x0861, "ne"}, /* ??? */ +//{0x086B, ""}, /* Quechua (Ecuador) */ + {0x0873, "ti"}, /* ??? */ + {0x0C01, "ar"}, /* Arabic (Egypt) */ + {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ + {0x0C07, "de"}, /* German (Austria) */ + {0x0C09, "en"}, /* English (Australia) */ + {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ + {0x0C0C, "fr"}, /* French (Canada) */ + {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ + {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ +//{0x0C6B, ""}, /* Quechua (Peru) */ + {0x1001, "ar"}, /* Arabic (Libya) */ + {0x1004, "zh-sg"}, /* Chinese (Singapore) */ + {0x1007, "de"}, /* German (Luxembourg) */ + {0x1009, "en"}, /* English (Canada) */ + {0x100A, "es"}, /* Spanish (Guatemala) */ + {0x100C, "fr"}, /* French (Switzerland) */ + {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ + {0x103B, "smj"}, /* Sami (Lule) (Norway) */ + {0x1401, "ar"}, /* Arabic (Algeria) */ +//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ + {0x1407, "de"}, /* German (Liechtenstein) */ + {0x1409, "en"}, /* English (New Zealand) */ + {0x140A, "es"}, /* Spanish (Costa Rica) */ + {0x140C, "fr"}, /* French (Luxembourg) */ + {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ +//{0x143B, ""}, /* Sami (Lule) (Sweden) */ + {0x1801, "ar"}, /* Arabic (Morocco) */ + {0x1809, "en"}, /* English (Ireland) */ + {0x180A, "es"}, /* Spanish (Panama) */ + {0x180C, "fr"}, /* French (Principality of Monaco) */ +//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ + {0x183B, "sma"}, /* Sami (Southern) (Norway) */ + {0x1C01, "ar"}, /* Arabic (Tunisia) */ + {0x1C09, "en"}, /* English (South Africa) */ + {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ + {0x1C0C, "fr"}, /* ??? */ +//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ +//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ + {0x2001, "ar"}, /* Arabic (Oman) */ + {0x2009, "en"}, /* English (Jamaica) */ + {0x200A, "es"}, /* Spanish (Venezuela) */ + {0x200C, "fr"}, /* ??? */ + {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ + {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ + {0x2401, "ar"}, /* Arabic (Yemen) */ + {0x2409, "en"}, /* English (Caribbean) */ + {0x240A, "es"}, /* Spanish (Colombia) */ + {0x240C, "fr"}, /* ??? */ + {0x243B, "smn"}, /* Sami (Inari) (Finland) */ + {0x2801, "ar"}, /* Arabic (Syria) */ + {0x2809, "en"}, /* English (Belize) */ + {0x280A, "es"}, /* Spanish (Peru) */ + {0x280C, "fr"}, /* ??? */ + {0x2C01, "ar"}, /* Arabic (Jordan) */ + {0x2C09, "en"}, /* English (Trinidad and Tobago) */ + {0x2C0A, "es"}, /* Spanish (Argentina) */ + {0x2C0C, "fr"}, /* ??? */ + {0x3001, "ar"}, /* Arabic (Lebanon) */ + {0x3009, "en"}, /* English (Zimbabwe) */ + {0x300A, "es"}, /* Spanish (Ecuador) */ + {0x300C, "fr"}, /* ??? */ + {0x3401, "ar"}, /* Arabic (Kuwait) */ + {0x3409, "en"}, /* English (Republic of the Philippines) */ + {0x340A, "es"}, /* Spanish (Chile) */ + {0x340C, "fr"}, /* ??? */ + {0x3801, "ar"}, /* Arabic (U.A.E.) */ + {0x380A, "es"}, /* Spanish (Uruguay) */ + {0x380C, "fr"}, /* ??? */ + {0x3C01, "ar"}, /* Arabic (Bahrain) */ + {0x3C09, "en"}, /* ??? */ + {0x3C0A, "es"}, /* Spanish (Paraguay) */ + {0x3C0C, "fr"}, /* ??? */ + {0x4001, "ar"}, /* Arabic (Qatar) */ + {0x4009, "en"}, /* English (India) */ + {0x400A, "es"}, /* Spanish (Bolivia) */ + {0x4409, "en"}, /* English (Malaysia) */ + {0x440A, "es"}, /* Spanish (El Salvador) */ + {0x4809, "en"}, /* English (Singapore) */ + {0x480A, "es"}, /* Spanish (Honduras) */ + {0x4C0A, "es"}, /* Spanish (Nicaragua) */ + {0x500A, "es"}, /* Spanish (Puerto Rico) */ + {0x540A, "es"}, /* Spanish (United States) */ + {0xE40A, "es"}, /* ??? */ + {0xE40C, "fr"}, /* ??? */ +}; + +static const hb_ot_language_map_t +hb_mac_language_map[] = +{ + { 0, "en"}, /* English */ + { 1, "fr"}, /* French */ + { 2, "de"}, /* German */ + { 3, "it"}, /* Italian */ + { 4, "nl"}, /* Dutch */ + { 5, "sv"}, /* Swedish */ + { 6, "es"}, /* Spanish */ + { 7, "da"}, /* Danish */ + { 8, "pt"}, /* Portuguese */ + { 9, "no"}, /* Norwegian */ + { 10, "he"}, /* Hebrew */ + { 11, "ja"}, /* Japanese */ + { 12, "ar"}, /* Arabic */ + { 13, "fi"}, /* Finnish */ + { 14, "el"}, /* Greek */ + { 15, "is"}, /* Icelandic */ + { 16, "mt"}, /* Maltese */ + { 17, "tr"}, /* Turkish */ + { 18, "hr"}, /* Croatian */ + { 19, "zh-tw"}, /* Chinese (Traditional) */ + { 20, "ur"}, /* Urdu */ + { 21, "hi"}, /* Hindi */ + { 22, "th"}, /* Thai */ + { 23, "ko"}, /* Korean */ + { 24, "lt"}, /* Lithuanian */ + { 25, "pl"}, /* Polish */ + { 26, "hu"}, /* Hungarian */ + { 27, "et"}, /* Estonian */ + { 28, "lv"}, /* Latvian */ +//{ 29, ""}, /* Sami */ + { 30, "fo"}, /* Faroese */ + { 31, "fa"}, /* Farsi/Persian */ + { 32, "ru"}, /* Russian */ + { 33, "zh-cn"}, /* Chinese (Simplified) */ + { 34, "nl"}, /* Flemish */ + { 35, "ga"}, /* Irish Gaelic */ + { 36, "sq"}, /* Albanian */ + { 37, "ro"}, /* Romanian */ + { 38, "cs"}, /* Czech */ + { 39, "sk"}, /* Slovak */ + { 40, "sl"}, /* Slovenian */ + { 41, "yi"}, /* Yiddish */ + { 42, "sr"}, /* Serbian */ + { 43, "mk"}, /* Macedonian */ + { 44, "bg"}, /* Bulgarian */ + { 45, "uk"}, /* Ukrainian */ + { 46, "be"}, /* Byelorussian */ + { 47, "uz"}, /* Uzbek */ + { 48, "kk"}, /* Kazakh */ + { 49, "az"}, /* Azerbaijani (Cyrillic script) */ + { 50, "az"}, /* Azerbaijani (Arabic script) */ + { 51, "hy"}, /* Armenian */ + { 52, "ka"}, /* Georgian */ + { 53, "mo"}, /* Moldavian */ + { 54, "ky"}, /* Kirghiz */ + { 55, "tg"}, /* Tajiki */ + { 56, "tk"}, /* Turkmen */ + { 57, "mn"}, /* Mongolian (Mongolian script) */ + { 58, "mn"}, /* Mongolian (Cyrillic script) */ + { 59, "ps"}, /* Pashto */ + { 60, "ku"}, /* Kurdish */ + { 61, "ks"}, /* Kashmiri */ + { 62, "sd"}, /* Sindhi */ + { 63, "bo"}, /* Tibetan */ + { 64, "ne"}, /* Nepali */ + { 65, "sa"}, /* Sanskrit */ + { 66, "mr"}, /* Marathi */ + { 67, "bn"}, /* Bengali */ + { 68, "as"}, /* Assamese */ + { 69, "gu"}, /* Gujarati */ + { 70, "pa"}, /* Punjabi */ + { 71, "or"}, /* Oriya */ + { 72, "ml"}, /* Malayalam */ + { 73, "kn"}, /* Kannada */ + { 74, "ta"}, /* Tamil */ + { 75, "te"}, /* Telugu */ + { 76, "si"}, /* Sinhalese */ + { 77, "my"}, /* Burmese */ + { 78, "km"}, /* Khmer */ + { 79, "lo"}, /* Lao */ + { 80, "vi"}, /* Vietnamese */ + { 81, "id"}, /* Indonesian */ + { 82, "tl"}, /* Tagalog */ + { 83, "ms"}, /* Malay (Roman script) */ + { 84, "ms"}, /* Malay (Arabic script) */ + { 85, "am"}, /* Amharic */ + { 86, "ti"}, /* Tigrinya */ + { 87, "om"}, /* Galla */ + { 88, "so"}, /* Somali */ + { 89, "sw"}, /* Swahili */ + { 90, "rw"}, /* Kinyarwanda/Ruanda */ + { 91, "rn"}, /* Rundi */ + { 92, "ny"}, /* Nyanja/Chewa */ + { 93, "mg"}, /* Malagasy */ + { 94, "eo"}, /* Esperanto */ + {128, "cy"}, /* Welsh */ + {129, "eu"}, /* Basque */ + {130, "ca"}, /* Catalan */ + {131, "la"}, /* Latin */ + {132, "qu"}, /* Quechua */ + {133, "gn"}, /* Guarani */ + {134, "ay"}, /* Aymara */ + {135, "tt"}, /* Tatar */ + {136, "ug"}, /* Uighur */ + {137, "dz"}, /* Dzongkha */ + {138, "jw"}, /* Javanese (Roman script) */ + {139, "su"}, /* Sundanese (Roman script) */ + {140, "gl"}, /* Galician */ + {141, "af"}, /* Afrikaans */ + {142, "br"}, /* Breton */ + {143, "iu"}, /* Inuktitut */ + {144, "gd"}, /* Scottish Gaelic */ + {145, "gv"}, /* Manx Gaelic */ + {146, "ga"}, /* Irish Gaelic (with dot above) */ + {147, "to"}, /* Tongan */ + {148, "el"}, /* Greek (polytonic) */ + {149, "ik"}, /* Greenlandic */ + {150, "az"}, /* Azerbaijani (Roman script) */ +}; + +static hb_language_t +_hb_ot_name_language_for (unsigned int code, + const hb_ot_language_map_t *array, + unsigned int len) +{ + const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) + hb_bsearch (&code, + array, + len, + sizeof (array[0]), + hb_ot_language_map_t::cmp); + + if (entry) + return hb_language_from_string (entry->lang, -1); + + return HB_LANGUAGE_INVALID; +} + + +inline hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_ms_language_map, + ARRAY_LENGTH (hb_ms_language_map)); +} + +inline hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_mac_language_map, + ARRAY_LENGTH (hb_mac_language_map)); +} #endif /* HB_OT_NAME_LANGUAGE_HH */ diff --git a/test/api/fonts/nameID.dup.expected.ttf b/test/api/fonts/nameID.dup.expected.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e9e7ff5b4c3c254d6128e11971fed1e64a1f83e5 GIT binary patch literal 2340 zcmZWq4Qx}_6+ZX9XZzVP@q3wxOCBWe@yH*sn~)z5(ulfh5@69FCF%NJl!h2PA*pa< zh=EipZTbhP%TL*;D#2*02~8cX%JnN733O7V(M{V_#xyp;rdF!dR&9l#mDq&nZ13FX zkidGad(QdJJ@@!K_wNA#03S>O56MkE^^K{K=Zn$vU+jaiL^KHsxdA}>5gW1HDYfox z*9pXD5cduzwWD{ox=Q$+7WNJ^?t_HOmUMAh&dq#Fzh^ZEQ+HpbOM%;F1;#YC~kuoGAbCtwoNFaejb zx{c5W`(Y4%0?k|-d;k_4f(sbu&kcf~I}R$ZL6Oi3e&HZU$j$G(4;GVOg6y1yV&_$G zVk}Syc2Re?ks;)eIZg5}(HECx-29e-5G6rX?HFyRWH3azASElc5aokvC*>Si&BLD=(`2$6Q=!r|g*kLh*N~yv z9-{7GSC7$w6g8yi3DTO55G@MQT2$U(rkYHt=^kSyf@dH$Ey7f)iNYl&owjt_a?vH+{SJe2^-6{-Uu)U`5J1UV(-JtqnUcCD&z6q zw7dn+B3n^T$`pHVHmuS#S>t6wWWsBtg=lC^t>3q$t3W3R0$G!ApyzjJ^P|jH+sO9Qe$u(+}@{KFPqUF&E$$x#HIh>0sabPyX=OR`%2!$X^pwyo$xJ1ct4W zGKJAAktmNfi}iMKUaZu6r)(Ypf2V9G0w>!ohsd+CJzl18qcbH7C0!kA3gKZQBJ;<``eMdPRRc5 zmE1paS;ucLp2`JJUBvU(k2`h^cWfDSSyFig{(0d{Nk~k(Ls>*1BFhXcu%IF|MYm=hnuKil-gBKYa4z+;^#~M}PCJcv?I>dhqzM7bf~1 ze>+a92~@oCpQ(SoH@g4Nv-u}xn<=_Ig2RDd4wlEYJ%_Kgd&6xd_ak?Mof!w_o4_A{ zxX=d)VJ{pI8lc~f5a2MBLNDG|mXGZ_{sp&U?mNNZ*)RBs{XQ3LcB5hQ*w(Ss7{=Kx z{{*}5-*41gN1+ZZB5`%Zk_pPQa%)4SB7s;3XUX~p?$`Wip5=`7t7~kF-~4cMWhwIs z13zx7Tf!_yIJkU?k6F$gk9RgI%yJ#s)8DEyOMGTq_nI%dH2?$hftI ziD#LpFC!^y6BA=h9A@G)6L}^o%E&G@V;7sTi_O?&`O4W`CT=iMQI2t2m^jSDUzo@< T@nAUyk1uyXb literal 0 HcmV?d00001 diff --git a/test/api/fonts/nameID.dup.origin.ttf b/test/api/fonts/nameID.dup.origin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aad75d421bd533c092d12f935d27a859aec6c26c GIT binary patch literal 170680 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 z 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 jwjfR_MgyKgSMv)q!A!KL+cRu8+ufdNdyuo#2~X Date: Wed, 24 Apr 2019 14:02:29 -0700 Subject: [PATCH 104/336] [subset] Update to use _subset2() for name table --- src/hb-ot-name-table.hh | 47 +++++++++-------------------------------- src/hb-subset.cc | 4 ++-- 2 files changed, 12 insertions(+), 39 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index fde808c19..056a77a06 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -158,32 +158,19 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } - size_t get_subsetted_size (const name *source_name, + void get_subsetted_ids (const name *source_name, const hb_subset_plan_t *plan, hb_vector_t& name_record_idx_to_retain) const { - size_t result = min_size; - - hb_face_t *face = plan->source; - accelerator_t acc; - acc.init (face); - for(unsigned int i = 0; i < count; i++) { - if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25) + if (format == 0 && (unsigned int) source_name->nameRecordZ[i].nameID > 25) continue; if (!hb_set_is_empty (plan->name_ids) && !hb_set_has (plan->name_ids, source_name->nameRecordZ[i].nameID)) continue; - result += acc.get_name (i).get_size (); name_record_idx_to_retain.push (i); } - - acc.fini (); - - result += name_record_idx_to_retain.length * NameRecord::static_size; - - return result; } bool serialize_name_record (hb_serialize_context_t *c, @@ -294,36 +281,22 @@ struct name return_trace (true); } - bool subset (hb_subset_plan_t *plan) const + bool subset (hb_subset_context_t *c) const { + hb_subset_plan_t *plan = c->plan; hb_vector_t name_record_idx_to_retain; - size_t dest_size = get_subsetted_size (this, plan, name_record_idx_to_retain); - name *dest = (name *) malloc (dest_size); - if(unlikely (!dest)) - { - DEBUG_MSG (SUBSET, nullptr, "Unable to alloc %lu for name subset output.", - (unsigned long) dest_size); - return false; - } + get_subsetted_ids (this, plan, name_record_idx_to_retain); - hb_serialize_context_t c (dest, dest_size); - name *name_prime = c.start_serialize (); - if (!name_prime || !name_prime->serialize (&c, this, plan, name_record_idx_to_retain)) + hb_serialize_context_t *serializer = c->serializer; + name *name_prime = serializer->start_embed (); + if (!name_prime || !name_prime->serialize (serializer, this, plan, name_record_idx_to_retain)) { - free (dest); DEBUG_MSG (SUBSET, nullptr, "Failed to serialize write new name."); - c.end_serialize (); return false; } - - c.end_serialize (); - - hb_blob_t *name_prime_blob = c.copy_blob (); - bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); - hb_blob_destroy (name_prime_blob); - - return result; + + return true; } bool sanitize_records (hb_sanitize_context_t *c) const diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 333e7d484..2165b8a72 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -88,7 +88,6 @@ _subset2 (hb_subset_plan_t *plan) serializer.start_serialize (); hb_subset_context_t c (plan, &serializer); result = table->subset (&c); - serializer.end_serialize (); if (serializer.ran_out_of_room) { buf_size += (buf_size >> 1) + 32; @@ -105,6 +104,7 @@ _subset2 (hb_subset_plan_t *plan) abort (); } + serializer.end_serialize (); if (result) { hb_blob_t *dest_blob = serializer.copy_blob (); @@ -160,7 +160,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset (plan); break; case HB_OT_TAG_name: - result = _subset (plan); + result = _subset2 (plan); break; case HB_OT_TAG_head: // TODO that won't work well if there is no glyf From 2f6ec35344db08d0c892152bc7a7eaa67e7c03f0 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 24 Apr 2019 15:15:36 -0700 Subject: [PATCH 105/336] Move implementations of hb-ot-name-language.cc into a hb-static.cc --- src/hb-aat-layout.hh | 1 - src/hb-ot-name-language-static.hh | 462 ++++++++++++++++++++++++++++++ src/hb-ot-name-language.hh | 432 +--------------------------- src/hb-static.cc | 2 + 4 files changed, 468 insertions(+), 429 deletions(-) create mode 100644 src/hb-ot-name-language-static.hh diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 1ed009e12..9a0e4468f 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -32,7 +32,6 @@ #include "hb-ot-shape.hh" #include "hb-aat-ltag-table.hh" - struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; diff --git a/src/hb-ot-name-language-static.hh b/src/hb-ot-name-language-static.hh new file mode 100644 index 000000000..fac317856 --- /dev/null +++ b/src/hb-ot-name-language-static.hh @@ -0,0 +1,462 @@ +/* + * 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_NAME_LANGUAGE_STATIC_HH +#define HB_OT_NAME_LANGUAGE_STATIC_HH + +#include "hb-ot-name-language.hh" + +/* Following two tables were generated by joining FreeType, FontConfig, + * and OpenType specification language lists, then filled in missing + * entries using: + * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings + */ + +struct hb_ot_language_map_t +{ + static int cmp (const void *key, const void *item) + { + unsigned int a = * (unsigned int *) key; + unsigned int b = ((const hb_ot_language_map_t *) item)->code; + return a < b ? -1 : a > b ? +1 : 0; + } + + uint16_t code; + char lang[6]; +}; + +static const hb_ot_language_map_t +hb_ms_language_map[] = +{ + {0x0001, "ar"}, /* ??? */ + {0x0004, "zh"}, /* ??? */ + {0x0009, "en"}, /* ??? */ + {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ + {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ + {0x0403, "ca"}, /* Catalan (Catalan) */ + {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ + {0x0405, "cs"}, /* Czech (Czech Republic) */ + {0x0406, "da"}, /* Danish (Denmark) */ + {0x0407, "de"}, /* German (Germany) */ + {0x0408, "el"}, /* Greek (Greece) */ + {0x0409, "en"}, /* English (United States) */ + {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ + {0x040B, "fi"}, /* Finnish (Finland) */ + {0x040C, "fr"}, /* French (France) */ + {0x040D, "he"}, /* Hebrew (Israel) */ + {0x040E, "hu"}, /* Hungarian (Hungary) */ + {0x040F, "is"}, /* Icelandic (Iceland) */ + {0x0410, "it"}, /* Italian (Italy) */ + {0x0411, "ja"}, /* Japanese (Japan) */ + {0x0412, "ko"}, /* Korean (Korea) */ + {0x0413, "nl"}, /* Dutch (Netherlands) */ + {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ + {0x0415, "pl"}, /* Polish (Poland) */ + {0x0416, "pt"}, /* Portuguese (Brazil) */ + {0x0417, "rm"}, /* Romansh (Switzerland) */ + {0x0418, "ro"}, /* Romanian (Romania) */ + {0x0419, "ru"}, /* Russian (Russia) */ + {0x041A, "hr"}, /* Croatian (Croatia) */ + {0x041B, "sk"}, /* Slovak (Slovakia) */ + {0x041C, "sq"}, /* Albanian (Albania) */ + {0x041D, "sv"}, /* Swedish (Sweden) */ + {0x041E, "th"}, /* Thai (Thailand) */ + {0x041F, "tr"}, /* Turkish (Turkey) */ + {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ + {0x0421, "id"}, /* Indonesian (Indonesia) */ + {0x0422, "uk"}, /* Ukrainian (Ukraine) */ + {0x0423, "be"}, /* Belarusian (Belarus) */ + {0x0424, "sl"}, /* Slovenian (Slovenia) */ + {0x0425, "et"}, /* Estonian (Estonia) */ + {0x0426, "lv"}, /* Latvian (Latvia) */ + {0x0427, "lt"}, /* Lithuanian (Lithuania) */ + {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ + {0x0429, "fa"}, /* Persian (Iran) */ + {0x042A, "vi"}, /* Vietnamese (Vietnam) */ + {0x042B, "hy"}, /* Armenian (Armenia) */ + {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ + {0x042D, "eu"}, /* Basque (Basque) */ + {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ + {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ + {0x0430, "st"}, /* ??? */ + {0x0431, "ts"}, /* ??? */ + {0x0432, "tn"}, /* Setswana (South Africa) */ + {0x0433, "ven"}, /* ??? */ + {0x0434, "xh"}, /* isiXhosa (South Africa) */ + {0x0435, "zu"}, /* isiZulu (South Africa) */ + {0x0436, "af"}, /* Afrikaans (South Africa) */ + {0x0437, "ka"}, /* Georgian (Georgia) */ + {0x0438, "fo"}, /* Faroese (Faroe Islands) */ + {0x0439, "hi"}, /* Hindi (India) */ + {0x043A, "mt"}, /* Maltese (Malta) */ + {0x043B, "se"}, /* Sami (Northern) (Norway) */ + {0x043C, "ga"}, /* ??? */ + {0x043D, "yi"}, /* ??? */ + {0x043E, "ms"}, /* Malay (Malaysia) */ + {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ + {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ + {0x0441, "sw"}, /* Kiswahili (Kenya) */ + {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ + {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ + {0x0444, "tt"}, /* Tatar (Russia) */ + {0x0445, "bn"}, /* Bengali (India) */ + {0x0446, "pa"}, /* Punjabi (India) */ + {0x0447, "gu"}, /* Gujarati (India) */ + {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ + {0x0449, "ta"}, /* Tamil (India) */ + {0x044A, "te"}, /* Telugu (India) */ + {0x044B, "kn"}, /* Kannada (India) */ + {0x044C, "ml"}, /* Malayalam (India) */ + {0x044D, "as"}, /* Assamese (India) */ + {0x044E, "mr"}, /* Marathi (India) */ + {0x044F, "sa"}, /* Sanskrit (India) */ + {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ + {0x0451, "bo"}, /* Tibetan (PRC) */ + {0x0452, "cy"}, /* Welsh (United Kingdom) */ + {0x0453, "km"}, /* Khmer (Cambodia) */ + {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ + {0x0455, "my"}, /* ??? */ + {0x0456, "gl"}, /* Galician (Galician) */ + {0x0457, "kok"}, /* Konkani (India) */ + {0x0458, "mni"}, /* ??? */ + {0x0459, "sd"}, /* ??? */ + {0x045A, "syr"}, /* Syriac (Syria) */ + {0x045B, "si"}, /* Sinhala (Sri Lanka) */ + {0x045C, "chr"}, /* ??? */ + {0x045D, "iu"}, /* Inuktitut (Canada) */ + {0x045E, "am"}, /* Amharic (Ethiopia) */ + {0x0460, "ks"}, /* ??? */ + {0x0461, "ne"}, /* Nepali (Nepal) */ + {0x0462, "fy"}, /* Frisian (Netherlands) */ + {0x0463, "ps"}, /* Pashto (Afghanistan) */ + {0x0464, "phi"}, /* Filipino (Philippines) */ + {0x0465, "div"}, /* Divehi (Maldives) */ + {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ + {0x046A, "yo"}, /* Yoruba (Nigeria) */ + {0x046B, "quz"}, /* Quechua (Bolivia) */ + {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ + {0x046D, "ba"}, /* Bashkir (Russia) */ + {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ + {0x046F, "kl"}, /* Greenlandic (Greenland) */ + {0x0470, "ibo"}, /* Igbo (Nigeria) */ + {0x0471, "kau"}, /* ??? */ + {0x0472, "om"}, /* ??? */ + {0x0473, "ti"}, /* ??? */ + {0x0474, "gn"}, /* ??? */ + {0x0475, "haw"}, /* ??? */ + {0x0476, "la"}, /* ??? */ + {0x0477, "so"}, /* ??? */ + {0x0478, "ii"}, /* Yi (PRC) */ + {0x0479, "pap"}, /* ??? */ + {0x047A, "arn"}, /* Mapudungun (Chile) */ + {0x047C, "moh"}, /* Mohawk (Mohawk) */ + {0x047E, "br"}, /* Breton (France) */ + {0x0480, "ug"}, /* Uighur (PRC) */ + {0x0481, "mi"}, /* Maori (New Zealand) */ + {0x0482, "oc"}, /* Occitan (France) */ + {0x0483, "co"}, /* Corsican (France) */ + {0x0484, "gsw"}, /* Alsatian (France) */ + {0x0485, "sah"}, /* Yakut (Russia) */ + {0x0486, "qut"}, /* K'iche (Guatemala) */ + {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ + {0x0488, "wo"}, /* Wolof (Senegal) */ + {0x048C, "fa"}, /* Dari (Afghanistan) */ + {0x0801, "ar"}, /* Arabic (Iraq) */ + {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ + {0x0807, "de"}, /* German (Switzerland) */ + {0x0809, "en"}, /* English (United Kingdom) */ + {0x080A, "es"}, /* Spanish (Mexico) */ + {0x080C, "fr"}, /* French (Belgium) */ + {0x0810, "it"}, /* Italian (Switzerland) */ + {0x0812, "ko"}, /* ??? */ + {0x0813, "nl"}, /* Dutch (Belgium) */ + {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ + {0x0816, "pt"}, /* Portuguese (Portugal) */ + {0x0818, "mo"}, /* ??? */ + {0x0819, "ru"}, /* ??? */ + {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ + {0x081D, "sv"}, /* Sweden (Finland) */ + {0x0820, "ur"}, /* ??? */ + {0x0827, "lt"}, /* ??? */ + {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ + {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ +//{0x083B, ""}, /* Sami (Northern) (Sweden) */ + {0x083C, "gd"}, /* Irish (Ireland) */ + {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ + {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ + {0x0845, "bn"}, /* Bengali (Bangladesh) */ + {0x0846, "ar"}, /* ??? */ + {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ + {0x0851, "dz"}, /* ??? */ + {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ + {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ + {0x0861, "ne"}, /* ??? */ +//{0x086B, ""}, /* Quechua (Ecuador) */ + {0x0873, "ti"}, /* ??? */ + {0x0C01, "ar"}, /* Arabic (Egypt) */ + {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ + {0x0C07, "de"}, /* German (Austria) */ + {0x0C09, "en"}, /* English (Australia) */ + {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ + {0x0C0C, "fr"}, /* French (Canada) */ + {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ + {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ +//{0x0C6B, ""}, /* Quechua (Peru) */ + {0x1001, "ar"}, /* Arabic (Libya) */ + {0x1004, "zh-sg"}, /* Chinese (Singapore) */ + {0x1007, "de"}, /* German (Luxembourg) */ + {0x1009, "en"}, /* English (Canada) */ + {0x100A, "es"}, /* Spanish (Guatemala) */ + {0x100C, "fr"}, /* French (Switzerland) */ + {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ + {0x103B, "smj"}, /* Sami (Lule) (Norway) */ + {0x1401, "ar"}, /* Arabic (Algeria) */ +//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ + {0x1407, "de"}, /* German (Liechtenstein) */ + {0x1409, "en"}, /* English (New Zealand) */ + {0x140A, "es"}, /* Spanish (Costa Rica) */ + {0x140C, "fr"}, /* French (Luxembourg) */ + {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ +//{0x143B, ""}, /* Sami (Lule) (Sweden) */ + {0x1801, "ar"}, /* Arabic (Morocco) */ + {0x1809, "en"}, /* English (Ireland) */ + {0x180A, "es"}, /* Spanish (Panama) */ + {0x180C, "fr"}, /* French (Principality of Monaco) */ +//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ + {0x183B, "sma"}, /* Sami (Southern) (Norway) */ + {0x1C01, "ar"}, /* Arabic (Tunisia) */ + {0x1C09, "en"}, /* English (South Africa) */ + {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ + {0x1C0C, "fr"}, /* ??? */ +//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ +//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ + {0x2001, "ar"}, /* Arabic (Oman) */ + {0x2009, "en"}, /* English (Jamaica) */ + {0x200A, "es"}, /* Spanish (Venezuela) */ + {0x200C, "fr"}, /* ??? */ + {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ + {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ + {0x2401, "ar"}, /* Arabic (Yemen) */ + {0x2409, "en"}, /* English (Caribbean) */ + {0x240A, "es"}, /* Spanish (Colombia) */ + {0x240C, "fr"}, /* ??? */ + {0x243B, "smn"}, /* Sami (Inari) (Finland) */ + {0x2801, "ar"}, /* Arabic (Syria) */ + {0x2809, "en"}, /* English (Belize) */ + {0x280A, "es"}, /* Spanish (Peru) */ + {0x280C, "fr"}, /* ??? */ + {0x2C01, "ar"}, /* Arabic (Jordan) */ + {0x2C09, "en"}, /* English (Trinidad and Tobago) */ + {0x2C0A, "es"}, /* Spanish (Argentina) */ + {0x2C0C, "fr"}, /* ??? */ + {0x3001, "ar"}, /* Arabic (Lebanon) */ + {0x3009, "en"}, /* English (Zimbabwe) */ + {0x300A, "es"}, /* Spanish (Ecuador) */ + {0x300C, "fr"}, /* ??? */ + {0x3401, "ar"}, /* Arabic (Kuwait) */ + {0x3409, "en"}, /* English (Republic of the Philippines) */ + {0x340A, "es"}, /* Spanish (Chile) */ + {0x340C, "fr"}, /* ??? */ + {0x3801, "ar"}, /* Arabic (U.A.E.) */ + {0x380A, "es"}, /* Spanish (Uruguay) */ + {0x380C, "fr"}, /* ??? */ + {0x3C01, "ar"}, /* Arabic (Bahrain) */ + {0x3C09, "en"}, /* ??? */ + {0x3C0A, "es"}, /* Spanish (Paraguay) */ + {0x3C0C, "fr"}, /* ??? */ + {0x4001, "ar"}, /* Arabic (Qatar) */ + {0x4009, "en"}, /* English (India) */ + {0x400A, "es"}, /* Spanish (Bolivia) */ + {0x4409, "en"}, /* English (Malaysia) */ + {0x440A, "es"}, /* Spanish (El Salvador) */ + {0x4809, "en"}, /* English (Singapore) */ + {0x480A, "es"}, /* Spanish (Honduras) */ + {0x4C0A, "es"}, /* Spanish (Nicaragua) */ + {0x500A, "es"}, /* Spanish (Puerto Rico) */ + {0x540A, "es"}, /* Spanish (United States) */ + {0xE40A, "es"}, /* ??? */ + {0xE40C, "fr"}, /* ??? */ +}; + +static const hb_ot_language_map_t +hb_mac_language_map[] = +{ + { 0, "en"}, /* English */ + { 1, "fr"}, /* French */ + { 2, "de"}, /* German */ + { 3, "it"}, /* Italian */ + { 4, "nl"}, /* Dutch */ + { 5, "sv"}, /* Swedish */ + { 6, "es"}, /* Spanish */ + { 7, "da"}, /* Danish */ + { 8, "pt"}, /* Portuguese */ + { 9, "no"}, /* Norwegian */ + { 10, "he"}, /* Hebrew */ + { 11, "ja"}, /* Japanese */ + { 12, "ar"}, /* Arabic */ + { 13, "fi"}, /* Finnish */ + { 14, "el"}, /* Greek */ + { 15, "is"}, /* Icelandic */ + { 16, "mt"}, /* Maltese */ + { 17, "tr"}, /* Turkish */ + { 18, "hr"}, /* Croatian */ + { 19, "zh-tw"}, /* Chinese (Traditional) */ + { 20, "ur"}, /* Urdu */ + { 21, "hi"}, /* Hindi */ + { 22, "th"}, /* Thai */ + { 23, "ko"}, /* Korean */ + { 24, "lt"}, /* Lithuanian */ + { 25, "pl"}, /* Polish */ + { 26, "hu"}, /* Hungarian */ + { 27, "et"}, /* Estonian */ + { 28, "lv"}, /* Latvian */ +//{ 29, ""}, /* Sami */ + { 30, "fo"}, /* Faroese */ + { 31, "fa"}, /* Farsi/Persian */ + { 32, "ru"}, /* Russian */ + { 33, "zh-cn"}, /* Chinese (Simplified) */ + { 34, "nl"}, /* Flemish */ + { 35, "ga"}, /* Irish Gaelic */ + { 36, "sq"}, /* Albanian */ + { 37, "ro"}, /* Romanian */ + { 38, "cs"}, /* Czech */ + { 39, "sk"}, /* Slovak */ + { 40, "sl"}, /* Slovenian */ + { 41, "yi"}, /* Yiddish */ + { 42, "sr"}, /* Serbian */ + { 43, "mk"}, /* Macedonian */ + { 44, "bg"}, /* Bulgarian */ + { 45, "uk"}, /* Ukrainian */ + { 46, "be"}, /* Byelorussian */ + { 47, "uz"}, /* Uzbek */ + { 48, "kk"}, /* Kazakh */ + { 49, "az"}, /* Azerbaijani (Cyrillic script) */ + { 50, "az"}, /* Azerbaijani (Arabic script) */ + { 51, "hy"}, /* Armenian */ + { 52, "ka"}, /* Georgian */ + { 53, "mo"}, /* Moldavian */ + { 54, "ky"}, /* Kirghiz */ + { 55, "tg"}, /* Tajiki */ + { 56, "tk"}, /* Turkmen */ + { 57, "mn"}, /* Mongolian (Mongolian script) */ + { 58, "mn"}, /* Mongolian (Cyrillic script) */ + { 59, "ps"}, /* Pashto */ + { 60, "ku"}, /* Kurdish */ + { 61, "ks"}, /* Kashmiri */ + { 62, "sd"}, /* Sindhi */ + { 63, "bo"}, /* Tibetan */ + { 64, "ne"}, /* Nepali */ + { 65, "sa"}, /* Sanskrit */ + { 66, "mr"}, /* Marathi */ + { 67, "bn"}, /* Bengali */ + { 68, "as"}, /* Assamese */ + { 69, "gu"}, /* Gujarati */ + { 70, "pa"}, /* Punjabi */ + { 71, "or"}, /* Oriya */ + { 72, "ml"}, /* Malayalam */ + { 73, "kn"}, /* Kannada */ + { 74, "ta"}, /* Tamil */ + { 75, "te"}, /* Telugu */ + { 76, "si"}, /* Sinhalese */ + { 77, "my"}, /* Burmese */ + { 78, "km"}, /* Khmer */ + { 79, "lo"}, /* Lao */ + { 80, "vi"}, /* Vietnamese */ + { 81, "id"}, /* Indonesian */ + { 82, "tl"}, /* Tagalog */ + { 83, "ms"}, /* Malay (Roman script) */ + { 84, "ms"}, /* Malay (Arabic script) */ + { 85, "am"}, /* Amharic */ + { 86, "ti"}, /* Tigrinya */ + { 87, "om"}, /* Galla */ + { 88, "so"}, /* Somali */ + { 89, "sw"}, /* Swahili */ + { 90, "rw"}, /* Kinyarwanda/Ruanda */ + { 91, "rn"}, /* Rundi */ + { 92, "ny"}, /* Nyanja/Chewa */ + { 93, "mg"}, /* Malagasy */ + { 94, "eo"}, /* Esperanto */ + {128, "cy"}, /* Welsh */ + {129, "eu"}, /* Basque */ + {130, "ca"}, /* Catalan */ + {131, "la"}, /* Latin */ + {132, "qu"}, /* Quechua */ + {133, "gn"}, /* Guarani */ + {134, "ay"}, /* Aymara */ + {135, "tt"}, /* Tatar */ + {136, "ug"}, /* Uighur */ + {137, "dz"}, /* Dzongkha */ + {138, "jw"}, /* Javanese (Roman script) */ + {139, "su"}, /* Sundanese (Roman script) */ + {140, "gl"}, /* Galician */ + {141, "af"}, /* Afrikaans */ + {142, "br"}, /* Breton */ + {143, "iu"}, /* Inuktitut */ + {144, "gd"}, /* Scottish Gaelic */ + {145, "gv"}, /* Manx Gaelic */ + {146, "ga"}, /* Irish Gaelic (with dot above) */ + {147, "to"}, /* Tongan */ + {148, "el"}, /* Greek (polytonic) */ + {149, "ik"}, /* Greenlandic */ + {150, "az"}, /* Azerbaijani (Roman script) */ +}; + + +static hb_language_t +_hb_ot_name_language_for (unsigned int code, + const hb_ot_language_map_t *array, + unsigned int len) +{ + const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) + hb_bsearch (&code, + array, + len, + sizeof (array[0]), + hb_ot_language_map_t::cmp); + + if (entry) + return hb_language_from_string (entry->lang, -1); + + return HB_LANGUAGE_INVALID; +} + +hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_ms_language_map, + ARRAY_LENGTH (hb_ms_language_map)); +} + +hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_mac_language_map, + ARRAY_LENGTH (hb_mac_language_map)); +} + +#endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */ diff --git a/src/hb-ot-name-language.hh b/src/hb-ot-name-language.hh index a5449764c..903076c0d 100644 --- a/src/hb-ot-name-language.hh +++ b/src/hb-ot-name-language.hh @@ -29,436 +29,12 @@ #include "hb.hh" -/* Following two tables were generated by joining FreeType, FontConfig, - * and OpenType specification language lists, then filled in missing - * entries using: - * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings - */ -struct hb_ot_language_map_t -{ - static int cmp (const void *key, const void *item) - { - unsigned int a = * (unsigned int *) key; - unsigned int b = ((const hb_ot_language_map_t *) item)->code; - return a < b ? -1 : a > b ? +1 : 0; - } +HB_INTERNAL hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code); - uint16_t code; - char lang[6]; -}; - - -static const hb_ot_language_map_t -hb_ms_language_map[] = -{ - {0x0001, "ar"}, /* ??? */ - {0x0004, "zh"}, /* ??? */ - {0x0009, "en"}, /* ??? */ - {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ - {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ - {0x0403, "ca"}, /* Catalan (Catalan) */ - {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ - {0x0405, "cs"}, /* Czech (Czech Republic) */ - {0x0406, "da"}, /* Danish (Denmark) */ - {0x0407, "de"}, /* German (Germany) */ - {0x0408, "el"}, /* Greek (Greece) */ - {0x0409, "en"}, /* English (United States) */ - {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ - {0x040B, "fi"}, /* Finnish (Finland) */ - {0x040C, "fr"}, /* French (France) */ - {0x040D, "he"}, /* Hebrew (Israel) */ - {0x040E, "hu"}, /* Hungarian (Hungary) */ - {0x040F, "is"}, /* Icelandic (Iceland) */ - {0x0410, "it"}, /* Italian (Italy) */ - {0x0411, "ja"}, /* Japanese (Japan) */ - {0x0412, "ko"}, /* Korean (Korea) */ - {0x0413, "nl"}, /* Dutch (Netherlands) */ - {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ - {0x0415, "pl"}, /* Polish (Poland) */ - {0x0416, "pt"}, /* Portuguese (Brazil) */ - {0x0417, "rm"}, /* Romansh (Switzerland) */ - {0x0418, "ro"}, /* Romanian (Romania) */ - {0x0419, "ru"}, /* Russian (Russia) */ - {0x041A, "hr"}, /* Croatian (Croatia) */ - {0x041B, "sk"}, /* Slovak (Slovakia) */ - {0x041C, "sq"}, /* Albanian (Albania) */ - {0x041D, "sv"}, /* Swedish (Sweden) */ - {0x041E, "th"}, /* Thai (Thailand) */ - {0x041F, "tr"}, /* Turkish (Turkey) */ - {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ - {0x0421, "id"}, /* Indonesian (Indonesia) */ - {0x0422, "uk"}, /* Ukrainian (Ukraine) */ - {0x0423, "be"}, /* Belarusian (Belarus) */ - {0x0424, "sl"}, /* Slovenian (Slovenia) */ - {0x0425, "et"}, /* Estonian (Estonia) */ - {0x0426, "lv"}, /* Latvian (Latvia) */ - {0x0427, "lt"}, /* Lithuanian (Lithuania) */ - {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ - {0x0429, "fa"}, /* Persian (Iran) */ - {0x042A, "vi"}, /* Vietnamese (Vietnam) */ - {0x042B, "hy"}, /* Armenian (Armenia) */ - {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ - {0x042D, "eu"}, /* Basque (Basque) */ - {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ - {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ - {0x0430, "st"}, /* ??? */ - {0x0431, "ts"}, /* ??? */ - {0x0432, "tn"}, /* Setswana (South Africa) */ - {0x0433, "ven"}, /* ??? */ - {0x0434, "xh"}, /* isiXhosa (South Africa) */ - {0x0435, "zu"}, /* isiZulu (South Africa) */ - {0x0436, "af"}, /* Afrikaans (South Africa) */ - {0x0437, "ka"}, /* Georgian (Georgia) */ - {0x0438, "fo"}, /* Faroese (Faroe Islands) */ - {0x0439, "hi"}, /* Hindi (India) */ - {0x043A, "mt"}, /* Maltese (Malta) */ - {0x043B, "se"}, /* Sami (Northern) (Norway) */ - {0x043C, "ga"}, /* ??? */ - {0x043D, "yi"}, /* ??? */ - {0x043E, "ms"}, /* Malay (Malaysia) */ - {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ - {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ - {0x0441, "sw"}, /* Kiswahili (Kenya) */ - {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ - {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ - {0x0444, "tt"}, /* Tatar (Russia) */ - {0x0445, "bn"}, /* Bengali (India) */ - {0x0446, "pa"}, /* Punjabi (India) */ - {0x0447, "gu"}, /* Gujarati (India) */ - {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ - {0x0449, "ta"}, /* Tamil (India) */ - {0x044A, "te"}, /* Telugu (India) */ - {0x044B, "kn"}, /* Kannada (India) */ - {0x044C, "ml"}, /* Malayalam (India) */ - {0x044D, "as"}, /* Assamese (India) */ - {0x044E, "mr"}, /* Marathi (India) */ - {0x044F, "sa"}, /* Sanskrit (India) */ - {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ - {0x0451, "bo"}, /* Tibetan (PRC) */ - {0x0452, "cy"}, /* Welsh (United Kingdom) */ - {0x0453, "km"}, /* Khmer (Cambodia) */ - {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ - {0x0455, "my"}, /* ??? */ - {0x0456, "gl"}, /* Galician (Galician) */ - {0x0457, "kok"}, /* Konkani (India) */ - {0x0458, "mni"}, /* ??? */ - {0x0459, "sd"}, /* ??? */ - {0x045A, "syr"}, /* Syriac (Syria) */ - {0x045B, "si"}, /* Sinhala (Sri Lanka) */ - {0x045C, "chr"}, /* ??? */ - {0x045D, "iu"}, /* Inuktitut (Canada) */ - {0x045E, "am"}, /* Amharic (Ethiopia) */ - {0x0460, "ks"}, /* ??? */ - {0x0461, "ne"}, /* Nepali (Nepal) */ - {0x0462, "fy"}, /* Frisian (Netherlands) */ - {0x0463, "ps"}, /* Pashto (Afghanistan) */ - {0x0464, "phi"}, /* Filipino (Philippines) */ - {0x0465, "div"}, /* Divehi (Maldives) */ - {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ - {0x046A, "yo"}, /* Yoruba (Nigeria) */ - {0x046B, "quz"}, /* Quechua (Bolivia) */ - {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ - {0x046D, "ba"}, /* Bashkir (Russia) */ - {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ - {0x046F, "kl"}, /* Greenlandic (Greenland) */ - {0x0470, "ibo"}, /* Igbo (Nigeria) */ - {0x0471, "kau"}, /* ??? */ - {0x0472, "om"}, /* ??? */ - {0x0473, "ti"}, /* ??? */ - {0x0474, "gn"}, /* ??? */ - {0x0475, "haw"}, /* ??? */ - {0x0476, "la"}, /* ??? */ - {0x0477, "so"}, /* ??? */ - {0x0478, "ii"}, /* Yi (PRC) */ - {0x0479, "pap"}, /* ??? */ - {0x047A, "arn"}, /* Mapudungun (Chile) */ - {0x047C, "moh"}, /* Mohawk (Mohawk) */ - {0x047E, "br"}, /* Breton (France) */ - {0x0480, "ug"}, /* Uighur (PRC) */ - {0x0481, "mi"}, /* Maori (New Zealand) */ - {0x0482, "oc"}, /* Occitan (France) */ - {0x0483, "co"}, /* Corsican (France) */ - {0x0484, "gsw"}, /* Alsatian (France) */ - {0x0485, "sah"}, /* Yakut (Russia) */ - {0x0486, "qut"}, /* K'iche (Guatemala) */ - {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ - {0x0488, "wo"}, /* Wolof (Senegal) */ - {0x048C, "fa"}, /* Dari (Afghanistan) */ - {0x0801, "ar"}, /* Arabic (Iraq) */ - {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ - {0x0807, "de"}, /* German (Switzerland) */ - {0x0809, "en"}, /* English (United Kingdom) */ - {0x080A, "es"}, /* Spanish (Mexico) */ - {0x080C, "fr"}, /* French (Belgium) */ - {0x0810, "it"}, /* Italian (Switzerland) */ - {0x0812, "ko"}, /* ??? */ - {0x0813, "nl"}, /* Dutch (Belgium) */ - {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ - {0x0816, "pt"}, /* Portuguese (Portugal) */ - {0x0818, "mo"}, /* ??? */ - {0x0819, "ru"}, /* ??? */ - {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ - {0x081D, "sv"}, /* Sweden (Finland) */ - {0x0820, "ur"}, /* ??? */ - {0x0827, "lt"}, /* ??? */ - {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ - {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ -//{0x083B, ""}, /* Sami (Northern) (Sweden) */ - {0x083C, "gd"}, /* Irish (Ireland) */ - {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ - {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ - {0x0845, "bn"}, /* Bengali (Bangladesh) */ - {0x0846, "ar"}, /* ??? */ - {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ - {0x0851, "dz"}, /* ??? */ - {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ - {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ - {0x0861, "ne"}, /* ??? */ -//{0x086B, ""}, /* Quechua (Ecuador) */ - {0x0873, "ti"}, /* ??? */ - {0x0C01, "ar"}, /* Arabic (Egypt) */ - {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ - {0x0C07, "de"}, /* German (Austria) */ - {0x0C09, "en"}, /* English (Australia) */ - {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ - {0x0C0C, "fr"}, /* French (Canada) */ - {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ - {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ -//{0x0C6B, ""}, /* Quechua (Peru) */ - {0x1001, "ar"}, /* Arabic (Libya) */ - {0x1004, "zh-sg"}, /* Chinese (Singapore) */ - {0x1007, "de"}, /* German (Luxembourg) */ - {0x1009, "en"}, /* English (Canada) */ - {0x100A, "es"}, /* Spanish (Guatemala) */ - {0x100C, "fr"}, /* French (Switzerland) */ - {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ - {0x103B, "smj"}, /* Sami (Lule) (Norway) */ - {0x1401, "ar"}, /* Arabic (Algeria) */ -//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ - {0x1407, "de"}, /* German (Liechtenstein) */ - {0x1409, "en"}, /* English (New Zealand) */ - {0x140A, "es"}, /* Spanish (Costa Rica) */ - {0x140C, "fr"}, /* French (Luxembourg) */ - {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ -//{0x143B, ""}, /* Sami (Lule) (Sweden) */ - {0x1801, "ar"}, /* Arabic (Morocco) */ - {0x1809, "en"}, /* English (Ireland) */ - {0x180A, "es"}, /* Spanish (Panama) */ - {0x180C, "fr"}, /* French (Principality of Monaco) */ -//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ - {0x183B, "sma"}, /* Sami (Southern) (Norway) */ - {0x1C01, "ar"}, /* Arabic (Tunisia) */ - {0x1C09, "en"}, /* English (South Africa) */ - {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ - {0x1C0C, "fr"}, /* ??? */ -//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ -//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ - {0x2001, "ar"}, /* Arabic (Oman) */ - {0x2009, "en"}, /* English (Jamaica) */ - {0x200A, "es"}, /* Spanish (Venezuela) */ - {0x200C, "fr"}, /* ??? */ - {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ - {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ - {0x2401, "ar"}, /* Arabic (Yemen) */ - {0x2409, "en"}, /* English (Caribbean) */ - {0x240A, "es"}, /* Spanish (Colombia) */ - {0x240C, "fr"}, /* ??? */ - {0x243B, "smn"}, /* Sami (Inari) (Finland) */ - {0x2801, "ar"}, /* Arabic (Syria) */ - {0x2809, "en"}, /* English (Belize) */ - {0x280A, "es"}, /* Spanish (Peru) */ - {0x280C, "fr"}, /* ??? */ - {0x2C01, "ar"}, /* Arabic (Jordan) */ - {0x2C09, "en"}, /* English (Trinidad and Tobago) */ - {0x2C0A, "es"}, /* Spanish (Argentina) */ - {0x2C0C, "fr"}, /* ??? */ - {0x3001, "ar"}, /* Arabic (Lebanon) */ - {0x3009, "en"}, /* English (Zimbabwe) */ - {0x300A, "es"}, /* Spanish (Ecuador) */ - {0x300C, "fr"}, /* ??? */ - {0x3401, "ar"}, /* Arabic (Kuwait) */ - {0x3409, "en"}, /* English (Republic of the Philippines) */ - {0x340A, "es"}, /* Spanish (Chile) */ - {0x340C, "fr"}, /* ??? */ - {0x3801, "ar"}, /* Arabic (U.A.E.) */ - {0x380A, "es"}, /* Spanish (Uruguay) */ - {0x380C, "fr"}, /* ??? */ - {0x3C01, "ar"}, /* Arabic (Bahrain) */ - {0x3C09, "en"}, /* ??? */ - {0x3C0A, "es"}, /* Spanish (Paraguay) */ - {0x3C0C, "fr"}, /* ??? */ - {0x4001, "ar"}, /* Arabic (Qatar) */ - {0x4009, "en"}, /* English (India) */ - {0x400A, "es"}, /* Spanish (Bolivia) */ - {0x4409, "en"}, /* English (Malaysia) */ - {0x440A, "es"}, /* Spanish (El Salvador) */ - {0x4809, "en"}, /* English (Singapore) */ - {0x480A, "es"}, /* Spanish (Honduras) */ - {0x4C0A, "es"}, /* Spanish (Nicaragua) */ - {0x500A, "es"}, /* Spanish (Puerto Rico) */ - {0x540A, "es"}, /* Spanish (United States) */ - {0xE40A, "es"}, /* ??? */ - {0xE40C, "fr"}, /* ??? */ -}; - -static const hb_ot_language_map_t -hb_mac_language_map[] = -{ - { 0, "en"}, /* English */ - { 1, "fr"}, /* French */ - { 2, "de"}, /* German */ - { 3, "it"}, /* Italian */ - { 4, "nl"}, /* Dutch */ - { 5, "sv"}, /* Swedish */ - { 6, "es"}, /* Spanish */ - { 7, "da"}, /* Danish */ - { 8, "pt"}, /* Portuguese */ - { 9, "no"}, /* Norwegian */ - { 10, "he"}, /* Hebrew */ - { 11, "ja"}, /* Japanese */ - { 12, "ar"}, /* Arabic */ - { 13, "fi"}, /* Finnish */ - { 14, "el"}, /* Greek */ - { 15, "is"}, /* Icelandic */ - { 16, "mt"}, /* Maltese */ - { 17, "tr"}, /* Turkish */ - { 18, "hr"}, /* Croatian */ - { 19, "zh-tw"}, /* Chinese (Traditional) */ - { 20, "ur"}, /* Urdu */ - { 21, "hi"}, /* Hindi */ - { 22, "th"}, /* Thai */ - { 23, "ko"}, /* Korean */ - { 24, "lt"}, /* Lithuanian */ - { 25, "pl"}, /* Polish */ - { 26, "hu"}, /* Hungarian */ - { 27, "et"}, /* Estonian */ - { 28, "lv"}, /* Latvian */ -//{ 29, ""}, /* Sami */ - { 30, "fo"}, /* Faroese */ - { 31, "fa"}, /* Farsi/Persian */ - { 32, "ru"}, /* Russian */ - { 33, "zh-cn"}, /* Chinese (Simplified) */ - { 34, "nl"}, /* Flemish */ - { 35, "ga"}, /* Irish Gaelic */ - { 36, "sq"}, /* Albanian */ - { 37, "ro"}, /* Romanian */ - { 38, "cs"}, /* Czech */ - { 39, "sk"}, /* Slovak */ - { 40, "sl"}, /* Slovenian */ - { 41, "yi"}, /* Yiddish */ - { 42, "sr"}, /* Serbian */ - { 43, "mk"}, /* Macedonian */ - { 44, "bg"}, /* Bulgarian */ - { 45, "uk"}, /* Ukrainian */ - { 46, "be"}, /* Byelorussian */ - { 47, "uz"}, /* Uzbek */ - { 48, "kk"}, /* Kazakh */ - { 49, "az"}, /* Azerbaijani (Cyrillic script) */ - { 50, "az"}, /* Azerbaijani (Arabic script) */ - { 51, "hy"}, /* Armenian */ - { 52, "ka"}, /* Georgian */ - { 53, "mo"}, /* Moldavian */ - { 54, "ky"}, /* Kirghiz */ - { 55, "tg"}, /* Tajiki */ - { 56, "tk"}, /* Turkmen */ - { 57, "mn"}, /* Mongolian (Mongolian script) */ - { 58, "mn"}, /* Mongolian (Cyrillic script) */ - { 59, "ps"}, /* Pashto */ - { 60, "ku"}, /* Kurdish */ - { 61, "ks"}, /* Kashmiri */ - { 62, "sd"}, /* Sindhi */ - { 63, "bo"}, /* Tibetan */ - { 64, "ne"}, /* Nepali */ - { 65, "sa"}, /* Sanskrit */ - { 66, "mr"}, /* Marathi */ - { 67, "bn"}, /* Bengali */ - { 68, "as"}, /* Assamese */ - { 69, "gu"}, /* Gujarati */ - { 70, "pa"}, /* Punjabi */ - { 71, "or"}, /* Oriya */ - { 72, "ml"}, /* Malayalam */ - { 73, "kn"}, /* Kannada */ - { 74, "ta"}, /* Tamil */ - { 75, "te"}, /* Telugu */ - { 76, "si"}, /* Sinhalese */ - { 77, "my"}, /* Burmese */ - { 78, "km"}, /* Khmer */ - { 79, "lo"}, /* Lao */ - { 80, "vi"}, /* Vietnamese */ - { 81, "id"}, /* Indonesian */ - { 82, "tl"}, /* Tagalog */ - { 83, "ms"}, /* Malay (Roman script) */ - { 84, "ms"}, /* Malay (Arabic script) */ - { 85, "am"}, /* Amharic */ - { 86, "ti"}, /* Tigrinya */ - { 87, "om"}, /* Galla */ - { 88, "so"}, /* Somali */ - { 89, "sw"}, /* Swahili */ - { 90, "rw"}, /* Kinyarwanda/Ruanda */ - { 91, "rn"}, /* Rundi */ - { 92, "ny"}, /* Nyanja/Chewa */ - { 93, "mg"}, /* Malagasy */ - { 94, "eo"}, /* Esperanto */ - {128, "cy"}, /* Welsh */ - {129, "eu"}, /* Basque */ - {130, "ca"}, /* Catalan */ - {131, "la"}, /* Latin */ - {132, "qu"}, /* Quechua */ - {133, "gn"}, /* Guarani */ - {134, "ay"}, /* Aymara */ - {135, "tt"}, /* Tatar */ - {136, "ug"}, /* Uighur */ - {137, "dz"}, /* Dzongkha */ - {138, "jw"}, /* Javanese (Roman script) */ - {139, "su"}, /* Sundanese (Roman script) */ - {140, "gl"}, /* Galician */ - {141, "af"}, /* Afrikaans */ - {142, "br"}, /* Breton */ - {143, "iu"}, /* Inuktitut */ - {144, "gd"}, /* Scottish Gaelic */ - {145, "gv"}, /* Manx Gaelic */ - {146, "ga"}, /* Irish Gaelic (with dot above) */ - {147, "to"}, /* Tongan */ - {148, "el"}, /* Greek (polytonic) */ - {149, "ik"}, /* Greenlandic */ - {150, "az"}, /* Azerbaijani (Roman script) */ -}; - -static hb_language_t -_hb_ot_name_language_for (unsigned int code, - const hb_ot_language_map_t *array, - unsigned int len) -{ - const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) - hb_bsearch (&code, - array, - len, - sizeof (array[0]), - hb_ot_language_map_t::cmp); - - if (entry) - return hb_language_from_string (entry->lang, -1); - - return HB_LANGUAGE_INVALID; -} - - -inline hb_language_t -_hb_ot_name_language_for_ms_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_ms_language_map, - ARRAY_LENGTH (hb_ms_language_map)); -} - -inline hb_language_t -_hb_ot_name_language_for_mac_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_mac_language_map, - ARRAY_LENGTH (hb_mac_language_map)); -} +HB_INTERNAL hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code); #endif /* HB_OT_NAME_LANGUAGE_HH */ diff --git a/src/hb-static.cc b/src/hb-static.cc index 4c5158860..d2d8044a7 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -36,6 +36,8 @@ #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" +#include "hb-ot-name-language-static.hh" + #ifndef HB_NO_VISIBILITY 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 8c8922a019eb1ceb8beffc05ca638ee0ca25b565 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Thu, 25 Apr 2019 09:17:58 -0700 Subject: [PATCH 106/336] [subset] Updates due to changes in resolve_links() on master branch --- src/Makefile.sources | 1 + src/hb-ot-name-table.hh | 7 +++++-- src/hb-static.cc | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index 803d229ac..e61315be6 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -84,6 +84,7 @@ HB_BASE_sources = \ hb-ot-math-table.hh \ hb-ot-math.cc \ hb-ot-maxp-table.hh \ + hb-ot-name-language-static.hh \ hb-ot-name-language.hh \ hb-ot-name-table.hh \ hb-ot-name.cc \ diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 056a77a06..72deb10b4 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -187,8 +187,11 @@ struct name } c->push (); - if (!c->embed (source_name->nameRecordZ[idx])) + + NameRecord *p = c->embed (source_name->nameRecordZ[idx]); + if (!p) return false; + p->offset = 0; } return true; @@ -233,7 +236,7 @@ struct name hb_serialize_context_t *c, unsigned length) { - hb_hashmap_t id_str_idx_map; + hb_hashmap_t id_str_idx_map; for (int i = length-1; i >= 0; i--) { unsigned objidx = c->pop_pack (); diff --git a/src/hb-static.cc b/src/hb-static.cc index d2d8044a7..6b89183ca 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -36,9 +36,8 @@ #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" -#include "hb-ot-name-language-static.hh" - #ifndef HB_NO_VISIBILITY +#include "hb-ot-name-language-static.hh" 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)] = {}; /*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; From 750b65e9a980efc13e50ea5d0388ecf06e7a93b1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 17:14:25 -0700 Subject: [PATCH 107/336] [meta] Add hb_type_identity<> To block template argument deduction. --- src/hb-meta.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index c3efe48a6..b80358c2a 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -65,6 +65,9 @@ template <> struct hb_priority<0> {}; #define HB_FUNCOBJ(x) static_const x HB_UNUSED +template struct hb_match_identity { typedef T type; }; +template using hb_type_identity = typename hb_match_identity::type; + struct { template @@ -96,6 +99,7 @@ template struct hb_match_pointer { typedef T type; enum { valu template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value +/* TODO Add feature-parity to std::decay. */ template using hb_decay = hb_remove_const>; #define hb_is_cr_convertible_to(A, B) ( \ From 2b051e7aa147c78cfbf953b6f0eb18c25b732eb2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Apr 2019 10:01:11 -0700 Subject: [PATCH 108/336] [subset] Check error after calling serializer end --- src/hb-subset.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 2165b8a72..b40eba361 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -99,12 +99,11 @@ _subset2 (hb_subset_plan_t *plan) } goto retry; } - if (serializer.in_error ()) - { - abort (); - } - serializer.end_serialize (); + + if (serializer.in_error ()) + abort (); + if (result) { hb_blob_t *dest_blob = serializer.copy_blob (); From 6977a95fed8a35d6e915ed3fc3a3ea8709f3d4a4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Apr 2019 10:05:25 -0700 Subject: [PATCH 109/336] [subset] Don't crash if subsetting GSUB/GPOS fails Fixes fuzzer issue. --- src/hb-subset.cc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index b40eba361..5f482e18a 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -68,11 +68,11 @@ template static bool _subset2 (hb_subset_plan_t *plan) { + bool result = true; hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table (plan->source); const TableType *table = source_blob->as (); hb_tag_t tag = TableType::tableTag; - hb_bool_t result = false; if (source_blob->data) { hb_vector_t buf; @@ -87,7 +87,7 @@ _subset2 (hb_subset_plan_t *plan) hb_serialize_context_t serializer ((void *) buf, buf_size); serializer.start_serialize (); hb_subset_context_t c (plan, &serializer); - result = table->subset (&c); + bool needed = table->subset (&c); if (serializer.ran_out_of_room) { buf_size += (buf_size >> 1) + 32; @@ -101,20 +101,21 @@ _subset2 (hb_subset_plan_t *plan) } serializer.end_serialize (); - if (serializer.in_error ()) - abort (); + result = !serializer.in_error (); if (result) { - hb_blob_t *dest_blob = serializer.copy_blob (); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); - result = c.plan->add_table (tag, dest_blob); - hb_blob_destroy (dest_blob); - } - else - { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); - result = true; + if (needed) + { + hb_blob_t *dest_blob = serializer.copy_blob (); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); + result = c.plan->add_table (tag, dest_blob); + hb_blob_destroy (dest_blob); + } + else + { + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); + } } } else From 62c6e170728303f4225aaa25523675fc260ae1ab Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Apr 2019 10:55:07 -0700 Subject: [PATCH 110/336] [test] Add crbug.com/oss-fuzz/14474 testcase Fixed at 6977a95f --- ...-minimized-hb-subset-fuzzer-5716947896893440 | Bin 0 -> 65833 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 new file mode 100644 index 0000000000000000000000000000000000000000..639132038d0e7f0bb13b81d38993453b5781e591 GIT binary patch literal 65833 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 literal 0 HcmV?d00001 From 6d6edc8b25395c87477181a647a8e6d02f2cad4f Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Apr 2019 11:54:07 -0700 Subject: [PATCH 111/336] [valgrind] Use libtool and support run-subset-fuzzer-tests (#1668) --- test/fuzzing/Makefile.am | 4 +- test/fuzzing/run-shape-fuzzer-tests.py | 28 ++++----- test/fuzzing/run-subset-fuzzer-tests.py | 75 +++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index a77df7061..5bd2d7e6d 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -55,8 +55,8 @@ hb_subset_fuzzer_CPPFLAGS = $(AM_CPPFLAGS) hb_subset_fuzzer_DEPENDENCIES = $(top_builddir)/src/libharfbuzz-subset.la check: - EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py - EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py + EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-shape-fuzzer-tests.py + EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-subset-fuzzer-tests.py check-valgrind: $(AM_V_at)RUN_VALGRIND=1 $(MAKE) $(AM_MAKEFLGS) check diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index 90ed509c7..ba480dd52 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -67,36 +67,36 @@ please provide it as the first argument to the tool""") print ('hb_shape_fuzzer:', hb_shape_fuzzer) fails = 0 +libtool = os.environ.get('LIBTOOL') valgrind = None if os.environ.get('RUN_VALGRIND', ''): valgrind = which ('valgrind') if valgrind is None: print ("""Valgrind requested but not found.""") sys.exit (1) + if libtool is None: + print ("""Valgrind support is currently autotools only and needs libtool but not found.""") + parent_path = os.path.join (srcdir, "fonts") for file in os.listdir (parent_path): path = os.path.join(parent_path, file) - text, returncode = cmd ([hb_shape_fuzzer, path]) - if text.strip (): + if valgrind: + text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --error-exitcode=1', '--', hb_shape_fuzzer, path]) + else: + text, returncode = cmd ([hb_shape_fuzzer, path]) + if 'error' in text: + returncode = 1 + + if not valgrind and text.strip (): print (text) - failed = False - if returncode != 0 or 'error' in text: + if returncode != 0: print ('failure on %s' % file) - failed = True - - if valgrind: - text, returncode = cmd ([valgrind, '--error-exitcode=1', '--leak-check=full', hb_shape_fuzzer, path]) - if returncode: - print (text) - print ('failure on %s' % file) - failed = True - - if failed: fails = fails + 1 + if fails: print ("%i shape fuzzer related tests failed." % fails) sys.exit (1) diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py index 7392a92ec..3ac22889e 100755 --- a/test/fuzzing/run-subset-fuzzer-tests.py +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -2,7 +2,54 @@ from __future__ import print_function, division, absolute_import -import sys, os, subprocess +import sys, os, subprocess, tempfile, threading + + +def which(program): + # https://stackoverflow.com/a/377028 + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, _ = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + + return None + + +def cmd(command): + # https://stackoverflow.com/a/4408409 + # https://stackoverflow.com/a/10012262 + with tempfile.TemporaryFile() as tempf: + p = subprocess.Popen (command, stderr=tempf) + is_killed = {'value': False} + + def timeout(p, is_killed): + is_killed['value'] = True + p.kill() + timer = threading.Timer (2, timeout, [p, is_killed]) + + try: + timer.start() + p.wait () + tempf.seek (0) + text = tempf.read().decode ("utf-8").strip () + returncode = p.returncode + finally: + timer.cancel() + + if is_killed['value']: + text = 'error: timeout, ' + text + returncode = 1 + + return text, returncode + srcdir = os.environ.get ("srcdir", ".") EXEEXT = os.environ.get ("EXEEXT", "") @@ -20,21 +67,37 @@ please provide it as the first argument to the tool""") print ('hb_subset_fuzzer:', hb_subset_fuzzer) fails = 0 +libtool = os.environ.get('LIBTOOL') +valgrind = None +if os.environ.get('RUN_VALGRIND', ''): + valgrind = which ('valgrind') + if valgrind is None: + print ("""Valgrind requested but not found.""") + sys.exit (1) + if libtool is None: + print ("""Valgrind support is currently autotools only and needs libtool but not found.""") + + def run_dir (parent_path): global fails for file in os.listdir (parent_path): path = os.path.join(parent_path, file) print ("running subset fuzzer against %s" % path) - p = subprocess.Popen ([hb_subset_fuzzer, path]) + if valgrind: + text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --show-leak-kinds=all --error-exitcode=1', '--', hb_subset_fuzzer, path]) + else: + text, returncode = cmd ([hb_subset_fuzzer, path]) + if 'error' in text: + returncode = 1 - if p.wait () != 0: + if not valgrind and text.strip (): + print (text) + + if returncode != 0: print ("failed for %s" % path) fails = fails + 1 - if p.wait () != 0: - print ("failed for %s" % path) - fails = fails + 1 run_dir (os.path.join (srcdir, "..", "subset", "data", "fonts")) # TODO running these tests very slow tests. Fix and re-enable From 4aa546b70ad7b11154b901e67f98c1ec6bc5c364 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Mon, 29 Apr 2019 14:16:51 -0400 Subject: [PATCH 112/336] Allow some Balinese Po & So as aksara modre bases --- src/gen-use-table.py | 10 ++++++++-- src/hb-ot-shape-complex-use-table.cc | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 029e66e53..1a33b8af5 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -48,6 +48,12 @@ defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block') # TODO Characters that are not in Unicode Indic files, but used in USE data[0][0x034F] = defaults[0] data[0][0x2060] = defaults[0] +# TODO https://github.com/harfbuzz/harfbuzz/pull/1685 +data[0][0x1B5B] = 'Consonant_Placeholder' +data[0][0x1B5C] = 'Consonant_Placeholder' +data[0][0x1B5F] = 'Consonant_Placeholder' +data[0][0x1B62] = 'Consonant_Placeholder' +data[0][0x1B68] = 'Consonant_Placeholder' # TODO https://github.com/roozbehp/unicode-data/issues/9 data[0][0x11C44] = 'Consonant_Placeholder' data[0][0x11C45] = 'Consonant_Placeholder' @@ -171,7 +177,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, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or + (UGC == Po and not U in [0x104B, 0x104E, 0x1B5B, 0x1B5C, 0x1B5F, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or False # SPEC-DRAFT-OUTDATED! U == 0x002D ) def is_BASE_NUM(U, UISC, UGC): @@ -228,7 +234,7 @@ def is_REPHA(U, UISC, UGC): def is_SYM(U, UISC, UGC): if U == 0x25CC: return False #SPEC-DRAFT #SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter - return UGC in [So, Sc] + return UGC in [So, Sc] and U not in [0x1B62, 0x1B68] def is_SYM_MOD(U, UISC, UGC): return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73] def is_VARIATION_SELECTOR(U, UISC, UGC): diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index cb5c358cd..ddf7053db 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -318,8 +318,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, /* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, - /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, + /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB, + /* 1B60 */ O, O, GB, O, O, O, O, O, GB, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, /* Sundanese */ From e200d165a4e8a5f901165c705d617b6e457ec595 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Apr 2019 02:10:50 +0430 Subject: [PATCH 113/336] [ci] Remove crosscompile-notest-freebsd9 bot It was testing an old version of freebsd and now it's image is gone. We really like to test the environment. --- .circleci/config.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c901ebf1..9eeb1549e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -235,15 +235,6 @@ jobs: - run: CFLAGS="-Wno-attributes" CXXFLAGS="-Wno-attributes" ./autogen.sh --prefix=/usr/local/djgpp --host=i586-pc-msdosdjgpp - run: make -j32 - crosscompile-notest-freebsd9: - docker: - - image: donbowman/freebsd-cross-build - steps: - - checkout - - run: apt update && apt install -y pkg-config ragel - - run: ./autogen.sh --prefix=/freebsd --host=x86_64-pc-freebsd9 - - run: make -j32 - crosscompile-notest-psvita: docker: - image: dockcross/base @@ -327,7 +318,6 @@ workflows: # they can't be test thus are without tests ## autotools - crosscompile-notest-djgpp - - crosscompile-notest-freebsd9 - crosscompile-notest-psvita ## cmake From 9542bdd0ed2d581cdb4bd950ac3cd7e3bf899478 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Apr 2019 14:52:28 -0700 Subject: [PATCH 114/336] Add color channels getters ABI (#1513) So can be used with language wrappers --- src/hb-common.cc | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/hb-common.h | 44 ++++++++++++---------------------------- 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index 60d16c8a4..c453443e7 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -1160,6 +1160,59 @@ hb_variation_to_string (hb_variation_t *variation, buf[len] = '\0'; } +/** + * hb_color_get_alpha: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_alpha) (hb_color_t color) +{ + return hb_color_get_alpha (color); +} + +/** + * hb_color_get_red: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_red) (hb_color_t color) +{ + return hb_color_get_red (color); +} + +/** + * hb_color_get_green: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_green) (hb_color_t color) +{ + return hb_color_get_green (color); +} + +/** + * hb_color_get_blue: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_blue) (hb_color_t color) +{ + return hb_color_get_blue (color); +} + + /* If there is no visibility control, then hb-static.cc will NOT * define anything. Instead, we get it to define one set in here * only, so only libharfbuzz.so defines them, not other libs. */ diff --git a/src/hb-common.h b/src/hb-common.h index 371b2bfc9..edd9ffb86 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -467,39 +467,21 @@ typedef uint32_t hb_color_t; #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a))) -/** - * hb_color_get_alpha: - * - * - * - * Since: 2.1.0 - */ +HB_EXTERN uint8_t +hb_color_get_alpha (hb_color_t color); #define hb_color_get_alpha(color) ((color) & 0xFF) -/** - * hb_color_get_red: - * - * - * - * Since: 2.1.0 - */ -#define hb_color_get_red(color) (((color) >> 8) & 0xFF) -/** - * hb_color_get_green: - * - * - * - * Since: 2.1.0 - */ -#define hb_color_get_green(color) (((color) >> 16) & 0xFF) -/** - * hb_color_get_blue: - * - * - * - * Since: 2.1.0 - */ -#define hb_color_get_blue(color) (((color) >> 24) & 0xFF) +HB_EXTERN uint8_t +hb_color_get_red (hb_color_t color); +#define hb_color_get_red(color) (((color) >> 8) & 0xFF) + +HB_EXTERN uint8_t +hb_color_get_green (hb_color_t color); +#define hb_color_get_green(color) (((color) >> 16) & 0xFF) + +HB_EXTERN uint8_t +hb_color_get_blue (hb_color_t color); +#define hb_color_get_blue(color) (((color) >> 24) & 0xFF) HB_END_DECLS From 6d9a86ae7535ea8e3c108a49c6da877a78cdac26 Mon Sep 17 00:00:00 2001 From: Nathan Willis Date: Tue, 30 Apr 2019 16:09:01 +0100 Subject: [PATCH 115/336] [Docs] Usermanual; fixes to Object Model chapter --- docs/usermanual-object-model.xml | 35 ++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/docs/usermanual-object-model.xml b/docs/usermanual-object-model.xml index f0b76ce91..f571c477f 100644 --- a/docs/usermanual-object-model.xml +++ b/docs/usermanual-object-model.xml @@ -90,7 +90,7 @@ fonts, which represent instances of a - face will all of their parameters specified. + face with all of their parameters specified. @@ -103,7 +103,10 @@ shape plans, which store the settings - that HarfBuzz will use when shaping a particular text segment. + that HarfBuzz will use when shaping a particular text + segment. Shape plans are not generally used by client + programs directly, but as we will see in a later chapter, + they are still valuable to understand. @@ -124,9 +127,11 @@ blob directly from the contents of a file. - Client programs can increase the reference count on an object by - calling its reference() method. Whenever a - client program is finished with an object, it should call its + All objects are created with an initial reference count of + 1. Client programs can increase the reference + count on an object by calling its + reference() method. Whenever a client + program is finished with an object, it should call its corresponding destroy() method. The destroy method will decrease the reference count on the object and, whenever the reference count reaches zero, it will also destroy @@ -134,7 +139,9 @@ All of HarfBuzz's object-lifecycle-management APIs are - thread-safe, even when the object as a whole is not thread-safe . + thread-safe (unless you compiled HarfBuzz from source with the + HB_NO_MT configuration flag), even when the + object as a whole is not thread-safe. It is also permissible to reference() or to destroy() the NULL value. @@ -152,7 +159,7 @@ make_immutable() methods to mark an object as immutable and is_immutable() methods to test whether or not an object is immutable. Attempts to use - setter functions on immutable objects will fail; see the API + setter functions on immutable objects will fail silently; see the API Reference manual for specifics. @@ -161,10 +168,11 @@ they will need to make a duplicate of the original. - Finally, object constructors (and, indeed, as much of the API as - possible) will never return NULL. Instead, - if there is an allocation error, each constructor will - return an “empty” object singleton. + Finally, object constructors (and, indeed, as much of the + shaping API as possible) will never return + NULL. Instead, if there is an allocation + error, each constructor will return an “empty” object + singleton. These empty-object singletons are inert and safe (although @@ -208,8 +216,9 @@ Finally, each set_user_data() method allows the client program to set a replace Boolean - indicating whether or not the user_data - associated with a key ought to be replaceable. + indicating whether or not the function call should replace any + existing user_data + associated with the specified key. From fe4a0ac707802b5bb36787723f8d55a58c2946a5 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Tue, 30 Apr 2019 13:35:50 -0400 Subject: [PATCH 116/336] Fix some dead links --- src/gen-os2-unicode-ranges.py | 2 +- src/gen-use-table.py | 6 +++--- src/hb-ot-shape-complex-myanmar.hh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gen-os2-unicode-ranges.py b/src/gen-os2-unicode-ranges.py index 8cf598588..95f1f1156 100644 --- a/src/gen-os2-unicode-ranges.py +++ b/src/gen-os2-unicode-ranges.py @@ -2,7 +2,7 @@ # Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh # Input is a tab seperated list of unicode ranges from the otspec -# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1). +# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur). from __future__ import print_function, division, absolute_import diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 1a33b8af5..0060e101d 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -54,7 +54,7 @@ data[0][0x1B5C] = 'Consonant_Placeholder' data[0][0x1B5F] = 'Consonant_Placeholder' data[0][0x1B62] = 'Consonant_Placeholder' data[0][0x1B68] = 'Consonant_Placeholder' -# TODO https://github.com/roozbehp/unicode-data/issues/9 +# TODO https://github.com/harfbuzz/harfbuzz/issues/1035 data[0][0x11C44] = 'Consonant_Placeholder' data[0][0x11C45] = 'Consonant_Placeholder' # TODO https://github.com/harfbuzz/harfbuzz/pull/1399 @@ -240,11 +240,11 @@ def is_SYM_MOD(U, UISC, UGC): def is_VARIATION_SELECTOR(U, UISC, UGC): return 0xFE00 <= U <= 0xFE0F def is_VOWEL(U, UISC, UGC): - # https://github.com/roozbehp/unicode-data/issues/6 + # https://github.com/harfbuzz/harfbuzz/issues/376 return (UISC == Pure_Killer or (UGC != Lo and UISC in [Vowel, Vowel_Dependent] and U not in [0xAA29])) def is_VOWEL_MOD(U, UISC, UGC): - # https://github.com/roozbehp/unicode-data/issues/6 + # https://github.com/harfbuzz/harfbuzz/issues/376 return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or (UGC != Lo and (UISC == Bindu or U in [0xAA29]))) diff --git a/src/hb-ot-shape-complex-myanmar.hh b/src/hb-ot-shape-complex-myanmar.hh index 3e9537a64..9ec78ef89 100644 --- a/src/hb-ot-shape-complex-myanmar.hh +++ b/src/hb-ot-shape-complex-myanmar.hh @@ -146,7 +146,7 @@ set_myanmar_properties (hb_glyph_info_t &info) break; case 0xAA74u: case 0xAA75u: case 0xAA76u: - /* https://github.com/roozbehp/unicode-data/issues/3 */ + /* https://github.com/harfbuzz/harfbuzz/issues/218 */ cat = OT_C; break; } From f27fdca4aa438ec366ee17370fbc9fdeb962c397 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Apr 2019 13:01:04 -0700 Subject: [PATCH 117/336] [doc] Add documentation to hb_color_get_* and hb_directwrite_face_* (#1690) --- src/hb-common.cc | 12 ++++++++---- src/hb-directwrite.cc | 8 ++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index c453443e7..6db801cdd 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -1162,8 +1162,9 @@ hb_variation_to_string (hb_variation_t *variation, /** * hb_color_get_alpha: + * color: a #hb_color_t we are interested in its channels. * - * + * Return value: Alpha channel value of the given color * * Since: REPLACEME */ @@ -1175,8 +1176,9 @@ uint8_t /** * hb_color_get_red: + * color: a #hb_color_t we are interested in its channels. * - * + * Return value: Red channel value of the given color * * Since: REPLACEME */ @@ -1188,8 +1190,9 @@ uint8_t /** * hb_color_get_green: + * color: a #hb_color_t we are interested in its channels. * - * + * Return value: Green channel value of the given color * * Since: REPLACEME */ @@ -1201,8 +1204,9 @@ uint8_t /** * hb_color_get_blue: + * color: a #hb_color_t we are interested in its channels. * - * + * Return value: Blue channel value of the given color * * Since: REPLACEME */ diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index d8076c922..8f2e66025 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -930,7 +930,9 @@ _hb_directwrite_font_release (void *data) /** * hb_directwrite_face_create: - * @font_face: + * @font_face: a DirectWrite IDWriteFontFace object. + * + * Return value: #hb_face_t object corresponding to the given input * * Since: 2.4.0 **/ @@ -945,7 +947,9 @@ hb_directwrite_face_create (IDWriteFontFace *font_face) /** * hb_directwrite_face_get_font_face: -* @face: +* @face: a #hb_face_t object +* +* Return value: DirectWrite IDWriteFontFace object corresponding to the given input * * Since: REPLACEME **/ From 92588782d7a45e0c023c5f48cbd19b11cfa8f0d2 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Apr 2019 13:05:10 -0700 Subject: [PATCH 118/336] Remove space between right angle brackets now that we have C++11 (#1689) --- src/hb-aat-layout-ankr-table.hh | 2 +- src/hb-aat-layout-common.hh | 14 +++--- src/hb-aat-layout-just-table.hh | 4 +- src/hb-aat-layout-kerx-table.hh | 14 +++--- src/hb-aat-layout-lcar-table.hh | 2 +- src/hb-aat-layout-morx-table.hh | 14 +++--- src/hb-aat-layout-trak-table.hh | 2 +- src/hb-aat-ltag-table.hh | 2 +- src/hb-cff-interp-cs-common.hh | 2 +- src/hb-cff1-interp-cs.hh | 2 +- src/hb-cff2-interp-cs.hh | 2 +- src/hb-iter.hh | 4 +- src/hb-null.hh | 8 +-- src/hb-open-file.hh | 8 +-- src/hb-open-type.hh | 8 +-- src/hb-ot-color-cbdt-table.hh | 2 +- src/hb-ot-color-colr-table.hh | 4 +- src/hb-ot-color-cpal-table.hh | 8 +-- src/hb-ot-color-sbix-table.hh | 2 +- src/hb-ot-color-svg-table.hh | 4 +- src/hb-ot-kern-table.hh | 6 +-- src/hb-ot-layout-base-table.hh | 2 +- src/hb-ot-layout-common.hh | 10 ++-- src/hb-ot-layout-gdef-table.hh | 4 +- src/hb-ot-layout-gpos-table.hh | 6 +-- src/hb-ot-layout-gsub-table.hh | 18 +++---- src/hb-ot-layout-gsubgpos.hh | 86 ++++++++++++++++----------------- src/hb-ot-math-table.hh | 2 +- src/hb-ot-name-table.hh | 10 ++-- src/hb-ot-stat-table.hh | 4 +- src/hb-subset-cff1.cc | 2 +- src/test-iter.cc | 10 ++-- 32 files changed, 134 insertions(+), 134 deletions(-) diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh index 4087b8c1f..ef988841a 100644 --- a/src/hb-aat-layout-ankr-table.hh +++ b/src/hb-aat-layout-ankr-table.hh @@ -83,7 +83,7 @@ struct ankr protected: HBUINT16 version; /* Version number (set to zero) */ HBUINT16 flags; /* Flags (currently unused; set to zero) */ - LOffsetTo > > + LOffsetTo>> lookupTable; /* Offset to the table's lookup table */ LNNOffsetTo anchorData; /* Offset to the glyph data table */ diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 7c74d7938..95ac27128 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -125,7 +125,7 @@ struct LookupFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - VarSizedBinSearchArrayOf > + VarSizedBinSearchArrayOf> segments; /* The actual segments. These must already be sorted, * according to the first word in each one (the last * glyph in each segment). */ @@ -164,7 +164,7 @@ struct LookupSegmentArray GlyphID last; /* Last GlyphID in this segment */ GlyphID first; /* First GlyphID in this segment */ - NNOffsetTo > + NNOffsetTo> valuesZ; /* A 16-bit offset from the start of * the table to the data. */ public: @@ -196,7 +196,7 @@ struct LookupFormat4 protected: HBUINT16 format; /* Format identifier--format = 4 */ - VarSizedBinSearchArrayOf > + VarSizedBinSearchArrayOf> segments; /* The actual segments. These must already be sorted, * according to the first word in each one (the last * glyph in each segment). */ @@ -253,7 +253,7 @@ struct LookupFormat6 protected: HBUINT16 format; /* Format identifier--format = 6 */ - VarSizedBinSearchArrayOf > + VarSizedBinSearchArrayOf> entries; /* The actual entries, sorted by glyph index. */ public: DEFINE_SIZE_ARRAY (8, entries); @@ -419,7 +419,7 @@ struct Lookup /* Ugly hand-coded null objects for template Lookup<> :(. */ extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2]; template -struct Null > { +struct Null> { static AAT::Lookup const & get_null () { return *reinterpret_cast *> (_hb_Null_AAT_Lookup); } }; @@ -510,7 +510,7 @@ struct StateTable const Entry &get_entry (int state, unsigned int klass) const { if (unlikely (klass >= nClasses)) - klass = StateTable >::CLASS_OUT_OF_BOUNDS; + klass = StateTable>::CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry *entries = (this+entryTable).arrayZ; @@ -631,7 +631,7 @@ struct StateTable classTable; /* Offset to the class table. */ NNOffsetTo, HBUINT> stateArrayTable;/* Offset to the state array. */ - NNOffsetTo >, HBUINT> + NNOffsetTo>, HBUINT> entryTable; /* Offset to the entry array. */ public: diff --git a/src/hb-aat-layout-just-table.hh b/src/hb-aat-layout-just-table.hh index d53f8f19e..e15c946a2 100644 --- a/src/hb-aat-layout-just-table.hh +++ b/src/hb-aat-layout-just-table.hh @@ -309,7 +309,7 @@ struct WidthDeltaPair public: DEFINE_SIZE_STATIC (24); }; - + typedef OT::LArrayOf WidthDeltaCluster; struct JustificationCategory @@ -371,7 +371,7 @@ struct JustificationHeader * of postcompensation subtable (set to zero if none). * * The postcompensation subtable, if present in the font. */ - Lookup > + Lookup> lookupTable; /* Lookup table associating glyphs with width delta * clusters. See the description of Width Delta Clusters * table for details on how to interpret the lookup values. */ diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index a64c80738..b740f1e8f 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -712,18 +712,18 @@ struct KerxSubTableFormat6 { struct Long { - LNNOffsetTo > rowIndexTable; - LNNOffsetTo > columnIndexTable; - LNNOffsetTo > array; + LNNOffsetTo> rowIndexTable; + LNNOffsetTo> columnIndexTable; + LNNOffsetTo> array; } l; struct Short { - LNNOffsetTo > rowIndexTable; - LNNOffsetTo > columnIndexTable; - LNNOffsetTo > array; + LNNOffsetTo> rowIndexTable; + LNNOffsetTo> columnIndexTable; + LNNOffsetTo> array; } s; } u; - LNNOffsetTo > vector; + LNNOffsetTo> vector; public: DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24); }; diff --git a/src/hb-aat-layout-lcar-table.hh b/src/hb-aat-layout-lcar-table.hh index 4be799fbc..cd96d034d 100644 --- a/src/hb-aat-layout-lcar-table.hh +++ b/src/hb-aat-layout-lcar-table.hh @@ -81,7 +81,7 @@ struct lcar protected: FixedVersion<>version; /* Version number of the ligature caret table */ HBUINT16 format; /* Format of the ligature caret table. */ - Lookup > + Lookup> lookup; /* data Lookup table associating glyphs */ public: diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 4a1d959ef..466842483 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -969,7 +969,7 @@ struct Chain void apply (hb_aat_apply_context_t *c, hb_mask_t flags) const { - const ChainSubtable *subtable = &StructAfter > (featureZ.as_array (featureCount)); + const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { @@ -1031,7 +1031,7 @@ struct Chain if (unlikely (!c->buffer->successful)) return; skip: - subtable = &StructAfter > (*subtable); + subtable = &StructAfter> (*subtable); c->set_lookup_index (c->lookup_index + 1); } } @@ -1049,13 +1049,13 @@ struct Chain if (!c->check_array (featureZ.arrayZ, featureCount)) return_trace (false); - const ChainSubtable *subtable = &StructAfter > (featureZ.as_array (featureCount)); + const ChainSubtable *subtable = &StructAfter> (featureZ.as_array (featureCount)); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { if (!subtable->sanitize (c)) return_trace (false); - subtable = &StructAfter > (*subtable); + subtable = &StructAfter> (*subtable); } return_trace (true); @@ -1095,7 +1095,7 @@ struct mortmorx for (unsigned int i = 0; i < count; i++) { map->chain_flags.push (chain->compile_flags (mapper)); - chain = &StructAfter > (*chain); + chain = &StructAfter> (*chain); } } @@ -1109,7 +1109,7 @@ struct mortmorx { chain->apply (c, c->plan->aat_map.chain_flags[i]); if (unlikely (!c->buffer->successful)) return; - chain = &StructAfter > (*chain); + chain = &StructAfter> (*chain); } } @@ -1125,7 +1125,7 @@ struct mortmorx { if (!chain->sanitize (c, version)) return_trace (false); - chain = &StructAfter > (*chain); + chain = &StructAfter> (*chain); } return_trace (true); diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index 0c8e4558f..2688270aa 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -66,7 +66,7 @@ struct TrackTableEntry NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ - NNOffsetTo > + NNOffsetTo> valuesZ; /* Offset from start of tracking table to * per-size tracking values for this track. */ diff --git a/src/hb-aat-ltag-table.hh b/src/hb-aat-ltag-table.hh index 6f34a0095..711f9aa6c 100644 --- a/src/hb-aat-ltag-table.hh +++ b/src/hb-aat-ltag-table.hh @@ -50,7 +50,7 @@ struct FTStringRange } protected: - NNOffsetTo > + NNOffsetTo> tag; /* Offset from the start of the table to * the beginning of the string */ HBUINT16 length; /* String length (in bytes) */ diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh index 283bdf14a..71bc29282 100644 --- a/src/hb-cff-interp-cs-common.hh +++ b/src/hb-cff-interp-cs-common.hh @@ -246,7 +246,7 @@ struct path_procs_null_t static void flex1 (ENV &env, PARAM& param) {} }; -template > +template > struct cs_opset_t : opset_t { static void process_op (op_code_t op, ENV &env, PARAM& param) diff --git a/src/hb-cff1-interp-cs.hh b/src/hb-cff1-interp-cs.hh index c7209ed80..cc528564c 100644 --- a/src/hb-cff1-interp-cs.hh +++ b/src/hb-cff1-interp-cs.hh @@ -81,7 +81,7 @@ struct cff1_cs_interp_env_t : cs_interp_env_t typedef cs_interp_env_t SUPER; }; -template > +template > struct cff1_cs_opset_t : cs_opset_t { /* PostScript-originated legacy opcodes (OpCode_add etc) are unsupported */ diff --git a/src/hb-cff2-interp-cs.hh b/src/hb-cff2-interp-cs.hh index 49e5ee739..1faf20831 100644 --- a/src/hb-cff2-interp-cs.hh +++ b/src/hb-cff2-interp-cs.hh @@ -193,7 +193,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t typedef cs_interp_env_t SUPER; }; -template > +template > struct cff2_cs_opset_t : cs_opset_t { static void process_op (op_code_t op, cff2_cs_interp_env_t &env, PARAM& param) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index f0947282d..6fe984fc6 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -387,7 +387,7 @@ struct template struct hb_zip_iter_t : hb_iter_t, - hb_pair_t > + hb_pair_t> { hb_zip_iter_t () {} hb_zip_iter_t (const A& a, const B& b) : a (a), b (b) {} @@ -427,7 +427,7 @@ template struct hb_enumerate_iter_t : hb_iter_t, - hb_pair_t > + hb_pair_t> { hb_enumerate_iter_t (const Iter& it) : i (0), it (it) {} diff --git a/src/hb-null.hh b/src/hb-null.hh index 1e20a47e9..562c4abc0 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 @@ -67,7 +67,7 @@ template struct _hb_static_size { enum { value = sizeof (T) }; }; template -struct _hb_static_size > +struct _hb_static_size> { enum { value = T::static_size }; }; template @@ -95,7 +95,7 @@ struct Null { template struct NullHelper { - typedef hb_remove_const > Type; + typedef hb_remove_const> Type; static const Type & get_null () { return Null::get_null (); } }; #define Null(Type) NullHelper::get_null () @@ -148,7 +148,7 @@ static inline Type& Crap () { template struct CrapHelper { - typedef hb_remove_const > Type; + typedef hb_remove_const> Type; static Type & get_crap () { return Crap (); } }; #define Crap(Type) CrapHelper::get_crap () diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 7e916aeb6..0689facd0 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -222,7 +222,7 @@ struct TTCHeaderVersion1 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ - LArrayOf > + LArrayOf> table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: @@ -334,7 +334,7 @@ struct ResourceTypeRecord protected: Tag tag; /* Resource type. */ HBUINT16 resCountM1; /* Number of resources minus 1. */ - NNOffsetTo > + NNOffsetTo> resourcesZ; /* Offset from beginning of resource type list * to reference item list for this type. */ public: @@ -390,7 +390,7 @@ struct ResourceMap HBUINT32 reserved1; /* Reserved for handle to next resource map */ HBUINT16 resreved2; /* Reserved for file reference number */ HBUINT16 attrs; /* Resource fork attribute */ - NNOffsetTo > + NNOffsetTo> typeList; /* Offset from beginning of map to * resource type list */ Offset16 nameList; /* Offset from beginning of map to @@ -422,7 +422,7 @@ struct ResourceForkHeader } protected: - LNNOffsetTo > + LNNOffsetTo> data; /* Offset from beginning of resource fork * to resource data */ LNNOffsetTo diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 041b9843f..bde059602 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -442,7 +442,7 @@ struct UnsizedArrayOf /* Unsized array of offset's */ template -using UnsizedOffsetArrayOf = UnsizedArrayOf >; +using UnsizedOffsetArrayOf = UnsizedArrayOf>; /* Unsized array of offsets relative to the beginning of the array itself. */ template @@ -628,9 +628,9 @@ using PString = ArrayOf; /* Array of Offset's */ template -using OffsetArrayOf = ArrayOf >; +using OffsetArrayOf = ArrayOf>; template -using LOffsetArrayOf = ArrayOf >; +using LOffsetArrayOf = ArrayOf>; template using LOffsetLArrayOf = ArrayOf, HBUINT32>; @@ -882,7 +882,7 @@ struct BinSearchHeader }; template -using BinSearchArrayOf = SortedArrayOf >; +using BinSearchArrayOf = SortedArrayOf>; struct VarSizedBinSearchHeader diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 333ceaaba..b6dc364a1 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -144,7 +144,7 @@ struct IndexSubtableFormat1Or3 } IndexSubtableHeader header; - UnsizedArrayOf > + UnsizedArrayOf> offsetArrayZ; public: DEFINE_SIZE_ARRAY(8, offsetArrayZ); diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index a57911ad0..90f89d583 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -125,9 +125,9 @@ struct COLR protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ - LNNOffsetTo > + LNNOffsetTo> baseGlyphsZ; /* Offset to Base Glyph records. */ - LNNOffsetTo > + LNNOffsetTo> layersZ; /* Offset to Layer Records. */ HBUINT16 numLayers; /* Number of Layer Records. */ public: diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index 407049350..7df7059a8 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -87,15 +87,15 @@ struct CPALV1Tail } protected: - LNNOffsetTo > + LNNOffsetTo> paletteFlagsZ; /* Offset from the beginning of CPAL table to * the Palette Type Array. Set to 0 if no array * is provided. */ - LNNOffsetTo > + LNNOffsetTo> paletteLabelsZ; /* Offset from the beginning of CPAL table to * the palette labels array. Set to 0 if no * array is provided. */ - LNNOffsetTo > + LNNOffsetTo> colorLabelsZ; /* Offset from the beginning of CPAL table to * the color labels array. Set to 0 * if no array is provided. */ @@ -176,7 +176,7 @@ struct CPAL HBUINT16 numPalettes; /* Number of palettes in the table. */ HBUINT16 numColorRecords; /* Total number of color records, combined for * all palettes. */ - LNNOffsetTo > + LNNOffsetTo> colorRecordsZ; /* Offset from the beginning of CPAL table to * the first ColorRecord. */ UnsizedArrayOf diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index f6bdbb3dd..670c05504 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -121,7 +121,7 @@ struct SBIXStrike HBUINT16 resolution; /* The device pixel density (in PPI) for which this * strike was designed. (E.g., 96 PPI, 192 PPI.) */ protected: - UnsizedArrayOf > + UnsizedArrayOf> imageOffsetsZ; /* Offset from the beginning of the strike data header * to bitmap data for an individual glyph ID. */ public: diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index 6e8eddf24..926d61e0f 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -62,7 +62,7 @@ struct SVGDocumentIndexEntry * this index entry. */ HBUINT16 endGlyphID; /* The last glyph ID in the range described by * this index entry. Must be >= startGlyphID. */ - LNNOffsetTo > + LNNOffsetTo> svgDoc; /* Offset from the beginning of the SVG Document Index * to an SVG document. Must be non-zero. */ HBUINT32 svgDocLength; /* Length of the SVG document. @@ -107,7 +107,7 @@ struct SVG protected: HBUINT16 version; /* Table version (starting at 0). */ - LOffsetTo > + LOffsetTo> svgDocEntries; /* Offset (relative to the start of the SVG table) to the * SVG Documents Index. Must be non-zero. */ /* Array of SVG Document Index Entries. */ diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index ec6a3c84c..0b55dabdc 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -47,9 +47,9 @@ struct KernSubTableFormat3 int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { hb_array_t kernValue = kernValueZ.as_array (kernValueCount); - hb_array_t leftClass = StructAfter > (kernValue).as_array (glyphCount); - hb_array_t rightClass = StructAfter > (leftClass).as_array (glyphCount); - hb_array_t kernIndex = StructAfter > (rightClass).as_array (leftClassCount * rightClassCount); + hb_array_t leftClass = StructAfter> (kernValue).as_array (glyphCount); + hb_array_t rightClass = StructAfter> (leftClass).as_array (glyphCount); + hb_array_t kernIndex = StructAfter> (rightClass).as_array (leftClassCount * rightClassCount); unsigned int leftC = leftClass[left]; unsigned int rightC = rightClass[right]; diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 7ef573ea8..091236294 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -447,7 +447,7 @@ struct Axis } protected: - OffsetTo > + OffsetTo> baseTagList; /* Offset to BaseTagList table, from beginning * of Axis table (may be NULL) * Array of 4-byte baseline identification tags — must diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index b85d1226e..c8dcc3208 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -103,7 +103,7 @@ struct Record }; template -struct RecordArrayOf : SortedArrayOf > +struct RecordArrayOf : SortedArrayOf> { const OffsetTo& get_offset (unsigned int i) const { return (*this)[i].offset; } @@ -649,14 +649,14 @@ struct Lookup template const TSubTable& get_subtable (unsigned int i) const - { return this+CastR > (subTable)[i]; } + { return this+CastR> (subTable)[i]; } template const OffsetArrayOf& get_subtables () const - { return CastR > (subTable); } + { return CastR> (subTable); } template OffsetArrayOf& get_subtables () - { return CastR > (subTable); } + { return CastR> (subTable); } unsigned int get_size () const { @@ -774,7 +774,7 @@ struct Lookup if (!markFilteringSet.sanitize (c)) return_trace (false); } - if (unlikely (!CastR > > (subTable) + if (unlikely (!CastR>> (subTable) .sanitize (c, this, get_type ()))) return_trace (false); diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index dc8b9b847..5d9a3ec78 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -220,7 +220,7 @@ struct LigGlyph { if (caret_count) { - hb_array_t > array = carets.sub_array (start_offset, caret_count); + hb_array_t > array = carets.sub_array (start_offset, caret_count); unsigned int count = array.length; for (unsigned int i = 0; i < count; i++) caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store); @@ -296,7 +296,7 @@ struct MarkGlyphSetsFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - ArrayOf > + ArrayOf> coverage; /* Array of long offsets to mark set * coverage tables */ public: diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index a7257dfbb..407ce9e27 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -174,11 +174,11 @@ struct ValueFormat : HBUINT16 } HB_INTERNAL static OffsetTo& get_device (Value* value) - { return *CastP > (value); } + { return *CastP> (value); } HB_INTERNAL static const OffsetTo& get_device (const Value* value, bool *worked=nullptr) { if (worked) *worked |= bool (*value); - return *CastP > (value); + return *CastP> (value); } HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr) @@ -393,7 +393,7 @@ struct AnchorMatrix HBUINT16 rows; /* Number of rows */ protected: - UnsizedArrayOf > + UnsizedArrayOf> matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ public: diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 10c35e32c..be78c1aaa 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -983,7 +983,7 @@ struct ReverseChainSingleSubstFormat1 if (!(this+coverage).intersects (glyphs)) return false; - const OffsetArrayOf &lookahead = StructAfter > (backtrack); + const OffsetArrayOf &lookahead = StructAfter> (backtrack); unsigned int count; @@ -1004,8 +1004,8 @@ struct ReverseChainSingleSubstFormat1 { if (!intersects (c->glyphs)) return; - const OffsetArrayOf &lookahead = StructAfter > (backtrack); - const ArrayOf &substitute = StructAfter > (lookahead); + const OffsetArrayOf &lookahead = StructAfter> (backtrack); + const ArrayOf &substitute = StructAfter> (lookahead); + hb_zip (this+coverage, substitute) | hb_filter (*c->glyphs, hb_first) @@ -1024,12 +1024,12 @@ struct ReverseChainSingleSubstFormat1 for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return; - const OffsetArrayOf &lookahead = StructAfter > (backtrack); + const OffsetArrayOf &lookahead = StructAfter> (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return; - const ArrayOf &substitute = StructAfter > (lookahead); + const ArrayOf &substitute = StructAfter> (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -1048,8 +1048,8 @@ struct ReverseChainSingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const OffsetArrayOf &lookahead = StructAfter > (backtrack); - const ArrayOf &substitute = StructAfter > (lookahead); + const OffsetArrayOf &lookahead = StructAfter> (backtrack); + const ArrayOf &substitute = StructAfter> (lookahead); unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, @@ -1084,10 +1084,10 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); - const OffsetArrayOf &lookahead = StructAfter > (backtrack); + const OffsetArrayOf &lookahead = StructAfter> (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const ArrayOf &substitute = StructAfter > (lookahead); + const ArrayOf &substitute = StructAfter> (lookahead); return_trace (substitute.sanitize (c)); } diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 840c142ab..6b0b7ad5d 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -1299,7 +1299,7 @@ struct Rule void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { - const UnsizedArrayOf &lookupRecord = StructAfter > + const UnsizedArrayOf &lookupRecord = StructAfter> (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); context_closure_lookup (c, inputCount, inputZ.arrayZ, @@ -1310,7 +1310,7 @@ struct Rule void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { - const UnsizedArrayOf &lookupRecord = StructAfter > + const UnsizedArrayOf &lookupRecord = StructAfter> (inputZ.as_array (inputCount ? inputCount - 1 : 0)); context_collect_glyphs_lookup (c, inputCount, inputZ.arrayZ, @@ -1321,7 +1321,7 @@ struct Rule bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { - const UnsizedArrayOf &lookupRecord = StructAfter > + const UnsizedArrayOf &lookupRecord = StructAfter> (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return context_would_apply_lookup (c, inputCount, inputZ.arrayZ, @@ -1333,7 +1333,7 @@ struct Rule ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const UnsizedArrayOf &lookupRecord = StructAfter > + const UnsizedArrayOf &lookupRecord = StructAfter> (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } @@ -1751,7 +1751,7 @@ struct ContextFormat3 HBUINT16 glyphCount; /* Number of glyphs in the input glyph * sequence */ HBUINT16 lookupCount; /* Number of LookupRecords */ - UnsizedArrayOf > + UnsizedArrayOf> coverageZ; /* Array of offsets to Coverage * table in glyph sequence order */ /*UnsizedArrayOf @@ -1923,8 +1923,8 @@ struct ChainRule { bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const { - const HeadlessArrayOf &input = StructAfter > (backtrack); - const ArrayOf &lookahead = StructAfter > (input); + const HeadlessArrayOf &input = StructAfter> (backtrack); + const ArrayOf &lookahead = StructAfter> (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -1935,9 +1935,9 @@ struct ChainRule void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { - const HeadlessArrayOf &input = StructAfter > (backtrack); - const ArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const HeadlessArrayOf &input = StructAfter> (backtrack); + const ArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -1949,9 +1949,9 @@ struct ChainRule void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { - const HeadlessArrayOf &input = StructAfter > (backtrack); - const ArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const HeadlessArrayOf &input = StructAfter> (backtrack); + const ArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -1963,9 +1963,9 @@ struct ChainRule bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { - const HeadlessArrayOf &input = StructAfter > (backtrack); - const ArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const HeadlessArrayOf &input = StructAfter> (backtrack); + const ArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); return chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -1976,9 +1976,9 @@ struct ChainRule bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const HeadlessArrayOf &input = StructAfter > (backtrack); - const ArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const HeadlessArrayOf &input = StructAfter> (backtrack); + const ArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -1990,11 +1990,11 @@ struct ChainRule { TRACE_SANITIZE (this); if (!backtrack.sanitize (c)) return_trace (false); - const HeadlessArrayOf &input = StructAfter > (backtrack); + const HeadlessArrayOf &input = StructAfter> (backtrack); if (!input.sanitize (c)) return_trace (false); - const ArrayOf &lookahead = StructAfter > (input); + const ArrayOf &lookahead = StructAfter> (input); if (!lookahead.sanitize (c)) return_trace (false); - const ArrayOf &lookup = StructAfter > (lookahead); + const ArrayOf &lookup = StructAfter> (lookahead); return_trace (lookup.sanitize (c)); } @@ -2330,12 +2330,12 @@ struct ChainContextFormat3 { bool intersects (const hb_set_t *glyphs) const { - const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &input = StructAfter> (backtrack); if (!(this+input[0]).intersects (glyphs)) return false; - const OffsetArrayOf &lookahead = StructAfter > (input); + const OffsetArrayOf &lookahead = StructAfter> (input); struct ChainContextClosureLookupContext lookup_context = { {intersects_coverage}, {this, this, this} @@ -2349,13 +2349,13 @@ struct ChainContextFormat3 void closure (hb_closure_context_t *c) const { - const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &input = StructAfter> (backtrack); if (!(this+input[0]).intersects (c->glyphs)) return; - const OffsetArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const OffsetArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); struct ChainContextClosureLookupContext lookup_context = { {intersects_coverage}, {this, this, this} @@ -2370,12 +2370,12 @@ struct ChainContextFormat3 void collect_glyphs (hb_collect_glyphs_context_t *c) const { - const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &input = StructAfter> (backtrack); (this+input[0]).add_coverage (c->input); - const OffsetArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const OffsetArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); struct ChainContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, {this, this, this} @@ -2390,9 +2390,9 @@ struct ChainContextFormat3 bool would_apply (hb_would_apply_context_t *c) const { - const OffsetArrayOf &input = StructAfter > (backtrack); - const OffsetArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const OffsetArrayOf &input = StructAfter> (backtrack); + const OffsetArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {match_coverage}, {this, this, this} @@ -2406,20 +2406,20 @@ struct ChainContextFormat3 const Coverage &get_coverage () const { - const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &input = StructAfter> (backtrack); return this+input[0]; } bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &input = StructAfter> (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const OffsetArrayOf &lookahead = StructAfter > (input); - const ArrayOf &lookup = StructAfter > (lookahead); + const OffsetArrayOf &lookahead = StructAfter> (input); + const ArrayOf &lookup = StructAfter> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {match_coverage}, {this, this, this} @@ -2442,12 +2442,12 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (!backtrack.sanitize (c, this)) return_trace (false); - const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &input = StructAfter> (backtrack); if (!input.sanitize (c, this)) return_trace (false); if (!input.len) return_trace (false); /* To be consistent with Context. */ - const OffsetArrayOf &lookahead = StructAfter > (input); + const OffsetArrayOf &lookahead = StructAfter> (input); if (!lookahead.sanitize (c, this)) return_trace (false); - const ArrayOf &lookup = StructAfter > (lookahead); + const ArrayOf &lookup = StructAfter> (lookahead); return_trace (lookup.sanitize (c)); } @@ -2674,9 +2674,9 @@ struct GSUBGPOS typedef OffsetListOf TLookupList; /* TODO Use intersects() to count how many subtables survive? */ - CastR > (out->lookupList) + CastR> (out->lookupList) .serialize_subset (c, - this+CastR > (lookupList), + this+CastR> (lookupList), out); if (version.to_int () >= 0x00010001u) @@ -2700,7 +2700,7 @@ struct GSUBGPOS likely (version.major == 1) && scriptList.sanitize (c, this) && featureList.sanitize (c, this) && - CastR > (lookupList).sanitize (c, this) && + CastR> (lookupList).sanitize (c, this) && (version.to_int () < 0x00010001u || featureVars.sanitize (c, this))); } diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index 62bf072e9..dd6226404 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -664,7 +664,7 @@ struct MathVariants /* Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical/horizontal direction. */ - UnsizedArrayOf > + UnsizedArrayOf> glyphConstruction; public: diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 72deb10b4..c8b38a68d 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -213,7 +213,7 @@ struct name c->push (); char *new_pos = c->allocate_size (size); - + if (unlikely (new_pos == nullptr)) { acc.fini (); @@ -233,7 +233,7 @@ struct name } bool pack_record_and_strings (name *dest_name_unpacked, - hb_serialize_context_t *c, + hb_serialize_context_t *c, unsigned length) { hb_hashmap_t id_str_idx_map; @@ -243,7 +243,7 @@ struct name id_str_idx_map.set ((unsigned)i, objidx); } - const void *base = & (dest_name_unpacked->nameRecordZ[length]); + const void *base = & (dest_name_unpacked->nameRecordZ[length]); for (int i = length-1; i >= 0; i--) { unsigned str_idx = id_str_idx_map.get ((unsigned)i); @@ -298,7 +298,7 @@ struct name DEBUG_MSG (SUBSET, nullptr, "Failed to serialize write new name."); return false; } - + return true; } @@ -409,7 +409,7 @@ struct name /* We only implement format 0 for now. */ HBUINT16 format; /* Format selector (=0/1). */ HBUINT16 count; /* Number of name records. */ - NNOffsetTo > + NNOffsetTo> stringOffset; /* Offset to start of string storage (from start of table). */ UnsizedArrayOf nameRecordZ; /* The name records where count is the number of records. */ diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh index 04a2ee99e..e29d1ced7 100644 --- a/src/hb-ot-stat-table.hh +++ b/src/hb-ot-stat-table.hh @@ -249,7 +249,7 @@ struct STAT * in the 'fvar' table. In all fonts, must * be greater than zero if axisValueCount * is greater than zero. */ - LNNOffsetTo > + LNNOffsetTo> designAxesOffset; /* Offset in bytes from the beginning of * the STAT table to the start of the design @@ -257,7 +257,7 @@ struct STAT * set to zero; if designAxisCount is greater * than zero, must be greater than zero. */ HBUINT16 axisValueCount; /* The number of axis value tables. */ - LNNOffsetTo > > + LNNOffsetTo>> offsetToAxisValueOffsets; /* Offset in bytes from the beginning of * the STAT table to the start of the design diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index 601cbe9a1..39bf5acdd 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -912,7 +912,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, /* top dict INDEX */ { assert (plan.offsets.topDictInfo.offset == (unsigned) (c.head - c.start)); - CFF1IndexOf *dest = c.start_embed< CFF1IndexOf > (); + CFF1IndexOf *dest = c.start_embed< CFF1IndexOf> (); if (dest == nullptr) return false; cff1_top_dict_op_serializer_t topSzr; top_dict_modifiers_t modifier (plan.offsets, plan.topDictModSIDs); diff --git a/src/test-iter.cc b/src/test-iter.cc index 3de340145..01ec93a7e 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -56,7 +56,7 @@ struct some_array_t typedef array_iter_t iter_t; array_iter_t iter () { return array_iter_t (arr); } operator array_iter_t () { return iter (); } - operator hb_iter_t > () { return iter (); } + operator hb_iter_t> () { return iter (); } private: hb_array_t arr; @@ -134,9 +134,9 @@ main (int argc, char **argv) (void) static_cast, int&>&> (sa); test_iterable (sa); - test_iterable > (); - test_iterable > (); - test_iterable > (); + test_iterable> (); + test_iterable> (); + test_iterable> (); test_iterable (); test_iterable (); @@ -144,7 +144,7 @@ main (int argc, char **argv) hb_any (st); - hb_array_t > pa; + hb_array_t> pa; pa->as_array (); + hb_iter (src) From 026ab825c8e41980e286be911cc6fbb958dd7cd3 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Wed, 1 May 2019 16:15:58 -0400 Subject: [PATCH 119/336] Add dotted circles to more broken clusters --- src/gen-use-table.py | 9 + src/hb-ot-shape-complex-myanmar-machine.hh | 196 +++---- src/hb-ot-shape-complex-myanmar-machine.rl | 4 +- src/hb-ot-shape-complex-use-machine.hh | 602 +++++++++++---------- src/hb-ot-shape-complex-use-machine.rl | 11 +- src/hb-ot-shape-complex-use-table.cc | 2 +- 6 files changed, 433 insertions(+), 391 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 0060e101d..9b1a00a68 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -47,6 +47,14 @@ defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block') # TODO Characters that are not in Unicode Indic files, but used in USE data[0][0x034F] = defaults[0] +data[0][0x1B61] = defaults[0] +data[0][0x1B63] = defaults[0] +data[0][0x1B64] = defaults[0] +data[0][0x1B65] = defaults[0] +data[0][0x1B66] = defaults[0] +data[0][0x1B67] = defaults[0] +data[0][0x1B69] = defaults[0] +data[0][0x1B6A] = defaults[0] data[0][0x2060] = defaults[0] # TODO https://github.com/harfbuzz/harfbuzz/pull/1685 data[0][0x1B5B] = 'Consonant_Placeholder' @@ -222,6 +230,7 @@ def is_Word_Joiner(U, UISC, UGC): def is_OTHER(U, UISC, UGC): #SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters return (UISC == Other + and not is_SYM(U, UISC, UGC) and not is_SYM_MOD(U, UISC, UGC) and not is_CGJ(U, UISC, UGC) and not is_Word_Joiner(U, UISC, UGC) diff --git a/src/hb-ot-shape-complex-myanmar-machine.hh b/src/hb-ot-shape-complex-myanmar-machine.hh index 0c19e4f68..d03832fa7 100644 --- a/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/src/hb-ot-shape-complex-myanmar-machine.hh @@ -38,9 +38,9 @@ static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, - 0 + 3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, + 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, + 1u, 32u, 8u, 8u, 0 }; static const char _myanmar_syllable_machine_key_spans[] = { @@ -48,8 +48,9 @@ static const char _myanmar_syllable_machine_key_spans[] = { 27, 27, 27, 27, 16, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 25, 4, 25, 23, 21, 21, 27, 27, 27, - 27, 28, 27, 32, 27, 27, 27, 27, - 27, 28, 27, 27, 27, 27, 32, 1 + 27, 16, 28, 27, 27, 27, 27, 27, + 28, 27, 27, 27, 27, 28, 27, 32, + 32, 1 }; static const short _myanmar_syllable_machine_index_offsets[] = { @@ -57,8 +58,9 @@ static const short _myanmar_syllable_machine_index_offsets[] = { 187, 215, 243, 271, 299, 316, 344, 372, 400, 428, 456, 485, 513, 541, 569, 597, 623, 628, 654, 678, 700, 722, 750, 778, - 806, 834, 863, 891, 924, 952, 980, 1008, - 1036, 1064, 1093, 1121, 1149, 1177, 1205, 1238 + 806, 834, 851, 880, 908, 936, 964, 992, + 1020, 1049, 1077, 1105, 1133, 1161, 1190, 1218, + 1251, 1284 }; static const char _myanmar_syllable_machine_indicies[] = { @@ -136,108 +138,115 @@ static const char _myanmar_syllable_machine_indicies[] = { 21, 22, 23, 24, 24, 21, 25, 21, 26, 21, 21, 21, 21, 21, 21, 21, 27, 21, 21, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 21, 3, 3, 44, + 33, 34, 35, 36, 21, 45, 45, 44, 5, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 45, 44, 44, 44, 44, 44, - 44, 14, 44, 44, 44, 18, 44, 3, - 3, 44, 5, 44, 3, 3, 44, 5, + 44, 44, 46, 44, 44, 44, 44, 44, + 44, 14, 44, 44, 44, 18, 44, 45, + 45, 44, 5, 44, 45, 45, 44, 5, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 14, 44, 44, 44, 18, 44, 46, 44, - 3, 3, 44, 5, 44, 14, 44, 44, - 44, 44, 44, 44, 44, 47, 44, 44, - 44, 44, 44, 44, 14, 44, 3, 3, + 14, 44, 44, 44, 18, 44, 47, 44, + 45, 45, 44, 5, 44, 14, 44, 44, + 44, 44, 44, 44, 44, 48, 44, 44, + 44, 44, 44, 44, 14, 44, 45, 45, 44, 5, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 47, 44, 44, 44, 44, - 44, 44, 14, 44, 3, 3, 44, 5, + 44, 44, 44, 48, 44, 44, 44, 44, + 44, 44, 14, 44, 45, 45, 44, 5, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 14, 44, 2, 44, 3, 3, 44, 5, + 14, 44, 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, - 44, 48, 44, 44, 48, 44, 44, 44, - 14, 49, 44, 44, 18, 44, 2, 44, - 3, 3, 44, 5, 44, 6, 44, 44, + 44, 49, 44, 44, 49, 44, 44, 44, + 14, 50, 44, 44, 18, 44, 2, 44, + 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 14, 44, 44, 44, - 18, 44, 2, 44, 3, 3, 44, 5, + 18, 44, 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, - 44, 48, 44, 44, 44, 44, 44, 44, - 14, 49, 44, 44, 18, 44, 2, 44, - 3, 3, 44, 5, 44, 6, 44, 44, + 44, 49, 44, 44, 44, 44, 44, 44, + 14, 50, 44, 44, 18, 44, 2, 44, + 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 14, 49, 44, 44, - 18, 44, 22, 23, 24, 24, 21, 25, - 21, 26, 21, 21, 21, 21, 21, 21, - 21, 50, 21, 21, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 21, 22, - 51, 24, 24, 21, 25, 21, 26, 21, - 21, 21, 21, 21, 21, 21, 27, 21, - 21, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 21, 1, 1, 2, 3, 3, - 3, 44, 5, 44, 6, 1, 44, 44, - 44, 44, 1, 44, 8, 44, 44, 10, - 11, 12, 13, 14, 15, 16, 17, 18, - 19, 44, 1, 44, 2, 44, 3, 3, - 44, 5, 44, 6, 44, 44, 44, 44, - 44, 44, 44, 8, 44, 44, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 44, - 2, 44, 3, 3, 44, 5, 44, 6, - 44, 44, 44, 44, 44, 44, 44, 52, - 44, 44, 44, 44, 44, 44, 14, 15, - 16, 17, 18, 44, 2, 44, 3, 3, - 44, 5, 44, 6, 44, 44, 44, 44, + 44, 44, 44, 44, 14, 50, 44, 44, + 18, 44, 51, 51, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 51, 44, 2, 3, 45, 45, 44, + 5, 44, 6, 44, 44, 44, 44, 44, + 44, 44, 8, 44, 44, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 44, + 2, 44, 45, 45, 44, 5, 44, 6, + 44, 44, 44, 44, 44, 44, 44, 8, + 44, 44, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 44, 2, 44, 45, 45, + 44, 5, 44, 6, 44, 44, 44, 44, + 44, 44, 44, 52, 44, 44, 44, 44, 44, 44, 14, 15, 16, 17, 18, 44, - 2, 44, 3, 3, 44, 5, 44, 6, + 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 14, 15, - 16, 44, 18, 44, 2, 44, 3, 3, + 16, 17, 18, 44, 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 14, 44, 16, 44, 18, 44, - 2, 44, 3, 3, 44, 5, 44, 6, + 44, 44, 14, 15, 16, 44, 18, 44, + 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 14, 15, - 16, 17, 18, 52, 44, 2, 44, 3, - 3, 44, 5, 44, 6, 44, 44, 44, - 44, 44, 44, 44, 52, 44, 44, 10, - 44, 12, 44, 14, 15, 16, 17, 18, - 44, 2, 44, 3, 3, 44, 5, 44, + 44, 44, 44, 44, 44, 44, 14, 44, + 16, 44, 18, 44, 2, 44, 45, 45, + 44, 5, 44, 6, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 14, 15, 16, 17, 18, 52, + 44, 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, - 52, 44, 44, 10, 44, 44, 44, 14, - 15, 16, 17, 18, 44, 2, 44, 3, - 3, 44, 5, 44, 6, 44, 44, 44, + 52, 44, 44, 10, 44, 12, 44, 14, + 15, 16, 17, 18, 44, 2, 44, 45, + 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, 52, 44, 44, 10, - 11, 12, 44, 14, 15, 16, 17, 18, - 44, 2, 3, 3, 3, 44, 5, 44, + 44, 44, 44, 14, 15, 16, 17, 18, + 44, 2, 44, 45, 45, 44, 5, 44, 6, 44, 44, 44, 44, 44, 44, 44, - 8, 44, 44, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 44, 1, 1, 53, - 53, 53, 53, 53, 53, 53, 53, 1, - 53, 53, 53, 53, 1, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 1, 53, 54, 53, - 0 + 52, 44, 44, 10, 11, 12, 44, 14, + 15, 16, 17, 18, 44, 2, 3, 45, + 45, 44, 5, 44, 6, 44, 44, 44, + 44, 44, 44, 44, 8, 44, 44, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 44, 22, 23, 24, 24, 21, 25, 21, + 26, 21, 21, 21, 21, 21, 21, 21, + 53, 21, 21, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 21, 22, 54, + 24, 24, 21, 25, 21, 26, 21, 21, + 21, 21, 21, 21, 21, 27, 21, 21, + 28, 29, 30, 31, 32, 33, 34, 35, + 36, 21, 1, 1, 2, 3, 45, 45, + 44, 5, 44, 6, 1, 44, 44, 44, + 44, 1, 44, 8, 44, 44, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 44, 1, 44, 1, 1, 55, 55, 55, + 55, 55, 55, 55, 55, 1, 55, 55, + 55, 55, 1, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 1, 55, 56, 55, 0 }; static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 23, 0, 0, 24, 30, 33, - 36, 46, 37, 42, 43, 44, 26, 39, - 40, 41, 29, 45, 47, 0, 2, 12, + 0, 1, 23, 33, 0, 24, 30, 45, + 35, 48, 36, 41, 42, 43, 26, 38, + 39, 40, 29, 44, 49, 0, 2, 12, 0, 3, 9, 13, 14, 19, 20, 21, 5, 16, 17, 18, 8, 22, 4, 6, - 7, 10, 11, 15, 0, 25, 27, 28, - 31, 32, 34, 35, 38, 0, 0 + 7, 10, 11, 15, 0, 0, 25, 27, + 28, 31, 32, 34, 37, 46, 47, 0, + 0 }; static const char _myanmar_syllable_machine_trans_actions[] = { - 3, 0, 0, 4, 5, 0, 0, 0, + 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 0, 0, - 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 10 + 0, 0, 0, 0, 7, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 10 }; static const char _myanmar_syllable_machine_to_state_actions[] = { @@ -246,7 +255,8 @@ static const char _myanmar_syllable_machine_to_state_actions[] = { 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 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 }; static const char _myanmar_syllable_machine_from_state_actions[] = { @@ -255,7 +265,8 @@ static const char _myanmar_syllable_machine_from_state_actions[] = { 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 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 }; static const short _myanmar_syllable_machine_eof_trans[] = { @@ -263,8 +274,9 @@ static const short _myanmar_syllable_machine_eof_trans[] = { 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 22, 22, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 54, 54 + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 22, 22, 45, + 56, 56 }; static const int myanmar_syllable_machine_start = 0; @@ -297,7 +309,7 @@ find_syllables (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 301 "hb-ot-shape-complex-myanmar-machine.hh" +#line 313 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -313,7 +325,7 @@ find_syllables (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 317 "hb-ot-shape-complex-myanmar-machine.hh" +#line 329 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -327,7 +339,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 331 "hb-ot-shape-complex-myanmar-machine.hh" +#line 343 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -345,11 +357,11 @@ _eof_trans: goto _again; switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { - case 7: + case 6: #line 86 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (consonant_syllable); }} break; - case 5: + case 4: #line 87 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (non_myanmar_cluster); }} break; @@ -357,7 +369,7 @@ _eof_trans: #line 88 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (punctuation_cluster); }} break; - case 4: + case 8: #line 89 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; @@ -365,11 +377,11 @@ _eof_trans: #line 90 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (non_myanmar_cluster); }} break; - case 6: + case 5: #line 86 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (consonant_syllable); }} break; - case 8: + case 7: #line 89 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; @@ -377,7 +389,7 @@ _eof_trans: #line 90 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (non_myanmar_cluster); }} break; -#line 381 "hb-ot-shape-complex-myanmar-machine.hh" +#line 393 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -386,7 +398,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 390 "hb-ot-shape-complex-myanmar-machine.hh" +#line 402 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/src/hb-ot-shape-complex-myanmar-machine.rl b/src/hb-ot-shape-complex-myanmar-machine.rl index 7845a86d4..c4e300fda 100644 --- a/src/hb-ot-shape-complex-myanmar-machine.rl +++ b/src/hb-ot-shape-complex-myanmar-machine.rl @@ -75,9 +75,9 @@ post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?; pwo_tone_group = PT A* DB? As?; complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?; -syllable_tail = (H | complex_syllable_tail); +syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail); -consonant_syllable = (k|CS)? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail; +consonant_syllable = (k|CS)? (c|IV|D|GB).VS? syllable_tail; punctuation_cluster = P V; broken_cluster = k? VS? syllable_tail; other = any; diff --git a/src/hb-ot-shape-complex-use-machine.hh b/src/hb-ot-shape-complex-use-machine.hh index c9410e4e5..f83e09fbc 100644 --- a/src/hb-ot-shape-complex-use-machine.hh +++ b/src/hb-ot-shape-complex-use-machine.hh @@ -36,279 +36,294 @@ #line 38 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 44u, 21u, 21u, 8u, 44u, 8u, 44u, - 1u, 15u, 1u, 1u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, - 8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 8u, 44u, 13u, 21u, 4u, 4u, 13u, 13u, - 8u, 44u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, - 8u, 44u, 8u, 44u, 1u, 39u, 1u, 15u, 12u, 44u, 1u, 44u, 8u, 44u, 21u, 42u, - 41u, 42u, 42u, 42u, 1u, 5u, 0 + 12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 44u, 21u, 21u, 8u, 44u, 8u, 44u, + 1u, 15u, 1u, 1u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, + 8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, + 8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 8u, 44u, 13u, 21u, 4u, 4u, 13u, 13u, + 8u, 44u, 8u, 44u, 41u, 42u, 42u, 42u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 39u, + 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, + 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 1u, 15u, + 4u, 4u, 13u, 21u, 13u, 13u, 12u, 44u, 1u, 44u, 8u, 44u, 41u, 42u, 42u, 42u, + 21u, 42u, 1u, 5u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 33, 15, 1, 33, 45, 1, 37, 37, - 15, 1, 37, 37, 32, 19, 19, 19, - 32, 32, 32, 37, 37, 37, 37, 37, - 37, 37, 37, 39, 37, 9, 1, 1, - 37, 37, 37, 32, 19, 19, 19, 32, - 32, 32, 37, 37, 37, 37, 37, 37, - 37, 37, 39, 15, 33, 44, 37, 22, - 2, 1, 5 + 33, 15, 1, 33, 45, 1, 37, 37, + 15, 1, 37, 37, 32, 19, 19, 19, + 32, 32, 32, 37, 37, 37, 37, 37, + 37, 37, 37, 39, 37, 9, 1, 1, + 37, 37, 2, 1, 37, 37, 37, 32, + 19, 19, 19, 32, 32, 32, 37, 37, + 37, 37, 37, 37, 37, 37, 39, 15, + 1, 9, 1, 33, 44, 37, 2, 1, + 22, 5 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 34, 50, 52, 86, 132, 134, 172, - 210, 226, 228, 266, 304, 337, 357, 377, - 397, 430, 463, 496, 534, 572, 610, 648, - 686, 724, 762, 800, 840, 878, 888, 890, - 892, 930, 968, 1006, 1039, 1059, 1079, 1099, - 1132, 1165, 1198, 1236, 1274, 1312, 1350, 1388, - 1426, 1464, 1502, 1542, 1558, 1592, 1637, 1675, - 1698, 1701, 1703 + 0, 34, 50, 52, 86, 132, 134, 172, + 210, 226, 228, 266, 304, 337, 357, 377, + 397, 430, 463, 496, 534, 572, 610, 648, + 686, 724, 762, 800, 840, 878, 888, 890, + 892, 930, 968, 971, 973, 1011, 1049, 1087, + 1120, 1140, 1160, 1180, 1213, 1246, 1279, 1317, + 1355, 1393, 1431, 1469, 1507, 1545, 1583, 1623, + 1639, 1641, 1651, 1653, 1687, 1732, 1770, 1773, + 1775, 1798 }; static const char _use_syllable_machine_indicies[] = { - 1, 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, 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, 0, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 4, 2, 3, 2, 6, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 6, 5, 7, 8, - 9, 7, 10, 8, 9, 9, 11, 9, - 9, 3, 12, 9, 9, 13, 7, 7, - 14, 15, 9, 9, 16, 17, 18, 19, - 20, 21, 22, 16, 23, 24, 25, 26, - 27, 28, 9, 29, 30, 31, 9, 9, - 9, 32, 33, 9, 35, 34, 37, 36, - 36, 38, 1, 36, 36, 39, 36, 36, - 36, 36, 36, 40, 41, 42, 43, 44, - 45, 46, 47, 41, 48, 40, 49, 50, - 51, 52, 36, 53, 54, 55, 36, 36, - 36, 36, 56, 36, 37, 36, 36, 38, - 1, 36, 36, 39, 36, 36, 36, 36, - 36, 57, 41, 42, 43, 44, 45, 46, - 47, 41, 48, 49, 49, 50, 51, 52, - 36, 53, 54, 55, 36, 36, 36, 36, - 56, 36, 38, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, - 59, 58, 38, 58, 37, 36, 36, 38, - 1, 36, 36, 39, 36, 36, 36, 36, - 36, 36, 41, 42, 43, 44, 45, 46, - 47, 41, 48, 49, 49, 50, 51, 52, - 36, 53, 54, 55, 36, 36, 36, 36, - 56, 36, 37, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 41, 42, 43, 44, 45, 36, 36, 36, - 36, 36, 36, 50, 51, 52, 36, 53, - 54, 55, 36, 36, 36, 36, 42, 36, - 37, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 42, - 43, 44, 45, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 53, 54, 55, - 36, 37, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 43, 44, 45, 36, 37, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 44, 45, - 36, 37, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 45, 36, 37, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 43, 44, 45, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 53, 54, 55, 36, 37, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 43, 44, - 45, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 54, 55, 36, 37, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 43, - 44, 45, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 55, 36, - 37, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 42, - 43, 44, 45, 36, 36, 36, 36, 36, - 36, 50, 51, 52, 36, 53, 54, 55, - 36, 36, 36, 36, 42, 36, 37, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 42, 43, 44, - 45, 36, 36, 36, 36, 36, 36, 36, - 51, 52, 36, 53, 54, 55, 36, 36, - 36, 36, 42, 36, 37, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 42, 43, 44, 45, 36, - 36, 36, 36, 36, 36, 36, 36, 52, - 36, 53, 54, 55, 36, 36, 36, 36, - 42, 36, 37, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 41, 42, 43, 44, 45, 36, 47, 41, - 36, 36, 36, 50, 51, 52, 36, 53, - 54, 55, 36, 36, 36, 36, 42, 36, - 37, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 41, 42, - 43, 44, 45, 36, 60, 41, 36, 36, - 36, 50, 51, 52, 36, 53, 54, 55, - 36, 36, 36, 36, 42, 36, 37, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 41, 42, 43, 44, - 45, 36, 36, 41, 36, 36, 36, 50, - 51, 52, 36, 53, 54, 55, 36, 36, - 36, 36, 42, 36, 37, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 41, 42, 43, 44, 45, 46, - 47, 41, 36, 36, 36, 50, 51, 52, - 36, 53, 54, 55, 36, 36, 36, 36, - 42, 36, 37, 36, 36, 38, 1, 36, - 36, 39, 36, 36, 36, 36, 36, 36, - 41, 42, 43, 44, 45, 46, 47, 41, - 48, 36, 49, 50, 51, 52, 36, 53, - 54, 55, 36, 36, 36, 36, 56, 36, - 38, 58, 58, 58, 58, 58, 58, 37, - 58, 58, 58, 58, 58, 58, 59, 58, - 58, 58, 58, 58, 58, 58, 42, 43, - 44, 45, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 53, 54, 55, 58, - 37, 36, 36, 38, 1, 36, 36, 39, - 36, 36, 36, 36, 36, 36, 41, 42, - 43, 44, 45, 46, 47, 41, 48, 40, - 49, 50, 51, 52, 36, 53, 54, 55, - 36, 36, 36, 36, 56, 36, 62, 61, - 61, 61, 61, 61, 61, 61, 63, 61, - 10, 64, 62, 61, 11, 65, 65, 3, - 6, 65, 65, 66, 65, 65, 65, 65, - 65, 67, 16, 17, 18, 19, 20, 21, - 22, 16, 23, 25, 25, 26, 27, 28, - 65, 29, 30, 31, 65, 65, 65, 65, - 33, 65, 11, 65, 65, 3, 6, 65, - 65, 66, 65, 65, 65, 65, 65, 65, - 16, 17, 18, 19, 20, 21, 22, 16, - 23, 25, 25, 26, 27, 28, 65, 29, - 30, 31, 65, 65, 65, 65, 33, 65, - 11, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 16, 17, - 18, 19, 20, 65, 65, 65, 65, 65, - 65, 26, 27, 28, 65, 29, 30, 31, - 65, 65, 65, 65, 17, 65, 11, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 17, 18, 19, - 20, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 29, 30, 31, 65, 11, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 18, - 19, 20, 65, 11, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 19, 20, 65, 11, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 20, 65, 11, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 18, 19, 20, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 29, 30, 31, 65, 11, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 18, 19, 20, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 30, 31, 65, 11, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 18, 19, 20, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 31, 65, 11, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 17, 18, 19, - 20, 65, 65, 65, 65, 65, 65, 26, - 27, 28, 65, 29, 30, 31, 65, 65, - 65, 65, 17, 65, 11, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 17, 18, 19, 20, 65, - 65, 65, 65, 65, 65, 65, 27, 28, - 65, 29, 30, 31, 65, 65, 65, 65, - 17, 65, 11, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 17, 18, 19, 20, 65, 65, 65, - 65, 65, 65, 65, 65, 28, 65, 29, - 30, 31, 65, 65, 65, 65, 17, 65, - 11, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 16, 17, - 18, 19, 20, 65, 22, 16, 65, 65, - 65, 26, 27, 28, 65, 29, 30, 31, - 65, 65, 65, 65, 17, 65, 11, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 16, 17, 18, 19, - 20, 65, 68, 16, 65, 65, 65, 26, - 27, 28, 65, 29, 30, 31, 65, 65, - 65, 65, 17, 65, 11, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 16, 17, 18, 19, 20, 65, - 65, 16, 65, 65, 65, 26, 27, 28, - 65, 29, 30, 31, 65, 65, 65, 65, - 17, 65, 11, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, - 16, 17, 18, 19, 20, 21, 22, 16, - 65, 65, 65, 26, 27, 28, 65, 29, - 30, 31, 65, 65, 65, 65, 17, 65, - 11, 65, 65, 3, 6, 65, 65, 66, - 65, 65, 65, 65, 65, 65, 16, 17, - 18, 19, 20, 21, 22, 16, 23, 65, - 25, 26, 27, 28, 65, 29, 30, 31, - 65, 65, 65, 65, 33, 65, 3, 65, - 65, 65, 65, 65, 65, 11, 65, 65, - 65, 65, 65, 65, 4, 65, 65, 65, - 65, 65, 65, 65, 17, 18, 19, 20, - 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 29, 30, 31, 65, 3, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 4, 69, 6, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 6, 69, - 8, 65, 65, 65, 8, 65, 65, 11, - 65, 65, 3, 6, 65, 65, 66, 65, - 65, 65, 65, 65, 65, 16, 17, 18, - 19, 20, 21, 22, 16, 23, 24, 25, - 26, 27, 28, 65, 29, 30, 31, 65, - 65, 65, 65, 33, 65, 11, 65, 65, - 3, 6, 65, 65, 66, 65, 65, 65, - 65, 65, 65, 16, 17, 18, 19, 20, - 21, 22, 16, 23, 24, 25, 26, 27, - 28, 65, 29, 30, 31, 65, 65, 65, - 65, 33, 65, 71, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 71, - 72, 70, 71, 72, 70, 72, 70, 8, - 69, 69, 69, 8, 69, 0 + 4, 2, 3, 2, 6, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 5, 7, 8, + 9, 7, 10, 11, 9, 9, 12, 9, + 9, 3, 13, 14, 9, 15, 7, 7, + 16, 17, 9, 9, 18, 19, 20, 21, + 22, 23, 24, 18, 25, 26, 27, 28, + 29, 30, 9, 31, 32, 33, 9, 34, + 35, 36, 37, 9, 39, 38, 41, 40, + 40, 42, 1, 40, 40, 43, 40, 40, + 40, 40, 40, 44, 45, 46, 47, 48, + 49, 50, 51, 45, 52, 44, 53, 54, + 55, 56, 40, 57, 58, 59, 40, 40, + 40, 40, 60, 40, 41, 40, 40, 42, + 1, 40, 40, 43, 40, 40, 40, 40, + 40, 61, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 53, 53, 54, 55, 56, + 40, 57, 58, 59, 40, 40, 40, 40, + 60, 40, 42, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, + 63, 62, 42, 62, 41, 40, 40, 42, + 1, 40, 40, 43, 40, 40, 40, 40, + 40, 40, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 53, 53, 54, 55, 56, + 40, 57, 58, 59, 40, 40, 40, 40, + 60, 40, 41, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 45, 46, 47, 48, 49, 40, 40, 40, + 40, 40, 40, 54, 55, 56, 40, 57, + 58, 59, 40, 40, 40, 40, 46, 40, + 41, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 46, + 47, 48, 49, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 57, 58, 59, + 40, 41, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 47, 48, 49, 40, 41, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 48, 49, + 40, 41, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 49, 40, 41, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 47, 48, 49, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 57, 58, 59, 40, 41, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 47, 48, + 49, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 58, 59, 40, 41, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 47, + 48, 49, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 59, 40, + 41, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 46, + 47, 48, 49, 40, 40, 40, 40, 40, + 40, 54, 55, 56, 40, 57, 58, 59, + 40, 40, 40, 40, 46, 40, 41, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 46, 47, 48, + 49, 40, 40, 40, 40, 40, 40, 40, + 55, 56, 40, 57, 58, 59, 40, 40, + 40, 40, 46, 40, 41, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 46, 47, 48, 49, 40, + 40, 40, 40, 40, 40, 40, 40, 56, + 40, 57, 58, 59, 40, 40, 40, 40, + 46, 40, 41, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 45, 46, 47, 48, 49, 40, 51, 45, + 40, 40, 40, 54, 55, 56, 40, 57, + 58, 59, 40, 40, 40, 40, 46, 40, + 41, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 45, 46, + 47, 48, 49, 40, 64, 45, 40, 40, + 40, 54, 55, 56, 40, 57, 58, 59, + 40, 40, 40, 40, 46, 40, 41, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 45, 46, 47, 48, + 49, 40, 40, 45, 40, 40, 40, 54, + 55, 56, 40, 57, 58, 59, 40, 40, + 40, 40, 46, 40, 41, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 45, 46, 47, 48, 49, 50, + 51, 45, 40, 40, 40, 54, 55, 56, + 40, 57, 58, 59, 40, 40, 40, 40, + 46, 40, 41, 40, 40, 42, 1, 40, + 40, 43, 40, 40, 40, 40, 40, 40, + 45, 46, 47, 48, 49, 50, 51, 45, + 52, 40, 53, 54, 55, 56, 40, 57, + 58, 59, 40, 40, 40, 40, 60, 40, + 42, 62, 62, 62, 62, 62, 62, 41, + 62, 62, 62, 62, 62, 62, 63, 62, + 62, 62, 62, 62, 62, 62, 46, 47, + 48, 49, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 57, 58, 59, 62, + 41, 40, 40, 42, 1, 40, 40, 43, + 40, 40, 40, 40, 40, 40, 45, 46, + 47, 48, 49, 50, 51, 45, 52, 44, + 53, 54, 55, 56, 40, 57, 58, 59, + 40, 40, 40, 40, 60, 40, 66, 65, + 65, 65, 65, 65, 65, 65, 67, 65, + 10, 68, 66, 65, 41, 40, 40, 42, + 1, 40, 40, 43, 40, 40, 40, 40, + 40, 69, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 44, 53, 54, 55, 56, + 40, 57, 58, 59, 40, 70, 71, 40, + 60, 40, 41, 40, 40, 42, 1, 40, + 40, 43, 40, 40, 40, 40, 40, 40, + 45, 46, 47, 48, 49, 50, 51, 45, + 52, 44, 53, 54, 55, 56, 40, 57, + 58, 59, 40, 70, 71, 40, 60, 40, + 70, 71, 72, 71, 72, 12, 73, 73, + 3, 6, 73, 73, 74, 73, 73, 73, + 73, 73, 75, 18, 19, 20, 21, 22, + 23, 24, 18, 25, 27, 27, 28, 29, + 30, 73, 31, 32, 33, 73, 73, 73, + 73, 37, 73, 12, 73, 73, 3, 6, + 73, 73, 74, 73, 73, 73, 73, 73, + 73, 18, 19, 20, 21, 22, 23, 24, + 18, 25, 27, 27, 28, 29, 30, 73, + 31, 32, 33, 73, 73, 73, 73, 37, + 73, 12, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 18, + 19, 20, 21, 22, 73, 73, 73, 73, + 73, 73, 28, 29, 30, 73, 31, 32, + 33, 73, 73, 73, 73, 19, 73, 12, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 19, 20, + 21, 22, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 31, 32, 33, 73, + 12, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 20, 21, 22, 73, 12, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 21, 22, 73, + 12, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 22, 73, 12, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 20, 21, 22, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 31, 32, 33, 73, 12, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 20, 21, 22, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 32, 33, 73, 12, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 20, 21, + 22, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 33, 73, 12, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 19, 20, + 21, 22, 73, 73, 73, 73, 73, 73, + 28, 29, 30, 73, 31, 32, 33, 73, + 73, 73, 73, 19, 73, 12, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 19, 20, 21, 22, + 73, 73, 73, 73, 73, 73, 73, 29, + 30, 73, 31, 32, 33, 73, 73, 73, + 73, 19, 73, 12, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 19, 20, 21, 22, 73, 73, + 73, 73, 73, 73, 73, 73, 30, 73, + 31, 32, 33, 73, 73, 73, 73, 19, + 73, 12, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 18, + 19, 20, 21, 22, 73, 24, 18, 73, + 73, 73, 28, 29, 30, 73, 31, 32, + 33, 73, 73, 73, 73, 19, 73, 12, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 18, 19, 20, + 21, 22, 73, 76, 18, 73, 73, 73, + 28, 29, 30, 73, 31, 32, 33, 73, + 73, 73, 73, 19, 73, 12, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 18, 19, 20, 21, 22, + 73, 73, 18, 73, 73, 73, 28, 29, + 30, 73, 31, 32, 33, 73, 73, 73, + 73, 19, 73, 12, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 18, 19, 20, 21, 22, 23, 24, + 18, 73, 73, 73, 28, 29, 30, 73, + 31, 32, 33, 73, 73, 73, 73, 19, + 73, 12, 73, 73, 3, 6, 73, 73, + 74, 73, 73, 73, 73, 73, 73, 18, + 19, 20, 21, 22, 23, 24, 18, 25, + 73, 27, 28, 29, 30, 73, 31, 32, + 33, 73, 73, 73, 73, 37, 73, 3, + 73, 73, 73, 73, 73, 73, 12, 73, + 73, 73, 73, 73, 73, 4, 73, 73, + 73, 73, 73, 73, 73, 19, 20, 21, + 22, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 31, 32, 33, 73, 3, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 4, 77, 78, + 73, 14, 73, 73, 73, 73, 73, 73, + 73, 79, 73, 14, 73, 6, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 6, 77, 8, + 73, 73, 73, 8, 73, 73, 12, 73, + 73, 3, 6, 14, 73, 74, 73, 73, + 73, 73, 73, 73, 18, 19, 20, 21, + 22, 23, 24, 18, 25, 26, 27, 28, + 29, 30, 73, 31, 32, 33, 73, 34, + 35, 73, 37, 73, 12, 73, 73, 3, + 6, 73, 73, 74, 73, 73, 73, 73, + 73, 73, 18, 19, 20, 21, 22, 23, + 24, 18, 25, 26, 27, 28, 29, 30, + 73, 31, 32, 33, 73, 73, 73, 73, + 37, 73, 34, 35, 73, 35, 73, 70, + 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 70, 71, 72, 8, 77, + 77, 77, 8, 77, 0 }; static const char _use_syllable_machine_trans_targs[] = { - 4, 8, 4, 32, 2, 4, 1, 5, - 6, 4, 29, 4, 51, 52, 53, 55, - 34, 35, 36, 37, 38, 45, 46, 48, - 54, 49, 42, 43, 44, 39, 40, 41, - 58, 50, 4, 4, 4, 4, 7, 0, - 28, 11, 12, 13, 14, 15, 22, 23, - 25, 26, 19, 20, 21, 16, 17, 18, - 27, 10, 4, 9, 24, 4, 30, 31, - 4, 4, 3, 33, 47, 4, 4, 56, - 57 + 4, 8, 4, 36, 2, 4, 1, 5, + 6, 4, 29, 32, 4, 55, 56, 59, + 60, 64, 38, 39, 40, 41, 42, 49, + 50, 52, 61, 53, 46, 47, 48, 43, + 44, 45, 62, 63, 65, 54, 4, 4, + 4, 4, 7, 0, 28, 11, 12, 13, + 14, 15, 22, 23, 25, 26, 19, 20, + 21, 16, 17, 18, 27, 10, 4, 9, + 24, 4, 30, 31, 4, 33, 34, 35, + 4, 4, 3, 37, 51, 4, 57, 58 }; static const char _use_syllable_machine_trans_actions[] = { 1, 0, 2, 3, 0, 4, 0, 0, - 7, 8, 0, 9, 10, 10, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 3, 3, 0, 0, 0, 0, 0, 0, - 0, 3, 11, 12, 13, 14, 7, 0, - 7, 0, 0, 0, 0, 0, 0, 0, - 0, 7, 0, 0, 0, 0, 0, 0, - 0, 7, 15, 0, 0, 16, 0, 0, - 17, 18, 0, 3, 0, 19, 20, 0, - 0 + 7, 8, 0, 7, 9, 10, 0, 10, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 11, 12, + 13, 14, 7, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 7, 15, 0, + 0, 16, 0, 0, 17, 7, 0, 0, + 18, 19, 0, 3, 0, 20, 0, 0 }; static const char _use_syllable_machine_to_state_actions[] = { @@ -319,7 +334,8 @@ static const char _use_syllable_machine_to_state_actions[] = { 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, 0, 0, 0, + 0, 0 }; static const char _use_syllable_machine_from_state_actions[] = { @@ -330,18 +346,20 @@ static const char _use_syllable_machine_from_state_actions[] = { 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, 0, 0, 0, + 0, 0 }; static const short _use_syllable_machine_eof_trans[] = { - 1, 3, 3, 6, 0, 35, 37, 37, - 59, 59, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 59, 37, 62, 65, 62, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 70, 70, 66, 66, 71, - 71, 71, 70 + 1, 3, 3, 6, 0, 39, 41, 41, + 63, 63, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 63, 41, 66, 69, 66, + 41, 41, 73, 73, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 78, + 74, 74, 74, 78, 74, 74, 74, 74, + 73, 78 }; static const int use_syllable_machine_start = 4; @@ -355,7 +373,7 @@ static const int use_syllable_machine_en_main = 4; -#line 143 "hb-ot-shape-complex-use-machine.rl" +#line 146 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ @@ -374,7 +392,7 @@ find_syllables (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 378 "hb-ot-shape-complex-use-machine.hh" +#line 396 "hb-ot-shape-complex-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -382,7 +400,7 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 163 "hb-ot-shape-complex-use-machine.rl" +#line 166 "hb-ot-shape-complex-use-machine.rl" p = 0; @@ -390,7 +408,7 @@ find_syllables (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 394 "hb-ot-shape-complex-use-machine.hh" +#line 412 "hb-ot-shape-complex-use-machine.hh" { int _slen; int _trans; @@ -404,7 +422,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 408 "hb-ot-shape-complex-use-machine.hh" +#line 426 "hb-ot-shape-complex-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -427,59 +445,59 @@ _eof_trans: {te = p+1;} break; case 12: -#line 132 "hb-ot-shape-complex-use-machine.rl" +#line 135 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (independent_cluster); }} break; case 14: -#line 134 "hb-ot-shape-complex-use-machine.rl" +#line 137 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (standard_cluster); }} break; case 9: -#line 138 "hb-ot-shape-complex-use-machine.rl" +#line 141 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; case 8: -#line 139 "hb-ot-shape-complex-use-machine.rl" +#line 142 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (non_cluster); }} break; case 11: -#line 132 "hb-ot-shape-complex-use-machine.rl" +#line 135 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (independent_cluster); }} break; case 15: -#line 133 "hb-ot-shape-complex-use-machine.rl" +#line 136 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (virama_terminated_cluster); }} break; case 13: -#line 134 "hb-ot-shape-complex-use-machine.rl" +#line 137 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (standard_cluster); }} break; case 17: -#line 135 "hb-ot-shape-complex-use-machine.rl" +#line 138 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} break; case 16: -#line 136 "hb-ot-shape-complex-use-machine.rl" +#line 139 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (numeral_cluster); }} break; - case 20: -#line 137 "hb-ot-shape-complex-use-machine.rl" + case 18: +#line 140 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (symbol_cluster); }} break; - case 18: -#line 138 "hb-ot-shape-complex-use-machine.rl" + case 19: +#line 141 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; - case 19: -#line 139 "hb-ot-shape-complex-use-machine.rl" + case 20: +#line 142 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (non_cluster); }} break; case 1: -#line 134 "hb-ot-shape-complex-use-machine.rl" +#line 137 "hb-ot-shape-complex-use-machine.rl" {{p = ((te))-1;}{ found_syllable (standard_cluster); }} break; case 4: -#line 138 "hb-ot-shape-complex-use-machine.rl" +#line 141 "hb-ot-shape-complex-use-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; case 2: @@ -497,16 +515,16 @@ _eof_trans: case 3: #line 1 "NONE" {te = p+1;} -#line 138 "hb-ot-shape-complex-use-machine.rl" +#line 141 "hb-ot-shape-complex-use-machine.rl" {act = 7;} break; case 10: #line 1 "NONE" {te = p+1;} -#line 139 "hb-ot-shape-complex-use-machine.rl" +#line 142 "hb-ot-shape-complex-use-machine.rl" {act = 8;} break; -#line 510 "hb-ot-shape-complex-use-machine.hh" +#line 528 "hb-ot-shape-complex-use-machine.hh" } _again: @@ -515,7 +533,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 519 "hb-ot-shape-complex-use-machine.hh" +#line 537 "hb-ot-shape-complex-use-machine.hh" } if ( ++p != pe ) @@ -531,7 +549,7 @@ _again: } -#line 171 "hb-ot-shape-complex-use-machine.rl" +#line 174 "hb-ot-shape-complex-use-machine.rl" } diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl index 7702cd94d..82803da0c 100644 --- a/src/hb-ot-shape-complex-use-machine.rl +++ b/src/hb-ot-shape-complex-use-machine.rl @@ -107,6 +107,9 @@ complex_syllable_tail = vowel_modifiers final_consonants ; +number_joiner_terminated_cluster_tail = (HN N VS?)* HN; +numeral_cluster_tail = (HN N VS?)+; +symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+; virama_terminated_cluster = (R|CS)? (B | GB) VS? @@ -119,12 +122,12 @@ standard_cluster = ; broken_cluster = R? - complex_syllable_tail + (complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail) ; -number_joiner_terminated_cluster = N VS? (HN N VS?)* HN; -numeral_cluster = N VS? (HN N VS?)*; -symbol_cluster = S VS? SMAbv* SMBlw*; +number_joiner_terminated_cluster = N VS? number_joiner_terminated_cluster_tail; +numeral_cluster = N VS? numeral_cluster_tail?; +symbol_cluster = (S | GB) VS? symbol_cluster_tail?; independent_cluster = (IND | O | Rsv | WJ) VS?; other = any; diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index ddf7053db..f47d5e847 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -319,7 +319,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, /* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB, - /* 1B60 */ O, O, GB, O, O, O, O, O, GB, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, + /* 1B60 */ O, S, GB, S, S, S, S, S, GB, S, S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, /* Sundanese */ From 14e1fabc41a9a5ead3d91d560773050469982f54 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Wed, 1 May 2019 21:29:06 -0400 Subject: [PATCH 120/336] Sync gen-vowel-constraints.py with current output --- src/gen-vowel-constraints.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gen-vowel-constraints.py b/src/gen-vowel-constraints.py index afb21d928..1340d97dc 100755 --- a/src/gen-vowel-constraints.py +++ b/src/gen-vowel-constraints.py @@ -180,6 +180,9 @@ print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB print ('\t\t\t\t hb_buffer_t *buffer,') print ('\t\t\t\t hb_font_t *font HB_UNUSED)') print ('{') +print ('#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS)') +print (' return;') +print ('#endif') print (' if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)') print (' return;') print () From bf22338f49fb1711f7cbcad2d9949d7962cdc0bc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 13:51:52 -0700 Subject: [PATCH 121/336] Remove dead code --- src/hb-algs.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index c3467800b..e0700100b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -86,9 +86,6 @@ struct (hb_deref_pointer (hb_forward (a)) (hb_forward (vs)...)) public: - template auto - impl2 (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) template auto operator () (Appl&& a, Vals &&...vs) const HB_AUTO_RETURN From 273ed6127bd9471fd11b3c1c7f232638f1ff1dba Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 14:04:51 -0700 Subject: [PATCH 122/336] [serializer] Add serialize_copy() --- src/hb-open-type.hh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index bde059602..17e8d2a97 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -305,6 +305,20 @@ struct OffsetTo : Offset return ret; } + template + bool serialize_copy (hb_serialize_context_t *c, const T &src, const void *base) + { + *this = 0; + if (has_null && &src == &Null (T)) + return false; + + c->push (); + + c->copy (src); + + c->add_link (*this, c->pop_pack (), base); + } + bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); From 88fdeeecc0ef57e41219d92c90f35f13cbd3a35e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 14:14:33 -0700 Subject: [PATCH 123/336] [serialize] Take arguments in copy() --- src/hb-open-type.hh | 6 +++--- src/hb-serialize.hh | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 17e8d2a97..cd80b3a7f 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -305,8 +305,8 @@ struct OffsetTo : Offset return ret; } - template - bool serialize_copy (hb_serialize_context_t *c, const T &src, const void *base) + template + bool serialize_copy (hb_serialize_context_t *c, const T &src, const void *base, Ts &&...ds) { *this = 0; if (has_null && &src == &Null (T)) @@ -314,7 +314,7 @@ struct OffsetTo : Offset c->push (); - c->copy (src); + c->copy (src, hb_forward (ds)...); c->add_link (*this, c->pop_pack (), base); } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 7566881a8..61195a4d7 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -366,8 +366,9 @@ struct hb_serialize_context_t return ret; } - template auto - _copy (const Type &obj, hb_priority<1>) const HB_RETURN (Type *, obj.copy (this)) + template auto + _copy (const Type &obj, hb_priority<1>, Ts &&...ds) const HB_RETURN + (Type *, obj.copy (this, hb_forward (ds)...)) template auto _copy (const Type &obj, hb_priority<0>) const -> decltype (&(obj = obj)) @@ -380,8 +381,9 @@ struct hb_serialize_context_t /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data * instead of memcpy(). */ - template - Type *copy (const Type &obj) { return _copy (obj, hb_prioritize); } + template + Type *copy (const Type &obj, Ts &&...ds) + { return _copy (obj, hb_prioritize, hb_forward (ds)...); } template hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } From 88a41472404a8e7754e1099ca4a5b2146dae5298 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 14:22:31 -0700 Subject: [PATCH 124/336] [serializer] Accept exact type in serialize_subset/copy() --- src/hb-open-type.hh | 12 ++++++------ src/hb-ot-layout-common.hh | 33 ++------------------------------- src/hb-ot-layout-gpos-table.hh | 6 ++++++ src/hb-ot-layout-gsub-table.hh | 6 ++++++ 4 files changed, 20 insertions(+), 37 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index cd80b3a7f..808e1829b 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -284,11 +284,11 @@ struct OffsetTo : Offset return * (Type *) Offset::serialize (c, base); } - template - bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts &&...ds) + template + bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts &&...ds) { *this = 0; - if (has_null && &src == &Null (T)) + if (has_null && &src == &Null (Type)) return false; auto *s = c->serializer; @@ -305,11 +305,11 @@ struct OffsetTo : Offset return ret; } - template - bool serialize_copy (hb_serialize_context_t *c, const T &src, const void *base, Ts &&...ds) + template + bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts &&...ds) { *this = 0; - if (has_null && &src == &Null (T)) + if (has_null && &src == &Null (Type)) return false; c->push (); diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index c8dcc3208..3089801d2 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -715,23 +715,6 @@ struct Lookup return_trace (true); } - /* Older compilers need this to NOT be locally defined in a function. */ - template - struct SubTableSubsetWrapper - { - SubTableSubsetWrapper (const TSubTable &subtable_, - unsigned int lookup_type_) : - subtable (subtable_), - lookup_type (lookup_type_) {} - - bool subset (hb_subset_context_t *c) const - { return subtable.dispatch (c, lookup_type); } - - private: - const TSubTable &subtable; - unsigned int lookup_type; - }; - template bool subset (hb_subset_context_t *c) const { @@ -746,23 +729,11 @@ struct Lookup OffsetArrayOf& out_subtables = out->get_subtables (); unsigned int count = subTable.len; for (unsigned int i = 0; i < count; i++) - { - SubTableSubsetWrapper wrapper (this+subtables[i], get_type ()); - - out_subtables[i].serialize_subset (c, wrapper, out); - } + out_subtables[i].serialize_subset (c, this+subtables[i], out, get_type ()); return_trace (true); } - /* Older compilers need this to NOT be locally defined in a function. */ - template - struct SubTableSanitizeWrapper : TSubTable - { - bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) const - { return this->dispatch (c, lookup_type); } - }; - template bool sanitize (hb_sanitize_context_t *c) const { @@ -774,7 +745,7 @@ struct Lookup if (!markFilteringSet.sanitize (c)) return_trace (false); } - if (unlikely (!CastR>> (subTable) + if (unlikely (!CastR> (subTable) .sanitize (c, this, get_type ()))) return_trace (false); diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 407ce9e27..4b752fc11 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1525,6 +1525,12 @@ struct PosLookupSubTable } } + /* XXX Remove? */ + bool subset (hb_subset_context_t *c, unsigned lookup_type) const + { return dispatch (c, lookup_type); } + bool sanitize (hb_sanitize_context_t *c, unsigned lookup_type) const + { return dispatch (c, lookup_type); } + protected: union { SinglePos single; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index be78c1aaa..4a6f48f91 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1170,6 +1170,12 @@ struct SubstLookupSubTable } } + /* XXX Remove? */ + bool subset (hb_subset_context_t *c, unsigned lookup_type) const + { return dispatch (c, lookup_type); } + bool sanitize (hb_sanitize_context_t *c, unsigned lookup_type) const + { return dispatch (c, lookup_type); } + protected: union { SingleSubst single; From 998b0b68ac2eafd1d5bca51b3723fa753e4db7c4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 14:39:52 -0700 Subject: [PATCH 125/336] [serializer] Add copy() to (Unsized)ArrayOf --- src/hb-open-type.hh | 41 +++++++++++++++++++++++++++++++++++++++++ src/hb-serialize.hh | 4 ++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 808e1829b..6fd6fa652 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -409,6 +409,36 @@ struct UnsizedArrayOf void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array (len).qsort (start, end); } + bool serialize (hb_serialize_context_t *c, unsigned int items_len) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend (*this, items_len))) return_trace (false); + return_trace (true); + } + template + bool serialize (hb_serialize_context_t *c, Iterator items) + { + TRACE_SERIALIZE (this); + unsigned count = items.len (); + if (unlikely (!serialize (c, count))) return_trace (false); + /* TODO Umm. Just exhaust the iterator instead? Being extra + * cautious right now.. */ + for (unsigned i = 0; i < count; i++, items++) + arrayZ[i] = *items; + return_trace (true); + } + + UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (*this); + if (unlikely (!out->serialize (c, count))) return_trace (nullptr); + for (unsigned i = 0; i < count; i++) + out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ + return_trace (out); + } + bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); @@ -580,6 +610,17 @@ struct ArrayOf return_trace (true); } + ArrayOf* copy (hb_serialize_context_t *c) + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (*this); + unsigned count = len; + if (unlikely (!out->serialize (c, count))) return_trace (nullptr); + for (unsigned i = 0; i < count; i++) + out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ + return_trace (out); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 61195a4d7..9fa0658b9 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -401,8 +401,8 @@ struct hb_serialize_context_t template Type *extend_min (Type &obj) { return extend_size (obj, obj.min_size); } - template - Type *extend (Type &obj) { return extend_size (obj, obj.get_size ()); } + template + Type *extend (Type &obj, Ts &&...ds) { return extend_size (obj, obj.get_size (hb_forward (ds)...)); } /* Output routines. */ hb_bytes_t copy_bytes () const From bf91b418b0e988619c230156f5f062c5d2802dd8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 14:42:37 -0700 Subject: [PATCH 126/336] [name] --- src/hb-ot-name-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index c8b38a68d..a15981ce5 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -98,8 +98,7 @@ struct NameRecord bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - /* We can check from base all the way up to the end of string... */ - return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); + return_trace (c->check_struct (this) && offset.sanitize (c, base, length)); } HBUINT16 platformID; /* Platform ID. */ @@ -107,7 +106,8 @@ struct NameRecord HBUINT16 languageID; /* Language ID. */ HBUINT16 nameID; /* Name ID. */ HBUINT16 length; /* String length (in bytes). */ - HBUINT16 offset; /* String offset from start of storage area (in bytes). */ + OffsetTo> + offset; /* String offset from start of storage area (in bytes). */ public: DEFINE_SIZE_STATIC (12); }; From 87810fc958e28d0c5e05097b1b3fe78d962fdc62 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 14:45:57 -0700 Subject: [PATCH 127/336] [name] Use variable forwarding to simplify sanitize() --- src/hb-ot-name-table.hh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index a15981ce5..91a52148e 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -306,11 +306,8 @@ struct name { TRACE_SANITIZE (this); const void *string_pool = (this+stringOffset).arrayZ; - unsigned int _count = count; - /* Move to run-time?! */ - for (unsigned int i = 0; i < _count; i++) - if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false); - return_trace (true); + /* TODO: Move to run-time?! */ + return_trace (nameRecordZ.sanitize (c, count, string_pool)); } bool sanitize (hb_sanitize_context_t *c) const From 0f1a6ce8268b197732aab40069bbda57eddac2e0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 15:03:41 -0700 Subject: [PATCH 128/336] [name] Fix format of susbetted table to 0 --- src/hb-ot-name-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 91a52148e..7f3b7a44c 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -267,7 +267,7 @@ struct name if (unlikely (!c->extend_min ((*this)))) return_trace (false); - this->format = source_name->format; + this->format = 0; this->count = name_record_idx_to_retain.length; this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; From 91176d5b778b44172591e82ba84127e5eff1372d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 15:12:07 -0700 Subject: [PATCH 129/336] [serialize] Check offset base is within (possibly end of) object --- src/hb-serialize.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 9fa0658b9..e7c6445d4 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -295,6 +295,7 @@ struct hb_serialize_context_t { const object_t::link_t &link = *link_it; const object_t &child = *packed[link.objidx]; + assert (link.bias <= parent.tail - parent.head); unsigned offset = (child.head - parent.head) - link.bias; if (link.is_wide) From 49b1c763a0459d586b7f0aa86eadd13d21b24867 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:19:34 -0700 Subject: [PATCH 130/336] [test] Run "fonttools ttx" instead of "ttx" --- test/subset/run-tests.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/subset/run-tests.py b/test/subset/run-tests.py index fb4684cf1..0a1bb1076 100755 --- a/test/subset/run-tests.py +++ b/test/subset/run-tests.py @@ -32,11 +32,11 @@ def which(program): return None -ttx = which ("ttx") +fonttools = which ("fonttools") ots_sanitize = which ("ots-sanitize") -if not ttx: - print("TTX is not present, skipping test.") +if not fonttools: + print("fonttools is not present, skipping test.") sys.exit (77) def cmd(command): @@ -101,8 +101,8 @@ def run_test(test, should_check_ots): return 0 def run_ttx (file): - print ("ttx %s" % file) - return cmd([ttx, "-q", "-o-", file]) + print ("fonttools ttx %s" % file) + return cmd([fonttools, "ttx", "-q", "-o-", file]) def strip_check_sum (ttx_string): return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]', From 7d497a3a92973d4cec14888b932091f49de1d190 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:20:03 -0700 Subject: [PATCH 131/336] [debug] Allow return_trace() to return any type --- src/hb-debug.hh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hb-debug.hh b/src/hb-debug.hh index 52d5942c6..00696058c 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -330,18 +330,20 @@ struct hb_auto_trace_t<0, ret_t> const char *message, ...) HB_PRINTF_FUNC(6, 7) {} - ret_t ret (ret_t v, - const char *func HB_UNUSED = nullptr, - unsigned int line HB_UNUSED = 0) { return v; } + template + T ret (T&& v, + const char *func HB_UNUSED = nullptr, + unsigned int line HB_UNUSED = 0) { return hb_forward (v); } }; /* For disabled tracing; optimize out everything. * https://github.com/harfbuzz/harfbuzz/pull/605 */ template struct hb_no_trace_t { - ret_t ret (ret_t v, - const char *func HB_UNUSED = "", - unsigned int line HB_UNUSED = 0) { return v; } + template + T ret (T&& v, + const char *func HB_UNUSED = nullptr, + unsigned int line HB_UNUSED = 0) { return hb_forward (v); } }; #define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__) From 8a32c9eecbdc907415195eca9ebad47c8acf2df5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:20:18 -0700 Subject: [PATCH 132/336] [serialize] Misc getting copy() to work --- src/hb-open-type.hh | 16 +++++++++------- src/hb-serialize.hh | 26 ++++++++++++++++---------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 6fd6fa652..1deb63a35 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -288,7 +288,7 @@ struct OffsetTo : Offset bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts &&...ds) { *this = 0; - if (has_null && &src == &Null (Type)) + if (has_null && &src == _hb_has_null::get_null ()) return false; auto *s = c->serializer; @@ -309,14 +309,16 @@ struct OffsetTo : Offset bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts &&...ds) { *this = 0; - if (has_null && &src == &Null (Type)) + if (has_null && &src == _hb_has_null::get_null ()) return false; c->push (); - c->copy (src, hb_forward (ds)...); + bool ret = c->copy (src, hb_forward (ds)...); c->add_link (*this, c->pop_pack (), base); + + return ret; } bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const @@ -429,10 +431,10 @@ struct UnsizedArrayOf return_trace (true); } - UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) + UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) const { TRACE_SERIALIZE (this); - auto *out = c->start_embed (*this); + auto *out = c->start_embed (this); if (unlikely (!out->serialize (c, count))) return_trace (nullptr); for (unsigned i = 0; i < count; i++) out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ @@ -610,10 +612,10 @@ struct ArrayOf return_trace (true); } - ArrayOf* copy (hb_serialize_context_t *c) + ArrayOf* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); - auto *out = c->start_embed (*this); + auto *out = c->start_embed (this); unsigned count = len; if (unlikely (!out->serialize (c, count))) return_trace (nullptr); for (unsigned i = 0; i < count; i++) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index e7c6445d4..12ba95445 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -71,7 +71,7 @@ struct hb_serialize_context_t { bool is_wide: 1; unsigned position : 31; - int bias; + unsigned bias; objidx_t objidx; }; @@ -323,6 +323,9 @@ struct hb_serialize_context_t allocate_size (alignment - l); } + template + Type *start_embed (const Type &_ HB_UNUSED) const + { return start_embed (); } template Type *start_embed (const Type *_ HB_UNUSED = nullptr) const { @@ -358,33 +361,36 @@ struct hb_serialize_context_t } template - Type *embed (const Type &obj) + Type *embed (const Type *obj) { - unsigned int size = obj.get_size (); + unsigned int size = obj->get_size (); Type *ret = this->allocate_size (size); if (unlikely (!ret)) return nullptr; - memcpy (ret, &obj, size); + memcpy (ret, obj, size); return ret; } + template + Type *embed (const Type &obj) + { return embed (&obj); } template auto - _copy (const Type &obj, hb_priority<1>, Ts &&...ds) const HB_RETURN - (Type *, obj.copy (this, hb_forward (ds)...)) + _copy (const Type &src, hb_priority<1>, Ts &&...ds) HB_RETURN + (Type *, src.copy (this, hb_forward (ds)...)) template auto - _copy (const Type &obj, hb_priority<0>) const -> decltype (&(obj = obj)) + _copy (const Type &src, hb_priority<0>) -> decltype (&(src = src)) { Type *ret = this->allocate_size (sizeof (Type)); if (unlikely (!ret)) return nullptr; - *ret = obj; + *ret = src; return ret; } /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data * instead of memcpy(). */ template - Type *copy (const Type &obj, Ts &&...ds) - { return _copy (obj, hb_prioritize, hb_forward (ds)...); } + Type *copy (const Type &src, Ts &&...ds) + { return _copy (src, hb_prioritize, hb_forward (ds)...); } template hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } From 431b6e1c449582619169722e16b472e872b02d58 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:22:32 -0700 Subject: [PATCH 133/336] [serialize] Disable assertion for now --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 12ba95445..d18934c4d 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -295,7 +295,7 @@ struct hb_serialize_context_t { const object_t::link_t &link = *link_it; const object_t &child = *packed[link.objidx]; - assert (link.bias <= parent.tail - parent.head); + //assert (link.bias <= parent.tail - parent.head); unsigned offset = (child.head - parent.head) - link.bias; if (link.is_wide) From 097bb3f0af391dbb5d498df548b769f165f35c8a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:25:00 -0700 Subject: [PATCH 134/336] [name] Minor changes --- src/hb-ot-name-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 7f3b7a44c..10a2255ab 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -106,7 +106,7 @@ struct NameRecord HBUINT16 languageID; /* Language ID. */ HBUINT16 nameID; /* Name ID. */ HBUINT16 length; /* String length (in bytes). */ - OffsetTo> + NNOffsetTo> offset; /* String offset from start of storage area (in bytes). */ public: DEFINE_SIZE_STATIC (12); @@ -261,7 +261,7 @@ struct name bool serialize (hb_serialize_context_t *c, const name *source_name, const hb_subset_plan_t *plan, - const hb_vector_t& name_record_idx_to_retain) + const hb_sorted_vector_t& name_record_idx_to_retain) { TRACE_SERIALIZE (this); @@ -287,7 +287,7 @@ struct name bool subset (hb_subset_context_t *c) const { hb_subset_plan_t *plan = c->plan; - hb_vector_t name_record_idx_to_retain; + hb_sorted_vector_t name_record_idx_to_retain; get_subsetted_ids (this, plan, name_record_idx_to_retain); From 8855af38a8497d7788924d368baa9eeae4916940 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:26:06 -0700 Subject: [PATCH 135/336] [name] Add NameRecord::copy() --- src/hb-ot-name-table.hh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 10a2255ab..00686ee2d 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -95,6 +95,16 @@ struct NameRecord return UNSUPPORTED; } + NameRecord* copy (hb_serialize_context_t *c, + const void *src_base, + const void *dst_base) const + { + auto *out = c->embed (this); + out->offset = 0; + out->offset.serialize_copy (c, src_base + offset, dst_base, length); + return out; + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); From c7f366fbbb208d0a9103ac4ee4ac00ff726c31e4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:29:07 -0700 Subject: [PATCH 136/336] [WIP] [name] Port to fancy serializer machinery --- src/hb-ot-name-table.hh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 00686ee2d..72c0c642c 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -279,17 +279,21 @@ struct name this->format = 0; this->count = name_record_idx_to_retain.length; - this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; + auto snap = c->snapshot (); + this->nameRecordZ.serialize (c, this->count); + this->stringOffset = c->length (); + c->revert (snap); - if (!serialize_name_record (c, source_name, name_record_idx_to_retain)) - return_trace (false); + auto src_array = source_name->nameRecordZ.as_array (source_name->count); + const void *src_base = &(source_name + source_name->stringOffset); + const void *dst_base = &(this + this->stringOffset); - if (!serialize_strings (c, source_name, plan, name_record_idx_to_retain)) - return_trace (false); + + hb_iter (name_record_idx_to_retain) + | hb_apply ([&] (unsigned _) { c->copy (src_array[_], src_base, dst_base); }) + ; - if (!pack_record_and_strings (this, c, name_record_idx_to_retain.length)) - return_trace (false); + assert (this->stringOffset == c->length ()); return_trace (true); } From 72e3eba8f87e2a8b145a4f98e24499f0aafe099b Mon Sep 17 00:00:00 2001 From: Cody Planteen Date: Thu, 2 May 2019 13:03:15 -0600 Subject: [PATCH 137/336] Add configuration option HB_NO_GETENV to disable use of getenv() --- src/hb.hh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index 0336ed568..11ca2fac4 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -343,19 +343,27 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); # if defined(_WIN32_WCE) /* Some things not defined on Windows CE. */ # define vsnprintf _vsnprintf -# define getenv(Name) nullptr +# ifndef HB_NO_GETENV +# define HB_NO_GETENV +# endif # if _WIN32_WCE < 0x800 # define setlocale(Category, Locale) "C" static int errno = 0; /* Use something better? */ # endif # elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) -# define getenv(Name) nullptr +# ifndef HB_NO_GETENV +# define HB_NO_GETENV +# endif # endif # if defined(_MSC_VER) && _MSC_VER < 1900 # define snprintf _snprintf # endif #endif +#ifdef HB_NO_GETENV +#define getenv(Name) nullptr +#endif + #if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT) /* atexit() is only safe to be called from shared libraries on certain * platforms. Whitelist. From 0d5fd168f8e3c1202358a82161a28e407149b1b4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 3 May 2019 10:37:32 -0700 Subject: [PATCH 138/336] Revert "[WIP] [name] Port to fancy serializer machinery" This reverts commit c7f366fbbb208d0a9103ac4ee4ac00ff726c31e4. Don't know how it got to master! --- src/hb-ot-name-table.hh | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 72c0c642c..00686ee2d 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -279,21 +279,17 @@ struct name this->format = 0; this->count = name_record_idx_to_retain.length; + this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; - auto snap = c->snapshot (); - this->nameRecordZ.serialize (c, this->count); - this->stringOffset = c->length (); - c->revert (snap); - auto src_array = source_name->nameRecordZ.as_array (source_name->count); - const void *src_base = &(source_name + source_name->stringOffset); - const void *dst_base = &(this + this->stringOffset); + if (!serialize_name_record (c, source_name, name_record_idx_to_retain)) + return_trace (false); - + hb_iter (name_record_idx_to_retain) - | hb_apply ([&] (unsigned _) { c->copy (src_array[_], src_base, dst_base); }) - ; + if (!serialize_strings (c, source_name, plan, name_record_idx_to_retain)) + return_trace (false); - assert (this->stringOffset == c->length ()); + if (!pack_record_and_strings (this, c, name_record_idx_to_retain.length)) + return_trace (false); return_trace (true); } From ac350c92fd6b04845c6240a5f3b77ceaf29e51d0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 5 May 2019 09:10:46 -0700 Subject: [PATCH 139/336] [dispatch] Try obj.dispatch(c) before trying c->dispatch(obj) --- src/hb-aat-layout-common.hh | 2 +- src/hb-dispatch.hh | 13 +++++++++++++ src/hb-ot-layout-gsubgpos.hh | 14 +++++++------- src/hb-sanitize.hh | 2 +- src/hb-subset.hh | 4 ++-- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 95ac27128..a17da372d 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -807,7 +807,7 @@ struct hb_aat_apply_context_t : { const char *get_name () { return "APPLY"; } template - return_t dispatch (const T &obj) { return obj.apply (this); } + return_t _dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } diff --git a/src/hb-dispatch.hh b/src/hb-dispatch.hh index c4347a6ca..e5820744e 100644 --- a/src/hb-dispatch.hh +++ b/src/hb-dispatch.hh @@ -38,12 +38,25 @@ template struct hb_dispatch_context_t { + private: + /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ + const Context* thiz () const { return static_cast (this); } + Context* thiz () { return static_cast< Context *> (this); } + public: static constexpr unsigned max_debug_depth = MaxDebugDepth; typedef Return return_t; template bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } + template + return_t dispatch (const T &obj) { return _dispatch_impl (obj, hb_prioritize); } static return_t no_dispatch_return_value () { return Context::default_return_value (); } static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; } + + private: + template + auto _dispatch_impl (const T &obj, hb_priority<1>) HB_AUTO_RETURN (obj.dispatch (thiz ())) + template + Return _dispatch_impl (const T &obj, hb_priority<0>) { return thiz()->_dispatch (obj); } }; diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 6b0b7ad5d..9960b4032 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -46,7 +46,7 @@ struct hb_intersects_context_t : { const char *get_name () { return "INTERSECTS"; } template - return_t dispatch (const T &obj) { return obj.intersects (this->glyphs); } + return_t _dispatch (const T &obj) { return obj.intersects (this->glyphs); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -64,7 +64,7 @@ struct hb_closure_context_t : const char *get_name () { return "CLOSURE"; } typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); template - return_t dispatch (const T &obj) { obj.closure (this); return hb_void_t (); } + return_t _dispatch (const T &obj) { obj.closure (this); return hb_void_t (); } static return_t default_return_value () { return hb_void_t (); } void recurse (unsigned int lookup_index) { @@ -128,7 +128,7 @@ struct hb_would_apply_context_t : { const char *get_name () { return "WOULD_APPLY"; } template - return_t dispatch (const T &obj) { return obj.would_apply (this); } + return_t _dispatch (const T &obj) { return obj.would_apply (this); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -156,7 +156,7 @@ struct hb_collect_glyphs_context_t : const char *get_name () { return "COLLECT_GLYPHS"; } typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); template - return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_void_t (); } + return_t _dispatch (const T &obj) { obj.collect_glyphs (this); return hb_void_t (); } static return_t default_return_value () { return hb_void_t (); } void recurse (unsigned int lookup_index) { @@ -235,7 +235,7 @@ struct hb_add_coverage_context_t : const char *get_name () { return "GET_COVERAGE"; } typedef const Coverage &return_t; template - return_t dispatch (const T &obj) { return obj.get_coverage (); } + return_t _dispatch (const T &obj) { return obj.get_coverage (); } static return_t default_return_value () { return Null(Coverage); } bool stop_sublookup_iteration (return_t r) const { @@ -438,7 +438,7 @@ struct hb_ot_apply_context_t : const char *get_name () { return "APPLY"; } typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); template - return_t dispatch (const T &obj) { return obj.apply (this); } + return_t _dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int sub_lookup_index) @@ -648,7 +648,7 @@ struct hb_get_subtables_context_t : /* Dispatch interface. */ const char *get_name () { return "GET_SUBTABLES"; } template - return_t dispatch (const T &obj) + return_t _dispatch (const T &obj) { hb_applicable_t *entry = array.push(); entry->init (obj, apply_to); diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index e58202cf7..9cf17e5f4 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -131,7 +131,7 @@ struct hb_sanitize_context_t : bool may_dispatch (const T *obj HB_UNUSED, const F *format) { return format->sanitize (this); } template - return_t dispatch (const T &obj) { return obj.sanitize (this); } + return_t _dispatch (const T &obj) { return obj.sanitize (this); } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } diff --git a/src/hb-subset.hh b/src/hb-subset.hh index 45cb763ec..795859dd1 100644 --- a/src/hb-subset.hh +++ b/src/hb-subset.hh @@ -41,8 +41,8 @@ struct hb_subset_context_t : { const char *get_name () { return "SUBSET"; } template - bool dispatch (const T &obj) { return obj.subset (this); } - static bool default_return_value () { return true; } + return_t _dispatch (const T &obj) { return obj.subset (this); } + static return_t default_return_value () { return true; } hb_subset_plan_t *plan; hb_serialize_context_t *serializer; From b10f65933a77434bf8d68058793037f38a8ed5a6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 5 May 2019 09:23:35 -0700 Subject: [PATCH 140/336] [dispatch] Use functionality from previous commit To remove a couple of unwanted wrapper methods --- src/hb-dispatch.hh | 15 +++++++++------ src/hb-open-type.hh | 10 +++++----- src/hb-ot-layout-gpos-table.hh | 6 ------ src/hb-ot-layout-gsub-table.hh | 6 ------ src/hb-sanitize.hh | 5 +++-- src/hb-subset.hh | 5 +++-- 6 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/hb-dispatch.hh b/src/hb-dispatch.hh index e5820744e..0293fd14e 100644 --- a/src/hb-dispatch.hh +++ b/src/hb-dispatch.hh @@ -47,16 +47,19 @@ struct hb_dispatch_context_t typedef Return return_t; template bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } - template - return_t dispatch (const T &obj) { return _dispatch_impl (obj, hb_prioritize); } + template + return_t dispatch (const T &obj, Ts &&...ds) + { return _dispatch_impl (obj, hb_prioritize, hb_forward (ds)...); } static return_t no_dispatch_return_value () { return Context::default_return_value (); } static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; } private: - template - auto _dispatch_impl (const T &obj, hb_priority<1>) HB_AUTO_RETURN (obj.dispatch (thiz ())) - template - Return _dispatch_impl (const T &obj, hb_priority<0>) { return thiz()->_dispatch (obj); } + template + auto _dispatch_impl (const T &obj, hb_priority<1>, Ts &&...ds) HB_AUTO_RETURN + (obj.dispatch (thiz (), hb_forward (ds)...)) + template + Return _dispatch_impl (const T &obj, hb_priority<0>, Ts &&...ds) + { return thiz()->_dispatch (obj, hb_forward (ds)...); } }; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 1deb63a35..2990b0d58 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -295,7 +295,7 @@ struct OffsetTo : Offset s->push (); - bool ret = src.subset (c, hb_forward (ds)...); + bool ret = c->dispatch (src, hb_forward (ds)...); if (ret || !has_null) s->add_link (*this, s->pop_pack (), base); @@ -336,7 +336,7 @@ struct OffsetTo : Offset TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && (this->is_null () || - StructAtOffset (base, *this).sanitize (c, hb_forward (ds)...) || + c->dispatch (StructAtOffset (base, *this), hb_forward (ds)...) || neuter (c))); } @@ -469,7 +469,7 @@ struct UnsizedArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -652,7 +652,7 @@ struct ArrayOf if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -828,7 +828,7 @@ struct ArrayOfM1 if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) return_trace (false); return_trace (true); } diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 4b752fc11..407ce9e27 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1525,12 +1525,6 @@ struct PosLookupSubTable } } - /* XXX Remove? */ - bool subset (hb_subset_context_t *c, unsigned lookup_type) const - { return dispatch (c, lookup_type); } - bool sanitize (hb_sanitize_context_t *c, unsigned lookup_type) const - { return dispatch (c, lookup_type); } - protected: union { SinglePos single; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 4a6f48f91..be78c1aaa 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1170,12 +1170,6 @@ struct SubstLookupSubTable } } - /* XXX Remove? */ - bool subset (hb_subset_context_t *c, unsigned lookup_type) const - { return dispatch (c, lookup_type); } - bool sanitize (hb_sanitize_context_t *c, unsigned lookup_type) const - { return dispatch (c, lookup_type); } - protected: union { SingleSubst single; diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index 9cf17e5f4..71bf3a859 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -130,8 +130,9 @@ struct hb_sanitize_context_t : template bool may_dispatch (const T *obj HB_UNUSED, const F *format) { return format->sanitize (this); } - template - return_t _dispatch (const T &obj) { return obj.sanitize (this); } + template + return_t _dispatch (const T &obj, Ts &&...ds) + { return obj.sanitize (this, hb_forward (ds)...); } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } diff --git a/src/hb-subset.hh b/src/hb-subset.hh index 795859dd1..4da2b675b 100644 --- a/src/hb-subset.hh +++ b/src/hb-subset.hh @@ -40,8 +40,9 @@ struct hb_subset_context_t : hb_dispatch_context_t { const char *get_name () { return "SUBSET"; } - template - return_t _dispatch (const T &obj) { return obj.subset (this); } + template + return_t _dispatch (const T &obj, Ts &&...ds) + { return obj.subset (this, hb_forward (ds)...); } static return_t default_return_value () { return true; } hb_subset_plan_t *plan; From c14efb8e68e31fb7537bcfe5eea779c0830a0b0c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 5 May 2019 09:54:58 -0700 Subject: [PATCH 141/336] Fix previous commit Priority should be given to specific over dispatch. Broke sanitize before. This fixes it, by moving prioritization to the context implementation, since the correct priority cannot be done in the dispatch implementation. Done for subset and sanitize only, which need it. --- src/hb-aat-layout-common.hh | 2 +- src/hb-dispatch.hh | 10 +--------- src/hb-ot-layout-gsubgpos.hh | 14 +++++++------- src/hb-sanitize.hh | 16 +++++++++++++--- src/hb-subset.hh | 15 ++++++++++++--- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index a17da372d..95ac27128 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -807,7 +807,7 @@ struct hb_aat_apply_context_t : { const char *get_name () { return "APPLY"; } template - return_t _dispatch (const T &obj) { return obj.apply (this); } + return_t dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } diff --git a/src/hb-dispatch.hh b/src/hb-dispatch.hh index 0293fd14e..6b497823d 100644 --- a/src/hb-dispatch.hh +++ b/src/hb-dispatch.hh @@ -49,17 +49,9 @@ struct hb_dispatch_context_t bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } template return_t dispatch (const T &obj, Ts &&...ds) - { return _dispatch_impl (obj, hb_prioritize, hb_forward (ds)...); } + { return obj.dispatch (thiz (), hb_forward (ds)...); } static return_t no_dispatch_return_value () { return Context::default_return_value (); } static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; } - - private: - template - auto _dispatch_impl (const T &obj, hb_priority<1>, Ts &&...ds) HB_AUTO_RETURN - (obj.dispatch (thiz (), hb_forward (ds)...)) - template - Return _dispatch_impl (const T &obj, hb_priority<0>, Ts &&...ds) - { return thiz()->_dispatch (obj, hb_forward (ds)...); } }; diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 9960b4032..6b0b7ad5d 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -46,7 +46,7 @@ struct hb_intersects_context_t : { const char *get_name () { return "INTERSECTS"; } template - return_t _dispatch (const T &obj) { return obj.intersects (this->glyphs); } + return_t dispatch (const T &obj) { return obj.intersects (this->glyphs); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -64,7 +64,7 @@ struct hb_closure_context_t : const char *get_name () { return "CLOSURE"; } typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); template - return_t _dispatch (const T &obj) { obj.closure (this); return hb_void_t (); } + return_t dispatch (const T &obj) { obj.closure (this); return hb_void_t (); } static return_t default_return_value () { return hb_void_t (); } void recurse (unsigned int lookup_index) { @@ -128,7 +128,7 @@ struct hb_would_apply_context_t : { const char *get_name () { return "WOULD_APPLY"; } template - return_t _dispatch (const T &obj) { return obj.would_apply (this); } + return_t dispatch (const T &obj) { return obj.would_apply (this); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } @@ -156,7 +156,7 @@ struct hb_collect_glyphs_context_t : const char *get_name () { return "COLLECT_GLYPHS"; } typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); template - return_t _dispatch (const T &obj) { obj.collect_glyphs (this); return hb_void_t (); } + return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_void_t (); } static return_t default_return_value () { return hb_void_t (); } void recurse (unsigned int lookup_index) { @@ -235,7 +235,7 @@ struct hb_add_coverage_context_t : const char *get_name () { return "GET_COVERAGE"; } typedef const Coverage &return_t; template - return_t _dispatch (const T &obj) { return obj.get_coverage (); } + return_t dispatch (const T &obj) { return obj.get_coverage (); } static return_t default_return_value () { return Null(Coverage); } bool stop_sublookup_iteration (return_t r) const { @@ -438,7 +438,7 @@ struct hb_ot_apply_context_t : const char *get_name () { return "APPLY"; } typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); template - return_t _dispatch (const T &obj) { return obj.apply (this); } + return_t dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value () { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } return_t recurse (unsigned int sub_lookup_index) @@ -648,7 +648,7 @@ struct hb_get_subtables_context_t : /* Dispatch interface. */ const char *get_name () { return "GET_SUBTABLES"; } template - return_t _dispatch (const T &obj) + return_t dispatch (const T &obj) { hb_applicable_t *entry = array.push(); entry->init (obj, apply_to); diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index 71bf3a859..6799b7862 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -130,13 +130,23 @@ struct hb_sanitize_context_t : template bool may_dispatch (const T *obj HB_UNUSED, const F *format) { return format->sanitize (this); } - template - return_t _dispatch (const T &obj, Ts &&...ds) - { return obj.sanitize (this, hb_forward (ds)...); } static return_t default_return_value () { return true; } static return_t no_dispatch_return_value () { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts &&...ds) HB_AUTO_RETURN + ( obj.sanitize (this, hb_forward (ds)...) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts &&...ds) HB_AUTO_RETURN + ( obj.dispatch (this, hb_forward (ds)...) ) + public: + template auto + dispatch (const T &obj, Ts &&...ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, hb_forward (ds)...) ) + + void init (hb_blob_t *b) { this->blob = hb_blob_reference (b); diff --git a/src/hb-subset.hh b/src/hb-subset.hh index 4da2b675b..1c3f41fdd 100644 --- a/src/hb-subset.hh +++ b/src/hb-subset.hh @@ -40,11 +40,20 @@ struct hb_subset_context_t : hb_dispatch_context_t { const char *get_name () { return "SUBSET"; } - template - return_t _dispatch (const T &obj, Ts &&...ds) - { return obj.subset (this, hb_forward (ds)...); } static return_t default_return_value () { return true; } + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts &&...ds) HB_AUTO_RETURN + ( obj.subset (this, hb_forward (ds)...) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts &&...ds) HB_AUTO_RETURN + ( obj.dispatch (this, hb_forward (ds)...) ) + public: + template auto + dispatch (const T &obj, Ts &&...ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, hb_forward (ds)...) ) + hb_subset_plan_t *plan; hb_serialize_context_t *serializer; unsigned int debug_depth; From 36bb24f7b4dbbe171b945639bac749c46785e17c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 5 May 2019 10:14:17 -0700 Subject: [PATCH 142/336] [dispatch] Forward arguments in all dispatch multiplexers --- src/hb-aat-layout-kerx-table.hh | 14 +++---- src/hb-aat-layout-morx-table.hh | 14 +++---- src/hb-ot-kern-table.hh | 16 ++++---- src/hb-ot-layout-common.hh | 6 +-- src/hb-ot-layout-gpos-table.hh | 68 ++++++++++++++++----------------- src/hb-ot-layout-gsub-table.hh | 58 ++++++++++++++-------------- src/hb-ot-layout-gsubgpos.hh | 32 ++++++++-------- 7 files changed, 104 insertions(+), 104 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index b740f1e8f..bb41fea9d 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -771,17 +771,17 @@ struct KerxSubTable unsigned int get_size () const { return u.header.length; } unsigned int get_type () const { return u.header.coverage & u.header.SubtableType; } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case 0: return_trace (c->dispatch (u.format0)); - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); - case 4: return_trace (c->dispatch (u.format4)); - case 6: return_trace (c->dispatch (u.format6)); + case 0: return_trace (c->dispatch (u.format0, hb_forward (ds)...)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward (ds)...)); + case 4: return_trace (c->dispatch (u.format4, hb_forward (ds)...)); + case 6: return_trace (c->dispatch (u.format6, hb_forward (ds)...)); default: return_trace (c->default_return_value ()); } } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 466842483..4c4ea6206 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -883,17 +883,17 @@ struct ChainSubtable Insertion = 5 }; - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case Rearrangement: return_trace (c->dispatch (u.rearrangement)); - case Contextual: return_trace (c->dispatch (u.contextual)); - case Ligature: return_trace (c->dispatch (u.ligature)); - case Noncontextual: return_trace (c->dispatch (u.noncontextual)); - case Insertion: return_trace (c->dispatch (u.insertion)); + case Rearrangement: return_trace (c->dispatch (u.rearrangement, hb_forward (ds)...)); + case Contextual: return_trace (c->dispatch (u.contextual, hb_forward (ds)...)); + case Ligature: return_trace (c->dispatch (u.ligature, hb_forward (ds)...)); + case Noncontextual: return_trace (c->dispatch (u.noncontextual, hb_forward (ds)...)); + case Insertion: return_trace (c->dispatch (u.insertion, hb_forward (ds)...)); default: return_trace (c->default_return_value ()); } } diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 0b55dabdc..1310b843c 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -121,16 +121,16 @@ struct KernSubTable } } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { case 0: return_trace (c->dispatch (u.format0)); - case 1: return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ()); + case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward (ds)...) : c->default_return_value ()); case 2: return_trace (c->dispatch (u.format2)); - case 3: return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ()); + case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward (ds)...) : c->default_return_value ()); default: return_trace (c->default_return_value ()); } } @@ -304,14 +304,14 @@ struct kern bool apply (AAT::hb_aat_apply_context_t *c) const { return dispatch (c); } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case 0: return_trace (c->dispatch (u.ot)); - case 1: return_trace (c->dispatch (u.aat)); + case 0: return_trace (c->dispatch (u.ot, hb_forward (ds)...)); + case 1: return_trace (c->dispatch (u.aat, hb_forward (ds)...)); default: return_trace (c->default_return_value ()); } } diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 3089801d2..09e7711c0 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -682,14 +682,14 @@ struct Lookup return flag; } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { unsigned int lookup_type = get_type (); TRACE_DISPATCH (this, lookup_type); unsigned int count = get_subtable_count (); for (unsigned int i = 0; i < count; i++) { - typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); + typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type, hb_forward (ds)...); if (c->stop_sublookup_iteration (r)) return_trace (r); } diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 407ce9e27..556e4316d 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -576,14 +576,14 @@ struct SinglePosFormat2 struct SinglePos { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -907,14 +907,14 @@ struct PairPosFormat2 struct PairPos { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1092,13 +1092,13 @@ struct CursivePosFormat1 struct CursivePos { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1208,13 +1208,13 @@ struct MarkBasePosFormat1 struct MarkBasePos { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1333,13 +1333,13 @@ struct MarkLigPosFormat1 struct MarkLigPos { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1455,13 +1455,13 @@ struct MarkMarkPosFormat1 struct MarkMarkPos { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1507,20 +1507,20 @@ struct PosLookupSubTable Extension = 9 }; - template - typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const + template + typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts &&...ds) const { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { - case Single: return_trace (u.single.dispatch (c)); - case Pair: return_trace (u.pair.dispatch (c)); - case Cursive: return_trace (u.cursive.dispatch (c)); - case MarkBase: return_trace (u.markBase.dispatch (c)); - case MarkLig: return_trace (u.markLig.dispatch (c)); - case MarkMark: return_trace (u.markMark.dispatch (c)); - case Context: return_trace (u.context.dispatch (c)); - case ChainContext: return_trace (u.chainContext.dispatch (c)); - case Extension: return_trace (u.extension.dispatch (c)); + case Single: return_trace (u.single.dispatch (c, hb_forward (ds)...)); + case Pair: return_trace (u.pair.dispatch (c, hb_forward (ds)...)); + case Cursive: return_trace (u.cursive.dispatch (c, hb_forward (ds)...)); + case MarkBase: return_trace (u.markBase.dispatch (c, hb_forward (ds)...)); + case MarkLig: return_trace (u.markLig.dispatch (c, hb_forward (ds)...)); + case MarkMark: return_trace (u.markMark.dispatch (c, hb_forward (ds)...)); + case Context: return_trace (u.context.dispatch (c, hb_forward (ds)...)); + case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward (ds)...)); + case Extension: return_trace (u.extension.dispatch (c, hb_forward (ds)...)); default: return_trace (c->default_return_value ()); } } @@ -1581,9 +1581,9 @@ struct PosLookup : Lookup template static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - template - typename context_t::return_t dispatch (context_t *c) const - { return Lookup::dispatch (c); } + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + { return Lookup::dispatch (c, hb_forward (ds)...); } bool subset (hb_subset_context_t *c) const { return Lookup::subset (c); } diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index be78c1aaa..c5ebe44ec 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -251,14 +251,14 @@ struct SingleSubst } } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -440,13 +440,13 @@ struct MultipleSubst } } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -614,13 +614,13 @@ struct AlternateSubst } } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -945,13 +945,13 @@ struct LigatureSubst } } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1113,13 +1113,13 @@ struct ReverseChainSingleSubstFormat1 struct ReverseChainSingleSubst { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1153,19 +1153,19 @@ struct SubstLookupSubTable ReverseChainSingle = 8 }; - template - typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const + template + typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts &&...ds) const { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { - case Single: return_trace (u.single.dispatch (c)); - case Multiple: return_trace (u.multiple.dispatch (c)); - case Alternate: return_trace (u.alternate.dispatch (c)); - case Ligature: return_trace (u.ligature.dispatch (c)); - case Context: return_trace (u.context.dispatch (c)); - case ChainContext: return_trace (u.chainContext.dispatch (c)); - case Extension: return_trace (u.extension.dispatch (c)); - case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c)); + case Single: return_trace (u.single.dispatch (c, hb_forward (ds)...)); + case Multiple: return_trace (u.multiple.dispatch (c, hb_forward (ds)...)); + case Alternate: return_trace (u.alternate.dispatch (c, hb_forward (ds)...)); + case Ligature: return_trace (u.ligature.dispatch (c, hb_forward (ds)...)); + case Context: return_trace (u.context.dispatch (c, hb_forward (ds)...)); + case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward (ds)...)); + case Extension: return_trace (u.extension.dispatch (c, hb_forward (ds)...)); + case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward (ds)...)); default: return_trace (c->default_return_value ()); } } @@ -1331,9 +1331,9 @@ struct SubstLookup : Lookup return ret; } - template - typename context_t::return_t dispatch (context_t *c) const - { return Lookup::dispatch (c); } + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + { return Lookup::dispatch (c, hb_forward (ds)...); } bool subset (hb_subset_context_t *c) const { return Lookup::subset (c); } diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 6b0b7ad5d..0b4031499 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -1763,15 +1763,15 @@ struct ContextFormat3 struct Context { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); - case 3: return_trace (c->dispatch (u.format3)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward (ds)...)); + case 3: return_trace (c->dispatch (u.format3, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -2474,15 +2474,15 @@ struct ChainContextFormat3 struct ChainContext { - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (c->dispatch (u.format1)); - case 2: return_trace (c->dispatch (u.format2)); - case 3: return_trace (c->dispatch (u.format3)); + case 1: return_trace (c->dispatch (u.format1, hb_forward (ds)...)); + case 2: return_trace (c->dispatch (u.format2, hb_forward (ds)...)); + case 3: return_trace (c->dispatch (u.format3, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -2510,12 +2510,12 @@ struct ExtensionFormat1 return StructAtOffset (this, offset); } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, format); if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); - return_trace (get_subtable ().dispatch (c, get_type ())); + return_trace (get_subtable ().dispatch (c, get_type (), hb_forward (ds)...)); } /* This is called from may_dispatch() above with hb_sanitize_context_t. */ @@ -2557,13 +2557,13 @@ struct Extension } } - template - typename context_t::return_t dispatch (context_t *c) const + template + typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return_trace (u.format1.dispatch (c)); + case 1: return_trace (u.format1.dispatch (c, hb_forward (ds)...)); default:return_trace (c->default_return_value ()); } } From 9f9890e9e82c620e733d123f421f7c63d91ce8e1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 6 May 2019 12:16:51 -0700 Subject: [PATCH 143/336] Remove HB_NO_OPTIONS in favor of HB_NO_GETENV Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-debug.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-debug.hh b/src/hb-debug.hh index 00696058c..e5328e916 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -63,7 +63,7 @@ extern HB_INTERNAL hb_atomic_int_t _hb_options; static inline hb_options_t hb_options () { -#if defined(HB_NO_OPTIONS) +#if defined(HB_NO_GETENV) return hb_options_t (); #endif /* Make a local copy, so we can access bitfield threadsafely. */ From e261dc3a4043230ae1b4f56e2cc7d3133b7da4ca Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 7 May 2019 01:24:55 +0430 Subject: [PATCH 144/336] Ignore -Wc++11-compat as we require C++11 actually pollutes gcc bots logs https://circleci.com/gh/harfbuzz/harfbuzz/85395 --- src/hb.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb.hh b/src/hb.hh index 11ca2fac4..86dccd6ef 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -121,6 +121,7 @@ #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang #pragma GCC diagnostic ignored "-Wstrict-aliasing" #pragma GCC diagnostic ignored "-Wtype-limits" +#pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it #endif #endif From 4c2fd05ca5fa34303b986c34948b512d770ab8fe Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 6 May 2019 19:57:15 -0700 Subject: [PATCH 145/336] [iter] Implement range-based for loops Part of https://github.com/harfbuzz/harfbuzz/issues/1648 --- src/hb-array.hh | 6 ++++ src/hb-iter.hh | 74 ++++++++++++++++++++++++++++++++++++-- src/hb-ot-layout-common.hh | 14 ++++++++ src/hb-set.hh | 3 ++ src/test-iter.cc | 28 ++++++++++++--- 5 files changed, 118 insertions(+), 7 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index b4619ee9a..37ca63d35 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -80,6 +80,8 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> length -= n; } unsigned __len__ () const { return length; } + bool operator != (const hb_array_t& o) const + { return arrayZ != o.arrayZ || length != o.length; } /* Extra operators. */ @@ -224,6 +226,10 @@ struct hb_sorted_array_t : hb_sorted_array_t& operator = (const hb_array_t &o) { hb_array_t (*this) = o; return *this; } + /* Iterator implementation. */ + bool operator != (const hb_sorted_array_t& o) const + { return this->arrayZ != o.arrayZ || this->length != o.length; } + 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)); } hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 6fe984fc6..3240fc37a 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -42,6 +42,17 @@ * copied by value. If the collection / object being iterated on * is writable, then the iterator returns lvalues, otherwise it * returns rvalues. + * + * TODO Document more. + * + * If iterator implementation implements operator!=, then can be + * used in range-based for loop. That comes free if the iterator + * is random-access. Otherwise, the range-based for loop incurs + * one traversal to find end(), which can be avoided if written + * as a while-style for loop, or if iterator implements a faster + * __end__() method. + * TODO When opting in for C++17, address this by changing return + * type of .end()? */ @@ -72,10 +83,13 @@ struct hb_iter_t /* Operators. */ iter_t iter () const { return *thiz(); } iter_t operator + () const { return *thiz(); } + iter_t begin () const { return *thiz(); } + iter_t end () const { return thiz()->__end__ (); } explicit operator bool () const { return thiz()->__more__ (); } unsigned len () const { return thiz()->__len__ (); } /* The following can only be enabled if item_t is reference type. Otherwise - * it will be returning pointer to temporary rvalue. */ + * it will be returning pointer to temporary rvalue. + * TODO Use a wrapper return type to fix for non-reference type. */ template hb_remove_reference* operator -> () const { return hb_addressof (**thiz()); } @@ -107,6 +121,8 @@ struct hb_iter_t #define HB_ITER_USING(Name) \ using item_t = typename Name::item_t; \ + using Name::begin; \ + using Name::end; \ using Name::item_size; \ using Name::is_iterator; \ using Name::iter; \ @@ -150,7 +166,6 @@ struct } HB_FUNCOBJ (hb_iter); - /* Mixin to fill in what the subclass doesn't provide. */ template struct hb_iter_fallback_mixin_t @@ -178,6 +193,18 @@ struct hb_iter_fallback_mixin_t void __prev__ () { *thiz() -= 1; } void __rewind__ (unsigned n) { while (n--) --*thiz(); } + /* Range-based for: Implement __end__() if can be done faster, + * and operator!=. */ + iter_t __end__ () const + { + if (thiz()->is_random_access_iterator) + return *thiz() + thiz()->len (); + /* Above expression loops twice. Following loops once. */ + auto it = *thiz(); + while (it) ++it; + return it; + } + protected: hb_iter_fallback_mixin_t () {} hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) {} @@ -250,6 +277,31 @@ struct hb_is_iterator_of { enum { hb_is_sorted_iterator_of (Iter, typename Iter::item_t) +/* Range-based 'for' for iterables. */ + +template +static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ()) + +template +static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ()) + +/* begin()/end() are NOT looked up non-ADL. So each namespace must declare them. + * Do it for namespace OT. */ +namespace OT { + +template +static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ()) + +template +static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ()) + +} + + /* * Adaptors, combiners, etc. */ @@ -279,6 +331,8 @@ struct hb_map_iter_t : void __forward__ (unsigned n) { it += n; } void __prev__ () { --it; } void __rewind__ (unsigned n) { it -= n; } + bool operator != (const hb_map_iter_t& o) const + { return it != o.it || f != o.f; } private: Iter it; @@ -322,6 +376,8 @@ struct hb_filter_iter_t : bool __more__ () const { return bool (it); } void __next__ () { do ++it; while (it && !p (f (*it))); } void __prev__ () { --it; } + bool operator != (const hb_filter_iter_t& o) const + { return it != o.it || p != o.p || f != o.f; } private: Iter it; @@ -407,6 +463,9 @@ struct hb_zip_iter_t : void __forward__ (unsigned n) { a += n; b += n; } void __prev__ () { --a; --b; } void __rewind__ (unsigned n) { a -= n; b -= n; } + hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); } + bool operator != (const hb_zip_iter_t& o) const + { return a != o.a || b != o.b; } private: A a; @@ -442,6 +501,17 @@ struct hb_enumerate_iter_t : void __forward__ (unsigned n) { i += n; it += n; } void __prev__ () { --i; --it; } void __rewind__ (unsigned n) { i -= n; it -= n; } + hb_enumerate_iter_t __end__ () const + { + if (is_random_access_iterator) + return *this + this->len (); + /* Above expression loops twice. Following loops once. */ + auto it = *this; + while (it) ++it; + return it; + } + bool operator != (const hb_enumerate_iter_t& o) const + { return i != o.i || it != o.it; } private: unsigned i; diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 09e7711c0..a527b3966 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -835,6 +835,8 @@ struct CoverageFormat1 bool more () const { return i < c->glyphArray.len; } void next () { i++; } hb_codepoint_t get_glyph () const { return c->glyphArray[i]; } + bool operator != (const iter_t& o) const + { return i != o.i || c != o.c; } private: const struct CoverageFormat1 *c; @@ -987,6 +989,8 @@ struct CoverageFormat2 j++; } hb_codepoint_t get_glyph () const { return j; } + bool operator != (const iter_t& o) const + { return i != o.i || j != o.j || c != o.c; } private: const struct CoverageFormat2 *c; @@ -1136,6 +1140,16 @@ struct Coverage default:return 0; } } + bool operator != (const iter_t& o) const + { + if (format != o.format) return true; + switch (format) + { + case 1: return u.format1 != o.u.format1; + case 2: return u.format2 != o.u.format2; + default:return false; + } + } private: unsigned int format; diff --git a/src/hb-set.hh b/src/hb-set.hh index 76100f6bc..332e07bd0 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -701,6 +701,9 @@ struct hb_set_t void __next__ () { s->next (&v); if (l) l--; } void __prev__ () { s->previous (&v); } unsigned __len__ () const { return l; } + iter_t end () const { return iter_t (*s); } + bool operator != (const iter_t& o) const + { return s != o.s || v != o.v; } protected: const hb_set_t *s; diff --git a/src/test-iter.cc b/src/test-iter.cc index 01ec93a7e..8f2fc809f 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -43,6 +43,7 @@ struct array_iter_t : hb_iter_with_fallback_t, T&> void __forward__ (unsigned n) { arr += n; } void __rewind__ (unsigned n) { arr -= n; } unsigned __len__ () const { return arr.length; } + bool operator != (const array_iter_t& o) { return arr != o.arr; } private: hb_array_t arr; @@ -66,12 +67,8 @@ struct some_array_t template static void -test_iterator (Iter it) +test_iterator_non_default_constructable (Iter it) { - Iter default_constructed; - - assert (!default_constructed); - /* Iterate over a copy of it. */ for (auto c = it.iter (); c; c++) *c; @@ -80,6 +77,10 @@ test_iterator (Iter it) for (auto c = +it; c; c++) *c; + /* Range-based for over a copy. */ + for (auto _ : +it) + (void) _; + it += it.len (); it = it + 10; it = 10 + it; @@ -90,11 +91,25 @@ test_iterator (Iter it) static_assert (true || it.is_sorted_iterator, ""); } +template +static void +test_iterator (Iter it) +{ + Iter default_constructed; + assert (!default_constructed); + + test_iterator_non_default_constructable (it); +} + template static void test_iterable (const Iterable &lst = Null(Iterable)) { + for (auto _ : lst) + (void) _; + // Test that can take iterator from. test_iterator (lst.iter ()); } @@ -141,6 +156,9 @@ main (int argc, char **argv) test_iterable (); test_iterator (hb_zip (st, v)); + test_iterator_non_default_constructable (hb_enumerate (st)); + //test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); + //test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_identity)); hb_any (st); From 0b1ca5a13b6921cb4d00f8651bb99fc7c7037ec2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 6 May 2019 23:04:32 -0700 Subject: [PATCH 146/336] [iter] Adjust hb_filter --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 3240fc37a..009511298 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -374,7 +374,7 @@ struct hb_filter_iter_t : static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; __item_t__ __item__ () const { return *it; } bool __more__ () const { return bool (it); } - void __next__ () { do ++it; while (it && !p (f (*it))); } + void __next__ () { do ++it; while (it && !hb_has (p, hb_get (f, *it))); } void __prev__ () { --it; } bool operator != (const hb_filter_iter_t& o) const { return it != o.it || p != o.p || f != o.f; } From 240f57e58d3b0161feb90621d5db9e2fc4d99b27 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 6 May 2019 23:17:39 -0700 Subject: [PATCH 147/336] Rename hb_deref_pointer() to hb_deref() --- src/hb-algs.hh | 12 ++++++------ src/hb-map.hh | 2 +- src/hb-meta.hh | 2 +- src/hb-serialize.hh | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index e0700100b..ee604e88c 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -50,7 +50,7 @@ struct { private: template auto - impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref_pointer (v).hash ()) + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) template auto @@ -73,17 +73,17 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - ((hb_deref_pointer (hb_forward (v1)).*hb_forward (a)) (hb_forward (vs)...)) + ((hb_deref (hb_forward (v1)).*hb_forward (a)) (hb_forward (vs)...)) /* Pointer-to-member. */ template auto impl (Appl&& a, hb_priority<1>, Val &&v) const HB_AUTO_RETURN - ((hb_deref_pointer (hb_forward (v))).*hb_forward (a)) + ((hb_deref (hb_forward (v))).*hb_forward (a)) /* Operator(). */ template auto impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (hb_forward (a)) (hb_forward (vs)...)) + (hb_deref (hb_forward (a)) (hb_forward (vs)...)) public: @@ -102,7 +102,7 @@ struct template auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref_pointer (hb_forward (p)).has (v)) + (hb_deref (hb_forward (p)).has (v)) template auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN @@ -127,7 +127,7 @@ struct template auto impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref_pointer (hb_forward (f)).get (hb_forward (v))) + (hb_deref (hb_forward (f)).get (hb_forward (v))) template auto impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN diff --git a/src/hb-map.hh b/src/hb-map.hh index bbb1bef5d..f27ca9cae 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -57,7 +57,7 @@ struct hb_hashmap_t void clear () { key = kINVALID; value = vINVALID; } - bool operator == (K o) { return hb_deref_pointer (key) == hb_deref_pointer (o); } + bool operator == (K o) { return hb_deref (key) == hb_deref (o); } bool operator == (const item_t &o) { return *this == o.key; } bool is_unused () const { return key == kINVALID; } bool is_tombstone () const { return key != kINVALID && value == vINVALID; } diff --git a/src/hb-meta.hh b/src/hb-meta.hh index b80358c2a..f7699d781 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -126,7 +126,7 @@ struct template auto operator () (T *v) const HB_AUTO_RETURN (*v) -} HB_FUNCOBJ (hb_deref_pointer); +} HB_FUNCOBJ (hb_deref); template struct hb_enable_if {}; diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index d18934c4d..afaa4c4f9 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -132,7 +132,7 @@ struct hb_serialize_context_t { return check_equal (v1 = v2, v2); } template bool propagate_error (T &&obj) - { return check_success (!hb_deref_pointer (obj).in_error ()); } + { return check_success (!hb_deref (obj).in_error ()); } template bool propagate_error (T1 &&o1, Ts &&...os) { return propagate_error (hb_forward (o1)) && From 72eb91deb9eb7a08e38e100a3234518651fe4cb8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 6 May 2019 23:39:13 -0700 Subject: [PATCH 148/336] Add hb_ref() Unused. --- src/hb-meta.hh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index f7699d781..9ca63cd97 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -128,6 +128,16 @@ struct } HB_FUNCOBJ (hb_deref); +struct +{ + template auto + operator () (T&& v) const HB_AUTO_RETURN (hb_forward (v)) + + template auto + operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v)) + +} HB_FUNCOBJ (hb_ref); + template struct hb_enable_if {}; template struct hb_enable_if { typedef T type; }; From 0bf86d9c5dcb0de206b38c3cf1824d2254376f37 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 6 May 2019 23:39:26 -0700 Subject: [PATCH 149/336] Whitespace --- src/hb-meta.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 9ca63cd97..52f686628 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -139,8 +139,8 @@ struct } HB_FUNCOBJ (hb_ref); -template struct hb_enable_if {}; -template struct hb_enable_if { typedef T type; }; +template struct hb_enable_if {}; +template struct hb_enable_if { typedef T type; }; #define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr template struct hb_is_same : hb_false_t {}; From 03a68165d8296ed5cc0eb2434500381419409e79 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 00:03:35 -0700 Subject: [PATCH 150/336] [meta] Add hb_reference_wrapper<> Functionality kinda superset of std:: counterpart. --- src/hb-meta.hh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 52f686628..fc64e9707 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -138,6 +138,27 @@ struct } HB_FUNCOBJ (hb_ref); +template +struct hb_reference_wrapper +{ + hb_reference_wrapper (T v) : v (v) {} + hb_reference_wrapper (const hb_reference_wrapper& o) : v (o.v) {} + bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } + bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } + T get () const { return v; } + T v; +}; +template +struct hb_reference_wrapper +{ + hb_reference_wrapper (T& v) : v (&v) {} + hb_reference_wrapper (const hb_reference_wrapper& o) : v (o.v) {} + bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } + bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } + T* get () const { return v; } + T* v; +}; + template struct hb_enable_if {}; template struct hb_enable_if { typedef T type; }; From 025eaa3c81214cdb20f2f588bab665512d21507c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 00:05:37 -0700 Subject: [PATCH 151/336] [iter] Make filter/map copyable --- src/hb-iter.hh | 18 +++++++++--------- src/test-iter.cc | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 009511298..549b78865 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -319,12 +319,12 @@ struct hb_map_iter_t : hb_iter_t, decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t)))> { - hb_map_iter_t (const Iter& it, Proj f) : it (it), f (f) {} + hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {} typedef decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t))) __item_t__; static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - __item_t__ __item__ () const { return hb_get (f, *it); } - __item_t__ __item_at__ (unsigned i) const { return hb_get (f, it[i]); } + __item_t__ __item__ () const { return hb_get (f.get (), *it); } + __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); } bool __more__ () const { return bool (it); } unsigned __len__ () const { return it.len (); } void __next__ () { ++it; } @@ -336,7 +336,7 @@ struct hb_map_iter_t : private: Iter it; - Proj f; + hb_reference_wrapper f; }; template @@ -367,22 +367,22 @@ struct hb_filter_iter_t : hb_iter_with_fallback_t, typename Iter::item_t> { - hb_filter_iter_t (const Iter& it_, Pred p, Proj f) : it (it_), p (p), f (f) - { while (it && !hb_has (p, hb_get (f, *it))) ++it; } + hb_filter_iter_t (const Iter& it_, Pred p_, Proj f_) : it (it_), p (p_), f (f_) + { while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; } typedef typename Iter::item_t __item_t__; static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; __item_t__ __item__ () const { return *it; } bool __more__ () const { return bool (it); } - void __next__ () { do ++it; while (it && !hb_has (p, hb_get (f, *it))); } + void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } void __prev__ () { --it; } bool operator != (const hb_filter_iter_t& o) const { return it != o.it || p != o.p || f != o.f; } private: Iter it; - Pred p; - Proj f; + hb_reference_wrapper p; + hb_reference_wrapper f; }; template struct hb_filter_iter_factory_t diff --git a/src/test-iter.cc b/src/test-iter.cc index 8f2fc809f..afbcbe9b5 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -157,8 +157,8 @@ main (int argc, char **argv) test_iterator (hb_zip (st, v)); test_iterator_non_default_constructable (hb_enumerate (st)); - //test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); - //test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_identity)); + test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); + test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_identity)); hb_any (st); From 8903040fcd09e7d7ad5112ac2a583718bb85795d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 00:13:11 -0700 Subject: [PATCH 152/336] Actually make it work --- src/hb-iter.hh | 2 ++ src/hb-meta.hh | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 549b78865..63a178ae3 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -331,6 +331,7 @@ struct hb_map_iter_t : void __forward__ (unsigned n) { it += n; } void __prev__ () { --it; } void __rewind__ (unsigned n) { it -= n; } + hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); } bool operator != (const hb_map_iter_t& o) const { return it != o.it || f != o.f; } @@ -376,6 +377,7 @@ struct hb_filter_iter_t : bool __more__ () const { return bool (it); } void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } void __prev__ () { --it; } + hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); } bool operator != (const hb_filter_iter_t& o) const { return it != o.it || p != o.p || f != o.f; } diff --git a/src/hb-meta.hh b/src/hb-meta.hh index fc64e9707..b65a09efe 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -145,17 +145,19 @@ struct hb_reference_wrapper hb_reference_wrapper (const hb_reference_wrapper& o) : v (o.v) {} bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } + operator T () const { return v; } T get () const { return v; } T v; }; template struct hb_reference_wrapper { - hb_reference_wrapper (T& v) : v (&v) {} + hb_reference_wrapper (T& v) : v (hb_addressof (v)) {} hb_reference_wrapper (const hb_reference_wrapper& o) : v (o.v) {} bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } - T* get () const { return v; } + operator T& () const { return *v; } + T& get () const { return *v; } T* v; }; From c3e0eafc80481f8c16516fdae1841c563e7253d4 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 7 May 2019 12:04:00 +0430 Subject: [PATCH 153/336] [ci] Upgrade Ubuntu 17.10 bots to 19.04 --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9eeb1549e..87d752589 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,7 @@ jobs: distcheck: docker: - - image: ubuntu:17.10 + - image: ubuntu:19.04 steps: - checkout - run: apt update && apt install -y ninja-build binutils libtool autoconf automake make cmake gcc g++ pkg-config ragel gtk-doc-tools libfontconfig1-dev libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip @@ -203,7 +203,7 @@ jobs: cmake-gcc: docker: - - image: ubuntu:17.10 + - image: ubuntu:19.04 steps: - checkout - run: apt update && apt install -y ninja-build binutils cmake gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip From 45f5e56236912359d0ac72310dcdba9259cfee66 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 00:33:32 -0700 Subject: [PATCH 154/336] Warn on -Wdeprecated --- src/hb.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb.hh b/src/hb.hh index 86dccd6ef..96db1f9d4 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -94,6 +94,7 @@ /* Warning. To be investigated if happens. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING #pragma GCC diagnostic warning "-Wbuiltin-macro-redefined" +#pragma GCC diagnostic warning "-Wdeprecated" #pragma GCC diagnostic warning "-Wdisabled-optimization" #pragma GCC diagnostic warning "-Wformat=2" #pragma GCC diagnostic warning "-Wignored-pragma-optimize" From fa2d97161f8b7de3d7a70e06d41b6f7e154012ad Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 00:34:50 -0700 Subject: [PATCH 155/336] Remove use of deprecated implicit copy/move assignment operators By removing custom copy constructor. --- src/hb-meta.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index b65a09efe..e8002f253 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -142,7 +142,6 @@ template struct hb_reference_wrapper { hb_reference_wrapper (T v) : v (v) {} - hb_reference_wrapper (const hb_reference_wrapper& o) : v (o.v) {} bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } operator T () const { return v; } @@ -153,7 +152,6 @@ template struct hb_reference_wrapper { hb_reference_wrapper (T& v) : v (hb_addressof (v)) {} - hb_reference_wrapper (const hb_reference_wrapper& o) : v (o.v) {} bool operator == (const hb_reference_wrapper& o) const { return v == o.v; } bool operator != (const hb_reference_wrapper& o) const { return v != o.v; } operator T& () const { return *v; } From c548fcedc404c03442c042059a71194d97d23bb6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:29:07 -0700 Subject: [PATCH 156/336] [WIP] [name] Port to fancy serializer machinery --- src/hb-ot-name-table.hh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 00686ee2d..72c0c642c 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -279,17 +279,21 @@ struct name this->format = 0; this->count = name_record_idx_to_retain.length; - this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; + auto snap = c->snapshot (); + this->nameRecordZ.serialize (c, this->count); + this->stringOffset = c->length (); + c->revert (snap); - if (!serialize_name_record (c, source_name, name_record_idx_to_retain)) - return_trace (false); + auto src_array = source_name->nameRecordZ.as_array (source_name->count); + const void *src_base = &(source_name + source_name->stringOffset); + const void *dst_base = &(this + this->stringOffset); - if (!serialize_strings (c, source_name, plan, name_record_idx_to_retain)) - return_trace (false); + + hb_iter (name_record_idx_to_retain) + | hb_apply ([&] (unsigned _) { c->copy (src_array[_], src_base, dst_base); }) + ; - if (!pack_record_and_strings (this, c, name_record_idx_to_retain.length)) - return_trace (false); + assert (this->stringOffset == c->length ()); return_trace (true); } From 5ac4ab686809be9352e91bc3213e1edf3ba66a93 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2019 16:29:07 -0700 Subject: [PATCH 157/336] [subset] fix for name table serializing with new serializer machinery --- src/hb-ot-name-table.hh | 8 ++++++-- test/api/fonts/nameID.expected.ttf | Bin 170696 -> 2388 bytes 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 72c0c642c..855b86811 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -99,10 +99,12 @@ struct NameRecord const void *src_base, const void *dst_base) const { + TRACE_SERIALIZE (this); auto *out = c->embed (this); - out->offset = 0; + if (unlikely (!out)) return_trace (nullptr); + out->offset.serialize_copy (c, src_base + offset, dst_base, length); - return out; + return_trace (out); } bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -292,6 +294,8 @@ struct name + hb_iter (name_record_idx_to_retain) | hb_apply ([&] (unsigned _) { c->copy (src_array[_], src_base, dst_base); }) ; + + if (unlikely (c->ran_out_of_room)) return_trace (false); assert (this->stringOffset == c->length ()); diff --git a/test/api/fonts/nameID.expected.ttf b/test/api/fonts/nameID.expected.ttf index ccd4b8bcd26816e7ffcd6afa58306373bc0534d9..00aecc0bbf60004d975f7fc12c716f34bbc728cd 100644 GIT binary patch delta 566 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%0Dkep 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 Date: Tue, 7 May 2019 11:01:02 -0700 Subject: [PATCH 158/336] [name] Remove dead code --- src/hb-ot-name-table.hh | 88 +---------------------------------------- 1 file changed, 1 insertion(+), 87 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 855b86811..07c3f28e6 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -102,7 +102,6 @@ struct NameRecord TRACE_SERIALIZE (this); auto *out = c->embed (this); if (unlikely (!out)) return_trace (nullptr); - out->offset.serialize_copy (c, src_base + offset, dst_base, length); return_trace (out); } @@ -185,91 +184,6 @@ struct name } } - bool serialize_name_record (hb_serialize_context_t *c, - const name *source_name, - const hb_vector_t& name_record_idx_to_retain) - { - for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) - { - unsigned int idx = name_record_idx_to_retain[i]; - if (unlikely (idx >= source_name->count)) - { - DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); - return false; - } - - c->push (); - - NameRecord *p = c->embed (source_name->nameRecordZ[idx]); - if (!p) - return false; - p->offset = 0; - } - - return true; - } - - bool serialize_strings (hb_serialize_context_t *c, - const name *source_name, - const hb_subset_plan_t *plan, - const hb_vector_t& name_record_idx_to_retain) - { - hb_face_t *face = plan->source; - accelerator_t acc; - acc.init (face); - - for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) - { - unsigned int idx = name_record_idx_to_retain[i]; - unsigned int size = acc.get_name (idx).get_size (); - - c->push (); - char *new_pos = c->allocate_size (size); - - if (unlikely (new_pos == nullptr)) - { - acc.fini (); - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %u.", - size); - return false; - } - - const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; - unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; - - memcpy (new_pos, source_string_pool + name_record_offset, size); - } - - acc.fini (); - return true; - } - - bool pack_record_and_strings (name *dest_name_unpacked, - hb_serialize_context_t *c, - unsigned length) - { - hb_hashmap_t id_str_idx_map; - for (int i = length-1; i >= 0; i--) - { - unsigned objidx = c->pop_pack (); - id_str_idx_map.set ((unsigned)i, objidx); - } - - const void *base = & (dest_name_unpacked->nameRecordZ[length]); - for (int i = length-1; i >= 0; i--) - { - unsigned str_idx = id_str_idx_map.get ((unsigned)i); - NameRecord& namerecord = dest_name_unpacked->nameRecordZ[i]; - c->add_link (namerecord.offset, str_idx, base); - c->pop_pack (); - } - - if (c->in_error ()) - return false; - - return true; - } - bool serialize (hb_serialize_context_t *c, const name *source_name, const hb_subset_plan_t *plan, @@ -294,7 +208,7 @@ struct name + hb_iter (name_record_idx_to_retain) | hb_apply ([&] (unsigned _) { c->copy (src_array[_], src_base, dst_base); }) ; - + if (unlikely (c->ran_out_of_room)) return_trace (false); assert (this->stringOffset == c->length ()); From 530ddbbc320bd24b4902ee6d49bf80242a591794 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:05:51 -0700 Subject: [PATCH 159/336] [serialize] Use range-based loop --- src/hb-serialize.hh | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index afaa4c4f9..1a6ed2116 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -287,26 +287,23 @@ struct hb_serialize_context_t { assert (!current); - for (auto obj_it = ++hb_iter (packed); obj_it; ++obj_it) + for (const object_t *parent : ++hb_iter (packed)) { - const object_t &parent = **obj_it; - - for (auto link_it = parent.links.iter (); link_it; ++link_it) + for (const object_t::link_t &link : parent->links) { - const object_t::link_t &link = *link_it; const object_t &child = *packed[link.objidx]; - //assert (link.bias <= parent.tail - parent.head); - unsigned offset = (child.head - parent.head) - link.bias; + //assert (link.bias <= parent->tail - parent->head); + unsigned offset = (child.head - parent->head) - link.bias; if (link.is_wide) { - auto &off = * ((BEInt *) (parent.head + link.position)); + auto &off = * ((BEInt *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset); } else { - auto &off = * ((BEInt *) (parent.head + link.position)); + auto &off = * ((BEInt *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset); } From e6a622b5b202533d64f83e71d7ff8a8104d46e26 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:06:43 -0700 Subject: [PATCH 160/336] [serialize] Enable bias assertion --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 1a6ed2116..4e270ce8c 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -292,7 +292,7 @@ struct hb_serialize_context_t for (const object_t::link_t &link : parent->links) { const object_t &child = *packed[link.objidx]; - //assert (link.bias <= parent->tail - parent->head); + assert (link.bias <= parent->tail - parent->head); unsigned offset = (child.head - parent->head) - link.bias; if (link.is_wide) From 521262b236dacf7b2b64e0a1d3c79d6a10b07063 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:08:08 -0700 Subject: [PATCH 161/336] [subset] Add TODO --- src/hb-subset.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 5f482e18a..800bd35c8 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -76,6 +76,8 @@ _subset2 (hb_subset_plan_t *plan) if (source_blob->data) { hb_vector_t buf; + /* TODO Not all tables are glyph-related. 'name' table size for example should not be + * affected by number of glyphs. Accommodate that. */ unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) From 9b05db33b54e6e5f0b4658f4c06e7fe563f8923b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:39:44 -0700 Subject: [PATCH 162/336] [ragel] Regenerate ragel-generated files using ragel 7.0.0.11 May 2018 --- src/hb-buffer-deserialize-json.hh | 1053 ++++---- src/hb-buffer-deserialize-text.hh | 1009 ++++---- src/hb-ot-shape-complex-indic-machine.hh | 2678 +++++++++++--------- src/hb-ot-shape-complex-khmer-machine.hh | 709 +++--- src/hb-ot-shape-complex-myanmar-machine.hh | 834 +++--- src/hb-ot-shape-complex-use-machine.hh | 1144 +++++---- 6 files changed, 3967 insertions(+), 3460 deletions(-) diff --git a/src/hb-buffer-deserialize-json.hh b/src/hb-buffer-deserialize-json.hh index 1f9e2e91d..8631d52e8 100644 --- a/src/hb-buffer-deserialize-json.hh +++ b/src/hb-buffer-deserialize-json.hh @@ -1,30 +1,28 @@ - -#line 1 "hb-buffer-deserialize-json.rl" /* - * Copyright © 2013 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. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2013 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. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_BUFFER_DESERIALIZE_JSON_HH #define HB_BUFFER_DESERIALIZE_JSON_HH @@ -32,400 +30,208 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, - 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, - 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, - 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 + 1u, 0u, 0u, 18u, 0u, 2u, 11u, 14u, + 16u, 17u, 2u, 2u, 0u, 8u, 0u, 7u, + 6u, 7u, 0u, 19u, 0u, 19u, 0u, 19u, + 2u, 2u, 0u, 8u, 0u, 7u, 6u, 7u, + 0u, 19u, 0u, 19u, 15u, 15u, 2u, 2u, + 0u, 8u, 0u, 7u, 0u, 19u, 0u, 19u, + 16u, 17u, 2u, 2u, 0u, 8u, 0u, 7u, + 6u, 7u, 0u, 19u, 0u, 19u, 2u, 2u, + 0u, 8u, 0u, 7u, 6u, 7u, 0u, 19u, + 0u, 19u, 2u, 2u, 0u, 8u, 0u, 7u, + 9u, 17u, 2u, 17u, 0u, 19u, 0u, 19u, + 0u, 10u, 0u, 18u, 1u, 0u, 0u }; -static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 7, 2, 1, 50, 49, - 10, 117, 117, 117, 1, 50, 49, 10, - 117, 117, 1, 1, 50, 49, 117, 117, - 2, 1, 50, 49, 10, 117, 117, 1, - 50, 49, 10, 117, 117, 1, 50, 49, - 58, 89, 117, 117, 85, 115, 0 +static const char _deserialize_json_char_class[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 4, 5, 1, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 8, 1, 1, 1, 1, 1, 1, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 1, 1, 10, 1, 5, 1, + 11, 9, 12, 13, 9, 9, 14, 9, + 9, 9, 9, 15, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 16, + 17, 9, 18, 1, 19, 0 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 151, 154, 156, 207, - 257, 268, 386, 504, 622, 624, 675, 725, - 736, 854, 972, 974, 976, 1027, 1077, 1195, - 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666, - 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069, - 2119, 2178, 2268, 2386, 2504, 2590, 2706 + 0, 0, 19, 22, 26, 28, 29, 38, + 46, 48, 68, 88, 108, 109, 118, 126, + 128, 148, 168, 169, 170, 179, 187, 207, + 227, 229, 230, 239, 247, 249, 269, 289, + 290, 299, 307, 309, 329, 349, 350, 359, + 367, 376, 392, 412, 432, 443, 462, 0 }; static const char _deserialize_json_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 1, 8, 1, - 9, 10, 1, 11, 1, 11, 11, 11, - 11, 11, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 11, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 12, 1, - 12, 12, 12, 12, 12, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 12, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 1, 14, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 1, 16, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 1, 18, 18, 18, - 18, 18, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 18, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 19, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 20, 1, 21, 21, 21, 21, 21, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 21, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 22, - 1, 18, 18, 18, 18, 18, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 18, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 19, 1, 1, 1, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 20, 1, 23, - 1, 23, 23, 23, 23, 23, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 24, 1, 24, 24, 24, 24, - 24, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 24, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 25, 1, 1, 26, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 1, 28, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 1, 30, 30, 30, 30, 30, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 30, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 31, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 32, 1, 30, - 30, 30, 30, 30, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 30, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 31, 1, 1, 1, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 32, 1, 33, 1, 34, - 1, 34, 34, 34, 34, 34, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 34, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 35, 35, 35, 35, - 35, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 35, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 36, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 40, 1, 38, 38, 38, 38, - 38, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 38, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 39, - 1, 1, 1, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 40, 1, 42, 43, 1, 44, 1, 44, - 44, 44, 44, 44, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 44, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 45, 1, 45, 45, 45, 45, 45, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 45, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 1, 47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 1, 49, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 1, 51, - 51, 51, 51, 51, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 51, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 52, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 51, 51, 51, - 51, 51, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 51, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 52, 1, 1, 1, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 53, 1, 54, 1, 54, 54, 54, - 54, 54, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 54, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 55, 1, - 55, 55, 55, 55, 55, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 55, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 56, 1, 1, 57, - 58, 58, 58, 58, 58, 58, 58, 58, - 58, 1, 59, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 1, 61, 61, 61, - 61, 61, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 61, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 62, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 63, 1, 61, 61, 61, 61, 61, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 61, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 62, 1, - 1, 1, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 63, - 1, 64, 1, 64, 64, 64, 64, 64, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 65, 1, 65, 65, - 65, 65, 65, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 65, 1, 66, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 67, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 1, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 1, 1, 1, 1, 1, 1, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 1, 70, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 71, 71, - 1, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 1, 1, 1, 1, 1, - 1, 1, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 1, 1, 1, 1, - 71, 1, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 1, 72, 72, 72, - 72, 72, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 72, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 73, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 74, 1, 72, 72, 72, 72, 72, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 73, 1, - 1, 1, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 74, - 1, 76, 76, 76, 76, 76, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 78, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 0 + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 3, 1, 4, 5, 6, + 7, 8, 9, 10, 11, 11, 1, 1, + 1, 1, 1, 1, 1, 12, 12, 1, + 1, 1, 13, 1, 14, 15, 16, 17, + 18, 1, 1, 19, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 20, 21, 1, 1, 3, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 18, 1, 1, 19, 1, 1, 17, 17, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 20, 23, 23, 1, 1, + 1, 1, 1, 1, 1, 24, 24, 1, + 1, 1, 25, 1, 26, 27, 28, 29, + 30, 1, 1, 31, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 32, 30, 1, 1, 31, + 1, 1, 29, 29, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 32, + 33, 34, 34, 1, 1, 1, 1, 1, + 1, 1, 35, 35, 1, 1, 1, 1, + 1, 36, 37, 38, 1, 1, 39, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 40, 38, + 1, 1, 39, 1, 1, 41, 41, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 40, 42, 43, 44, 44, 1, + 1, 1, 1, 1, 1, 1, 45, 45, + 1, 1, 1, 46, 1, 47, 48, 49, + 50, 51, 1, 1, 52, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 53, 51, 1, 1, + 52, 1, 1, 50, 50, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 53, 54, 54, 1, 1, 1, 1, 1, + 1, 1, 55, 55, 1, 1, 1, 56, + 1, 57, 58, 59, 60, 61, 1, 1, + 62, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 63, 61, 1, 1, 62, 1, 1, 60, + 60, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 63, 64, 64, 1, + 1, 1, 1, 1, 1, 1, 65, 65, + 1, 66, 1, 1, 1, 67, 68, 69, + 1, 69, 69, 69, 69, 69, 69, 69, + 70, 1, 71, 71, 71, 71, 1, 71, + 1, 71, 71, 71, 71, 71, 71, 71, + 72, 1, 1, 73, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 74, 72, 1, 1, 73, + 1, 1, 75, 75, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 74, + 76, 1, 1, 77, 1, 1, 1, 1, + 1, 1, 78, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 0 }; -static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 18, 24, - 37, 5, 12, 6, 7, 8, 9, 11, - 9, 11, 10, 2, 44, 10, 44, 13, - 14, 15, 16, 17, 16, 17, 10, 2, - 44, 19, 20, 21, 22, 23, 10, 2, - 44, 23, 25, 31, 26, 27, 28, 29, - 30, 29, 30, 10, 2, 44, 32, 33, - 34, 35, 36, 35, 36, 10, 2, 44, - 38, 39, 40, 42, 43, 41, 10, 41, - 10, 2, 44, 43, 44, 45, 46 +static const char _deserialize_json_index_defaults[] = { + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0 }; -static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 2, - 0, 0, 3, 3, 4, 0, 5, 0, - 0, 2, 2, 2, 0, 0, 6, 6, - 7, 0, 0, 0, 2, 2, 8, 8, - 9, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 10, 10, 11, 0, 0, - 2, 2, 2, 0, 0, 12, 12, 13, - 0, 0, 0, 2, 2, 2, 14, 0, - 15, 15, 16, 0, 0, 0, 0 +static const char _deserialize_json_trans_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 0 +}; + +static const char _deserialize_json_cond_targs[] = { + 1, 0, 2, 2, 3, 4, 18, 24, + 37, 5, 12, 6, 7, 8, 9, 11, + 9, 11, 10, 2, 44, 10, 44, 13, + 14, 15, 16, 17, 16, 17, 10, 2, + 44, 19, 20, 21, 22, 23, 10, 2, + 44, 23, 25, 31, 26, 27, 28, 29, + 30, 29, 30, 10, 2, 44, 32, 33, + 34, 35, 36, 35, 36, 10, 2, 44, + 38, 39, 40, 42, 43, 41, 10, 41, + 10, 2, 44, 43, 44, 45, 46, 0 +}; + +static const char _deserialize_json_cond_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 2, + 0, 0, 3, 3, 4, 0, 5, 0, + 0, 2, 2, 2, 0, 0, 6, 6, + 7, 0, 0, 0, 2, 2, 8, 8, + 9, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 10, 10, 11, 0, 0, + 2, 2, 2, 0, 0, 12, 12, 13, + 0, 0, 0, 2, 2, 2, 14, 0, + 15, 15, 16, 0, 0, 0, 0, 0 +}; + +static const char _deserialize_json_eof_cond_spaces[] = { + -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0 +}; + +static const char _deserialize_json_eof_cond_key_offs[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _deserialize_json_eof_cond_key_lens[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _deserialize_json_eof_cond_keys[] = { + 0 +}; + +static const char _deserialize_json_nfa_targs[] = { + 0, 0 +}; + +static const char _deserialize_json_nfa_offsets[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const char _deserialize_json_nfa_push_actions[] = { + 0, 0 +}; + +static const char _deserialize_json_nfa_pop_trans[] = { + 0, 0 }; static const int deserialize_json_start = 1; @@ -435,209 +241,254 @@ static const int deserialize_json_error = 0; static const int deserialize_json_en_main = 1; -#line 97 "hb-buffer-deserialize-json.rl" - static hb_bool_t _hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) +const char *buf, +unsigned int buf_len, +const char **end_ptr, +hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - { - *end_ptr = ++p; - } - - const char *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 466 "hb-buffer-deserialize-json.hh" + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? ',' : '[')) { - cs = deserialize_json_start; + *end_ptr = ++p; } - -#line 471 "hb-buffer-deserialize-json.hh" + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _deserialize_json_trans_keys + (cs<<1); - _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs]; - - _slen = _deserialize_json_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && - (*p) <= _keys[1] ? - (*p) - _keys[0] : _slen ]; - - cs = _deserialize_json_trans_targs[_trans]; - - if ( _deserialize_json_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: -#line 38 "hb-buffer-deserialize-json.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} - break; - case 5: -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 2: -#line 51 "hb-buffer-deserialize-json.rl" - { - tok = p; -} - break; - case 14: -#line 55 "hb-buffer-deserialize-json.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 15: -#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } - break; - case 8: -#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 10: -#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: -#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 3: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 6: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } - break; - case 16: -#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 4: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 624 "hb-buffer-deserialize-json.hh" + cs = (int)deserialize_json_start; } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - _out: {} + + { + unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; { + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; + _resume: { + _keys = ( _deserialize_json_trans_keys + ((cs<<1))); + _inds = ( _deserialize_json_indicies + (_deserialize_json_index_offsets[cs])); + + if ( ( (*( p))) <= 125 && ( (*( p))) >= 9 ) + { + int _ic = (int)_deserialize_json_char_class[(int)( (*( p))) - 9]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_deserialize_json_index_defaults[cs]; + } + else { + _trans = (unsigned int)_deserialize_json_index_defaults[cs]; + } + + goto _match_cond; + } + _match_cond: { + cs = (int)_deserialize_json_cond_targs[_trans]; + + if ( _deserialize_json_cond_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_json_cond_actions[_trans] ) { + case 1: { + { + #line 38 "hb-buffer-deserialize-json.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + + break; } + case 5: { + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 2: { + { + #line 51 "hb-buffer-deserialize-json.rl" + + tok = p; + } + + break; } + case 14: { + { + #line 55 "hb-buffer-deserialize-json.rl" + + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + + break; } + case 15: { + { + #line 62 "hb-buffer-deserialize-json.rl" + if (!parse_uint (tok, p, &info.codepoint)) return false; } + + break; } + case 8: { + { + #line 63 "hb-buffer-deserialize-json.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + + break; } + case 10: { + { + #line 64 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_offset )) return false; } + + break; } + case 12: { + { + #line 65 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + + break; } + case 3: { + { + #line 66 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + + break; } + case 6: { + { + #line 67 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + + break; } + case 16: { + { + #line 62 "hb-buffer-deserialize-json.rl" + if (!parse_uint (tok, p, &info.codepoint)) return false; } + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 9: { + { + #line 63 "hb-buffer-deserialize-json.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 11: { + { + #line 64 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_offset )) return false; } + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 13: { + { + #line 65 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 4: { + { + #line 66 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 7: { + { + #line 67 "hb-buffer-deserialize-json.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + { + #line 43 "hb-buffer-deserialize-json.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + } + + + } + _again: { + if ( cs == 0 ) + goto _out; + p += 1; + if ( p != pe ) + goto _resume; + } + _test_eof: { {} + } + _out: { {} + } + } } - -#line 125 "hb-buffer-deserialize-json.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/src/hb-buffer-deserialize-text.hh b/src/hb-buffer-deserialize-text.hh index 67f0a1252..28ab3f1cd 100644 --- a/src/hb-buffer-deserialize-text.hh +++ b/src/hb-buffer-deserialize-text.hh @@ -1,30 +1,28 @@ - -#line 1 "hb-buffer-deserialize-text.rl" /* - * Copyright © 2013 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. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2013 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. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_BUFFER_DESERIALIZE_TEXT_HH #define HB_BUFFER_DESERIALIZE_TEXT_HH @@ -32,277 +30,160 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { - 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, - 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 0 + 1u, 0u, 0u, 10u, 4u, 7u, 6u, 7u, + 4u, 7u, 6u, 7u, 6u, 7u, 4u, 7u, + 6u, 7u, 3u, 3u, 4u, 7u, 6u, 7u, + 3u, 7u, 0u, 12u, 0u, 12u, 1u, 0u, + 0u, 10u, 0u, 12u, 0u, 12u, 0u, 12u, + 0u, 12u, 0u, 12u, 0u, 12u, 0u, 12u, + 0u, 12u, 0u, 12u, 0u, 12u, 0u }; -static const char _deserialize_text_key_spans[] = { - 0, 114, 13, 10, 13, 10, 10, 13, - 10, 1, 13, 10, 14, 116, 116, 0, - 114, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116 +static const char _deserialize_text_char_class[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 3, 4, 5, 1, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 1, 1, 1, 8, 1, 1, 9, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 1, 1, 11, 1, 5, 1, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 1, 12, 0 }; static const short _deserialize_text_index_offsets[] = { - 0, 0, 115, 129, 140, 154, 165, 176, - 190, 201, 203, 217, 228, 243, 360, 477, - 478, 593, 710, 827, 944, 1061, 1178, 1295, - 1412, 1529, 1646 + 0, 0, 11, 15, 17, 21, 23, 25, + 29, 31, 32, 36, 38, 43, 56, 69, + 69, 80, 93, 106, 119, 132, 145, 158, + 171, 184, 197, 0 }; static const char _deserialize_text_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 1, 1, 1, 1, 1, - 1, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 1, 5, 1, 1, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 1, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 1, 10, 1, 1, - 11, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 1, 13, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 1, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 1, 17, 1, 1, 18, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 1, 20, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 1, 22, 1, 23, 1, 1, 24, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 1, 26, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 1, 22, 1, 1, - 1, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 1, 28, 28, 28, 28, - 28, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 30, 1, 1, 31, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 32, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 33, - 1, 34, 34, 34, 34, 34, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 34, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 36, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 1, 1, 1, 1, 1, 1, 1, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 1, 1, 1, 1, 1, 1, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 1, 28, 28, 28, 28, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 28, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 29, 1, 1, 1, - 1, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 1, 1, 1, 30, 1, - 1, 31, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 32, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 33, 1, 38, - 38, 38, 38, 38, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 38, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 39, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 40, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 42, 42, 42, 42, - 42, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 42, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 43, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 44, - 1, 42, 42, 42, 42, 42, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 42, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 44, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 40, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 41, 1, 45, 45, 45, 45, 45, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 46, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 48, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 49, 1, - 50, 50, 50, 50, 50, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 50, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 50, 50, 50, - 50, 50, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 51, - 1, 1, 1, 1, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 52, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 45, 45, 45, 45, 45, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 45, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 46, 1, 1, 1, - 1, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 1, 1, 1, 1, 1, - 1, 47, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 48, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 49, 1, 28, - 28, 28, 28, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 29, 1, 55, 55, 1, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 1, 1, 1, 30, 1, 1, 31, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 1, 1, 32, 1, 55, 1, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 1, 33, 1, 0 + 0, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 5, 1, 6, 7, 8, + 9, 10, 1, 11, 12, 13, 14, 15, + 16, 17, 1, 18, 19, 20, 21, 22, + 23, 1, 24, 25, 26, 27, 22, 1, + 1, 21, 21, 28, 1, 29, 1, 1, + 1, 1, 1, 30, 31, 1, 32, 33, + 34, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 35, 36, 0, 1, 1, + 1, 1, 1, 2, 3, 1, 1, 4, + 28, 1, 29, 1, 1, 1, 37, 37, + 30, 31, 1, 32, 33, 38, 1, 1, + 39, 1, 1, 1, 1, 1, 1, 1, + 40, 41, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 43, 44, 42, + 1, 1, 1, 1, 1, 14, 14, 1, + 1, 1, 43, 44, 38, 1, 1, 39, + 1, 1, 9, 9, 1, 1, 1, 40, + 41, 45, 1, 46, 1, 1, 1, 1, + 1, 1, 47, 1, 48, 49, 50, 1, + 51, 1, 1, 1, 1, 1, 1, 1, + 1, 52, 53, 50, 1, 51, 1, 1, + 1, 27, 27, 1, 1, 1, 52, 53, + 45, 1, 46, 1, 1, 1, 54, 54, + 1, 47, 1, 48, 49, 28, 1, 29, + 1, 55, 55, 55, 55, 30, 31, 55, + 32, 33, 0 }; -static const char _deserialize_text_trans_targs[] = { - 1, 0, 13, 17, 26, 3, 18, 21, - 18, 21, 5, 19, 20, 19, 20, 22, - 25, 8, 9, 12, 9, 12, 10, 11, - 23, 24, 23, 24, 14, 2, 6, 7, - 15, 16, 14, 15, 16, 17, 14, 4, - 15, 16, 14, 15, 16, 14, 2, 7, - 15, 16, 14, 2, 15, 16, 25, 26 +static const char _deserialize_text_index_defaults[] = { + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0 }; -static const char _deserialize_text_trans_actions[] = { - 0, 0, 1, 1, 1, 2, 2, 2, - 0, 0, 2, 2, 2, 0, 0, 2, - 2, 2, 2, 2, 0, 0, 3, 2, - 2, 2, 0, 0, 4, 5, 5, 5, - 4, 4, 0, 0, 0, 0, 6, 7, - 6, 6, 8, 8, 8, 9, 10, 10, - 9, 9, 11, 12, 11, 11, 0, 0 +static const char _deserialize_text_trans_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0 +}; + +static const char _deserialize_text_cond_targs[] = { + 1, 0, 13, 17, 26, 3, 18, 21, + 18, 21, 5, 19, 20, 19, 20, 22, + 25, 8, 9, 12, 9, 12, 10, 11, + 23, 24, 23, 24, 14, 2, 6, 7, + 15, 16, 14, 15, 16, 17, 14, 4, + 15, 16, 14, 15, 16, 14, 2, 7, + 15, 16, 14, 2, 15, 16, 25, 26, + 0 +}; + +static const char _deserialize_text_cond_actions[] = { + 0, 0, 1, 1, 1, 2, 2, 2, + 0, 0, 2, 2, 2, 0, 0, 2, + 2, 2, 2, 2, 0, 0, 3, 2, + 2, 2, 0, 0, 4, 5, 5, 5, + 4, 4, 0, 0, 0, 0, 6, 7, + 6, 6, 8, 8, 8, 9, 10, 10, + 9, 9, 11, 12, 11, 11, 0, 0, + 0 +}; + +static const char _deserialize_text_eof_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 0 +}; + +static const char _deserialize_text_eof_cond_key_offs[] = { + 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 +}; + +static const char _deserialize_text_eof_cond_key_lens[] = { + 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 +}; + +static const char _deserialize_text_eof_cond_keys[] = { + 0 }; static const char _deserialize_text_eof_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, - 0, 4, 6, 8, 8, 6, 9, 11, - 11, 9, 4 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, + 0, 4, 6, 8, 8, 6, 9, 11, + 11, 9, 4, 0 +}; + +static const char _deserialize_text_nfa_targs[] = { + 0, 0 +}; + +static const char _deserialize_text_nfa_offsets[] = { + 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 +}; + +static const char _deserialize_text_nfa_push_actions[] = { + 0, 0 +}; + +static const char _deserialize_text_nfa_pop_trans[] = { + 0, 0 }; static const int deserialize_text_start = 1; @@ -312,260 +193,338 @@ static const int deserialize_text_error = 0; static const int deserialize_text_en_main = 1; -#line 91 "hb-buffer-deserialize-text.rl" - static hb_bool_t _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) +const char *buf, +unsigned int buf_len, +const char **end_ptr, +hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? '|' : '[')) - { - *end_ptr = ++p; - } - - const char *eof = pe, *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 343 "hb-buffer-deserialize-text.hh" + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? '|' : '[')) { - cs = deserialize_text_start; + *end_ptr = ++p; } - -#line 348 "hb-buffer-deserialize-text.hh" + + const char *eof = pe, *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _deserialize_text_trans_keys + (cs<<1); - _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs]; - - _slen = _deserialize_text_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && - (*p) <= _keys[1] ? - (*p) - _keys[0] : _slen ]; - - cs = _deserialize_text_trans_targs[_trans]; - - if ( _deserialize_text_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _deserialize_text_trans_actions[_trans] ) { - case 2: -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} - break; - case 5: -#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 10: -#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 3: -#line 63 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: -#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 7: -#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 1: -#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} -#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; -} - break; - case 4: -#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 6: -#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 66 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 480 "hb-buffer-deserialize-text.hh" + cs = (int)deserialize_text_start; } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) + { - switch ( _deserialize_text_eof_actions[cs] ) { - case 4: -#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 6: -#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 8: -#line 66 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 557 "hb-buffer-deserialize-text.hh" + int _cpc; + int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; { + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; + _resume: { + _keys = ( _deserialize_text_trans_keys + ((cs<<1))); + _inds = ( _deserialize_text_indicies + (_deserialize_text_index_offsets[cs])); + + if ( ( (*( p))) <= 124 && ( (*( p))) >= 9 ) + { + int _ic = (int)_deserialize_text_char_class[(int)( (*( p))) - 9]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_deserialize_text_index_defaults[cs]; + } + else { + _trans = (unsigned int)_deserialize_text_index_defaults[cs]; + } + + goto _match_cond; + } + _match_cond: { + cs = (int)_deserialize_text_cond_targs[_trans]; + + if ( _deserialize_text_cond_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_text_cond_actions[_trans] ) { + case 2: { + { + #line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + + break; } + case 5: { + { + #line 55 "hb-buffer-deserialize-text.rl" + + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + + break; } + case 10: { + { + #line 62 "hb-buffer-deserialize-text.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + + break; } + case 3: { + { + #line 63 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_offset )) return false; } + + break; } + case 12: { + { + #line 64 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + + break; } + case 7: { + { + #line 65 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + + break; } + case 1: { + { + #line 38 "hb-buffer-deserialize-text.rl" + + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); + } + { + #line 51 "hb-buffer-deserialize-text.rl" + + tok = p; + } + + break; } + case 4: { + { + #line 55 "hb-buffer-deserialize-text.rl" + + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 9: { + { + #line 62 "hb-buffer-deserialize-text.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 11: { + { + #line 64 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 6: { + { + #line 65 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 8: { + { + #line 66 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + } + + + } + _again: { + if ( cs == 0 ) + goto _out; + p += 1; + if ( p != pe ) + goto _resume; + } + _test_eof: { {} + if ( p == eof ) + { + if ( _deserialize_text_eof_cond_spaces[cs] != -1 ) { + _cekeys = ( _deserialize_text_eof_cond_keys + (_deserialize_text_eof_cond_key_offs[cs])); + _klen = (int)_deserialize_text_eof_cond_key_lens[cs]; + _cpc = 0; + { + const char *_lower = _cekeys; + const char *_upper = _cekeys + _klen - 1; + const char *_mid; + while ( 1 ) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( _cpc < (int)(*( _mid)) ) + _upper = _mid - 1; + else if ( _cpc > (int)(*( _mid)) ) + _lower = _mid + 1; + else { + goto _ok; + } + } + cs = 0; + goto _out; + } + _ok: {} + } + switch ( _deserialize_text_eof_actions[cs] ) { + case 4: { + { + #line 55 "hb-buffer-deserialize-text.rl" + + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; + } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 9: { + { + #line 62 "hb-buffer-deserialize-text.rl" + if (!parse_uint (tok, p, &info.cluster )) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 11: { + { + #line 64 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_offset )) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 6: { + { + #line 65 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.x_advance)) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + case 8: { + { + #line 66 "hb-buffer-deserialize-text.rl" + if (!parse_int (tok, p, &pos.y_advance)) return false; } + { + #line 43 "hb-buffer-deserialize-text.rl" + + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; + } + + break; } + } + } + + } + _out: { {} + } + } } - } - - _out: {} - } - -#line 119 "hb-buffer-deserialize-text.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; } #endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/src/hb-ot-shape-complex-indic-machine.hh b/src/hb-ot-shape-complex-indic-machine.hh index 08b90e913..dbab7e042 100644 --- a/src/hb-ot-shape-complex-indic-machine.hh +++ b/src/hb-ot-shape-complex-indic-machine.hh @@ -1,30 +1,28 @@ - -#line 1 "hb-ot-shape-complex-indic-machine.rl" /* - * Copyright © 2011,2012 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. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2011,2012 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. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH @@ -32,952 +30,1226 @@ #include "hb.hh" -#line 36 "hb-ot-shape-complex-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, - 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, - 4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, - 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, - 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, - 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, - 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, - 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 8u, 8u, 4u, 8u, 5u, 7u, - 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, - 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, - 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, - 5u, 8u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, - 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, - 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, - 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, - 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, - 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, - 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, - 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, - 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, - 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, - 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, - 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 17u, 3u, 17u, - 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, - 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, - 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, - 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, - 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, - 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, - 1u, 16u, 1u, 16u, 4u, 13u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, - 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, - 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, - 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, - 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, - 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, - 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, - 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, - 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0 + 7u, 7u, 3u, 7u, 4u, 6u, 6u, 6u, + 4u, 7u, 4u, 6u, 6u, 6u, 4u, 7u, + 4u, 6u, 6u, 6u, 4u, 7u, 4u, 6u, + 6u, 6u, 3u, 7u, 5u, 5u, 14u, 14u, + 3u, 7u, 5u, 5u, 14u, 14u, 3u, 7u, + 5u, 5u, 14u, 14u, 3u, 7u, 5u, 5u, + 14u, 14u, 3u, 12u, 3u, 7u, 3u, 12u, + 3u, 7u, 3u, 12u, 3u, 7u, 3u, 12u, + 3u, 7u, 3u, 12u, 7u, 7u, 3u, 7u, + 4u, 6u, 6u, 6u, 4u, 7u, 4u, 6u, + 6u, 6u, 4u, 7u, 4u, 6u, 6u, 6u, + 4u, 7u, 4u, 6u, 6u, 6u, 3u, 7u, + 5u, 5u, 14u, 14u, 3u, 7u, 5u, 5u, + 14u, 14u, 3u, 7u, 5u, 5u, 14u, 14u, + 3u, 7u, 5u, 5u, 14u, 14u, 3u, 12u, + 3u, 7u, 3u, 12u, 3u, 7u, 3u, 12u, + 3u, 7u, 3u, 12u, 3u, 7u, 3u, 12u, + 7u, 7u, 3u, 7u, 4u, 6u, 6u, 6u, + 4u, 7u, 4u, 6u, 6u, 6u, 4u, 7u, + 4u, 6u, 6u, 6u, 4u, 7u, 4u, 6u, + 6u, 6u, 3u, 7u, 5u, 5u, 14u, 14u, + 3u, 7u, 5u, 5u, 14u, 14u, 3u, 7u, + 5u, 5u, 14u, 14u, 3u, 7u, 5u, 5u, + 14u, 14u, 3u, 12u, 3u, 7u, 3u, 12u, + 3u, 7u, 3u, 12u, 3u, 7u, 3u, 12u, + 3u, 7u, 7u, 7u, 3u, 7u, 4u, 6u, + 6u, 6u, 4u, 7u, 4u, 6u, 6u, 6u, + 4u, 7u, 4u, 6u, 6u, 6u, 4u, 7u, + 4u, 6u, 6u, 6u, 3u, 7u, 5u, 5u, + 14u, 14u, 3u, 7u, 5u, 5u, 14u, 14u, + 3u, 7u, 5u, 5u, 14u, 14u, 3u, 7u, + 5u, 5u, 14u, 14u, 3u, 12u, 3u, 7u, + 3u, 12u, 3u, 7u, 3u, 12u, 3u, 7u, + 3u, 12u, 3u, 7u, 3u, 12u, 3u, 12u, + 4u, 7u, 7u, 7u, 0u, 17u, 2u, 15u, + 2u, 15u, 3u, 15u, 0u, 14u, 2u, 15u, + 2u, 15u, 3u, 15u, 0u, 14u, 2u, 15u, + 2u, 15u, 3u, 15u, 0u, 14u, 2u, 15u, + 2u, 15u, 3u, 15u, 0u, 14u, 2u, 15u, + 2u, 15u, 3u, 15u, 4u, 9u, 4u, 9u, + 4u, 9u, 9u, 9u, 9u, 9u, 9u, 9u, + 4u, 9u, 2u, 9u, 4u, 9u, 2u, 9u, + 3u, 9u, 4u, 9u, 2u, 9u, 3u, 9u, + 4u, 9u, 2u, 9u, 3u, 9u, 4u, 9u, + 2u, 9u, 3u, 9u, 3u, 9u, 2u, 15u, + 2u, 15u, 0u, 14u, 0u, 14u, 0u, 14u, + 2u, 15u, 2u, 15u, 0u, 14u, 0u, 14u, + 0u, 14u, 2u, 15u, 2u, 15u, 0u, 14u, + 0u, 14u, 0u, 14u, 2u, 15u, 2u, 15u, + 0u, 14u, 0u, 14u, 0u, 14u, 2u, 15u, + 2u, 15u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 4u, 9u, 4u, 9u, 4u, 9u, 9u, 9u, + 9u, 9u, 9u, 9u, 4u, 9u, 2u, 9u, + 4u, 9u, 2u, 9u, 3u, 9u, 4u, 9u, + 2u, 9u, 3u, 9u, 4u, 9u, 2u, 9u, + 3u, 9u, 4u, 9u, 2u, 9u, 3u, 9u, + 3u, 9u, 2u, 15u, 2u, 15u, 0u, 14u, + 0u, 14u, 0u, 14u, 2u, 15u, 2u, 15u, + 0u, 14u, 0u, 14u, 0u, 14u, 2u, 15u, + 2u, 15u, 0u, 14u, 0u, 14u, 0u, 14u, + 2u, 15u, 2u, 15u, 0u, 14u, 0u, 14u, + 0u, 14u, 3u, 7u, 2u, 15u, 2u, 15u, + 3u, 15u, 0u, 14u, 2u, 15u, 2u, 15u, + 3u, 15u, 0u, 14u, 2u, 15u, 2u, 15u, + 3u, 15u, 0u, 14u, 2u, 15u, 2u, 15u, + 3u, 15u, 0u, 14u, 2u, 15u, 2u, 15u, + 3u, 15u, 4u, 9u, 4u, 9u, 4u, 9u, + 9u, 9u, 9u, 9u, 9u, 9u, 4u, 9u, + 2u, 9u, 4u, 9u, 2u, 9u, 3u, 9u, + 4u, 9u, 2u, 9u, 3u, 9u, 4u, 9u, + 2u, 9u, 3u, 9u, 4u, 9u, 2u, 9u, + 3u, 9u, 3u, 9u, 2u, 15u, 2u, 15u, + 0u, 14u, 0u, 14u, 0u, 14u, 2u, 15u, + 2u, 15u, 0u, 14u, 0u, 14u, 0u, 14u, + 2u, 15u, 2u, 15u, 0u, 14u, 0u, 14u, + 0u, 14u, 2u, 15u, 2u, 15u, 0u, 14u, + 0u, 14u, 0u, 14u, 3u, 12u, 2u, 15u, + 3u, 7u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 0u, 14u, 2u, 15u, 2u, 15u, 3u, 15u, + 4u, 9u, 4u, 9u, 4u, 9u, 9u, 9u, + 9u, 9u, 9u, 9u, 4u, 9u, 2u, 9u, + 4u, 9u, 2u, 9u, 3u, 9u, 4u, 9u, + 2u, 9u, 3u, 9u, 4u, 9u, 2u, 9u, + 3u, 9u, 4u, 9u, 2u, 9u, 3u, 9u, + 3u, 9u, 2u, 15u, 2u, 15u, 0u, 14u, + 0u, 14u, 0u, 14u, 2u, 15u, 2u, 15u, + 0u, 14u, 0u, 14u, 0u, 14u, 2u, 15u, + 2u, 15u, 0u, 14u, 0u, 14u, 0u, 14u, + 2u, 15u, 2u, 15u, 0u, 14u, 0u, 14u, + 0u, 14u, 2u, 15u, 0u, 15u, 2u, 15u, + 0u, 15u, 3u, 12u, 4u, 9u, 9u, 9u, + 9u, 9u, 9u, 9u, 4u, 9u, 0u, 14u, + 2u, 9u, 4u, 9u, 4u, 9u, 9u, 9u, + 9u, 9u, 9u, 9u, 4u, 9u, 0u, 14u, + 0u }; -static const char _indic_syllable_machine_key_spans[] = { - 1, 5, 3, 1, 4, 3, 1, 4, - 3, 1, 4, 3, 1, 5, 1, 1, - 5, 1, 1, 5, 1, 1, 5, 1, - 1, 10, 5, 10, 5, 10, 5, 10, - 5, 10, 1, 5, 3, 1, 4, 3, - 1, 4, 3, 1, 4, 3, 1, 5, - 1, 1, 5, 1, 1, 5, 1, 1, - 5, 1, 1, 10, 5, 10, 5, 10, - 5, 10, 5, 10, 1, 5, 3, 1, - 4, 3, 1, 4, 3, 1, 4, 3, - 1, 5, 1, 1, 5, 1, 1, 5, - 1, 1, 5, 1, 1, 10, 5, 10, - 5, 10, 5, 10, 5, 1, 5, 3, - 1, 4, 3, 1, 4, 3, 1, 4, - 3, 1, 5, 1, 1, 5, 1, 1, - 5, 1, 1, 5, 1, 1, 10, 5, - 10, 5, 10, 5, 10, 5, 10, 10, - 4, 1, 19, 15, 15, 14, 16, 15, - 15, 14, 16, 15, 15, 14, 16, 15, - 15, 14, 16, 15, 15, 14, 6, 6, - 6, 1, 1, 1, 6, 8, 6, 8, - 7, 6, 8, 7, 6, 8, 7, 6, - 8, 7, 7, 15, 15, 16, 16, 16, - 15, 15, 16, 16, 16, 15, 15, 16, - 16, 16, 15, 15, 16, 16, 16, 15, - 15, 15, 15, 14, 16, 15, 15, 14, - 16, 15, 15, 14, 16, 15, 15, 14, - 16, 15, 15, 14, 6, 6, 6, 1, - 1, 1, 6, 8, 6, 8, 7, 6, - 8, 7, 6, 8, 7, 6, 8, 7, - 7, 15, 15, 16, 16, 16, 15, 15, - 16, 16, 16, 15, 15, 16, 16, 16, - 15, 15, 16, 16, 16, 5, 15, 15, - 14, 16, 15, 15, 14, 16, 15, 15, - 14, 16, 15, 15, 14, 16, 15, 15, - 14, 6, 6, 6, 1, 1, 1, 6, - 8, 6, 8, 7, 6, 8, 7, 6, - 8, 7, 6, 8, 7, 7, 15, 15, - 16, 16, 16, 15, 15, 16, 16, 16, - 15, 15, 16, 16, 16, 15, 15, 16, - 16, 16, 10, 15, 5, 15, 15, 14, - 16, 15, 15, 14, 16, 15, 15, 14, - 16, 15, 15, 14, 16, 15, 15, 14, - 6, 6, 6, 1, 1, 1, 6, 8, - 6, 8, 7, 6, 8, 7, 6, 8, - 7, 6, 8, 7, 7, 15, 15, 16, - 16, 16, 15, 15, 16, 16, 16, 15, - 15, 16, 16, 16, 15, 15, 16, 16, - 16, 15, 17, 15, 17, 10, 6, 1, - 1, 1, 6, 16, 8, 6, 6, 1, - 1, 1, 6, 16 +static const char _indic_syllable_machine_char_class[] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 8, 13, 14, + 15, 16, 17, 0 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 8, 12, 14, 19, 23, 25, - 30, 34, 36, 41, 45, 47, 53, 55, - 57, 63, 65, 67, 73, 75, 77, 83, - 85, 87, 98, 104, 115, 121, 132, 138, - 149, 155, 166, 168, 174, 178, 180, 185, - 189, 191, 196, 200, 202, 207, 211, 213, - 219, 221, 223, 229, 231, 233, 239, 241, - 243, 249, 251, 253, 264, 270, 281, 287, - 298, 304, 315, 321, 332, 334, 340, 344, - 346, 351, 355, 357, 362, 366, 368, 373, - 377, 379, 385, 387, 389, 395, 397, 399, - 405, 407, 409, 415, 417, 419, 430, 436, - 447, 453, 464, 470, 481, 487, 489, 495, - 499, 501, 506, 510, 512, 517, 521, 523, - 528, 532, 534, 540, 542, 544, 550, 552, - 554, 560, 562, 564, 570, 572, 574, 585, - 591, 602, 608, 619, 625, 636, 642, 653, - 664, 669, 671, 691, 707, 723, 738, 755, - 771, 787, 802, 819, 835, 851, 866, 883, - 899, 915, 930, 947, 963, 979, 994, 1001, - 1008, 1015, 1017, 1019, 1021, 1028, 1037, 1044, - 1053, 1061, 1068, 1077, 1085, 1092, 1101, 1109, - 1116, 1125, 1133, 1141, 1157, 1173, 1190, 1207, - 1224, 1240, 1256, 1273, 1290, 1307, 1323, 1339, - 1356, 1373, 1390, 1406, 1422, 1439, 1456, 1473, - 1489, 1505, 1521, 1537, 1552, 1569, 1585, 1601, - 1616, 1633, 1649, 1665, 1680, 1697, 1713, 1729, - 1744, 1761, 1777, 1793, 1808, 1815, 1822, 1829, - 1831, 1833, 1835, 1842, 1851, 1858, 1867, 1875, - 1882, 1891, 1899, 1906, 1915, 1923, 1930, 1939, - 1947, 1955, 1971, 1987, 2004, 2021, 2038, 2054, - 2070, 2087, 2104, 2121, 2137, 2153, 2170, 2187, - 2204, 2220, 2236, 2253, 2270, 2287, 2293, 2309, - 2325, 2340, 2357, 2373, 2389, 2404, 2421, 2437, - 2453, 2468, 2485, 2501, 2517, 2532, 2549, 2565, - 2581, 2596, 2603, 2610, 2617, 2619, 2621, 2623, - 2630, 2639, 2646, 2655, 2663, 2670, 2679, 2687, - 2694, 2703, 2711, 2718, 2727, 2735, 2743, 2759, - 2775, 2792, 2809, 2826, 2842, 2858, 2875, 2892, - 2909, 2925, 2941, 2958, 2975, 2992, 3008, 3024, - 3041, 3058, 3075, 3086, 3102, 3108, 3124, 3140, - 3155, 3172, 3188, 3204, 3219, 3236, 3252, 3268, - 3283, 3300, 3316, 3332, 3347, 3364, 3380, 3396, - 3411, 3418, 3425, 3432, 3434, 3436, 3438, 3445, - 3454, 3461, 3470, 3478, 3485, 3494, 3502, 3509, - 3518, 3526, 3533, 3542, 3550, 3558, 3574, 3590, - 3607, 3624, 3641, 3657, 3673, 3690, 3707, 3724, - 3740, 3756, 3773, 3790, 3807, 3823, 3839, 3856, - 3873, 3890, 3906, 3924, 3940, 3958, 3969, 3976, - 3978, 3980, 3982, 3989, 4006, 4015, 4022, 4029, - 4031, 4033, 4035, 4042 + 0, 1, 6, 9, 10, 14, 17, 18, + 22, 25, 26, 30, 33, 34, 39, 40, + 41, 46, 47, 48, 53, 54, 55, 60, + 61, 62, 72, 77, 87, 92, 102, 107, + 117, 122, 132, 133, 138, 141, 142, 146, + 149, 150, 154, 157, 158, 162, 165, 166, + 171, 172, 173, 178, 179, 180, 185, 186, + 187, 192, 193, 194, 204, 209, 219, 224, + 234, 239, 249, 254, 264, 265, 270, 273, + 274, 278, 281, 282, 286, 289, 290, 294, + 297, 298, 303, 304, 305, 310, 311, 312, + 317, 318, 319, 324, 325, 326, 336, 341, + 351, 356, 366, 371, 381, 386, 387, 392, + 395, 396, 400, 403, 404, 408, 411, 412, + 416, 419, 420, 425, 426, 427, 432, 433, + 434, 439, 440, 441, 446, 447, 448, 458, + 463, 473, 478, 488, 493, 503, 508, 518, + 528, 532, 533, 551, 565, 579, 592, 607, + 621, 635, 648, 663, 677, 691, 704, 719, + 733, 747, 760, 775, 789, 803, 816, 822, + 828, 834, 835, 836, 837, 843, 851, 857, + 865, 872, 878, 886, 893, 899, 907, 914, + 920, 928, 935, 942, 956, 970, 985, 1000, + 1015, 1029, 1043, 1058, 1073, 1088, 1102, 1116, + 1131, 1146, 1161, 1175, 1189, 1204, 1219, 1234, + 1248, 1262, 1276, 1290, 1303, 1318, 1332, 1346, + 1359, 1374, 1388, 1402, 1415, 1430, 1444, 1458, + 1471, 1486, 1500, 1514, 1527, 1533, 1539, 1545, + 1546, 1547, 1548, 1554, 1562, 1568, 1576, 1583, + 1589, 1597, 1604, 1610, 1618, 1625, 1631, 1639, + 1646, 1653, 1667, 1681, 1696, 1711, 1726, 1740, + 1754, 1769, 1784, 1799, 1813, 1827, 1842, 1857, + 1872, 1886, 1900, 1915, 1930, 1945, 1950, 1964, + 1978, 1991, 2006, 2020, 2034, 2047, 2062, 2076, + 2090, 2103, 2118, 2132, 2146, 2159, 2174, 2188, + 2202, 2215, 2221, 2227, 2233, 2234, 2235, 2236, + 2242, 2250, 2256, 2264, 2271, 2277, 2285, 2292, + 2298, 2306, 2313, 2319, 2327, 2334, 2341, 2355, + 2369, 2384, 2399, 2414, 2428, 2442, 2457, 2472, + 2487, 2501, 2515, 2530, 2545, 2560, 2574, 2588, + 2603, 2618, 2633, 2643, 2657, 2662, 2676, 2690, + 2703, 2718, 2732, 2746, 2759, 2774, 2788, 2802, + 2815, 2830, 2844, 2858, 2871, 2886, 2900, 2914, + 2927, 2933, 2939, 2945, 2946, 2947, 2948, 2954, + 2962, 2968, 2976, 2983, 2989, 2997, 3004, 3010, + 3018, 3025, 3031, 3039, 3046, 3053, 3067, 3081, + 3096, 3111, 3126, 3140, 3154, 3169, 3184, 3199, + 3213, 3227, 3242, 3257, 3272, 3286, 3300, 3315, + 3330, 3345, 3359, 3375, 3389, 3405, 3415, 3421, + 3422, 3423, 3424, 3430, 3445, 3453, 3459, 3465, + 3466, 3467, 3468, 3474, 0 }; static const short _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 3, 4, 1, 0, - 5, 5, 4, 0, 4, 0, 6, 6, - 7, 1, 0, 8, 8, 7, 0, 7, - 0, 9, 9, 10, 1, 0, 11, 11, - 10, 0, 10, 0, 12, 12, 13, 1, - 0, 14, 14, 13, 0, 13, 0, 15, - 0, 0, 0, 1, 0, 16, 0, 17, - 0, 18, 12, 12, 13, 1, 0, 19, - 0, 20, 0, 21, 9, 9, 10, 1, - 0, 22, 0, 23, 0, 24, 6, 6, - 7, 1, 0, 25, 0, 26, 0, 2, - 3, 3, 4, 1, 0, 0, 0, 0, - 27, 0, 28, 3, 3, 4, 1, 0, - 28, 3, 3, 4, 1, 0, 0, 0, - 0, 29, 0, 30, 3, 3, 4, 1, - 0, 30, 3, 3, 4, 1, 0, 0, - 0, 0, 31, 0, 32, 3, 3, 4, - 1, 0, 32, 3, 3, 4, 1, 0, - 0, 0, 0, 33, 0, 34, 3, 3, - 4, 1, 0, 34, 3, 3, 4, 1, - 0, 0, 0, 0, 35, 0, 37, 36, - 38, 39, 39, 40, 37, 36, 41, 41, - 40, 36, 40, 36, 42, 42, 43, 37, - 36, 44, 44, 43, 36, 43, 36, 45, - 45, 46, 37, 36, 47, 47, 46, 36, - 46, 36, 48, 48, 49, 37, 36, 50, - 50, 49, 36, 49, 36, 51, 36, 36, - 36, 37, 36, 52, 36, 53, 36, 54, - 48, 48, 49, 37, 36, 55, 36, 56, - 36, 57, 45, 45, 46, 37, 36, 58, - 36, 59, 36, 60, 42, 42, 43, 37, - 36, 61, 36, 62, 36, 38, 39, 39, - 40, 37, 36, 36, 36, 36, 63, 36, - 64, 39, 39, 40, 37, 36, 64, 39, - 39, 40, 37, 36, 36, 36, 36, 65, - 36, 66, 39, 39, 40, 37, 36, 66, - 39, 39, 40, 37, 36, 36, 36, 36, - 67, 36, 68, 39, 39, 40, 37, 36, - 68, 39, 39, 40, 37, 36, 36, 36, - 36, 69, 36, 70, 39, 39, 40, 37, - 36, 70, 39, 39, 40, 37, 36, 36, - 36, 36, 71, 36, 73, 72, 74, 75, - 75, 76, 73, 72, 78, 78, 76, 77, - 76, 77, 79, 79, 80, 73, 72, 81, - 81, 80, 72, 80, 72, 82, 82, 83, - 73, 72, 84, 84, 83, 72, 83, 72, - 85, 85, 86, 73, 72, 87, 87, 86, - 72, 86, 72, 88, 72, 72, 72, 73, - 72, 89, 72, 90, 72, 91, 85, 85, - 86, 73, 72, 92, 72, 93, 72, 94, - 82, 82, 83, 73, 72, 95, 72, 96, - 72, 97, 79, 79, 80, 73, 72, 98, - 72, 99, 72, 74, 75, 75, 76, 73, - 72, 72, 72, 72, 100, 72, 101, 75, - 75, 76, 73, 72, 101, 75, 75, 76, - 73, 72, 72, 72, 72, 102, 72, 103, - 75, 75, 76, 73, 72, 103, 75, 75, - 76, 73, 72, 72, 72, 72, 104, 72, - 105, 75, 75, 76, 73, 72, 105, 75, - 75, 76, 73, 72, 72, 72, 72, 106, - 72, 107, 75, 75, 76, 73, 72, 109, - 108, 110, 111, 111, 112, 109, 108, 113, - 113, 112, 108, 112, 108, 114, 114, 115, - 109, 108, 116, 116, 115, 108, 115, 108, - 117, 117, 118, 109, 108, 119, 119, 118, - 108, 118, 108, 120, 120, 121, 109, 108, - 122, 122, 121, 108, 121, 108, 123, 108, - 108, 108, 109, 108, 124, 108, 125, 108, - 126, 120, 120, 121, 109, 108, 127, 108, - 128, 108, 129, 117, 117, 118, 109, 108, - 130, 108, 131, 108, 132, 114, 114, 115, - 109, 108, 133, 108, 134, 108, 110, 111, - 111, 112, 109, 108, 108, 108, 108, 135, - 108, 136, 111, 111, 112, 109, 108, 136, - 111, 111, 112, 109, 108, 108, 108, 108, - 137, 108, 138, 111, 111, 112, 109, 108, - 138, 111, 111, 112, 109, 108, 108, 108, - 108, 139, 108, 140, 111, 111, 112, 109, - 108, 140, 111, 111, 112, 109, 108, 108, - 108, 108, 141, 108, 142, 111, 111, 112, - 109, 108, 142, 111, 111, 112, 109, 108, - 108, 108, 108, 143, 108, 107, 75, 75, - 76, 73, 72, 72, 72, 72, 144, 72, - 78, 78, 76, 1, 0, 146, 145, 148, - 149, 150, 151, 152, 153, 76, 73, 147, - 154, 155, 155, 144, 147, 156, 157, 158, - 159, 160, 147, 162, 163, 164, 165, 4, - 1, 161, 166, 161, 161, 35, 161, 161, - 161, 167, 161, 168, 163, 169, 169, 4, - 1, 161, 166, 161, 161, 161, 161, 161, - 161, 167, 161, 163, 169, 169, 4, 1, - 161, 166, 161, 161, 161, 161, 161, 161, - 167, 161, 170, 161, 161, 161, 17, 171, - 161, 1, 161, 166, 161, 161, 161, 161, - 161, 170, 161, 172, 173, 174, 175, 4, - 1, 161, 166, 161, 161, 33, 161, 161, - 161, 167, 161, 176, 173, 177, 177, 4, - 1, 161, 166, 161, 161, 161, 161, 161, - 161, 167, 161, 173, 177, 177, 4, 1, - 161, 166, 161, 161, 161, 161, 161, 161, - 167, 161, 178, 161, 161, 161, 17, 179, - 161, 1, 161, 166, 161, 161, 161, 161, - 161, 178, 161, 180, 181, 182, 183, 4, - 1, 161, 166, 161, 161, 31, 161, 161, - 161, 167, 161, 184, 181, 185, 185, 4, - 1, 161, 166, 161, 161, 161, 161, 161, - 161, 167, 161, 181, 185, 185, 4, 1, - 161, 166, 161, 161, 161, 161, 161, 161, - 167, 161, 186, 161, 161, 161, 17, 187, - 161, 1, 161, 166, 161, 161, 161, 161, - 161, 186, 161, 188, 189, 190, 191, 4, - 1, 161, 166, 161, 161, 29, 161, 161, - 161, 167, 161, 192, 189, 193, 193, 4, - 1, 161, 166, 161, 161, 161, 161, 161, - 161, 167, 161, 189, 193, 193, 4, 1, - 161, 166, 161, 161, 161, 161, 161, 161, - 167, 161, 194, 161, 161, 161, 17, 195, - 161, 1, 161, 166, 161, 161, 161, 161, - 161, 194, 161, 196, 197, 198, 199, 4, - 1, 161, 166, 161, 161, 27, 161, 161, - 161, 167, 161, 200, 197, 201, 201, 4, - 1, 161, 166, 161, 161, 161, 161, 161, - 161, 167, 161, 197, 201, 201, 4, 1, - 161, 166, 161, 161, 161, 161, 161, 161, - 167, 161, 17, 202, 161, 1, 161, 166, - 161, 203, 203, 161, 1, 161, 166, 161, - 204, 161, 161, 205, 161, 166, 161, 166, - 161, 206, 161, 207, 161, 204, 161, 161, - 161, 161, 166, 161, 17, 161, 203, 203, - 161, 1, 161, 166, 161, 203, 202, 161, - 1, 161, 166, 161, 208, 26, 209, 210, - 7, 1, 161, 166, 161, 26, 209, 210, - 7, 1, 161, 166, 161, 209, 209, 7, - 1, 161, 166, 161, 211, 23, 212, 213, - 10, 1, 161, 166, 161, 23, 212, 213, - 10, 1, 161, 166, 161, 212, 212, 10, - 1, 161, 166, 161, 214, 20, 215, 216, - 13, 1, 161, 166, 161, 20, 215, 216, - 13, 1, 161, 166, 161, 215, 215, 13, - 1, 161, 166, 161, 217, 17, 203, 218, - 161, 1, 161, 166, 161, 17, 203, 218, - 161, 1, 161, 166, 161, 197, 201, 201, - 4, 1, 161, 166, 161, 196, 197, 201, - 201, 4, 1, 161, 166, 161, 161, 161, - 161, 161, 161, 167, 161, 196, 197, 198, - 201, 4, 1, 161, 166, 161, 161, 27, - 161, 161, 161, 167, 161, 194, 161, 219, - 161, 203, 203, 161, 1, 161, 166, 161, - 161, 161, 161, 161, 194, 161, 194, 161, - 161, 161, 203, 203, 161, 1, 161, 166, - 161, 161, 161, 161, 161, 194, 161, 194, - 161, 161, 161, 203, 195, 161, 1, 161, - 166, 161, 161, 161, 161, 161, 194, 161, - 188, 189, 193, 193, 4, 1, 161, 166, - 161, 161, 161, 161, 161, 161, 167, 161, - 188, 189, 190, 193, 4, 1, 161, 166, - 161, 161, 29, 161, 161, 161, 167, 161, - 186, 161, 220, 161, 203, 203, 161, 1, - 161, 166, 161, 161, 161, 161, 161, 186, - 161, 186, 161, 161, 161, 203, 203, 161, - 1, 161, 166, 161, 161, 161, 161, 161, - 186, 161, 186, 161, 161, 161, 203, 187, - 161, 1, 161, 166, 161, 161, 161, 161, - 161, 186, 161, 180, 181, 185, 185, 4, - 1, 161, 166, 161, 161, 161, 161, 161, - 161, 167, 161, 180, 181, 182, 185, 4, - 1, 161, 166, 161, 161, 31, 161, 161, - 161, 167, 161, 178, 161, 221, 161, 203, - 203, 161, 1, 161, 166, 161, 161, 161, - 161, 161, 178, 161, 178, 161, 161, 161, - 203, 203, 161, 1, 161, 166, 161, 161, - 161, 161, 161, 178, 161, 178, 161, 161, - 161, 203, 179, 161, 1, 161, 166, 161, - 161, 161, 161, 161, 178, 161, 172, 173, - 177, 177, 4, 1, 161, 166, 161, 161, - 161, 161, 161, 161, 167, 161, 172, 173, - 174, 177, 4, 1, 161, 166, 161, 161, - 33, 161, 161, 161, 167, 161, 170, 161, - 222, 161, 203, 203, 161, 1, 161, 166, - 161, 161, 161, 161, 161, 170, 161, 170, - 161, 161, 161, 203, 203, 161, 1, 161, - 166, 161, 161, 161, 161, 161, 170, 161, - 170, 161, 161, 161, 203, 171, 161, 1, - 161, 166, 161, 161, 161, 161, 161, 170, - 161, 162, 163, 169, 169, 4, 1, 161, - 166, 161, 161, 161, 161, 161, 161, 167, - 161, 162, 163, 164, 169, 4, 1, 161, - 166, 161, 161, 35, 161, 161, 161, 167, - 161, 224, 225, 226, 227, 40, 37, 223, - 228, 223, 223, 71, 223, 223, 223, 229, - 223, 230, 225, 231, 227, 40, 37, 223, - 228, 223, 223, 223, 223, 223, 223, 229, - 223, 225, 231, 227, 40, 37, 223, 228, - 223, 223, 223, 223, 223, 223, 229, 223, - 232, 223, 223, 223, 53, 233, 223, 37, - 223, 228, 223, 223, 223, 223, 223, 232, - 223, 234, 235, 236, 237, 40, 37, 223, - 228, 223, 223, 69, 223, 223, 223, 229, - 223, 238, 235, 239, 239, 40, 37, 223, - 228, 223, 223, 223, 223, 223, 223, 229, - 223, 235, 239, 239, 40, 37, 223, 228, - 223, 223, 223, 223, 223, 223, 229, 223, - 240, 223, 223, 223, 53, 241, 223, 37, - 223, 228, 223, 223, 223, 223, 223, 240, - 223, 242, 243, 244, 245, 40, 37, 223, - 228, 223, 223, 67, 223, 223, 223, 229, - 223, 246, 243, 247, 247, 40, 37, 223, - 228, 223, 223, 223, 223, 223, 223, 229, - 223, 243, 247, 247, 40, 37, 223, 228, - 223, 223, 223, 223, 223, 223, 229, 223, - 248, 223, 223, 223, 53, 249, 223, 37, - 223, 228, 223, 223, 223, 223, 223, 248, - 223, 250, 251, 252, 253, 40, 37, 223, - 228, 223, 223, 65, 223, 223, 223, 229, - 223, 254, 251, 255, 255, 40, 37, 223, - 228, 223, 223, 223, 223, 223, 223, 229, - 223, 251, 255, 255, 40, 37, 223, 228, - 223, 223, 223, 223, 223, 223, 229, 223, - 256, 223, 223, 223, 53, 257, 223, 37, - 223, 228, 223, 223, 223, 223, 223, 256, - 223, 258, 259, 260, 261, 40, 37, 223, - 228, 223, 223, 63, 223, 223, 223, 229, - 223, 262, 259, 263, 263, 40, 37, 223, - 228, 223, 223, 223, 223, 223, 223, 229, - 223, 259, 263, 263, 40, 37, 223, 228, - 223, 223, 223, 223, 223, 223, 229, 223, - 53, 264, 223, 37, 223, 228, 223, 265, - 265, 223, 37, 223, 228, 223, 266, 223, - 223, 267, 223, 228, 223, 228, 223, 268, - 223, 269, 223, 266, 223, 223, 223, 223, - 228, 223, 53, 223, 265, 265, 223, 37, - 223, 228, 223, 265, 264, 223, 37, 223, - 228, 223, 270, 62, 271, 272, 43, 37, - 223, 228, 223, 62, 271, 272, 43, 37, - 223, 228, 223, 271, 271, 43, 37, 223, - 228, 223, 273, 59, 274, 275, 46, 37, - 223, 228, 223, 59, 274, 275, 46, 37, - 223, 228, 223, 274, 274, 46, 37, 223, - 228, 223, 276, 56, 277, 278, 49, 37, - 223, 228, 223, 56, 277, 278, 49, 37, - 223, 228, 223, 277, 277, 49, 37, 223, - 228, 223, 279, 53, 265, 280, 223, 37, - 223, 228, 223, 53, 265, 280, 223, 37, - 223, 228, 223, 259, 263, 263, 40, 37, - 223, 228, 223, 258, 259, 263, 263, 40, - 37, 223, 228, 223, 223, 223, 223, 223, - 223, 229, 223, 258, 259, 260, 263, 40, - 37, 223, 228, 223, 223, 63, 223, 223, - 223, 229, 223, 256, 223, 281, 223, 265, - 265, 223, 37, 223, 228, 223, 223, 223, - 223, 223, 256, 223, 256, 223, 223, 223, - 265, 265, 223, 37, 223, 228, 223, 223, - 223, 223, 223, 256, 223, 256, 223, 223, - 223, 265, 257, 223, 37, 223, 228, 223, - 223, 223, 223, 223, 256, 223, 250, 251, - 255, 255, 40, 37, 223, 228, 223, 223, - 223, 223, 223, 223, 229, 223, 250, 251, - 252, 255, 40, 37, 223, 228, 223, 223, - 65, 223, 223, 223, 229, 223, 248, 223, - 282, 223, 265, 265, 223, 37, 223, 228, - 223, 223, 223, 223, 223, 248, 223, 248, - 223, 223, 223, 265, 265, 223, 37, 223, - 228, 223, 223, 223, 223, 223, 248, 223, - 248, 223, 223, 223, 265, 249, 223, 37, - 223, 228, 223, 223, 223, 223, 223, 248, - 223, 242, 243, 247, 247, 40, 37, 223, - 228, 223, 223, 223, 223, 223, 223, 229, - 223, 242, 243, 244, 247, 40, 37, 223, - 228, 223, 223, 67, 223, 223, 223, 229, - 223, 240, 223, 283, 223, 265, 265, 223, - 37, 223, 228, 223, 223, 223, 223, 223, - 240, 223, 240, 223, 223, 223, 265, 265, - 223, 37, 223, 228, 223, 223, 223, 223, - 223, 240, 223, 240, 223, 223, 223, 265, - 241, 223, 37, 223, 228, 223, 223, 223, - 223, 223, 240, 223, 234, 235, 239, 239, - 40, 37, 223, 228, 223, 223, 223, 223, - 223, 223, 229, 223, 234, 235, 236, 239, - 40, 37, 223, 228, 223, 223, 69, 223, - 223, 223, 229, 223, 232, 223, 284, 223, - 265, 265, 223, 37, 223, 228, 223, 223, - 223, 223, 223, 232, 223, 232, 223, 223, - 223, 265, 265, 223, 37, 223, 228, 223, - 223, 223, 223, 223, 232, 223, 232, 223, - 223, 223, 265, 233, 223, 37, 223, 228, - 223, 223, 223, 223, 223, 232, 223, 70, - 39, 39, 40, 37, 223, 224, 225, 231, - 227, 40, 37, 223, 228, 223, 223, 223, - 223, 223, 223, 229, 223, 286, 151, 287, - 287, 76, 73, 285, 154, 285, 285, 285, - 285, 285, 285, 158, 285, 151, 287, 287, - 76, 73, 285, 154, 285, 285, 285, 285, - 285, 285, 158, 285, 288, 285, 285, 285, - 90, 289, 285, 73, 285, 154, 285, 285, - 285, 285, 285, 288, 285, 290, 291, 292, - 293, 76, 73, 285, 154, 285, 285, 106, - 285, 285, 285, 158, 285, 294, 291, 295, - 295, 76, 73, 285, 154, 285, 285, 285, - 285, 285, 285, 158, 285, 291, 295, 295, - 76, 73, 285, 154, 285, 285, 285, 285, - 285, 285, 158, 285, 296, 285, 285, 285, - 90, 297, 285, 73, 285, 154, 285, 285, - 285, 285, 285, 296, 285, 298, 299, 300, - 301, 76, 73, 285, 154, 285, 285, 104, - 285, 285, 285, 158, 285, 302, 299, 303, - 303, 76, 73, 285, 154, 285, 285, 285, - 285, 285, 285, 158, 285, 299, 303, 303, - 76, 73, 285, 154, 285, 285, 285, 285, - 285, 285, 158, 285, 304, 285, 285, 285, - 90, 305, 285, 73, 285, 154, 285, 285, - 285, 285, 285, 304, 285, 306, 307, 308, - 309, 76, 73, 285, 154, 285, 285, 102, - 285, 285, 285, 158, 285, 310, 307, 311, - 311, 76, 73, 285, 154, 285, 285, 285, - 285, 285, 285, 158, 285, 307, 311, 311, - 76, 73, 285, 154, 285, 285, 285, 285, - 285, 285, 158, 285, 312, 285, 285, 285, - 90, 313, 285, 73, 285, 154, 285, 285, - 285, 285, 285, 312, 285, 314, 315, 316, - 317, 76, 73, 285, 154, 285, 285, 100, - 285, 285, 285, 158, 285, 318, 315, 319, - 319, 76, 73, 285, 154, 285, 285, 285, - 285, 285, 285, 158, 285, 315, 319, 319, - 76, 73, 285, 154, 285, 285, 285, 285, - 285, 285, 158, 285, 90, 320, 285, 73, - 285, 154, 285, 321, 321, 285, 73, 285, - 154, 285, 322, 285, 285, 323, 285, 154, - 285, 154, 285, 324, 285, 325, 285, 322, - 285, 285, 285, 285, 154, 285, 90, 285, - 321, 321, 285, 73, 285, 154, 285, 321, - 320, 285, 73, 285, 154, 285, 326, 99, - 327, 328, 80, 73, 285, 154, 285, 99, - 327, 328, 80, 73, 285, 154, 285, 327, - 327, 80, 73, 285, 154, 285, 329, 96, - 330, 331, 83, 73, 285, 154, 285, 96, - 330, 331, 83, 73, 285, 154, 285, 330, - 330, 83, 73, 285, 154, 285, 332, 93, - 333, 334, 86, 73, 285, 154, 285, 93, - 333, 334, 86, 73, 285, 154, 285, 333, - 333, 86, 73, 285, 154, 285, 335, 90, - 321, 336, 285, 73, 285, 154, 285, 90, - 321, 336, 285, 73, 285, 154, 285, 315, - 319, 319, 76, 73, 285, 154, 285, 314, - 315, 319, 319, 76, 73, 285, 154, 285, - 285, 285, 285, 285, 285, 158, 285, 314, - 315, 316, 319, 76, 73, 285, 154, 285, - 285, 100, 285, 285, 285, 158, 285, 312, - 285, 337, 285, 321, 321, 285, 73, 285, - 154, 285, 285, 285, 285, 285, 312, 285, - 312, 285, 285, 285, 321, 321, 285, 73, - 285, 154, 285, 285, 285, 285, 285, 312, - 285, 312, 285, 285, 285, 321, 313, 285, - 73, 285, 154, 285, 285, 285, 285, 285, - 312, 285, 306, 307, 311, 311, 76, 73, - 285, 154, 285, 285, 285, 285, 285, 285, - 158, 285, 306, 307, 308, 311, 76, 73, - 285, 154, 285, 285, 102, 285, 285, 285, - 158, 285, 304, 285, 338, 285, 321, 321, - 285, 73, 285, 154, 285, 285, 285, 285, - 285, 304, 285, 304, 285, 285, 285, 321, - 321, 285, 73, 285, 154, 285, 285, 285, - 285, 285, 304, 285, 304, 285, 285, 285, - 321, 305, 285, 73, 285, 154, 285, 285, - 285, 285, 285, 304, 285, 298, 299, 303, - 303, 76, 73, 285, 154, 285, 285, 285, - 285, 285, 285, 158, 285, 298, 299, 300, - 303, 76, 73, 285, 154, 285, 285, 104, - 285, 285, 285, 158, 285, 296, 285, 339, - 285, 321, 321, 285, 73, 285, 154, 285, - 285, 285, 285, 285, 296, 285, 296, 285, - 285, 285, 321, 321, 285, 73, 285, 154, - 285, 285, 285, 285, 285, 296, 285, 296, - 285, 285, 285, 321, 297, 285, 73, 285, - 154, 285, 285, 285, 285, 285, 296, 285, - 290, 291, 295, 295, 76, 73, 285, 154, - 285, 285, 285, 285, 285, 285, 158, 285, - 290, 291, 292, 295, 76, 73, 285, 154, - 285, 285, 106, 285, 285, 285, 158, 285, - 288, 285, 340, 285, 321, 321, 285, 73, - 285, 154, 285, 285, 285, 285, 285, 288, - 285, 288, 285, 285, 285, 321, 321, 285, - 73, 285, 154, 285, 285, 285, 285, 285, - 288, 285, 288, 285, 285, 285, 321, 289, - 285, 73, 285, 154, 285, 285, 285, 285, - 285, 288, 285, 107, 75, 75, 76, 73, - 341, 341, 341, 341, 144, 341, 150, 151, - 287, 287, 76, 73, 285, 154, 285, 285, - 285, 285, 285, 285, 158, 285, 107, 75, - 75, 76, 73, 341, 343, 344, 345, 346, - 112, 109, 342, 347, 342, 342, 143, 342, - 342, 342, 348, 342, 349, 344, 346, 346, - 112, 109, 342, 347, 342, 342, 342, 342, - 342, 342, 348, 342, 344, 346, 346, 112, - 109, 342, 347, 342, 342, 342, 342, 342, - 342, 348, 342, 350, 342, 342, 342, 125, - 351, 342, 109, 342, 347, 342, 342, 342, - 342, 342, 350, 342, 352, 353, 354, 355, - 112, 109, 342, 347, 342, 342, 141, 342, - 342, 342, 348, 342, 356, 353, 357, 357, - 112, 109, 342, 347, 342, 342, 342, 342, - 342, 342, 348, 342, 353, 357, 357, 112, - 109, 342, 347, 342, 342, 342, 342, 342, - 342, 348, 342, 358, 342, 342, 342, 125, - 359, 342, 109, 342, 347, 342, 342, 342, - 342, 342, 358, 342, 360, 361, 362, 363, - 112, 109, 342, 347, 342, 342, 139, 342, - 342, 342, 348, 342, 364, 361, 365, 365, - 112, 109, 342, 347, 342, 342, 342, 342, - 342, 342, 348, 342, 361, 365, 365, 112, - 109, 342, 347, 342, 342, 342, 342, 342, - 342, 348, 342, 366, 342, 342, 342, 125, - 367, 342, 109, 342, 347, 342, 342, 342, - 342, 342, 366, 342, 368, 369, 370, 371, - 112, 109, 342, 347, 342, 342, 137, 342, - 342, 342, 348, 342, 372, 369, 373, 373, - 112, 109, 342, 347, 342, 342, 342, 342, - 342, 342, 348, 342, 369, 373, 373, 112, - 109, 342, 347, 342, 342, 342, 342, 342, - 342, 348, 342, 374, 342, 342, 342, 125, - 375, 342, 109, 342, 347, 342, 342, 342, - 342, 342, 374, 342, 376, 377, 378, 379, - 112, 109, 342, 347, 342, 342, 135, 342, - 342, 342, 348, 342, 380, 377, 381, 381, - 112, 109, 342, 347, 342, 342, 342, 342, - 342, 342, 348, 342, 377, 381, 381, 112, - 109, 342, 347, 342, 342, 342, 342, 342, - 342, 348, 342, 125, 382, 342, 109, 342, - 347, 342, 383, 383, 342, 109, 342, 347, - 342, 384, 342, 342, 385, 342, 347, 342, - 347, 342, 386, 342, 387, 342, 384, 342, - 342, 342, 342, 347, 342, 125, 342, 383, - 383, 342, 109, 342, 347, 342, 383, 382, - 342, 109, 342, 347, 342, 388, 134, 389, - 390, 115, 109, 342, 347, 342, 134, 389, - 390, 115, 109, 342, 347, 342, 389, 389, - 115, 109, 342, 347, 342, 391, 131, 392, - 393, 118, 109, 342, 347, 342, 131, 392, - 393, 118, 109, 342, 347, 342, 392, 392, - 118, 109, 342, 347, 342, 394, 128, 395, - 396, 121, 109, 342, 347, 342, 128, 395, - 396, 121, 109, 342, 347, 342, 395, 395, - 121, 109, 342, 347, 342, 397, 125, 383, - 398, 342, 109, 342, 347, 342, 125, 383, - 398, 342, 109, 342, 347, 342, 377, 381, - 381, 112, 109, 342, 347, 342, 376, 377, - 381, 381, 112, 109, 342, 347, 342, 342, - 342, 342, 342, 342, 348, 342, 376, 377, - 378, 381, 112, 109, 342, 347, 342, 342, - 135, 342, 342, 342, 348, 342, 374, 342, - 399, 342, 383, 383, 342, 109, 342, 347, - 342, 342, 342, 342, 342, 374, 342, 374, - 342, 342, 342, 383, 383, 342, 109, 342, - 347, 342, 342, 342, 342, 342, 374, 342, - 374, 342, 342, 342, 383, 375, 342, 109, - 342, 347, 342, 342, 342, 342, 342, 374, - 342, 368, 369, 373, 373, 112, 109, 342, - 347, 342, 342, 342, 342, 342, 342, 348, - 342, 368, 369, 370, 373, 112, 109, 342, - 347, 342, 342, 137, 342, 342, 342, 348, - 342, 366, 342, 400, 342, 383, 383, 342, - 109, 342, 347, 342, 342, 342, 342, 342, - 366, 342, 366, 342, 342, 342, 383, 383, - 342, 109, 342, 347, 342, 342, 342, 342, - 342, 366, 342, 366, 342, 342, 342, 383, - 367, 342, 109, 342, 347, 342, 342, 342, - 342, 342, 366, 342, 360, 361, 365, 365, - 112, 109, 342, 347, 342, 342, 342, 342, - 342, 342, 348, 342, 360, 361, 362, 365, - 112, 109, 342, 347, 342, 342, 139, 342, - 342, 342, 348, 342, 358, 342, 401, 342, - 383, 383, 342, 109, 342, 347, 342, 342, - 342, 342, 342, 358, 342, 358, 342, 342, - 342, 383, 383, 342, 109, 342, 347, 342, - 342, 342, 342, 342, 358, 342, 358, 342, - 342, 342, 383, 359, 342, 109, 342, 347, - 342, 342, 342, 342, 342, 358, 342, 352, - 353, 357, 357, 112, 109, 342, 347, 342, - 342, 342, 342, 342, 342, 348, 342, 352, - 353, 354, 357, 112, 109, 342, 347, 342, - 342, 141, 342, 342, 342, 348, 342, 350, - 342, 402, 342, 383, 383, 342, 109, 342, - 347, 342, 342, 342, 342, 342, 350, 342, - 350, 342, 342, 342, 383, 383, 342, 109, - 342, 347, 342, 342, 342, 342, 342, 350, - 342, 350, 342, 342, 342, 383, 351, 342, - 109, 342, 347, 342, 342, 342, 342, 342, - 350, 342, 343, 344, 346, 346, 112, 109, - 342, 347, 342, 342, 342, 342, 342, 342, - 348, 342, 148, 149, 150, 151, 403, 287, - 76, 73, 285, 154, 155, 155, 144, 285, - 285, 148, 158, 285, 162, 404, 164, 165, - 4, 1, 161, 166, 161, 161, 35, 161, - 161, 161, 167, 161, 170, 149, 150, 151, - 405, 406, 76, 407, 161, 408, 161, 155, - 144, 161, 161, 170, 158, 161, 107, 409, - 409, 76, 407, 161, 166, 161, 161, 144, - 161, 410, 161, 161, 411, 161, 408, 161, - 408, 161, 412, 161, 207, 161, 410, 161, - 161, 161, 161, 408, 161, 170, 161, 222, - 107, 409, 409, 76, 407, 161, 166, 161, - 161, 161, 161, 161, 170, 161, 414, 413, - 415, 415, 413, 146, 413, 416, 413, 415, - 415, 413, 146, 413, 416, 413, 417, 413, - 413, 418, 413, 416, 413, 416, 413, 419, - 413, 420, 413, 417, 413, 413, 413, 413, - 416, 413, 148, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 155, 341, 341, 341, - 341, 148, 341, 0 + 1, 2, 3, 3, 4, 1, 5, 5, + 4, 4, 6, 6, 7, 1, 8, 8, + 7, 7, 9, 9, 10, 1, 11, 11, + 10, 10, 12, 12, 13, 1, 14, 14, + 13, 13, 15, 0, 0, 0, 1, 16, + 17, 18, 12, 12, 13, 1, 19, 20, + 21, 9, 9, 10, 1, 22, 23, 24, + 6, 6, 7, 1, 25, 26, 2, 3, + 3, 4, 1, 0, 0, 0, 0, 27, + 28, 3, 3, 4, 1, 28, 3, 3, + 4, 1, 0, 0, 0, 0, 29, 30, + 3, 3, 4, 1, 30, 3, 3, 4, + 1, 0, 0, 0, 0, 31, 32, 3, + 3, 4, 1, 32, 3, 3, 4, 1, + 0, 0, 0, 0, 33, 34, 3, 3, + 4, 1, 34, 3, 3, 4, 1, 0, + 0, 0, 0, 35, 37, 38, 39, 39, + 40, 37, 41, 41, 40, 40, 42, 42, + 43, 37, 44, 44, 43, 43, 45, 45, + 46, 37, 47, 47, 46, 46, 48, 48, + 49, 37, 50, 50, 49, 49, 51, 36, + 36, 36, 37, 52, 53, 54, 48, 48, + 49, 37, 55, 56, 57, 45, 45, 46, + 37, 58, 59, 60, 42, 42, 43, 37, + 61, 62, 38, 39, 39, 40, 37, 36, + 36, 36, 36, 63, 64, 39, 39, 40, + 37, 64, 39, 39, 40, 37, 36, 36, + 36, 36, 65, 66, 39, 39, 40, 37, + 66, 39, 39, 40, 37, 36, 36, 36, + 36, 67, 68, 39, 39, 40, 37, 68, + 39, 39, 40, 37, 36, 36, 36, 36, + 69, 70, 39, 39, 40, 37, 70, 39, + 39, 40, 37, 36, 36, 36, 36, 71, + 73, 74, 75, 75, 76, 73, 78, 78, + 76, 76, 79, 79, 80, 73, 81, 81, + 80, 80, 82, 82, 83, 73, 84, 84, + 83, 83, 85, 85, 86, 73, 87, 87, + 86, 86, 88, 72, 72, 72, 73, 89, + 90, 91, 85, 85, 86, 73, 92, 93, + 94, 82, 82, 83, 73, 95, 96, 97, + 79, 79, 80, 73, 98, 99, 74, 75, + 75, 76, 73, 72, 72, 72, 72, 100, + 101, 75, 75, 76, 73, 101, 75, 75, + 76, 73, 72, 72, 72, 72, 102, 103, + 75, 75, 76, 73, 103, 75, 75, 76, + 73, 72, 72, 72, 72, 104, 105, 75, + 75, 76, 73, 105, 75, 75, 76, 73, + 72, 72, 72, 72, 106, 107, 75, 75, + 76, 73, 109, 110, 111, 111, 112, 109, + 113, 113, 112, 112, 114, 114, 115, 109, + 116, 116, 115, 115, 117, 117, 118, 109, + 119, 119, 118, 118, 120, 120, 121, 109, + 122, 122, 121, 121, 123, 108, 108, 108, + 109, 124, 125, 126, 120, 120, 121, 109, + 127, 128, 129, 117, 117, 118, 109, 130, + 131, 132, 114, 114, 115, 109, 133, 134, + 110, 111, 111, 112, 109, 108, 108, 108, + 108, 135, 136, 111, 111, 112, 109, 136, + 111, 111, 112, 109, 108, 108, 108, 108, + 137, 138, 111, 111, 112, 109, 138, 111, + 111, 112, 109, 108, 108, 108, 108, 139, + 140, 111, 111, 112, 109, 140, 111, 111, + 112, 109, 108, 108, 108, 108, 141, 142, + 111, 111, 112, 109, 142, 111, 111, 112, + 109, 108, 108, 108, 108, 143, 107, 75, + 75, 76, 73, 72, 72, 72, 72, 144, + 78, 78, 76, 1, 146, 148, 149, 150, + 151, 152, 153, 76, 73, 147, 154, 155, + 155, 144, 156, 157, 158, 159, 160, 162, + 163, 164, 165, 4, 1, 161, 166, 161, + 161, 35, 161, 161, 167, 168, 163, 169, + 169, 4, 1, 161, 166, 161, 161, 161, + 161, 161, 167, 163, 169, 169, 4, 1, + 161, 166, 161, 161, 161, 161, 161, 167, + 170, 161, 161, 161, 17, 171, 161, 1, + 161, 166, 161, 161, 161, 161, 170, 172, + 173, 174, 175, 4, 1, 161, 166, 161, + 161, 33, 161, 161, 167, 176, 173, 177, + 177, 4, 1, 161, 166, 161, 161, 161, + 161, 161, 167, 173, 177, 177, 4, 1, + 161, 166, 161, 161, 161, 161, 161, 167, + 178, 161, 161, 161, 17, 179, 161, 1, + 161, 166, 161, 161, 161, 161, 178, 180, + 181, 182, 183, 4, 1, 161, 166, 161, + 161, 31, 161, 161, 167, 184, 181, 185, + 185, 4, 1, 161, 166, 161, 161, 161, + 161, 161, 167, 181, 185, 185, 4, 1, + 161, 166, 161, 161, 161, 161, 161, 167, + 186, 161, 161, 161, 17, 187, 161, 1, + 161, 166, 161, 161, 161, 161, 186, 188, + 189, 190, 191, 4, 1, 161, 166, 161, + 161, 29, 161, 161, 167, 192, 189, 193, + 193, 4, 1, 161, 166, 161, 161, 161, + 161, 161, 167, 189, 193, 193, 4, 1, + 161, 166, 161, 161, 161, 161, 161, 167, + 194, 161, 161, 161, 17, 195, 161, 1, + 161, 166, 161, 161, 161, 161, 194, 196, + 197, 198, 199, 4, 1, 161, 166, 161, + 161, 27, 161, 161, 167, 200, 197, 201, + 201, 4, 1, 161, 166, 161, 161, 161, + 161, 161, 167, 197, 201, 201, 4, 1, + 161, 166, 161, 161, 161, 161, 161, 167, + 17, 202, 161, 1, 161, 166, 203, 203, + 161, 1, 161, 166, 204, 161, 161, 205, + 161, 166, 166, 206, 207, 204, 161, 161, + 161, 161, 166, 17, 161, 203, 203, 161, + 1, 161, 166, 203, 202, 161, 1, 161, + 166, 208, 26, 209, 210, 7, 1, 161, + 166, 26, 209, 210, 7, 1, 161, 166, + 209, 209, 7, 1, 161, 166, 211, 23, + 212, 213, 10, 1, 161, 166, 23, 212, + 213, 10, 1, 161, 166, 212, 212, 10, + 1, 161, 166, 214, 20, 215, 216, 13, + 1, 161, 166, 20, 215, 216, 13, 1, + 161, 166, 215, 215, 13, 1, 161, 166, + 217, 17, 203, 218, 161, 1, 161, 166, + 17, 203, 218, 161, 1, 161, 166, 197, + 201, 201, 4, 1, 161, 166, 196, 197, + 201, 201, 4, 1, 161, 166, 161, 161, + 161, 161, 161, 167, 196, 197, 198, 201, + 4, 1, 161, 166, 161, 161, 27, 161, + 161, 167, 194, 161, 219, 161, 203, 203, + 161, 1, 161, 166, 161, 161, 161, 161, + 194, 194, 161, 161, 161, 203, 203, 161, + 1, 161, 166, 161, 161, 161, 161, 194, + 194, 161, 161, 161, 203, 195, 161, 1, + 161, 166, 161, 161, 161, 161, 194, 188, + 189, 193, 193, 4, 1, 161, 166, 161, + 161, 161, 161, 161, 167, 188, 189, 190, + 193, 4, 1, 161, 166, 161, 161, 29, + 161, 161, 167, 186, 161, 220, 161, 203, + 203, 161, 1, 161, 166, 161, 161, 161, + 161, 186, 186, 161, 161, 161, 203, 203, + 161, 1, 161, 166, 161, 161, 161, 161, + 186, 186, 161, 161, 161, 203, 187, 161, + 1, 161, 166, 161, 161, 161, 161, 186, + 180, 181, 185, 185, 4, 1, 161, 166, + 161, 161, 161, 161, 161, 167, 180, 181, + 182, 185, 4, 1, 161, 166, 161, 161, + 31, 161, 161, 167, 178, 161, 221, 161, + 203, 203, 161, 1, 161, 166, 161, 161, + 161, 161, 178, 178, 161, 161, 161, 203, + 203, 161, 1, 161, 166, 161, 161, 161, + 161, 178, 178, 161, 161, 161, 203, 179, + 161, 1, 161, 166, 161, 161, 161, 161, + 178, 172, 173, 177, 177, 4, 1, 161, + 166, 161, 161, 161, 161, 161, 167, 172, + 173, 174, 177, 4, 1, 161, 166, 161, + 161, 33, 161, 161, 167, 170, 161, 222, + 161, 203, 203, 161, 1, 161, 166, 161, + 161, 161, 161, 170, 170, 161, 161, 161, + 203, 203, 161, 1, 161, 166, 161, 161, + 161, 161, 170, 170, 161, 161, 161, 203, + 171, 161, 1, 161, 166, 161, 161, 161, + 161, 170, 162, 163, 169, 169, 4, 1, + 161, 166, 161, 161, 161, 161, 161, 167, + 162, 163, 164, 169, 4, 1, 161, 166, + 161, 161, 35, 161, 161, 167, 224, 225, + 226, 227, 40, 37, 223, 228, 223, 223, + 71, 223, 223, 229, 230, 225, 231, 227, + 40, 37, 223, 228, 223, 223, 223, 223, + 223, 229, 225, 231, 227, 40, 37, 223, + 228, 223, 223, 223, 223, 223, 229, 232, + 223, 223, 223, 53, 233, 223, 37, 223, + 228, 223, 223, 223, 223, 232, 234, 235, + 236, 237, 40, 37, 223, 228, 223, 223, + 69, 223, 223, 229, 238, 235, 239, 239, + 40, 37, 223, 228, 223, 223, 223, 223, + 223, 229, 235, 239, 239, 40, 37, 223, + 228, 223, 223, 223, 223, 223, 229, 240, + 223, 223, 223, 53, 241, 223, 37, 223, + 228, 223, 223, 223, 223, 240, 242, 243, + 244, 245, 40, 37, 223, 228, 223, 223, + 67, 223, 223, 229, 246, 243, 247, 247, + 40, 37, 223, 228, 223, 223, 223, 223, + 223, 229, 243, 247, 247, 40, 37, 223, + 228, 223, 223, 223, 223, 223, 229, 248, + 223, 223, 223, 53, 249, 223, 37, 223, + 228, 223, 223, 223, 223, 248, 250, 251, + 252, 253, 40, 37, 223, 228, 223, 223, + 65, 223, 223, 229, 254, 251, 255, 255, + 40, 37, 223, 228, 223, 223, 223, 223, + 223, 229, 251, 255, 255, 40, 37, 223, + 228, 223, 223, 223, 223, 223, 229, 256, + 223, 223, 223, 53, 257, 223, 37, 223, + 228, 223, 223, 223, 223, 256, 258, 259, + 260, 261, 40, 37, 223, 228, 223, 223, + 63, 223, 223, 229, 262, 259, 263, 263, + 40, 37, 223, 228, 223, 223, 223, 223, + 223, 229, 259, 263, 263, 40, 37, 223, + 228, 223, 223, 223, 223, 223, 229, 53, + 264, 223, 37, 223, 228, 265, 265, 223, + 37, 223, 228, 266, 223, 223, 267, 223, + 228, 228, 268, 269, 266, 223, 223, 223, + 223, 228, 53, 223, 265, 265, 223, 37, + 223, 228, 265, 264, 223, 37, 223, 228, + 270, 62, 271, 272, 43, 37, 223, 228, + 62, 271, 272, 43, 37, 223, 228, 271, + 271, 43, 37, 223, 228, 273, 59, 274, + 275, 46, 37, 223, 228, 59, 274, 275, + 46, 37, 223, 228, 274, 274, 46, 37, + 223, 228, 276, 56, 277, 278, 49, 37, + 223, 228, 56, 277, 278, 49, 37, 223, + 228, 277, 277, 49, 37, 223, 228, 279, + 53, 265, 280, 223, 37, 223, 228, 53, + 265, 280, 223, 37, 223, 228, 259, 263, + 263, 40, 37, 223, 228, 258, 259, 263, + 263, 40, 37, 223, 228, 223, 223, 223, + 223, 223, 229, 258, 259, 260, 263, 40, + 37, 223, 228, 223, 223, 63, 223, 223, + 229, 256, 223, 281, 223, 265, 265, 223, + 37, 223, 228, 223, 223, 223, 223, 256, + 256, 223, 223, 223, 265, 265, 223, 37, + 223, 228, 223, 223, 223, 223, 256, 256, + 223, 223, 223, 265, 257, 223, 37, 223, + 228, 223, 223, 223, 223, 256, 250, 251, + 255, 255, 40, 37, 223, 228, 223, 223, + 223, 223, 223, 229, 250, 251, 252, 255, + 40, 37, 223, 228, 223, 223, 65, 223, + 223, 229, 248, 223, 282, 223, 265, 265, + 223, 37, 223, 228, 223, 223, 223, 223, + 248, 248, 223, 223, 223, 265, 265, 223, + 37, 223, 228, 223, 223, 223, 223, 248, + 248, 223, 223, 223, 265, 249, 223, 37, + 223, 228, 223, 223, 223, 223, 248, 242, + 243, 247, 247, 40, 37, 223, 228, 223, + 223, 223, 223, 223, 229, 242, 243, 244, + 247, 40, 37, 223, 228, 223, 223, 67, + 223, 223, 229, 240, 223, 283, 223, 265, + 265, 223, 37, 223, 228, 223, 223, 223, + 223, 240, 240, 223, 223, 223, 265, 265, + 223, 37, 223, 228, 223, 223, 223, 223, + 240, 240, 223, 223, 223, 265, 241, 223, + 37, 223, 228, 223, 223, 223, 223, 240, + 234, 235, 239, 239, 40, 37, 223, 228, + 223, 223, 223, 223, 223, 229, 234, 235, + 236, 239, 40, 37, 223, 228, 223, 223, + 69, 223, 223, 229, 232, 223, 284, 223, + 265, 265, 223, 37, 223, 228, 223, 223, + 223, 223, 232, 232, 223, 223, 223, 265, + 265, 223, 37, 223, 228, 223, 223, 223, + 223, 232, 232, 223, 223, 223, 265, 233, + 223, 37, 223, 228, 223, 223, 223, 223, + 232, 70, 39, 39, 40, 37, 224, 225, + 231, 227, 40, 37, 223, 228, 223, 223, + 223, 223, 223, 229, 286, 151, 287, 287, + 76, 73, 285, 154, 285, 285, 285, 285, + 285, 158, 151, 287, 287, 76, 73, 285, + 154, 285, 285, 285, 285, 285, 158, 288, + 285, 285, 285, 90, 289, 285, 73, 285, + 154, 285, 285, 285, 285, 288, 290, 291, + 292, 293, 76, 73, 285, 154, 285, 285, + 106, 285, 285, 158, 294, 291, 295, 295, + 76, 73, 285, 154, 285, 285, 285, 285, + 285, 158, 291, 295, 295, 76, 73, 285, + 154, 285, 285, 285, 285, 285, 158, 296, + 285, 285, 285, 90, 297, 285, 73, 285, + 154, 285, 285, 285, 285, 296, 298, 299, + 300, 301, 76, 73, 285, 154, 285, 285, + 104, 285, 285, 158, 302, 299, 303, 303, + 76, 73, 285, 154, 285, 285, 285, 285, + 285, 158, 299, 303, 303, 76, 73, 285, + 154, 285, 285, 285, 285, 285, 158, 304, + 285, 285, 285, 90, 305, 285, 73, 285, + 154, 285, 285, 285, 285, 304, 306, 307, + 308, 309, 76, 73, 285, 154, 285, 285, + 102, 285, 285, 158, 310, 307, 311, 311, + 76, 73, 285, 154, 285, 285, 285, 285, + 285, 158, 307, 311, 311, 76, 73, 285, + 154, 285, 285, 285, 285, 285, 158, 312, + 285, 285, 285, 90, 313, 285, 73, 285, + 154, 285, 285, 285, 285, 312, 314, 315, + 316, 317, 76, 73, 285, 154, 285, 285, + 100, 285, 285, 158, 318, 315, 319, 319, + 76, 73, 285, 154, 285, 285, 285, 285, + 285, 158, 315, 319, 319, 76, 73, 285, + 154, 285, 285, 285, 285, 285, 158, 90, + 320, 285, 73, 285, 154, 321, 321, 285, + 73, 285, 154, 322, 285, 285, 323, 285, + 154, 154, 324, 325, 322, 285, 285, 285, + 285, 154, 90, 285, 321, 321, 285, 73, + 285, 154, 321, 320, 285, 73, 285, 154, + 326, 99, 327, 328, 80, 73, 285, 154, + 99, 327, 328, 80, 73, 285, 154, 327, + 327, 80, 73, 285, 154, 329, 96, 330, + 331, 83, 73, 285, 154, 96, 330, 331, + 83, 73, 285, 154, 330, 330, 83, 73, + 285, 154, 332, 93, 333, 334, 86, 73, + 285, 154, 93, 333, 334, 86, 73, 285, + 154, 333, 333, 86, 73, 285, 154, 335, + 90, 321, 336, 285, 73, 285, 154, 90, + 321, 336, 285, 73, 285, 154, 315, 319, + 319, 76, 73, 285, 154, 314, 315, 319, + 319, 76, 73, 285, 154, 285, 285, 285, + 285, 285, 158, 314, 315, 316, 319, 76, + 73, 285, 154, 285, 285, 100, 285, 285, + 158, 312, 285, 337, 285, 321, 321, 285, + 73, 285, 154, 285, 285, 285, 285, 312, + 312, 285, 285, 285, 321, 321, 285, 73, + 285, 154, 285, 285, 285, 285, 312, 312, + 285, 285, 285, 321, 313, 285, 73, 285, + 154, 285, 285, 285, 285, 312, 306, 307, + 311, 311, 76, 73, 285, 154, 285, 285, + 285, 285, 285, 158, 306, 307, 308, 311, + 76, 73, 285, 154, 285, 285, 102, 285, + 285, 158, 304, 285, 338, 285, 321, 321, + 285, 73, 285, 154, 285, 285, 285, 285, + 304, 304, 285, 285, 285, 321, 321, 285, + 73, 285, 154, 285, 285, 285, 285, 304, + 304, 285, 285, 285, 321, 305, 285, 73, + 285, 154, 285, 285, 285, 285, 304, 298, + 299, 303, 303, 76, 73, 285, 154, 285, + 285, 285, 285, 285, 158, 298, 299, 300, + 303, 76, 73, 285, 154, 285, 285, 104, + 285, 285, 158, 296, 285, 339, 285, 321, + 321, 285, 73, 285, 154, 285, 285, 285, + 285, 296, 296, 285, 285, 285, 321, 321, + 285, 73, 285, 154, 285, 285, 285, 285, + 296, 296, 285, 285, 285, 321, 297, 285, + 73, 285, 154, 285, 285, 285, 285, 296, + 290, 291, 295, 295, 76, 73, 285, 154, + 285, 285, 285, 285, 285, 158, 290, 291, + 292, 295, 76, 73, 285, 154, 285, 285, + 106, 285, 285, 158, 288, 285, 340, 285, + 321, 321, 285, 73, 285, 154, 285, 285, + 285, 285, 288, 288, 285, 285, 285, 321, + 321, 285, 73, 285, 154, 285, 285, 285, + 285, 288, 288, 285, 285, 285, 321, 289, + 285, 73, 285, 154, 285, 285, 285, 285, + 288, 107, 75, 75, 76, 73, 341, 341, + 341, 341, 144, 150, 151, 287, 287, 76, + 73, 285, 154, 285, 285, 285, 285, 285, + 158, 107, 75, 75, 76, 73, 343, 344, + 345, 346, 112, 109, 342, 347, 342, 342, + 143, 342, 342, 348, 349, 344, 346, 346, + 112, 109, 342, 347, 342, 342, 342, 342, + 342, 348, 344, 346, 346, 112, 109, 342, + 347, 342, 342, 342, 342, 342, 348, 350, + 342, 342, 342, 125, 351, 342, 109, 342, + 347, 342, 342, 342, 342, 350, 352, 353, + 354, 355, 112, 109, 342, 347, 342, 342, + 141, 342, 342, 348, 356, 353, 357, 357, + 112, 109, 342, 347, 342, 342, 342, 342, + 342, 348, 353, 357, 357, 112, 109, 342, + 347, 342, 342, 342, 342, 342, 348, 358, + 342, 342, 342, 125, 359, 342, 109, 342, + 347, 342, 342, 342, 342, 358, 360, 361, + 362, 363, 112, 109, 342, 347, 342, 342, + 139, 342, 342, 348, 364, 361, 365, 365, + 112, 109, 342, 347, 342, 342, 342, 342, + 342, 348, 361, 365, 365, 112, 109, 342, + 347, 342, 342, 342, 342, 342, 348, 366, + 342, 342, 342, 125, 367, 342, 109, 342, + 347, 342, 342, 342, 342, 366, 368, 369, + 370, 371, 112, 109, 342, 347, 342, 342, + 137, 342, 342, 348, 372, 369, 373, 373, + 112, 109, 342, 347, 342, 342, 342, 342, + 342, 348, 369, 373, 373, 112, 109, 342, + 347, 342, 342, 342, 342, 342, 348, 374, + 342, 342, 342, 125, 375, 342, 109, 342, + 347, 342, 342, 342, 342, 374, 376, 377, + 378, 379, 112, 109, 342, 347, 342, 342, + 135, 342, 342, 348, 380, 377, 381, 381, + 112, 109, 342, 347, 342, 342, 342, 342, + 342, 348, 377, 381, 381, 112, 109, 342, + 347, 342, 342, 342, 342, 342, 348, 125, + 382, 342, 109, 342, 347, 383, 383, 342, + 109, 342, 347, 384, 342, 342, 385, 342, + 347, 347, 386, 387, 384, 342, 342, 342, + 342, 347, 125, 342, 383, 383, 342, 109, + 342, 347, 383, 382, 342, 109, 342, 347, + 388, 134, 389, 390, 115, 109, 342, 347, + 134, 389, 390, 115, 109, 342, 347, 389, + 389, 115, 109, 342, 347, 391, 131, 392, + 393, 118, 109, 342, 347, 131, 392, 393, + 118, 109, 342, 347, 392, 392, 118, 109, + 342, 347, 394, 128, 395, 396, 121, 109, + 342, 347, 128, 395, 396, 121, 109, 342, + 347, 395, 395, 121, 109, 342, 347, 397, + 125, 383, 398, 342, 109, 342, 347, 125, + 383, 398, 342, 109, 342, 347, 377, 381, + 381, 112, 109, 342, 347, 376, 377, 381, + 381, 112, 109, 342, 347, 342, 342, 342, + 342, 342, 348, 376, 377, 378, 381, 112, + 109, 342, 347, 342, 342, 135, 342, 342, + 348, 374, 342, 399, 342, 383, 383, 342, + 109, 342, 347, 342, 342, 342, 342, 374, + 374, 342, 342, 342, 383, 383, 342, 109, + 342, 347, 342, 342, 342, 342, 374, 374, + 342, 342, 342, 383, 375, 342, 109, 342, + 347, 342, 342, 342, 342, 374, 368, 369, + 373, 373, 112, 109, 342, 347, 342, 342, + 342, 342, 342, 348, 368, 369, 370, 373, + 112, 109, 342, 347, 342, 342, 137, 342, + 342, 348, 366, 342, 400, 342, 383, 383, + 342, 109, 342, 347, 342, 342, 342, 342, + 366, 366, 342, 342, 342, 383, 383, 342, + 109, 342, 347, 342, 342, 342, 342, 366, + 366, 342, 342, 342, 383, 367, 342, 109, + 342, 347, 342, 342, 342, 342, 366, 360, + 361, 365, 365, 112, 109, 342, 347, 342, + 342, 342, 342, 342, 348, 360, 361, 362, + 365, 112, 109, 342, 347, 342, 342, 139, + 342, 342, 348, 358, 342, 401, 342, 383, + 383, 342, 109, 342, 347, 342, 342, 342, + 342, 358, 358, 342, 342, 342, 383, 383, + 342, 109, 342, 347, 342, 342, 342, 342, + 358, 358, 342, 342, 342, 383, 359, 342, + 109, 342, 347, 342, 342, 342, 342, 358, + 352, 353, 357, 357, 112, 109, 342, 347, + 342, 342, 342, 342, 342, 348, 352, 353, + 354, 357, 112, 109, 342, 347, 342, 342, + 141, 342, 342, 348, 350, 342, 402, 342, + 383, 383, 342, 109, 342, 347, 342, 342, + 342, 342, 350, 350, 342, 342, 342, 383, + 383, 342, 109, 342, 347, 342, 342, 342, + 342, 350, 350, 342, 342, 342, 383, 351, + 342, 109, 342, 347, 342, 342, 342, 342, + 350, 343, 344, 346, 346, 112, 109, 342, + 347, 342, 342, 342, 342, 342, 348, 148, + 149, 150, 151, 403, 287, 76, 73, 285, + 154, 155, 155, 144, 285, 148, 158, 162, + 404, 164, 165, 4, 1, 161, 166, 161, + 161, 35, 161, 161, 167, 170, 149, 150, + 151, 405, 406, 76, 407, 161, 408, 161, + 155, 144, 161, 170, 158, 107, 409, 409, + 76, 407, 161, 166, 161, 161, 144, 410, + 161, 161, 411, 161, 408, 408, 412, 207, + 410, 161, 161, 161, 161, 408, 170, 161, + 222, 107, 409, 409, 76, 407, 161, 166, + 161, 161, 161, 161, 170, 414, 413, 415, + 415, 413, 146, 413, 416, 415, 415, 413, + 146, 413, 416, 417, 413, 413, 418, 413, + 416, 416, 419, 420, 417, 413, 413, 413, + 413, 416, 148, 341, 341, 341, 341, 341, + 341, 341, 341, 341, 155, 341, 341, 341, + 148, 0 }; -static const short _indic_syllable_machine_trans_targs[] = { - 138, 160, 166, 2, 167, 3, 5, 170, - 6, 8, 173, 9, 11, 176, 12, 14, - 15, 159, 17, 18, 175, 20, 21, 172, - 23, 24, 169, 179, 183, 184, 188, 189, - 193, 194, 198, 199, 138, 222, 228, 36, - 229, 37, 39, 232, 40, 42, 235, 43, - 45, 238, 46, 48, 49, 221, 51, 52, - 237, 54, 55, 234, 57, 58, 231, 241, - 245, 246, 250, 251, 255, 256, 260, 262, - 138, 283, 289, 70, 290, 138, 71, 73, - 293, 74, 76, 296, 77, 79, 299, 80, - 82, 83, 282, 85, 86, 298, 88, 89, - 295, 91, 92, 292, 302, 306, 307, 311, - 312, 316, 317, 321, 138, 346, 352, 103, - 353, 104, 106, 356, 107, 109, 359, 110, - 112, 362, 113, 115, 116, 345, 118, 119, - 361, 121, 122, 358, 124, 125, 355, 365, - 369, 370, 374, 375, 379, 380, 384, 385, - 323, 138, 398, 138, 139, 201, 263, 265, - 322, 324, 285, 325, 386, 387, 301, 396, - 403, 138, 140, 142, 33, 200, 162, 178, - 141, 32, 143, 196, 144, 146, 31, 195, - 145, 30, 147, 191, 148, 150, 29, 190, - 149, 28, 151, 186, 152, 154, 27, 185, - 153, 26, 155, 181, 156, 158, 25, 180, - 157, 1, 165, 0, 161, 164, 163, 138, - 168, 4, 22, 171, 7, 19, 174, 10, - 16, 177, 13, 182, 187, 192, 197, 138, - 202, 204, 67, 261, 224, 240, 203, 66, - 205, 258, 206, 208, 65, 257, 207, 64, - 209, 253, 210, 212, 63, 252, 211, 62, - 213, 248, 214, 216, 61, 247, 215, 60, - 217, 243, 218, 220, 59, 242, 219, 35, - 227, 34, 223, 226, 225, 138, 230, 38, - 56, 233, 41, 53, 236, 44, 50, 239, - 47, 244, 249, 254, 259, 138, 264, 100, - 266, 319, 267, 269, 99, 318, 268, 98, - 270, 314, 271, 273, 97, 313, 272, 96, - 274, 309, 275, 277, 95, 308, 276, 94, - 278, 304, 279, 281, 93, 303, 280, 69, - 288, 68, 284, 287, 286, 138, 291, 72, - 90, 294, 75, 87, 297, 78, 84, 300, - 81, 305, 310, 315, 320, 138, 138, 326, - 328, 134, 133, 348, 364, 327, 329, 382, - 330, 332, 132, 381, 331, 131, 333, 377, - 334, 336, 130, 376, 335, 129, 337, 372, - 338, 340, 128, 371, 339, 127, 341, 367, - 342, 344, 126, 366, 343, 102, 351, 101, - 347, 350, 349, 138, 354, 105, 123, 357, - 108, 120, 360, 111, 117, 363, 114, 368, - 373, 378, 383, 135, 388, 389, 395, 390, - 392, 136, 391, 394, 393, 138, 397, 137, - 400, 399, 402, 401, 138 +static const short _indic_syllable_machine_index_defaults[] = { + 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, + 0, 0, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 72, 72, 77, 77, + 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 72, + 0, 145, 147, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, 341, 285, 341, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 285, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 413, 413, 413, 413, + 413, 413, 413, 341, 0 }; -static const char _indic_syllable_machine_trans_actions[] = { - 1, 0, 2, 0, 2, 0, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 0, - 0, 2, 0, 0, 2, 0, 0, 2, - 0, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 3, 0, 2, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 4, 0, 2, 0, 2, 5, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 6, 2, 6, 2, - 6, 2, 6, 2, 7, 0, 2, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 6, 8, 0, 11, 2, 2, 6, 0, - 12, 12, 0, 2, 6, 2, 6, 2, - 0, 13, 2, 0, 0, 2, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 2, 2, 0, 0, 2, - 2, 0, 2, 0, 0, 0, 0, 14, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 2, 2, 2, 2, 15, - 2, 0, 0, 2, 0, 2, 2, 0, - 2, 2, 2, 0, 0, 2, 2, 0, - 2, 2, 2, 0, 0, 2, 2, 0, - 2, 2, 2, 0, 0, 2, 2, 0, - 2, 2, 2, 0, 0, 2, 2, 0, - 2, 0, 0, 0, 0, 16, 2, 0, - 0, 2, 0, 0, 2, 0, 0, 2, - 0, 2, 2, 2, 2, 17, 6, 0, - 6, 2, 6, 0, 0, 6, 6, 0, - 6, 2, 6, 0, 0, 6, 6, 0, - 6, 2, 6, 0, 0, 6, 6, 0, - 6, 2, 6, 0, 0, 6, 6, 0, - 2, 0, 0, 0, 0, 18, 2, 0, - 0, 2, 0, 0, 2, 0, 0, 2, - 0, 2, 2, 2, 2, 19, 20, 2, - 0, 0, 0, 0, 2, 2, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 2, - 2, 0, 0, 2, 2, 0, 2, 0, - 0, 0, 0, 21, 2, 0, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 2, - 2, 2, 2, 0, 0, 22, 22, 0, - 0, 0, 0, 0, 0, 23, 2, 0, - 0, 0, 0, 0, 24 +static const char _indic_syllable_machine_trans_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 0 +}; + +static const short _indic_syllable_machine_cond_targs[] = { + 138, 160, 166, 2, 167, 3, 5, 170, + 6, 8, 173, 9, 11, 176, 12, 14, + 15, 159, 17, 18, 175, 20, 21, 172, + 23, 24, 169, 179, 183, 184, 188, 189, + 193, 194, 198, 199, 138, 222, 228, 36, + 229, 37, 39, 232, 40, 42, 235, 43, + 45, 238, 46, 48, 49, 221, 51, 52, + 237, 54, 55, 234, 57, 58, 231, 241, + 245, 246, 250, 251, 255, 256, 260, 262, + 138, 283, 289, 70, 290, 138, 71, 73, + 293, 74, 76, 296, 77, 79, 299, 80, + 82, 83, 282, 85, 86, 298, 88, 89, + 295, 91, 92, 292, 302, 306, 307, 311, + 312, 316, 317, 321, 138, 346, 352, 103, + 353, 104, 106, 356, 107, 109, 359, 110, + 112, 362, 113, 115, 116, 345, 118, 119, + 361, 121, 122, 358, 124, 125, 355, 365, + 369, 370, 374, 375, 379, 380, 384, 385, + 323, 138, 398, 138, 139, 201, 263, 265, + 322, 324, 285, 325, 386, 387, 301, 396, + 403, 138, 140, 142, 33, 200, 162, 178, + 141, 32, 143, 196, 144, 146, 31, 195, + 145, 30, 147, 191, 148, 150, 29, 190, + 149, 28, 151, 186, 152, 154, 27, 185, + 153, 26, 155, 181, 156, 158, 25, 180, + 157, 1, 165, 0, 161, 164, 163, 138, + 168, 4, 22, 171, 7, 19, 174, 10, + 16, 177, 13, 182, 187, 192, 197, 138, + 202, 204, 67, 261, 224, 240, 203, 66, + 205, 258, 206, 208, 65, 257, 207, 64, + 209, 253, 210, 212, 63, 252, 211, 62, + 213, 248, 214, 216, 61, 247, 215, 60, + 217, 243, 218, 220, 59, 242, 219, 35, + 227, 34, 223, 226, 225, 138, 230, 38, + 56, 233, 41, 53, 236, 44, 50, 239, + 47, 244, 249, 254, 259, 138, 264, 100, + 266, 319, 267, 269, 99, 318, 268, 98, + 270, 314, 271, 273, 97, 313, 272, 96, + 274, 309, 275, 277, 95, 308, 276, 94, + 278, 304, 279, 281, 93, 303, 280, 69, + 288, 68, 284, 287, 286, 138, 291, 72, + 90, 294, 75, 87, 297, 78, 84, 300, + 81, 305, 310, 315, 320, 138, 138, 326, + 328, 134, 133, 348, 364, 327, 329, 382, + 330, 332, 132, 381, 331, 131, 333, 377, + 334, 336, 130, 376, 335, 129, 337, 372, + 338, 340, 128, 371, 339, 127, 341, 367, + 342, 344, 126, 366, 343, 102, 351, 101, + 347, 350, 349, 138, 354, 105, 123, 357, + 108, 120, 360, 111, 117, 363, 114, 368, + 373, 378, 383, 135, 388, 389, 395, 390, + 392, 136, 391, 394, 393, 138, 397, 137, + 400, 399, 402, 401, 138, 0 +}; + +static const char _indic_syllable_machine_cond_actions[] = { + 1, 0, 2, 0, 2, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 0, 2, 0, + 2, 0, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 4, 0, 2, 0, 2, 5, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 0, + 0, 0, 2, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 6, 2, 6, 2, + 6, 2, 6, 2, 7, 0, 2, 0, + 2, 0, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 6, 8, 0, 11, 2, 2, 6, 0, + 12, 12, 0, 2, 6, 2, 6, 2, + 0, 13, 2, 0, 0, 2, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 0, 0, 0, 0, 14, + 2, 0, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 2, 2, 2, 2, 15, + 2, 0, 0, 2, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 0, 0, 0, 0, 16, 2, 0, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 2, 2, 2, 2, 17, 6, 0, + 6, 2, 6, 0, 0, 6, 6, 0, + 6, 2, 6, 0, 0, 6, 6, 0, + 6, 2, 6, 0, 0, 6, 6, 0, + 6, 2, 6, 0, 0, 6, 6, 0, + 2, 0, 0, 0, 0, 18, 2, 0, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 2, 2, 2, 2, 19, 20, 2, + 0, 0, 0, 0, 2, 2, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 0, + 0, 0, 0, 21, 2, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 2, + 2, 2, 2, 0, 0, 22, 22, 0, + 0, 0, 0, 0, 0, 23, 2, 0, + 0, 0, 0, 0, 24, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { - 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, - 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, - 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, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; static const char _indic_syllable_machine_from_state_actions[] = { - 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, - 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, - 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, - 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, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 10, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + +static const char _indic_syllable_machine_eof_cond_spaces[] = { + -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0 +}; + +static const char _indic_syllable_machine_eof_cond_key_offs[] = { + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + +static const char _indic_syllable_machine_eof_cond_key_lens[] = { + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + +static const char _indic_syllable_machine_eof_cond_keys[] = { + 0 }; static const short _indic_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 73, 73, 78, 78, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 73, - 1, 146, 0, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 342, 286, 342, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 286, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 414, 414, 414, 414, - 414, 414, 414, 342 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 73, 73, 78, 78, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 73, + 1, 146, 0, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 342, 286, 342, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 286, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 414, 414, 414, 414, + 414, 414, 414, 342, 0 +}; + +static const char _indic_syllable_machine_nfa_targs[] = { + 0, 0 +}; + +static const char _indic_syllable_machine_nfa_offsets[] = { + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + +static const char _indic_syllable_machine_nfa_push_actions[] = { + 0, 0 +}; + +static const char _indic_syllable_machine_nfa_pop_trans[] = { + 0, 0 }; static const int indic_syllable_machine_start = 138; @@ -987,209 +1259,333 @@ static const int indic_syllable_machine_error = -1; static const int indic_syllable_machine_en_main = 138; -#line 36 "hb-ot-shape-complex-indic-machine.rl" -#line 93 "hb-ot-shape-complex-indic-machine.rl" - - #define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial=1; \ +} HB_STMT_END static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts, te, act; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 1014 "hb-ot-shape-complex-indic-machine.hh" + unsigned int p, pe, eof, ts, te, act; + int cs; + hb_glyph_info_t *info = buffer->info; + { - cs = indic_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)indic_syllable_machine_start; + ts = 0; + te = 0; + act = 0; } - -#line 113 "hb-ot-shape-complex-indic-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 1030 "hb-ot-shape-complex-indic-machine.hh" + + + p=0; + pe = eof = buffer->len; + + unsigned int syllable_serial=1; + { - int _slen; - int _trans; - const unsigned char *_keys; - const short *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _indic_syllable_machine_from_state_actions[cs] ) { - case 10: -#line 1 "NONE" - {ts = p;} - break; -#line 1044 "hb-ot-shape-complex-indic-machine.hh" + int _cpc; + int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const short * _inds; { + if ( p == pe ) + goto _test_eof; + _resume: { + switch ( _indic_syllable_machine_from_state_actions[cs] ) { + case 10: { + { + #line 1 "NONE" + {ts = p;}} + + break; } + } + + _keys = ( _indic_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _indic_syllable_machine_indicies + (_indic_syllable_machine_index_offsets[cs])); + + if ( (info[p].indic_category()) <= 19 && (info[p].indic_category()) >= 1 ) + { + int _ic = (int)_indic_syllable_machine_char_class[(int)(info[p].indic_category()) - 1]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_indic_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_indic_syllable_machine_index_defaults[cs]; + } + + goto _match_cond; + } + _match_cond: { + cs = (int)_indic_syllable_machine_cond_targs[_trans]; + + if ( _indic_syllable_machine_cond_actions[_trans] == 0 ) + goto _again; + + switch ( _indic_syllable_machine_cond_actions[_trans] ) { + case 2: { + { + #line 1 "NONE" + {te = p+1;}} + + break; } + case 14: { + { + #line 84 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ + #line 84 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 16: { + { + #line 85 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ + #line 85 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (vowel_syllable); }}} + + break; } + case 21: { + { + #line 86 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ + #line 86 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (standalone_cluster); }}} + + break; } + case 24: { + { + #line 87 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ + #line 87 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (symbol_cluster); }}} + + break; } + case 18: { + { + #line 88 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ + #line 88 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 11: { + { + #line 89 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ + #line 89 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (non_indic_cluster); }}} + + break; } + case 13: { + { + #line 84 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p = p - 1;{ + #line 84 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 15: { + { + #line 85 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p = p - 1;{ + #line 85 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (vowel_syllable); }}} + + break; } + case 20: { + { + #line 86 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p = p - 1;{ + #line 86 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (standalone_cluster); }}} + + break; } + case 23: { + { + #line 87 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p = p - 1;{ + #line 87 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (symbol_cluster); }}} + + break; } + case 17: { + { + #line 88 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p = p - 1;{ + #line 88 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 19: { + { + #line 89 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p = p - 1;{ + #line 89 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (non_indic_cluster); }}} + + break; } + case 1: { + { + #line 84 "hb-ot-shape-complex-indic-machine.rl" + {p = ((te))-1; + { + #line 84 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 3: { + { + #line 85 "hb-ot-shape-complex-indic-machine.rl" + {p = ((te))-1; + { + #line 85 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (vowel_syllable); }}} + + break; } + case 7: { + { + #line 86 "hb-ot-shape-complex-indic-machine.rl" + {p = ((te))-1; + { + #line 86 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (standalone_cluster); }}} + + break; } + case 8: { + { + #line 87 "hb-ot-shape-complex-indic-machine.rl" + {p = ((te))-1; + { + #line 87 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (symbol_cluster); }}} + + break; } + case 4: { + { + #line 88 "hb-ot-shape-complex-indic-machine.rl" + {p = ((te))-1; + { + #line 88 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 5: { + { + #line 1 "NONE" + {switch( act ) { + case 1: { + p = ((te))-1; + { + #line 84 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (consonant_syllable); } break; } + case 5: { + p = ((te))-1; + { + #line 88 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (broken_cluster); } break; } + case 6: { + p = ((te))-1; + { + #line 89 "hb-ot-shape-complex-indic-machine.rl" + found_syllable (non_indic_cluster); } break; } + }} + } + + break; } + case 22: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 84 "hb-ot-shape-complex-indic-machine.rl" + {act = 1;}} + + break; } + case 6: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 88 "hb-ot-shape-complex-indic-machine.rl" + {act = 5;}} + + break; } + case 12: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 89 "hb-ot-shape-complex-indic-machine.rl" + {act = 6;}} + + break; } + } + + + } + _again: { + switch ( _indic_syllable_machine_to_state_actions[cs] ) { + case 9: { + { + #line 1 "NONE" + {ts = 0;}} + + break; } + } + + p += 1; + if ( p != pe ) + goto _resume; + } + _test_eof: { {} + if ( p == eof ) + { + if ( _indic_syllable_machine_eof_cond_spaces[cs] != -1 ) { + _cekeys = ( _indic_syllable_machine_eof_cond_keys + (_indic_syllable_machine_eof_cond_key_offs[cs])); + _klen = (int)_indic_syllable_machine_eof_cond_key_lens[cs]; + _cpc = 0; + { + const char *_lower = _cekeys; + const char *_upper = _cekeys + _klen - 1; + const char *_mid; + while ( 1 ) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( _cpc < (int)(*( _mid)) ) + _upper = _mid - 1; + else if ( _cpc > (int)(*( _mid)) ) + _lower = _mid + 1; + else { + goto _ok; + } + } + cs = -1; + goto _out; + } + _ok: {} + } + if ( _indic_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_indic_syllable_machine_eof_trans[cs] - 1; + goto _match_cond; + } + } + + } + _out: { {} + } + } } - - _keys = _indic_syllable_machine_trans_keys + (cs<<1); - _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs]; - - _slen = _indic_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) && - ( info[p].indic_category()) <= _keys[1] ? - ( info[p].indic_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _indic_syllable_machine_trans_targs[_trans]; - - if ( _indic_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _indic_syllable_machine_trans_actions[_trans] ) { - case 2: -#line 1 "NONE" - {te = p+1;} - break; - case 14: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (consonant_syllable); }} - break; - case 16: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (vowel_syllable); }} - break; - case 21: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (standalone_cluster); }} - break; - case 24: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (symbol_cluster); }} - break; - case 18: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} - break; - case 11: -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (non_indic_cluster); }} - break; - case 13: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} - break; - case 15: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (vowel_syllable); }} - break; - case 20: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (standalone_cluster); }} - break; - case 23: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} - break; - case 17: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 19: -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (non_indic_cluster); }} - break; - case 1: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} - break; - case 3: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (vowel_syllable); }} - break; - case 7: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (standalone_cluster); }} - break; - case 8: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (symbol_cluster); }} - break; - case 4: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; - case 5: -#line 1 "NONE" - { switch( act ) { - case 1: - {{p = ((te))-1;} found_syllable (consonant_syllable); } - break; - case 5: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - case 6: - {{p = ((te))-1;} found_syllable (non_indic_cluster); } - break; - } - } - break; - case 22: -#line 1 "NONE" - {te = p+1;} -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {act = 1;} - break; - case 6: -#line 1 "NONE" - {te = p+1;} -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {act = 5;} - break; - case 12: -#line 1 "NONE" - {te = p+1;} -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {act = 6;} - break; -#line 1167 "hb-ot-shape-complex-indic-machine.hh" - } - -_again: - switch ( _indic_syllable_machine_to_state_actions[cs] ) { - case 9: -#line 1 "NONE" - {ts = 0;} - break; -#line 1176 "hb-ot-shape-complex-indic-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _indic_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _indic_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 121 "hb-ot-shape-complex-indic-machine.rl" - + } #endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-khmer-machine.hh b/src/hb-ot-shape-complex-khmer-machine.hh index 65e0ffc85..034b65750 100644 --- a/src/hb-ot-shape-complex-khmer-machine.hh +++ b/src/hb-ot-shape-complex-khmer-machine.hh @@ -1,30 +1,28 @@ - -#line 1 "hb-ot-shape-complex-khmer-machine.rl" /* - * Copyright © 2011,2012 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. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2011,2012 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. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH @@ -32,180 +30,185 @@ #include "hb.hh" -#line 36 "hb-ot-shape-complex-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { - 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, - 5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, - 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u, - 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u, - 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u, - 0 + 2u, 8u, 2u, 6u, 2u, 8u, 2u, 6u, + 0u, 0u, 2u, 6u, 2u, 8u, 2u, 6u, + 2u, 8u, 2u, 6u, 2u, 6u, 2u, 8u, + 2u, 6u, 0u, 0u, 2u, 6u, 2u, 8u, + 2u, 6u, 2u, 8u, 2u, 6u, 2u, 8u, + 0u, 11u, 2u, 11u, 2u, 11u, 2u, 11u, + 7u, 7u, 2u, 7u, 2u, 11u, 2u, 11u, + 2u, 11u, 0u, 0u, 2u, 8u, 2u, 11u, + 2u, 11u, 7u, 7u, 2u, 7u, 2u, 11u, + 2u, 11u, 0u, 0u, 2u, 11u, 2u, 11u, + 0u }; -static const char _khmer_syllable_machine_key_spans[] = { - 22, 17, 22, 17, 16, 17, 22, 17, - 22, 17, 17, 22, 17, 16, 17, 22, - 17, 22, 17, 22, 29, 25, 25, 25, - 1, 18, 25, 25, 25, 16, 22, 25, - 25, 1, 18, 25, 25, 16, 25, 25 +static const char _khmer_syllable_machine_char_class[] = { + 0, 0, 1, 1, 2, 2, 1, 1, + 1, 1, 3, 3, 1, 4, 1, 0, + 1, 1, 1, 5, 6, 7, 1, 1, + 1, 8, 9, 10, 11, 0 }; static const short _khmer_syllable_machine_index_offsets[] = { - 0, 23, 41, 64, 82, 99, 117, 140, - 158, 181, 199, 217, 240, 258, 275, 293, - 316, 334, 357, 375, 398, 428, 454, 480, - 506, 508, 527, 553, 579, 605, 622, 645, - 671, 697, 699, 718, 744, 770, 787, 813 + 0, 7, 12, 19, 24, 25, 30, 37, + 42, 49, 54, 59, 66, 71, 72, 77, + 84, 89, 96, 101, 108, 120, 130, 140, + 150, 151, 157, 167, 177, 187, 188, 195, + 205, 215, 216, 222, 232, 242, 243, 253, + 0 }; static const char _khmer_syllable_machine_indicies[] = { - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 3, 0, 0, 0, 0, 4, 0, 1, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 4, 0, - 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 6, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10, 0, 0, - 0, 0, 4, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 11, 11, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 4, 0, 11, 11, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 0, 14, - 14, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 15, - 13, 14, 14, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 16, 16, 16, 16, 17, 16, - 18, 18, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 17, 16, 19, 19, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 19, 16, 20, 20, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 21, 16, 22, 22, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 23, 16, 16, - 16, 16, 17, 16, 22, 22, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 23, 16, 24, 24, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 25, 16, - 16, 16, 16, 17, 16, 24, 24, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 25, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 26, 15, - 16, 16, 16, 16, 17, 16, 28, 28, - 27, 27, 29, 29, 27, 27, 27, 27, - 2, 2, 27, 30, 27, 28, 27, 27, - 27, 27, 15, 19, 27, 27, 27, 17, - 23, 25, 21, 27, 32, 32, 31, 31, - 31, 31, 31, 31, 31, 33, 31, 31, - 31, 31, 31, 2, 3, 6, 31, 31, - 31, 4, 10, 12, 8, 31, 34, 34, - 31, 31, 31, 31, 31, 31, 31, 35, - 31, 31, 31, 31, 31, 31, 3, 6, - 31, 31, 31, 4, 10, 12, 8, 31, - 5, 5, 31, 31, 31, 31, 31, 31, - 31, 35, 31, 31, 31, 31, 31, 31, - 4, 6, 31, 31, 31, 31, 31, 31, - 8, 31, 6, 31, 7, 7, 31, 31, - 31, 31, 31, 31, 31, 35, 31, 31, - 31, 31, 31, 31, 8, 6, 31, 36, - 36, 31, 31, 31, 31, 31, 31, 31, - 35, 31, 31, 31, 31, 31, 31, 10, - 6, 31, 31, 31, 4, 31, 31, 8, - 31, 37, 37, 31, 31, 31, 31, 31, - 31, 31, 35, 31, 31, 31, 31, 31, - 31, 12, 6, 31, 31, 31, 4, 10, - 31, 8, 31, 34, 34, 31, 31, 31, - 31, 31, 31, 31, 33, 31, 31, 31, - 31, 31, 31, 3, 6, 31, 31, 31, - 4, 10, 12, 8, 31, 28, 28, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 28, 31, 14, 14, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 15, 38, - 38, 38, 38, 17, 38, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 41, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 18, - 18, 39, 39, 39, 39, 39, 39, 39, - 41, 39, 39, 39, 39, 39, 39, 17, - 19, 39, 39, 39, 39, 39, 39, 21, - 39, 19, 39, 20, 20, 39, 39, 39, - 39, 39, 39, 39, 41, 39, 39, 39, - 39, 39, 39, 21, 19, 39, 42, 42, - 39, 39, 39, 39, 39, 39, 39, 41, - 39, 39, 39, 39, 39, 39, 23, 19, - 39, 39, 39, 17, 39, 39, 21, 39, - 43, 43, 39, 39, 39, 39, 39, 39, - 39, 41, 39, 39, 39, 39, 39, 39, - 25, 19, 39, 39, 39, 17, 23, 39, - 21, 39, 44, 44, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 44, 39, 45, 45, 39, 39, 39, - 39, 39, 39, 39, 30, 39, 39, 39, - 39, 39, 26, 15, 19, 39, 39, 39, - 17, 23, 25, 21, 39, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 30, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 0 + 1, 0, 0, 2, 3, 0, 4, 1, + 0, 0, 0, 3, 1, 0, 0, 0, + 3, 0, 4, 5, 0, 0, 0, 4, + 6, 7, 0, 0, 0, 8, 9, 0, + 0, 0, 10, 0, 4, 9, 0, 0, + 0, 10, 11, 0, 0, 0, 12, 0, + 4, 11, 0, 0, 0, 12, 14, 13, + 13, 13, 15, 14, 16, 16, 16, 15, + 16, 17, 18, 16, 16, 16, 17, 19, + 20, 16, 16, 16, 21, 22, 16, 16, + 16, 23, 16, 17, 22, 16, 16, 16, + 23, 24, 16, 16, 16, 25, 16, 17, + 24, 16, 16, 16, 25, 14, 16, 16, + 26, 15, 16, 17, 28, 27, 29, 2, + 30, 27, 15, 19, 17, 23, 25, 21, + 32, 31, 33, 2, 3, 6, 4, 10, + 12, 8, 34, 31, 35, 31, 3, 6, + 4, 10, 12, 8, 5, 31, 35, 31, + 4, 6, 31, 31, 31, 8, 6, 7, + 31, 35, 31, 8, 6, 36, 31, 35, + 31, 10, 6, 4, 31, 31, 8, 37, + 31, 35, 31, 12, 6, 4, 10, 31, + 8, 34, 31, 33, 31, 3, 6, 4, + 10, 12, 8, 28, 14, 38, 38, 38, + 15, 38, 17, 40, 39, 41, 39, 15, + 19, 17, 23, 25, 21, 18, 39, 41, + 39, 17, 19, 39, 39, 39, 21, 19, + 20, 39, 41, 39, 21, 19, 42, 39, + 41, 39, 23, 19, 17, 39, 39, 21, + 43, 39, 41, 39, 25, 19, 17, 23, + 39, 21, 44, 45, 39, 30, 26, 15, + 19, 17, 23, 25, 21, 40, 39, 30, + 39, 15, 19, 17, 23, 25, 21, 0 }; -static const char _khmer_syllable_machine_trans_targs[] = { - 20, 1, 28, 22, 23, 3, 24, 5, - 25, 7, 26, 9, 27, 20, 10, 31, - 20, 32, 12, 33, 14, 34, 16, 35, - 18, 36, 39, 20, 21, 30, 37, 20, - 0, 29, 2, 4, 6, 8, 20, 20, - 11, 13, 15, 17, 38, 19 +static const char _khmer_syllable_machine_index_defaults[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 27, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 38, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 0 }; -static const char _khmer_syllable_machine_trans_actions[] = { - 1, 0, 2, 2, 2, 0, 0, 0, - 2, 0, 2, 0, 2, 3, 0, 4, - 5, 2, 0, 0, 0, 2, 0, 2, - 0, 2, 4, 8, 2, 9, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, - 0, 0, 0, 0, 4, 0 +static const char _khmer_syllable_machine_trans_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0 +}; + +static const char _khmer_syllable_machine_cond_targs[] = { + 20, 1, 28, 22, 23, 3, 24, 5, + 25, 7, 26, 9, 27, 20, 10, 31, + 20, 32, 12, 33, 14, 34, 16, 35, + 18, 36, 39, 20, 21, 30, 37, 20, + 0, 29, 2, 4, 6, 8, 20, 20, + 11, 13, 15, 17, 38, 19, 0 +}; + +static const char _khmer_syllable_machine_cond_actions[] = { + 1, 0, 2, 2, 2, 0, 0, 0, + 2, 0, 2, 0, 2, 3, 0, 4, + 5, 2, 0, 0, 0, 2, 0, 2, + 0, 2, 4, 8, 2, 9, 0, 10, + 0, 0, 0, 0, 0, 0, 11, 12, + 0, 0, 0, 0, 4, 0, 0 }; static const char _khmer_syllable_machine_to_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 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, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; static const char _khmer_syllable_machine_from_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 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, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; -static const unsigned char _khmer_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 39, 40, - 40, 40, 40, 40, 40, 40, 40, 40 +static const char _khmer_syllable_machine_eof_cond_spaces[] = { + -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0 +}; + +static const char _khmer_syllable_machine_eof_cond_key_offs[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const char _khmer_syllable_machine_eof_cond_key_lens[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const char _khmer_syllable_machine_eof_cond_keys[] = { + 0 +}; + +static const char _khmer_syllable_machine_eof_trans[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 14, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 39, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 0 +}; + +static const char _khmer_syllable_machine_nfa_targs[] = { + 0, 0 +}; + +static const char _khmer_syllable_machine_nfa_offsets[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const char _khmer_syllable_machine_nfa_push_actions[] = { + 0, 0 +}; + +static const char _khmer_syllable_machine_nfa_pop_trans[] = { + 0, 0 }; static const int khmer_syllable_machine_start = 20; @@ -215,156 +218,228 @@ static const int khmer_syllable_machine_error = -1; static const int khmer_syllable_machine_en_main = 20; -#line 36 "hb-ot-shape-complex-khmer-machine.rl" -#line 80 "hb-ot-shape-complex-khmer-machine.rl" - - #define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial=1; \ +} HB_STMT_END static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 242 "hb-ot-shape-complex-khmer-machine.hh" + unsigned int p, pe, eof, ts, te, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + { - cs = khmer_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)khmer_syllable_machine_start; + ts = 0; + te = 0; + act = 0; } - -#line 100 "hb-ot-shape-complex-khmer-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 258 "hb-ot-shape-complex-khmer-machine.hh" + + + p=0; + pe = eof = buffer->len; + + unsigned int syllable_serial=1; + { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _khmer_syllable_machine_from_state_actions[cs] ) { - case 7: -#line 1 "NONE" - {ts = p;} - break; -#line 272 "hb-ot-shape-complex-khmer-machine.hh" + int _cpc; + int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; { + if ( p == pe ) + goto _test_eof; + _resume: { + switch ( _khmer_syllable_machine_from_state_actions[cs] ) { + case 7: { + { + #line 1 "NONE" + {ts = p;}} + + break; } + } + + _keys = ( _khmer_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _khmer_syllable_machine_indicies + (_khmer_syllable_machine_index_offsets[cs])); + + if ( (info[p].khmer_category()) <= 29 && (info[p].khmer_category()) >= 1 ) + { + int _ic = (int)_khmer_syllable_machine_char_class[(int)(info[p].khmer_category()) - 1]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs]; + } + + goto _match_cond; + } + _match_cond: { + cs = (int)_khmer_syllable_machine_cond_targs[_trans]; + + if ( _khmer_syllable_machine_cond_actions[_trans] == 0 ) + goto _again; + + switch ( _khmer_syllable_machine_cond_actions[_trans] ) { + case 2: { + { + #line 1 "NONE" + {te = p+1;}} + + break; } + case 8: { + { + #line 76 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ + #line 76 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (non_khmer_cluster); }}} + + break; } + case 10: { + { + #line 74 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ + #line 74 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 12: { + { + #line 75 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ + #line 75 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 11: { + { + #line 76 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ + #line 76 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (non_khmer_cluster); }}} + + break; } + case 1: { + { + #line 74 "hb-ot-shape-complex-khmer-machine.rl" + {p = ((te))-1; + { + #line 74 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 5: { + { + #line 75 "hb-ot-shape-complex-khmer-machine.rl" + {p = ((te))-1; + { + #line 75 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 3: { + { + #line 1 "NONE" + {switch( act ) { + case 2: { + p = ((te))-1; + { + #line 75 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (broken_cluster); } break; } + case 3: { + p = ((te))-1; + { + #line 76 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (non_khmer_cluster); } break; } + }} + } + + break; } + case 4: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 75 "hb-ot-shape-complex-khmer-machine.rl" + {act = 2;}} + + break; } + case 9: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 76 "hb-ot-shape-complex-khmer-machine.rl" + {act = 3;}} + + break; } + } + + + } + _again: { + switch ( _khmer_syllable_machine_to_state_actions[cs] ) { + case 6: { + { + #line 1 "NONE" + {ts = 0;}} + + break; } + } + + p += 1; + if ( p != pe ) + goto _resume; + } + _test_eof: { {} + if ( p == eof ) + { + if ( _khmer_syllable_machine_eof_cond_spaces[cs] != -1 ) { + _cekeys = ( _khmer_syllable_machine_eof_cond_keys + (_khmer_syllable_machine_eof_cond_key_offs[cs])); + _klen = (int)_khmer_syllable_machine_eof_cond_key_lens[cs]; + _cpc = 0; + { + const char *_lower = _cekeys; + const char *_upper = _cekeys + _klen - 1; + const char *_mid; + while ( 1 ) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( _cpc < (int)(*( _mid)) ) + _upper = _mid - 1; + else if ( _cpc > (int)(*( _mid)) ) + _lower = _mid + 1; + else { + goto _ok; + } + } + cs = -1; + goto _out; + } + _ok: {} + } + if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_khmer_syllable_machine_eof_trans[cs] - 1; + goto _match_cond; + } + } + + } + _out: { {} + } + } } - - _keys = _khmer_syllable_machine_trans_keys + (cs<<1); - _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs]; - - _slen = _khmer_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) && - ( info[p].khmer_category()) <= _keys[1] ? - ( info[p].khmer_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _khmer_syllable_machine_trans_targs[_trans]; - - if ( _khmer_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _khmer_syllable_machine_trans_actions[_trans] ) { - case 2: -#line 1 "NONE" - {te = p+1;} - break; - case 8: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (non_khmer_cluster); }} - break; - case 10: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} - break; - case 12: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 11: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (non_khmer_cluster); }} - break; - case 1: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} - break; - case 5: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; - case 3: -#line 1 "NONE" - { switch( act ) { - case 2: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - case 3: - {{p = ((te))-1;} found_syllable (non_khmer_cluster); } - break; - } - } - break; - case 4: -#line 1 "NONE" - {te = p+1;} -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {act = 2;} - break; - case 9: -#line 1 "NONE" - {te = p+1;} -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {act = 3;} - break; -#line 342 "hb-ot-shape-complex-khmer-machine.hh" - } - -_again: - switch ( _khmer_syllable_machine_to_state_actions[cs] ) { - case 6: -#line 1 "NONE" - {ts = 0;} - break; -#line 351 "hb-ot-shape-complex-khmer-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _khmer_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 108 "hb-ot-shape-complex-khmer-machine.rl" - + } #endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-myanmar-machine.hh b/src/hb-ot-shape-complex-myanmar-machine.hh index d03832fa7..f40a47999 100644 --- a/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/src/hb-ot-shape-complex-myanmar-machine.hh @@ -1,30 +1,28 @@ - -#line 1 "hb-ot-shape-complex-myanmar-machine.rl" /* - * Copyright © 2011,2012 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. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2011,2012 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. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH @@ -32,251 +30,276 @@ #include "hb.hh" -#line 36 "hb-ot-shape-complex-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { - 1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, - 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, - 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, - 1u, 32u, 8u, 8u, 0 + 0u, 21u, 1u, 20u, 3u, 19u, 3u, 5u, + 3u, 19u, 1u, 15u, 3u, 15u, 3u, 15u, + 1u, 19u, 1u, 19u, 1u, 19u, 1u, 19u, + 0u, 8u, 1u, 19u, 1u, 19u, 1u, 19u, + 1u, 19u, 1u, 19u, 1u, 20u, 1u, 19u, + 1u, 19u, 1u, 19u, 1u, 19u, 3u, 19u, + 3u, 5u, 3u, 19u, 1u, 15u, 3u, 15u, + 3u, 15u, 1u, 19u, 1u, 19u, 1u, 19u, + 1u, 19u, 0u, 8u, 1u, 20u, 1u, 19u, + 1u, 19u, 1u, 19u, 1u, 19u, 1u, 19u, + 1u, 20u, 1u, 19u, 1u, 19u, 1u, 19u, + 1u, 19u, 1u, 20u, 1u, 19u, 0u, 20u, + 0u, 8u, 5u, 5u, 0u }; -static const char _myanmar_syllable_machine_key_spans[] = { - 32, 28, 25, 4, 25, 23, 21, 21, - 27, 27, 27, 27, 16, 27, 27, 27, - 27, 27, 28, 27, 27, 27, 27, 25, - 4, 25, 23, 21, 21, 27, 27, 27, - 27, 16, 28, 27, 27, 27, 27, 27, - 28, 27, 27, 27, 27, 28, 27, 32, - 32, 1 -}; - -static const short _myanmar_syllable_machine_index_offsets[] = { - 0, 33, 62, 88, 93, 119, 143, 165, - 187, 215, 243, 271, 299, 316, 344, 372, - 400, 428, 456, 485, 513, 541, 569, 597, - 623, 628, 654, 678, 700, 722, 750, 778, - 806, 834, 851, 880, 908, 936, 964, 992, - 1020, 1049, 1077, 1105, 1133, 1161, 1190, 1218, - 1251, 1284 -}; - -static const char _myanmar_syllable_machine_indicies[] = { - 1, 1, 2, 3, 4, 4, 0, 5, - 0, 6, 1, 0, 0, 0, 0, 7, - 0, 8, 9, 0, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 1, - 0, 22, 23, 24, 24, 21, 25, 21, - 26, 21, 21, 21, 21, 21, 21, 21, - 27, 21, 21, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 21, 24, 24, - 21, 25, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 38, 21, 21, 21, 21, - 21, 21, 32, 21, 21, 21, 36, 21, - 24, 24, 21, 25, 21, 24, 24, 21, - 25, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 32, 21, 21, 21, 36, 21, 39, - 21, 24, 24, 21, 25, 21, 32, 21, - 21, 21, 21, 21, 21, 21, 40, 21, - 21, 21, 21, 21, 21, 32, 21, 24, - 24, 21, 25, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 40, 21, 21, 21, - 21, 21, 21, 32, 21, 24, 24, 21, - 25, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 32, 21, 22, 21, 24, 24, 21, - 25, 21, 26, 21, 21, 21, 21, 21, - 21, 21, 41, 21, 21, 41, 21, 21, - 21, 32, 42, 21, 21, 36, 21, 22, - 21, 24, 24, 21, 25, 21, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 32, 21, 21, - 21, 36, 21, 22, 21, 24, 24, 21, - 25, 21, 26, 21, 21, 21, 21, 21, - 21, 21, 41, 21, 21, 21, 21, 21, - 21, 32, 42, 21, 21, 36, 21, 22, - 21, 24, 24, 21, 25, 21, 26, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 32, 42, 21, - 21, 36, 21, 1, 1, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 1, 21, 22, 21, 24, 24, - 21, 25, 21, 26, 21, 21, 21, 21, - 21, 21, 21, 27, 21, 21, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 21, - 22, 21, 24, 24, 21, 25, 21, 26, - 21, 21, 21, 21, 21, 21, 21, 43, - 21, 21, 21, 21, 21, 21, 32, 33, - 34, 35, 36, 21, 22, 21, 24, 24, - 21, 25, 21, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 32, 33, 34, 35, 36, 21, - 22, 21, 24, 24, 21, 25, 21, 26, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 33, - 34, 21, 36, 21, 22, 21, 24, 24, - 21, 25, 21, 26, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 32, 21, 34, 21, 36, 21, - 22, 21, 24, 24, 21, 25, 21, 26, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 32, 33, - 34, 35, 36, 43, 21, 22, 21, 24, - 24, 21, 25, 21, 26, 21, 21, 21, - 21, 21, 21, 21, 43, 21, 21, 28, - 21, 30, 21, 32, 33, 34, 35, 36, - 21, 22, 21, 24, 24, 21, 25, 21, - 26, 21, 21, 21, 21, 21, 21, 21, - 43, 21, 21, 28, 21, 21, 21, 32, - 33, 34, 35, 36, 21, 22, 21, 24, - 24, 21, 25, 21, 26, 21, 21, 21, - 21, 21, 21, 21, 43, 21, 21, 28, - 29, 30, 21, 32, 33, 34, 35, 36, - 21, 22, 23, 24, 24, 21, 25, 21, - 26, 21, 21, 21, 21, 21, 21, 21, - 27, 21, 21, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 21, 45, 45, 44, - 5, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 46, 44, 44, 44, 44, 44, - 44, 14, 44, 44, 44, 18, 44, 45, - 45, 44, 5, 44, 45, 45, 44, 5, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 14, 44, 44, 44, 18, 44, 47, 44, - 45, 45, 44, 5, 44, 14, 44, 44, - 44, 44, 44, 44, 44, 48, 44, 44, - 44, 44, 44, 44, 14, 44, 45, 45, - 44, 5, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 48, 44, 44, 44, 44, - 44, 44, 14, 44, 45, 45, 44, 5, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 14, 44, 2, 44, 45, 45, 44, 5, - 44, 6, 44, 44, 44, 44, 44, 44, - 44, 49, 44, 44, 49, 44, 44, 44, - 14, 50, 44, 44, 18, 44, 2, 44, - 45, 45, 44, 5, 44, 6, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 14, 44, 44, 44, - 18, 44, 2, 44, 45, 45, 44, 5, - 44, 6, 44, 44, 44, 44, 44, 44, - 44, 49, 44, 44, 44, 44, 44, 44, - 14, 50, 44, 44, 18, 44, 2, 44, - 45, 45, 44, 5, 44, 6, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 14, 50, 44, 44, - 18, 44, 51, 51, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 51, 44, 2, 3, 45, 45, 44, - 5, 44, 6, 44, 44, 44, 44, 44, - 44, 44, 8, 44, 44, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 44, - 2, 44, 45, 45, 44, 5, 44, 6, - 44, 44, 44, 44, 44, 44, 44, 8, - 44, 44, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 44, 2, 44, 45, 45, - 44, 5, 44, 6, 44, 44, 44, 44, - 44, 44, 44, 52, 44, 44, 44, 44, - 44, 44, 14, 15, 16, 17, 18, 44, - 2, 44, 45, 45, 44, 5, 44, 6, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 14, 15, - 16, 17, 18, 44, 2, 44, 45, 45, - 44, 5, 44, 6, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 14, 15, 16, 44, 18, 44, - 2, 44, 45, 45, 44, 5, 44, 6, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 14, 44, - 16, 44, 18, 44, 2, 44, 45, 45, - 44, 5, 44, 6, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 14, 15, 16, 17, 18, 52, - 44, 2, 44, 45, 45, 44, 5, 44, - 6, 44, 44, 44, 44, 44, 44, 44, - 52, 44, 44, 10, 44, 12, 44, 14, - 15, 16, 17, 18, 44, 2, 44, 45, - 45, 44, 5, 44, 6, 44, 44, 44, - 44, 44, 44, 44, 52, 44, 44, 10, - 44, 44, 44, 14, 15, 16, 17, 18, - 44, 2, 44, 45, 45, 44, 5, 44, - 6, 44, 44, 44, 44, 44, 44, 44, - 52, 44, 44, 10, 11, 12, 44, 14, - 15, 16, 17, 18, 44, 2, 3, 45, - 45, 44, 5, 44, 6, 44, 44, 44, - 44, 44, 44, 44, 8, 44, 44, 10, - 11, 12, 13, 14, 15, 16, 17, 18, - 44, 22, 23, 24, 24, 21, 25, 21, - 26, 21, 21, 21, 21, 21, 21, 21, - 53, 21, 21, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 21, 22, 54, - 24, 24, 21, 25, 21, 26, 21, 21, - 21, 21, 21, 21, 21, 27, 21, 21, - 28, 29, 30, 31, 32, 33, 34, 35, - 36, 21, 1, 1, 2, 3, 45, 45, - 44, 5, 44, 6, 1, 44, 44, 44, - 44, 1, 44, 8, 44, 44, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, - 44, 1, 44, 1, 1, 55, 55, 55, - 55, 55, 55, 55, 55, 1, 55, 55, - 55, 55, 1, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 1, 55, 56, 55, 0 -}; - -static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 23, 33, 0, 24, 30, 45, - 35, 48, 36, 41, 42, 43, 26, 38, - 39, 40, 29, 44, 49, 0, 2, 12, - 0, 3, 9, 13, 14, 19, 20, 21, - 5, 16, 17, 18, 8, 22, 4, 6, - 7, 10, 11, 15, 0, 0, 25, 27, - 28, 31, 32, 34, 37, 46, 47, 0, +static const char _myanmar_syllable_machine_char_class[] = { + 0, 0, 1, 2, 3, 3, 4, 5, + 4, 6, 7, 4, 4, 4, 4, 8, + 4, 9, 10, 4, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 7, 0 }; -static const char _myanmar_syllable_machine_trans_actions[] = { - 3, 0, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, - 10 +static const short _myanmar_syllable_machine_index_offsets[] = { + 0, 22, 42, 59, 62, 79, 94, 107, + 120, 139, 158, 177, 196, 205, 224, 243, + 262, 281, 300, 320, 339, 358, 377, 396, + 413, 416, 433, 448, 461, 474, 493, 512, + 531, 550, 559, 579, 598, 617, 636, 655, + 674, 694, 713, 732, 751, 770, 790, 809, + 830, 839, 0 +}; + +static const char _myanmar_syllable_machine_indicies[] = { + 1, 2, 3, 4, 0, 5, 6, 1, + 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 22, 23, + 24, 21, 25, 26, 21, 21, 27, 21, + 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 24, 21, 25, 21, 21, 21, + 38, 21, 21, 21, 21, 21, 32, 21, + 21, 21, 36, 24, 21, 25, 24, 21, + 25, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 32, 21, 21, 21, 36, 39, + 21, 24, 21, 25, 32, 21, 21, 40, + 21, 21, 21, 21, 21, 32, 24, 21, + 25, 21, 21, 21, 40, 21, 21, 21, + 21, 21, 32, 24, 21, 25, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 32, + 22, 21, 24, 21, 25, 26, 21, 21, + 41, 21, 41, 21, 21, 21, 32, 42, + 21, 21, 36, 22, 21, 24, 21, 25, + 26, 21, 21, 21, 21, 21, 21, 21, + 21, 32, 21, 21, 21, 36, 22, 21, + 24, 21, 25, 26, 21, 21, 41, 21, + 21, 21, 21, 21, 32, 42, 21, 21, + 36, 22, 21, 24, 21, 25, 26, 21, + 21, 21, 21, 21, 21, 21, 21, 32, + 42, 21, 21, 36, 1, 21, 21, 21, + 21, 21, 21, 21, 1, 22, 21, 24, + 21, 25, 26, 21, 21, 27, 21, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 22, 21, 24, 21, 25, 26, 21, 21, + 43, 21, 21, 21, 21, 21, 32, 33, + 34, 35, 36, 22, 21, 24, 21, 25, + 26, 21, 21, 21, 21, 21, 21, 21, + 21, 32, 33, 34, 35, 36, 22, 21, + 24, 21, 25, 26, 21, 21, 21, 21, + 21, 21, 21, 21, 32, 33, 34, 21, + 36, 22, 21, 24, 21, 25, 26, 21, + 21, 21, 21, 21, 21, 21, 21, 32, + 21, 34, 21, 36, 22, 21, 24, 21, + 25, 26, 21, 21, 21, 21, 21, 21, + 21, 21, 32, 33, 34, 35, 36, 43, + 22, 21, 24, 21, 25, 26, 21, 21, + 43, 21, 28, 21, 30, 21, 32, 33, + 34, 35, 36, 22, 21, 24, 21, 25, + 26, 21, 21, 43, 21, 28, 21, 21, + 21, 32, 33, 34, 35, 36, 22, 21, + 24, 21, 25, 26, 21, 21, 43, 21, + 28, 29, 30, 21, 32, 33, 34, 35, + 36, 22, 23, 24, 21, 25, 26, 21, + 21, 27, 21, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 45, 44, 5, 44, + 44, 44, 46, 44, 44, 44, 44, 44, + 14, 44, 44, 44, 18, 45, 44, 5, + 45, 44, 5, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 14, 44, 44, 44, + 18, 47, 44, 45, 44, 5, 14, 44, + 44, 48, 44, 44, 44, 44, 44, 14, + 45, 44, 5, 44, 44, 44, 48, 44, + 44, 44, 44, 44, 14, 45, 44, 5, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 14, 2, 44, 45, 44, 5, 6, + 44, 44, 49, 44, 49, 44, 44, 44, + 14, 50, 44, 44, 18, 2, 44, 45, + 44, 5, 6, 44, 44, 44, 44, 44, + 44, 44, 44, 14, 44, 44, 44, 18, + 2, 44, 45, 44, 5, 6, 44, 44, + 49, 44, 44, 44, 44, 44, 14, 50, + 44, 44, 18, 2, 44, 45, 44, 5, + 6, 44, 44, 44, 44, 44, 44, 44, + 44, 14, 50, 44, 44, 18, 51, 44, + 44, 44, 44, 44, 44, 44, 51, 2, + 3, 45, 44, 5, 6, 44, 44, 8, + 44, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 2, 44, 45, 44, 5, + 6, 44, 44, 8, 44, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 2, 44, + 45, 44, 5, 6, 44, 44, 52, 44, + 44, 44, 44, 44, 14, 15, 16, 17, + 18, 2, 44, 45, 44, 5, 6, 44, + 44, 44, 44, 44, 44, 44, 44, 14, + 15, 16, 17, 18, 2, 44, 45, 44, + 5, 6, 44, 44, 44, 44, 44, 44, + 44, 44, 14, 15, 16, 44, 18, 2, + 44, 45, 44, 5, 6, 44, 44, 44, + 44, 44, 44, 44, 44, 14, 44, 16, + 44, 18, 2, 44, 45, 44, 5, 6, + 44, 44, 44, 44, 44, 44, 44, 44, + 14, 15, 16, 17, 18, 52, 2, 44, + 45, 44, 5, 6, 44, 44, 52, 44, + 10, 44, 12, 44, 14, 15, 16, 17, + 18, 2, 44, 45, 44, 5, 6, 44, + 44, 52, 44, 10, 44, 44, 44, 14, + 15, 16, 17, 18, 2, 44, 45, 44, + 5, 6, 44, 44, 52, 44, 10, 11, + 12, 44, 14, 15, 16, 17, 18, 2, + 3, 45, 44, 5, 6, 44, 44, 8, + 44, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 22, 23, 24, 21, 25, 26, + 21, 21, 53, 21, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 22, 54, + 24, 21, 25, 26, 21, 21, 27, 21, + 28, 29, 30, 31, 32, 33, 34, 35, + 36, 1, 2, 3, 45, 44, 5, 6, + 1, 1, 8, 44, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 1, 55, + 55, 55, 55, 55, 55, 1, 1, 56, + 0 +}; + +static const char _myanmar_syllable_machine_index_defaults[] = { + 0, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 21, 21, 44, + 55, 55, 0 +}; + +static const char _myanmar_syllable_machine_trans_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0 +}; + +static const char _myanmar_syllable_machine_cond_targs[] = { + 0, 1, 23, 33, 0, 24, 30, 45, + 35, 48, 36, 41, 42, 43, 26, 38, + 39, 40, 29, 44, 49, 0, 2, 12, + 0, 3, 9, 13, 14, 19, 20, 21, + 5, 16, 17, 18, 8, 22, 4, 6, + 7, 10, 11, 15, 0, 0, 25, 27, + 28, 31, 32, 34, 37, 46, 47, 0, + 0, 0 +}; + +static const char _myanmar_syllable_machine_cond_actions[] = { + 3, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, + 10, 0 }; static const char _myanmar_syllable_machine_to_state_actions[] = { - 1, 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, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 + 1, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 }; static const char _myanmar_syllable_machine_from_state_actions[] = { - 2, 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, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 2, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const char _myanmar_syllable_machine_eof_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 0 +}; + +static const char _myanmar_syllable_machine_eof_cond_key_offs[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const char _myanmar_syllable_machine_eof_cond_key_lens[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const char _myanmar_syllable_machine_eof_cond_keys[] = { + 0 +}; + +static const char _myanmar_syllable_machine_eof_trans[] = { + 0, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 22, 22, 45, + 56, 56, 0 +}; + +static const char _myanmar_syllable_machine_nfa_targs[] = { 0, 0 }; -static const short _myanmar_syllable_machine_eof_trans[] = { - 0, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 22, 22, 45, - 56, 56 +static const char _myanmar_syllable_machine_nfa_offsets[] = { + 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +static const char _myanmar_syllable_machine_nfa_push_actions[] = { + 0, 0 +}; + +static const char _myanmar_syllable_machine_nfa_pop_trans[] = { + 0, 0 }; static const int myanmar_syllable_machine_start = 0; @@ -286,136 +309,199 @@ static const int myanmar_syllable_machine_error = -1; static const int myanmar_syllable_machine_en_main = 0; -#line 36 "hb-ot-shape-complex-myanmar-machine.rl" -#line 94 "hb-ot-shape-complex-myanmar-machine.rl" - - #define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial=1; \ +} HB_STMT_END static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 313 "hb-ot-shape-complex-myanmar-machine.hh" + unsigned int p, pe, eof, ts, te, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + { - cs = myanmar_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)myanmar_syllable_machine_start; + ts = 0; + te = 0; } - -#line 114 "hb-ot-shape-complex-myanmar-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 329 "hb-ot-shape-complex-myanmar-machine.hh" + + + p=0; + pe = eof = buffer->len; + + unsigned int syllable_serial=1; + { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _myanmar_syllable_machine_from_state_actions[cs] ) { - case 2: -#line 1 "NONE" - {ts = p;} - break; -#line 343 "hb-ot-shape-complex-myanmar-machine.hh" + int _cpc; + int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; { + if ( p == pe ) + goto _test_eof; + _resume: { + switch ( _myanmar_syllable_machine_from_state_actions[cs] ) { + case 2: { + { + #line 1 "NONE" + {ts = p;}} + + break; } + } + + _keys = ( _myanmar_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _myanmar_syllable_machine_indicies + (_myanmar_syllable_machine_index_offsets[cs])); + + if ( (info[p].myanmar_category()) <= 32 && (info[p].myanmar_category()) >= 1 ) + { + int _ic = (int)_myanmar_syllable_machine_char_class[(int)(info[p].myanmar_category()) - 1]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_myanmar_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_myanmar_syllable_machine_index_defaults[cs]; + } + + goto _match_cond; + } + _match_cond: { + cs = (int)_myanmar_syllable_machine_cond_targs[_trans]; + + if ( _myanmar_syllable_machine_cond_actions[_trans] == 0 ) + goto _again; + + switch ( _myanmar_syllable_machine_cond_actions[_trans] ) { + case 6: { + { + #line 86 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ + #line 86 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 4: { + { + #line 87 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ + #line 87 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (non_myanmar_cluster); }}} + + break; } + case 10: { + { + #line 88 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ + #line 88 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (punctuation_cluster); }}} + + break; } + case 8: { + { + #line 89 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ + #line 89 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 3: { + { + #line 90 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ + #line 90 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (non_myanmar_cluster); }}} + + break; } + case 5: { + { + #line 86 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p = p - 1;{ + #line 86 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (consonant_syllable); }}} + + break; } + case 7: { + { + #line 89 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p = p - 1;{ + #line 89 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 9: { + { + #line 90 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p = p - 1;{ + #line 90 "hb-ot-shape-complex-myanmar-machine.rl" + found_syllable (non_myanmar_cluster); }}} + + break; } + } + + + } + _again: { + switch ( _myanmar_syllable_machine_to_state_actions[cs] ) { + case 1: { + { + #line 1 "NONE" + {ts = 0;}} + + break; } + } + + p += 1; + if ( p != pe ) + goto _resume; + } + _test_eof: { {} + if ( p == eof ) + { + if ( _myanmar_syllable_machine_eof_cond_spaces[cs] != -1 ) { + _cekeys = ( _myanmar_syllable_machine_eof_cond_keys + (_myanmar_syllable_machine_eof_cond_key_offs[cs])); + _klen = (int)_myanmar_syllable_machine_eof_cond_key_lens[cs]; + _cpc = 0; + { + const char *_lower = _cekeys; + const char *_upper = _cekeys + _klen - 1; + const char *_mid; + while ( 1 ) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( _cpc < (int)(*( _mid)) ) + _upper = _mid - 1; + else if ( _cpc > (int)(*( _mid)) ) + _lower = _mid + 1; + else { + goto _ok; + } + } + cs = -1; + goto _out; + } + _ok: {} + } + if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_myanmar_syllable_machine_eof_trans[cs] - 1; + goto _match_cond; + } + } + + } + _out: { {} + } + } } - - _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); - _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs]; - - _slen = _myanmar_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) && - ( info[p].myanmar_category()) <= _keys[1] ? - ( info[p].myanmar_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _myanmar_syllable_machine_trans_targs[_trans]; - - if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { - case 6: -#line 86 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (consonant_syllable); }} - break; - case 4: -#line 87 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (non_myanmar_cluster); }} - break; - case 10: -#line 88 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (punctuation_cluster); }} - break; - case 8: -#line 89 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} - break; - case 3: -#line 90 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (non_myanmar_cluster); }} - break; - case 5: -#line 86 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} - break; - case 7: -#line 89 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 9: -#line 90 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (non_myanmar_cluster); }} - break; -#line 393 "hb-ot-shape-complex-myanmar-machine.hh" - } - -_again: - switch ( _myanmar_syllable_machine_to_state_actions[cs] ) { - case 1: -#line 1 "NONE" - {ts = 0;} - break; -#line 402 "hb-ot-shape-complex-myanmar-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _myanmar_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 122 "hb-ot-shape-complex-myanmar-machine.rl" - + } #undef found_syllable diff --git a/src/hb-ot-shape-complex-use-machine.hh b/src/hb-ot-shape-complex-use-machine.hh index f83e09fbc..e4b1884cf 100644 --- a/src/hb-ot-shape-complex-use-machine.hh +++ b/src/hb-ot-shape-complex-use-machine.hh @@ -1,32 +1,30 @@ - -#line 1 "hb-ot-shape-complex-use-machine.rl" /* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 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. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2015 Mozilla Foundation. +* Copyright © 2015 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. +* +* Mozilla Author(s): Jonathan Kew +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH @@ -34,332 +32,370 @@ #include "hb.hh" -#line 38 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 44u, 21u, 21u, 8u, 44u, 8u, 44u, - 1u, 15u, 1u, 1u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, - 8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 8u, 44u, 13u, 21u, 4u, 4u, 13u, 13u, - 8u, 44u, 8u, 44u, 41u, 42u, 42u, 42u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 39u, - 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, - 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 1u, 15u, - 4u, 4u, 13u, 21u, 13u, 13u, 12u, 44u, 1u, 44u, 8u, 44u, 41u, 42u, 42u, 42u, - 21u, 42u, 1u, 5u, 0 + 7u, 33u, 1u, 9u, 1u, 1u, 7u, 33u, + 0u, 33u, 12u, 12u, 5u, 33u, 5u, 33u, + 1u, 9u, 1u, 1u, 5u, 33u, 5u, 33u, + 5u, 29u, 5u, 17u, 5u, 17u, 5u, 17u, + 5u, 29u, 5u, 29u, 5u, 29u, 5u, 33u, + 5u, 33u, 5u, 33u, 5u, 33u, 5u, 33u, + 5u, 33u, 5u, 33u, 5u, 33u, 1u, 29u, + 5u, 33u, 8u, 12u, 3u, 3u, 8u, 8u, + 5u, 33u, 5u, 33u, 30u, 31u, 31u, 31u, + 5u, 33u, 5u, 33u, 5u, 33u, 5u, 29u, + 5u, 17u, 5u, 17u, 5u, 17u, 5u, 29u, + 5u, 29u, 5u, 29u, 5u, 33u, 5u, 33u, + 5u, 33u, 5u, 33u, 5u, 33u, 5u, 33u, + 5u, 33u, 5u, 33u, 1u, 29u, 1u, 9u, + 3u, 3u, 8u, 12u, 8u, 8u, 7u, 33u, + 1u, 33u, 5u, 33u, 30u, 31u, 31u, 31u, + 12u, 31u, 1u, 4u, 0u }; -static const char _use_syllable_machine_key_spans[] = { - 33, 15, 1, 33, 45, 1, 37, 37, - 15, 1, 37, 37, 32, 19, 19, 19, - 32, 32, 32, 37, 37, 37, 37, 37, - 37, 37, 37, 39, 37, 9, 1, 1, - 37, 37, 2, 1, 37, 37, 37, 32, - 19, 19, 19, 32, 32, 32, 37, 37, - 37, 37, 37, 37, 37, 37, 39, 15, - 1, 9, 1, 33, 44, 37, 2, 1, - 22, 5 +static const char _use_syllable_machine_char_class[] = { + 0, 1, 2, 0, 3, 4, 2, 2, + 5, 2, 2, 6, 7, 8, 2, 9, + 0, 0, 10, 11, 2, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 2, 27, 28, 29, + 2, 30, 31, 32, 33, 0 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 34, 50, 52, 86, 132, 134, 172, - 210, 226, 228, 266, 304, 337, 357, 377, - 397, 430, 463, 496, 534, 572, 610, 648, - 686, 724, 762, 800, 840, 878, 888, 890, - 892, 930, 968, 971, 973, 1011, 1049, 1087, - 1120, 1140, 1160, 1180, 1213, 1246, 1279, 1317, - 1355, 1393, 1431, 1469, 1507, 1545, 1583, 1623, - 1639, 1641, 1651, 1653, 1687, 1732, 1770, 1773, - 1775, 1798 + 0, 27, 36, 37, 64, 98, 99, 128, + 157, 166, 167, 196, 225, 250, 263, 276, + 289, 314, 339, 364, 393, 422, 451, 480, + 509, 538, 567, 596, 625, 654, 659, 660, + 661, 690, 719, 721, 722, 751, 780, 809, + 834, 847, 860, 873, 898, 923, 948, 977, + 1006, 1035, 1064, 1093, 1122, 1151, 1180, 1209, + 1218, 1219, 1224, 1225, 1252, 1285, 1314, 1316, + 1317, 1337, 0 }; static const char _use_syllable_machine_indicies[] = { - 1, 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, 0, 3, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, - 4, 2, 3, 2, 6, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 6, 5, 7, 8, - 9, 7, 10, 11, 9, 9, 12, 9, - 9, 3, 13, 14, 9, 15, 7, 7, - 16, 17, 9, 9, 18, 19, 20, 21, - 22, 23, 24, 18, 25, 26, 27, 28, - 29, 30, 9, 31, 32, 33, 9, 34, - 35, 36, 37, 9, 39, 38, 41, 40, - 40, 42, 1, 40, 40, 43, 40, 40, - 40, 40, 40, 44, 45, 46, 47, 48, - 49, 50, 51, 45, 52, 44, 53, 54, - 55, 56, 40, 57, 58, 59, 40, 40, - 40, 40, 60, 40, 41, 40, 40, 42, - 1, 40, 40, 43, 40, 40, 40, 40, - 40, 61, 45, 46, 47, 48, 49, 50, - 51, 45, 52, 53, 53, 54, 55, 56, - 40, 57, 58, 59, 40, 40, 40, 40, - 60, 40, 42, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, - 63, 62, 42, 62, 41, 40, 40, 42, - 1, 40, 40, 43, 40, 40, 40, 40, - 40, 40, 45, 46, 47, 48, 49, 50, - 51, 45, 52, 53, 53, 54, 55, 56, - 40, 57, 58, 59, 40, 40, 40, 40, - 60, 40, 41, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 45, 46, 47, 48, 49, 40, 40, 40, - 40, 40, 40, 54, 55, 56, 40, 57, - 58, 59, 40, 40, 40, 40, 46, 40, - 41, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 46, - 47, 48, 49, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 57, 58, 59, - 40, 41, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 47, 48, 49, 40, 41, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 48, 49, - 40, 41, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 49, 40, 41, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 47, 48, 49, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 57, 58, 59, 40, 41, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 47, 48, - 49, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 58, 59, 40, 41, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 47, - 48, 49, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 59, 40, - 41, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 46, - 47, 48, 49, 40, 40, 40, 40, 40, - 40, 54, 55, 56, 40, 57, 58, 59, - 40, 40, 40, 40, 46, 40, 41, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 46, 47, 48, - 49, 40, 40, 40, 40, 40, 40, 40, - 55, 56, 40, 57, 58, 59, 40, 40, - 40, 40, 46, 40, 41, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 46, 47, 48, 49, 40, - 40, 40, 40, 40, 40, 40, 40, 56, - 40, 57, 58, 59, 40, 40, 40, 40, - 46, 40, 41, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 45, 46, 47, 48, 49, 40, 51, 45, - 40, 40, 40, 54, 55, 56, 40, 57, - 58, 59, 40, 40, 40, 40, 46, 40, - 41, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 45, 46, - 47, 48, 49, 40, 64, 45, 40, 40, - 40, 54, 55, 56, 40, 57, 58, 59, - 40, 40, 40, 40, 46, 40, 41, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 45, 46, 47, 48, - 49, 40, 40, 45, 40, 40, 40, 54, - 55, 56, 40, 57, 58, 59, 40, 40, - 40, 40, 46, 40, 41, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 45, 46, 47, 48, 49, 50, - 51, 45, 40, 40, 40, 54, 55, 56, - 40, 57, 58, 59, 40, 40, 40, 40, - 46, 40, 41, 40, 40, 42, 1, 40, - 40, 43, 40, 40, 40, 40, 40, 40, - 45, 46, 47, 48, 49, 50, 51, 45, - 52, 40, 53, 54, 55, 56, 40, 57, - 58, 59, 40, 40, 40, 40, 60, 40, - 42, 62, 62, 62, 62, 62, 62, 41, - 62, 62, 62, 62, 62, 62, 63, 62, - 62, 62, 62, 62, 62, 62, 46, 47, - 48, 49, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 57, 58, 59, 62, - 41, 40, 40, 42, 1, 40, 40, 43, - 40, 40, 40, 40, 40, 40, 45, 46, - 47, 48, 49, 50, 51, 45, 52, 44, - 53, 54, 55, 56, 40, 57, 58, 59, - 40, 40, 40, 40, 60, 40, 66, 65, - 65, 65, 65, 65, 65, 65, 67, 65, - 10, 68, 66, 65, 41, 40, 40, 42, - 1, 40, 40, 43, 40, 40, 40, 40, - 40, 69, 45, 46, 47, 48, 49, 50, - 51, 45, 52, 44, 53, 54, 55, 56, - 40, 57, 58, 59, 40, 70, 71, 40, - 60, 40, 41, 40, 40, 42, 1, 40, - 40, 43, 40, 40, 40, 40, 40, 40, - 45, 46, 47, 48, 49, 50, 51, 45, - 52, 44, 53, 54, 55, 56, 40, 57, - 58, 59, 40, 70, 71, 40, 60, 40, - 70, 71, 72, 71, 72, 12, 73, 73, - 3, 6, 73, 73, 74, 73, 73, 73, - 73, 73, 75, 18, 19, 20, 21, 22, - 23, 24, 18, 25, 27, 27, 28, 29, - 30, 73, 31, 32, 33, 73, 73, 73, - 73, 37, 73, 12, 73, 73, 3, 6, - 73, 73, 74, 73, 73, 73, 73, 73, - 73, 18, 19, 20, 21, 22, 23, 24, - 18, 25, 27, 27, 28, 29, 30, 73, - 31, 32, 33, 73, 73, 73, 73, 37, - 73, 12, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 18, - 19, 20, 21, 22, 73, 73, 73, 73, - 73, 73, 28, 29, 30, 73, 31, 32, - 33, 73, 73, 73, 73, 19, 73, 12, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 19, 20, - 21, 22, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 31, 32, 33, 73, - 12, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 20, 21, 22, 73, 12, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 21, 22, 73, - 12, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 22, 73, 12, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 20, 21, 22, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 31, 32, 33, 73, 12, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 20, 21, 22, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 32, 33, 73, 12, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 20, 21, - 22, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 33, 73, 12, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 19, 20, - 21, 22, 73, 73, 73, 73, 73, 73, - 28, 29, 30, 73, 31, 32, 33, 73, - 73, 73, 73, 19, 73, 12, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 19, 20, 21, 22, - 73, 73, 73, 73, 73, 73, 73, 29, - 30, 73, 31, 32, 33, 73, 73, 73, - 73, 19, 73, 12, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 19, 20, 21, 22, 73, 73, - 73, 73, 73, 73, 73, 73, 30, 73, - 31, 32, 33, 73, 73, 73, 73, 19, - 73, 12, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 18, - 19, 20, 21, 22, 73, 24, 18, 73, - 73, 73, 28, 29, 30, 73, 31, 32, - 33, 73, 73, 73, 73, 19, 73, 12, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 18, 19, 20, - 21, 22, 73, 76, 18, 73, 73, 73, - 28, 29, 30, 73, 31, 32, 33, 73, - 73, 73, 73, 19, 73, 12, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 18, 19, 20, 21, 22, - 73, 73, 18, 73, 73, 73, 28, 29, - 30, 73, 31, 32, 33, 73, 73, 73, - 73, 19, 73, 12, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 18, 19, 20, 21, 22, 23, 24, - 18, 73, 73, 73, 28, 29, 30, 73, - 31, 32, 33, 73, 73, 73, 73, 19, - 73, 12, 73, 73, 3, 6, 73, 73, - 74, 73, 73, 73, 73, 73, 73, 18, - 19, 20, 21, 22, 23, 24, 18, 25, - 73, 27, 28, 29, 30, 73, 31, 32, - 33, 73, 73, 73, 73, 37, 73, 3, - 73, 73, 73, 73, 73, 73, 12, 73, - 73, 73, 73, 73, 73, 4, 73, 73, - 73, 73, 73, 73, 73, 19, 20, 21, - 22, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 31, 32, 33, 73, 3, - 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 4, 77, 78, - 73, 14, 73, 73, 73, 73, 73, 73, - 73, 79, 73, 14, 73, 6, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 6, 77, 8, - 73, 73, 73, 8, 73, 73, 12, 73, - 73, 3, 6, 14, 73, 74, 73, 73, - 73, 73, 73, 73, 18, 19, 20, 21, - 22, 23, 24, 18, 25, 26, 27, 28, - 29, 30, 73, 31, 32, 33, 73, 34, - 35, 73, 37, 73, 12, 73, 73, 3, - 6, 73, 73, 74, 73, 73, 73, 73, - 73, 73, 18, 19, 20, 21, 22, 23, - 24, 18, 25, 26, 27, 28, 29, 30, - 73, 31, 32, 33, 73, 73, 73, 73, - 37, 73, 34, 35, 73, 35, 73, 70, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 70, 71, 72, 8, 77, - 77, 77, 8, 77, 0 + 1, 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, 3, 2, 2, 2, 2, + 2, 2, 2, 4, 3, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 6, + 7, 8, 9, 10, 11, 12, 3, 13, + 14, 15, 16, 17, 9, 18, 19, 20, + 21, 22, 23, 24, 18, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 39, 41, 42, 1, 40, 43, + 40, 40, 44, 45, 46, 47, 48, 49, + 50, 51, 45, 52, 44, 53, 54, 55, + 56, 57, 58, 59, 40, 40, 40, 60, + 41, 42, 1, 40, 43, 40, 40, 61, + 45, 46, 47, 48, 49, 50, 51, 45, + 52, 53, 53, 54, 55, 56, 57, 58, + 59, 40, 40, 40, 60, 42, 62, 62, + 62, 62, 62, 62, 62, 63, 42, 41, + 42, 1, 40, 43, 40, 40, 40, 45, + 46, 47, 48, 49, 50, 51, 45, 52, + 53, 53, 54, 55, 56, 57, 58, 59, + 40, 40, 40, 60, 41, 40, 40, 40, + 40, 40, 40, 40, 45, 46, 47, 48, + 49, 40, 40, 40, 40, 40, 40, 54, + 55, 56, 57, 58, 59, 40, 40, 40, + 46, 41, 40, 40, 40, 40, 40, 40, + 40, 40, 46, 47, 48, 49, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 57, + 58, 59, 41, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 47, 48, 49, 41, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 48, 49, 41, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 49, 41, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 47, 48, 49, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 57, + 58, 59, 41, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 47, 48, 49, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 58, 59, 41, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 47, 48, 49, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 59, 41, 40, 40, 40, + 40, 40, 40, 40, 40, 46, 47, 48, + 49, 40, 40, 40, 40, 40, 40, 54, + 55, 56, 57, 58, 59, 40, 40, 40, + 46, 41, 40, 40, 40, 40, 40, 40, + 40, 40, 46, 47, 48, 49, 40, 40, + 40, 40, 40, 40, 40, 55, 56, 57, + 58, 59, 40, 40, 40, 46, 41, 40, + 40, 40, 40, 40, 40, 40, 40, 46, + 47, 48, 49, 40, 40, 40, 40, 40, + 40, 40, 40, 56, 57, 58, 59, 40, + 40, 40, 46, 41, 40, 40, 40, 40, + 40, 40, 40, 45, 46, 47, 48, 49, + 40, 51, 45, 40, 40, 40, 54, 55, + 56, 57, 58, 59, 40, 40, 40, 46, + 41, 40, 40, 40, 40, 40, 40, 40, + 45, 46, 47, 48, 49, 40, 64, 45, + 40, 40, 40, 54, 55, 56, 57, 58, + 59, 40, 40, 40, 46, 41, 40, 40, + 40, 40, 40, 40, 40, 45, 46, 47, + 48, 49, 40, 40, 45, 40, 40, 40, + 54, 55, 56, 57, 58, 59, 40, 40, + 40, 46, 41, 40, 40, 40, 40, 40, + 40, 40, 45, 46, 47, 48, 49, 50, + 51, 45, 40, 40, 40, 54, 55, 56, + 57, 58, 59, 40, 40, 40, 46, 41, + 42, 1, 40, 43, 40, 40, 40, 45, + 46, 47, 48, 49, 50, 51, 45, 52, + 40, 53, 54, 55, 56, 57, 58, 59, + 40, 40, 40, 60, 42, 62, 62, 62, + 41, 62, 62, 62, 63, 62, 62, 62, + 62, 46, 47, 48, 49, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 57, 58, + 59, 41, 42, 1, 40, 43, 40, 40, + 40, 45, 46, 47, 48, 49, 50, 51, + 45, 52, 44, 53, 54, 55, 56, 57, + 58, 59, 40, 40, 40, 60, 66, 65, + 65, 65, 67, 10, 66, 41, 42, 1, + 40, 43, 40, 40, 69, 45, 46, 47, + 48, 49, 50, 51, 45, 52, 44, 53, + 54, 55, 56, 57, 58, 59, 70, 71, + 40, 60, 41, 42, 1, 40, 43, 40, + 40, 40, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 44, 53, 54, 55, 56, + 57, 58, 59, 70, 71, 40, 60, 70, + 71, 71, 12, 3, 6, 73, 74, 73, + 73, 75, 18, 19, 20, 21, 22, 23, + 24, 18, 25, 27, 27, 28, 29, 30, + 31, 32, 33, 73, 73, 73, 37, 12, + 3, 6, 73, 74, 73, 73, 73, 18, + 19, 20, 21, 22, 23, 24, 18, 25, + 27, 27, 28, 29, 30, 31, 32, 33, + 73, 73, 73, 37, 12, 73, 73, 73, + 73, 73, 73, 73, 18, 19, 20, 21, + 22, 73, 73, 73, 73, 73, 73, 28, + 29, 30, 31, 32, 33, 73, 73, 73, + 19, 12, 73, 73, 73, 73, 73, 73, + 73, 73, 19, 20, 21, 22, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 31, + 32, 33, 12, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 20, 21, 22, 12, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 21, 22, 12, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 22, 12, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 20, 21, 22, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 31, + 32, 33, 12, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 20, 21, 22, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 32, 33, 12, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 20, 21, 22, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 33, 12, 73, 73, 73, + 73, 73, 73, 73, 73, 19, 20, 21, + 22, 73, 73, 73, 73, 73, 73, 28, + 29, 30, 31, 32, 33, 73, 73, 73, + 19, 12, 73, 73, 73, 73, 73, 73, + 73, 73, 19, 20, 21, 22, 73, 73, + 73, 73, 73, 73, 73, 29, 30, 31, + 32, 33, 73, 73, 73, 19, 12, 73, + 73, 73, 73, 73, 73, 73, 73, 19, + 20, 21, 22, 73, 73, 73, 73, 73, + 73, 73, 73, 30, 31, 32, 33, 73, + 73, 73, 19, 12, 73, 73, 73, 73, + 73, 73, 73, 18, 19, 20, 21, 22, + 73, 24, 18, 73, 73, 73, 28, 29, + 30, 31, 32, 33, 73, 73, 73, 19, + 12, 73, 73, 73, 73, 73, 73, 73, + 18, 19, 20, 21, 22, 73, 76, 18, + 73, 73, 73, 28, 29, 30, 31, 32, + 33, 73, 73, 73, 19, 12, 73, 73, + 73, 73, 73, 73, 73, 18, 19, 20, + 21, 22, 73, 73, 18, 73, 73, 73, + 28, 29, 30, 31, 32, 33, 73, 73, + 73, 19, 12, 73, 73, 73, 73, 73, + 73, 73, 18, 19, 20, 21, 22, 23, + 24, 18, 73, 73, 73, 28, 29, 30, + 31, 32, 33, 73, 73, 73, 19, 12, + 3, 6, 73, 74, 73, 73, 73, 18, + 19, 20, 21, 22, 23, 24, 18, 25, + 73, 27, 28, 29, 30, 31, 32, 33, + 73, 73, 73, 37, 3, 73, 73, 73, + 12, 73, 73, 73, 4, 73, 73, 73, + 73, 19, 20, 21, 22, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 31, 32, + 33, 3, 77, 77, 77, 77, 77, 77, + 77, 4, 78, 14, 73, 73, 73, 79, + 14, 6, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 6, 8, 73, 73, 8, + 12, 3, 6, 14, 74, 73, 73, 73, + 18, 19, 20, 21, 22, 23, 24, 18, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 73, 37, 12, 3, 6, + 73, 74, 73, 73, 73, 18, 19, 20, + 21, 22, 23, 24, 18, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 73, 73, + 73, 37, 34, 35, 35, 70, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 70, + 71, 8, 77, 77, 8, 0 }; -static const char _use_syllable_machine_trans_targs[] = { - 4, 8, 4, 36, 2, 4, 1, 5, - 6, 4, 29, 32, 4, 55, 56, 59, - 60, 64, 38, 39, 40, 41, 42, 49, - 50, 52, 61, 53, 46, 47, 48, 43, - 44, 45, 62, 63, 65, 54, 4, 4, - 4, 4, 7, 0, 28, 11, 12, 13, - 14, 15, 22, 23, 25, 26, 19, 20, - 21, 16, 17, 18, 27, 10, 4, 9, - 24, 4, 30, 31, 4, 33, 34, 35, - 4, 4, 3, 37, 51, 4, 57, 58 +static const char _use_syllable_machine_index_defaults[] = { + 0, 2, 2, 5, 9, 38, 40, 40, + 62, 62, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 62, 40, 65, 68, 65, + 40, 40, 72, 72, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 77, + 73, 73, 73, 77, 73, 73, 73, 73, + 72, 77, 0 }; -static const char _use_syllable_machine_trans_actions[] = { - 1, 0, 2, 3, 0, 4, 0, 0, - 7, 8, 0, 7, 9, 10, 0, 10, - 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 11, 12, - 13, 14, 7, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 7, 0, 0, - 0, 0, 0, 0, 0, 7, 15, 0, - 0, 16, 0, 0, 17, 7, 0, 0, - 18, 19, 0, 3, 0, 20, 0, 0 +static const char _use_syllable_machine_trans_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0 +}; + +static const char _use_syllable_machine_cond_targs[] = { + 4, 8, 4, 36, 2, 4, 1, 5, + 6, 4, 29, 32, 4, 55, 56, 59, + 60, 64, 38, 39, 40, 41, 42, 49, + 50, 52, 61, 53, 46, 47, 48, 43, + 44, 45, 62, 63, 65, 54, 4, 4, + 4, 4, 7, 0, 28, 11, 12, 13, + 14, 15, 22, 23, 25, 26, 19, 20, + 21, 16, 17, 18, 27, 10, 4, 9, + 24, 4, 30, 31, 4, 33, 34, 35, + 4, 4, 3, 37, 51, 4, 57, 58, + 0 +}; + +static const char _use_syllable_machine_cond_actions[] = { + 1, 0, 2, 3, 0, 4, 0, 0, + 7, 8, 0, 7, 9, 10, 0, 10, + 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 11, 12, + 13, 14, 7, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 7, 15, 0, + 0, 16, 0, 0, 17, 7, 0, 0, + 18, 19, 0, 3, 0, 20, 0, 0, + 0 }; static const char _use_syllable_machine_to_state_actions[] = { - 0, 0, 0, 0, 5, 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, 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, 0, 5, 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, 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 }; static const char _use_syllable_machine_from_state_actions[] = { - 0, 0, 0, 0, 6, 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, 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, 6, 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, 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 +}; + +static const char _use_syllable_machine_eof_cond_spaces[] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0 +}; + +static const char _use_syllable_machine_eof_cond_key_offs[] = { + 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, + 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, + 0, 0, 0 +}; + +static const char _use_syllable_machine_eof_cond_key_lens[] = { + 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, + 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, + 0, 0, 0 +}; + +static const char _use_syllable_machine_eof_cond_keys[] = { + 0 +}; + +static const char _use_syllable_machine_eof_trans[] = { + 1, 3, 3, 6, 0, 39, 41, 41, + 63, 63, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 63, 41, 66, 69, 66, + 41, 41, 73, 73, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 78, + 74, 74, 74, 78, 74, 74, 74, 74, + 73, 78, 0 +}; + +static const char _use_syllable_machine_nfa_targs[] = { 0, 0 }; -static const short _use_syllable_machine_eof_trans[] = { - 1, 3, 3, 6, 0, 39, 41, 41, - 63, 63, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 63, 41, 66, 69, 66, - 41, 41, 73, 73, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 78, - 74, 74, 74, 78, 74, 74, 74, 74, - 73, 78 +static const char _use_syllable_machine_nfa_offsets[] = { + 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, + 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, + 0, 0, 0 +}; + +static const char _use_syllable_machine_nfa_push_actions[] = { + 0, 0 +}; + +static const char _use_syllable_machine_nfa_pop_trans[] = { + 0, 0 }; static const int use_syllable_machine_start = 4; @@ -369,188 +405,292 @@ static const int use_syllable_machine_error = -1; static const int use_syllable_machine_en_main = 4; -#line 38 "hb-ot-shape-complex-use-machine.rl" -#line 146 "hb-ot-shape-complex-use-machine.rl" - - #define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial=1; \ +} HB_STMT_END static void find_syllables (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts, te, act; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 396 "hb-ot-shape-complex-use-machine.hh" + unsigned int p, pe, eof, ts, te, act; + int cs; + hb_glyph_info_t *info = buffer->info; + { - cs = use_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)use_syllable_machine_start; + ts = 0; + te = 0; + act = 0; } - -#line 166 "hb-ot-shape-complex-use-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 412 "hb-ot-shape-complex-use-machine.hh" + + + p=0; + pe = eof = buffer->len; + + unsigned int syllable_serial=1; + { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 6: -#line 1 "NONE" - {ts = p;} - break; -#line 426 "hb-ot-shape-complex-use-machine.hh" + int _cpc; + int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; { + if ( p == pe ) + goto _test_eof; + _resume: { + switch ( _use_syllable_machine_from_state_actions[cs] ) { + case 6: { + { + #line 1 "NONE" + {ts = p;}} + + break; } + } + + _keys = ( _use_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _use_syllable_machine_indicies + (_use_syllable_machine_index_offsets[cs])); + + if ( (info[p].use_category()) <= 44 ) + { + int _ic = (int)_use_syllable_machine_char_class[(int)(info[p].use_category()) - 0]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; + } + + goto _match_cond; + } + _match_cond: { + cs = (int)_use_syllable_machine_cond_targs[_trans]; + + if ( _use_syllable_machine_cond_actions[_trans] == 0 ) + goto _again; + + switch ( _use_syllable_machine_cond_actions[_trans] ) { + case 7: { + { + #line 1 "NONE" + {te = p+1;}} + + break; } + case 12: { + { + #line 135 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ + #line 135 "hb-ot-shape-complex-use-machine.rl" + found_syllable (independent_cluster); }}} + + break; } + case 14: { + { + #line 137 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ + #line 137 "hb-ot-shape-complex-use-machine.rl" + found_syllable (standard_cluster); }}} + + break; } + case 9: { + { + #line 141 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ + #line 141 "hb-ot-shape-complex-use-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 8: { + { + #line 142 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ + #line 142 "hb-ot-shape-complex-use-machine.rl" + found_syllable (non_cluster); }}} + + break; } + case 11: { + { + #line 135 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 135 "hb-ot-shape-complex-use-machine.rl" + found_syllable (independent_cluster); }}} + + break; } + case 15: { + { + #line 136 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 136 "hb-ot-shape-complex-use-machine.rl" + found_syllable (virama_terminated_cluster); }}} + + break; } + case 13: { + { + #line 137 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 137 "hb-ot-shape-complex-use-machine.rl" + found_syllable (standard_cluster); }}} + + break; } + case 17: { + { + #line 138 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 138 "hb-ot-shape-complex-use-machine.rl" + found_syllable (number_joiner_terminated_cluster); }}} + + break; } + case 16: { + { + #line 139 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 139 "hb-ot-shape-complex-use-machine.rl" + found_syllable (numeral_cluster); }}} + + break; } + case 18: { + { + #line 140 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 140 "hb-ot-shape-complex-use-machine.rl" + found_syllable (symbol_cluster); }}} + + break; } + case 19: { + { + #line 141 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 141 "hb-ot-shape-complex-use-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 20: { + { + #line 142 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ + #line 142 "hb-ot-shape-complex-use-machine.rl" + found_syllable (non_cluster); }}} + + break; } + case 1: { + { + #line 137 "hb-ot-shape-complex-use-machine.rl" + {p = ((te))-1; + { + #line 137 "hb-ot-shape-complex-use-machine.rl" + found_syllable (standard_cluster); }}} + + break; } + case 4: { + { + #line 141 "hb-ot-shape-complex-use-machine.rl" + {p = ((te))-1; + { + #line 141 "hb-ot-shape-complex-use-machine.rl" + found_syllable (broken_cluster); }}} + + break; } + case 2: { + { + #line 1 "NONE" + {switch( act ) { + case 7: { + p = ((te))-1; + { + #line 141 "hb-ot-shape-complex-use-machine.rl" + found_syllable (broken_cluster); } break; } + case 8: { + p = ((te))-1; + { + #line 142 "hb-ot-shape-complex-use-machine.rl" + found_syllable (non_cluster); } break; } + }} + } + + break; } + case 3: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 141 "hb-ot-shape-complex-use-machine.rl" + {act = 7;}} + + break; } + case 10: { + { + #line 1 "NONE" + {te = p+1;}} + { + #line 142 "hb-ot-shape-complex-use-machine.rl" + {act = 8;}} + + break; } + } + + + } + _again: { + switch ( _use_syllable_machine_to_state_actions[cs] ) { + case 5: { + { + #line 1 "NONE" + {ts = 0;}} + + break; } + } + + p += 1; + if ( p != pe ) + goto _resume; + } + _test_eof: { {} + if ( p == eof ) + { + if ( _use_syllable_machine_eof_cond_spaces[cs] != -1 ) { + _cekeys = ( _use_syllable_machine_eof_cond_keys + (_use_syllable_machine_eof_cond_key_offs[cs])); + _klen = (int)_use_syllable_machine_eof_cond_key_lens[cs]; + _cpc = 0; + { + const char *_lower = _cekeys; + const char *_upper = _cekeys + _klen - 1; + const char *_mid; + while ( 1 ) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( _cpc < (int)(*( _mid)) ) + _upper = _mid - 1; + else if ( _cpc > (int)(*( _mid)) ) + _lower = _mid + 1; + else { + goto _ok; + } + } + cs = -1; + goto _out; + } + _ok: {} + } + if ( _use_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_use_syllable_machine_eof_trans[cs] - 1; + goto _match_cond; + } + } + + } + _out: { {} + } + } } - - _keys = _use_syllable_machine_trans_keys + (cs<<1); - _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; - - _slen = _use_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) && - ( info[p].use_category()) <= _keys[1] ? - ( info[p].use_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _use_syllable_machine_trans_targs[_trans]; - - if ( _use_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 7: -#line 1 "NONE" - {te = p+1;} - break; - case 12: -#line 135 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (independent_cluster); }} - break; - case 14: -#line 137 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (standard_cluster); }} - break; - case 9: -#line 141 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} - break; - case 8: -#line 142 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (non_cluster); }} - break; - case 11: -#line 135 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (independent_cluster); }} - break; - case 15: -#line 136 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (virama_terminated_cluster); }} - break; - case 13: -#line 137 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (standard_cluster); }} - break; - case 17: -#line 138 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} - break; - case 16: -#line 139 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (numeral_cluster); }} - break; - case 18: -#line 140 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} - break; - case 19: -#line 141 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 20: -#line 142 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (non_cluster); }} - break; - case 1: -#line 137 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (standard_cluster); }} - break; - case 4: -#line 141 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; - case 2: -#line 1 "NONE" - { switch( act ) { - case 7: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - case 8: - {{p = ((te))-1;} found_syllable (non_cluster); } - break; - } - } - break; - case 3: -#line 1 "NONE" - {te = p+1;} -#line 141 "hb-ot-shape-complex-use-machine.rl" - {act = 7;} - break; - case 10: -#line 1 "NONE" - {te = p+1;} -#line 142 "hb-ot-shape-complex-use-machine.rl" - {act = 8;} - break; -#line 528 "hb-ot-shape-complex-use-machine.hh" - } - -_again: - switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 5: -#line 1 "NONE" - {ts = 0;} - break; -#line 537 "hb-ot-shape-complex-use-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _use_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _use_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 174 "hb-ot-shape-complex-use-machine.rl" - + } #undef found_syllable From 159fe962e90dd3b758ad10046b9d75cf87c1d4f3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:46:11 -0700 Subject: [PATCH 163/336] [doc] Make header search more resilient How stupid to scan all files... Sigh. --- docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile.am b/docs/Makefile.am index 9b54b40e1..a034912ca 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -33,7 +33,7 @@ SCAN_OPTIONS=--rebuild-types --deprecated-guards="HB_DISABLE_DEPRECATED" \ # Header files or dirs to ignore when scanning. Use base file/dir names # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code -IGNORE_HFILES=`cd $(top_srcdir)/src; find . -path './hb-*/*.h' | sed 's@^.*/@@'` +IGNORE_HFILES=`cd $(top_srcdir)/src; find . -path './*/*.h' | sed 's@^.*/@@'` if HAVE_GOBJECT else IGNORE_HFILES+=hb-gobject.h hb-gobject-enums.h hb-gobject-structs.h From 938de315756e08bd2b5fa816c7951640e5835b2e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:47:02 -0700 Subject: [PATCH 164/336] Comment --- src/hb-subset-glyf.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index 9095e9f76..d40233187 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -60,7 +60,7 @@ struct loca_data_t } }; -/** +/* * If hints are being dropped find the range which in glyf at which * the hinting instructions are located. Add them to the instruction_ranges * vector. From 1c81cff2d3f9df2c18ffbdfff02ed418560480c1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 11:51:10 -0700 Subject: [PATCH 165/336] Fix signed-comparison error on 32bit --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 4e270ce8c..27c8c1778 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -292,7 +292,7 @@ struct hb_serialize_context_t for (const object_t::link_t &link : parent->links) { const object_t &child = *packed[link.objidx]; - assert (link.bias <= parent->tail - parent->head); + assert (link.bias <= (size_t) (parent->tail - parent->head)); unsigned offset = (child.head - parent->head) - link.bias; if (link.is_wide) From 2eb7e0e0e923d096d2598133cacd6e5ee04a6a04 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 12:45:38 -0700 Subject: [PATCH 166/336] [serialize] Minor --- src/hb-serialize.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 27c8c1778..7e46df265 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -165,7 +165,7 @@ struct hb_serialize_context_t /* Only "pack" if there exist other objects... Otherwise, don't bother. * Saves a move. */ - if (packed.length == 1) + if (packed.length <= 1) return; pop_pack (); @@ -285,7 +285,10 @@ struct hb_serialize_context_t void resolve_links () { + if (unlikely (in_error ())) return; + assert (!current); + assert (packed.length > 1); for (const object_t *parent : ++hb_iter (packed)) { From 59ee61fddc76cd18f19f351bca7dd293eb610333 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 13:26:15 -0700 Subject: [PATCH 167/336] [name] Use iterators more --- src/hb-ot-name-table.hh | 46 ++++++++++++++--------------------------- src/hb-subset-plan.cc | 3 +++ 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 07c3f28e6..e4601ff25 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -169,44 +169,34 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } - void get_subsetted_ids (const name *source_name, - const hb_subset_plan_t *plan, - hb_vector_t& name_record_idx_to_retain) const - { - for(unsigned int i = 0; i < count; i++) - { - if (format == 0 && (unsigned int) source_name->nameRecordZ[i].nameID > 25) - continue; - if (!hb_set_is_empty (plan->name_ids) && - !hb_set_has (plan->name_ids, source_name->nameRecordZ[i].nameID)) - continue; - name_record_idx_to_retain.push (i); - } - } - bool serialize (hb_serialize_context_t *c, const name *source_name, - const hb_subset_plan_t *plan, - const hb_sorted_vector_t& name_record_idx_to_retain) + const hb_subset_plan_t *plan) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min ((*this)))) return_trace (false); + auto src_array = source_name->nameRecordZ.as_array (source_name->count); + + auto it = + + src_array + | hb_filter (plan->name_ids, &NameRecord::nameID) + ; + this->format = 0; - this->count = name_record_idx_to_retain.length; + this->count = it.len (); auto snap = c->snapshot (); this->nameRecordZ.serialize (c, this->count); this->stringOffset = c->length (); c->revert (snap); - auto src_array = source_name->nameRecordZ.as_array (source_name->count); const void *src_base = &(source_name + source_name->stringOffset); const void *dst_base = &(this + this->stringOffset); - + hb_iter (name_record_idx_to_retain) - | hb_apply ([&] (unsigned _) { c->copy (src_array[_], src_base, dst_base); }) + + it + | hb_apply ([&] (const NameRecord& _) { c->copy (_, src_base, dst_base); }) ; if (unlikely (c->ran_out_of_room)) return_trace (false); @@ -218,20 +208,14 @@ struct name bool subset (hb_subset_context_t *c) const { + TRACE_SUBSET (this); hb_subset_plan_t *plan = c->plan; - hb_sorted_vector_t name_record_idx_to_retain; - - get_subsetted_ids (this, plan, name_record_idx_to_retain); hb_serialize_context_t *serializer = c->serializer; name *name_prime = serializer->start_embed (); - if (!name_prime || !name_prime->serialize (serializer, this, plan, name_record_idx_to_retain)) - { - DEBUG_MSG (SUBSET, nullptr, "Failed to serialize write new name."); - return false; - } - - return true; + if (unlikely (!name_prime)) return_trace (false); + name_prime->serialize (serializer, this, plan); + return_trace (name_prime->count); } bool sanitize_records (hb_sanitize_context_t *c) const diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index fe636b190..901347b9f 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -207,6 +207,9 @@ hb_subset_plan_create (hb_face_t *face, plan->retain_gids = input->retain_gids; plan->unicodes = hb_set_create (); plan->name_ids = hb_set_reference (input->name_ids); + /* TODO Clean this up... */ + if (hb_set_is_empty (plan->name_ids)) + hb_set_add_range (plan->name_ids, 0, 0x7FFF); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); plan->codepoint_to_glyph = hb_map_create (); From f982b9d9f8d6b61efd2a3e89cc3d34923c1914b0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 13:29:01 -0700 Subject: [PATCH 168/336] [name] Clean up serialize() API --- src/hb-ot-name-table.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index e4601ff25..6a4ac093b 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -170,8 +170,8 @@ struct name { return min_size + count * nameRecordZ.item_size; } bool serialize (hb_serialize_context_t *c, - const name *source_name, - const hb_subset_plan_t *plan) + const name *source_name, + const hb_set_t *name_ids) { TRACE_SERIALIZE (this); @@ -181,7 +181,7 @@ struct name auto it = + src_array - | hb_filter (plan->name_ids, &NameRecord::nameID) + | hb_filter (name_ids, &NameRecord::nameID) ; this->format = 0; @@ -214,7 +214,7 @@ struct name hb_serialize_context_t *serializer = c->serializer; name *name_prime = serializer->start_embed (); if (unlikely (!name_prime)) return_trace (false); - name_prime->serialize (serializer, this, plan); + name_prime->serialize (serializer, this, plan->name_ids); return_trace (name_prime->count); } From 7c037bd2be2e794dfd882b806f684ad74c56dbb8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 13:37:43 -0700 Subject: [PATCH 169/336] [name] Clean up some more --- src/hb-meta.hh | 2 ++ src/hb-ot-name-table.hh | 30 ++++++++++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index e8002f253..f2134d6d8 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -163,6 +163,8 @@ struct hb_reference_wrapper template struct hb_enable_if {}; template struct hb_enable_if { typedef T type; }; #define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr +/* Concepts/Requires alias: */ +#define hb_requires(Cond) hb_enable_if((Cond)) template struct hb_is_same : hb_false_t {}; template struct hb_is_same : hb_true_t {}; diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 6a4ac093b..4e4da74bc 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -169,21 +169,16 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } + template bool serialize (hb_serialize_context_t *c, - const name *source_name, - const hb_set_t *name_ids) + Iterator it, + const void *src_string_pool) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min ((*this)))) return_trace (false); - auto src_array = source_name->nameRecordZ.as_array (source_name->count); - - auto it = - + src_array - | hb_filter (name_ids, &NameRecord::nameID) - ; - this->format = 0; this->count = it.len (); @@ -192,11 +187,10 @@ struct name this->stringOffset = c->length (); c->revert (snap); - const void *src_base = &(source_name + source_name->stringOffset); - const void *dst_base = &(this + this->stringOffset); + const void *dst_string_pool = &(this + this->stringOffset); + it - | hb_apply ([&] (const NameRecord& _) { c->copy (_, src_base, dst_base); }) + | hb_apply ([&] (const NameRecord& _) { c->copy (_, src_string_pool, dst_string_pool); }) ; if (unlikely (c->ran_out_of_room)) return_trace (false); @@ -209,12 +203,16 @@ struct name bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - hb_subset_plan_t *plan = c->plan; - hb_serialize_context_t *serializer = c->serializer; - name *name_prime = serializer->start_embed (); + name *name_prime = c->serializer->start_embed (); if (unlikely (!name_prime)) return_trace (false); - name_prime->serialize (serializer, this, plan->name_ids); + + auto it = + + nameRecordZ.as_array (count) + | hb_filter (c->plan->name_ids, &NameRecord::nameID) + ; + + name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset)); return_trace (name_prime->count); } From 52f6c04c1e0eab2aaa0c7d817b212c01ba993fe9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 13:45:48 -0700 Subject: [PATCH 170/336] Minor --- src/hb-serialize.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 7e46df265..dc9cc8226 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -290,13 +290,13 @@ struct hb_serialize_context_t assert (!current); assert (packed.length > 1); - for (const object_t *parent : ++hb_iter (packed)) + for (const object_t* parent : ++hb_iter (packed)) { for (const object_t::link_t &link : parent->links) { - const object_t &child = *packed[link.objidx]; + const object_t* child = packed[link.objidx]; assert (link.bias <= (size_t) (parent->tail - parent->head)); - unsigned offset = (child.head - parent->head) - link.bias; + unsigned offset = (child->head - parent->head) - link.bias; if (link.is_wide) { From c09d6c58e99dba50f29a569e4c53916b5b507ef1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 14:09:00 -0700 Subject: [PATCH 171/336] [iter] Require lvalue in operators that return reference --- src/hb-iter.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 63a178ae3..dc57e2be7 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -97,21 +97,21 @@ struct hb_iter_t item_t operator * () { return thiz()->__item__ (); } item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); } - iter_t& operator += (unsigned count) { thiz()->__forward__ (count); return *thiz(); } - iter_t& operator ++ () { thiz()->__next__ (); return *thiz(); } - iter_t& operator -= (unsigned count) { thiz()->__rewind__ (count); return *thiz(); } - iter_t& operator -- () { thiz()->__prev__ (); return *thiz(); } + iter_t& operator += (unsigned count) & { thiz()->__forward__ (count); return *thiz(); } + iter_t& operator ++ () & { thiz()->__next__ (); return *thiz(); } + iter_t operator ++ () && { thiz()->__next__ (); return *thiz(); } + iter_t& operator -= (unsigned count) & { thiz()->__rewind__ (count); return *thiz(); } + iter_t& operator -- () & { thiz()->__prev__ (); return *thiz(); } + iter_t operator -- () && { thiz()->__prev__ (); return *thiz(); } iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; } friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; } iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; } iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; } iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } template - iter_t& operator >> (T &v) { v = **thiz(); ++*thiz(); return *thiz(); } + iter_t& operator >> (T &v) & { v = **thiz(); ++*thiz(); return *thiz(); } template - iter_t& operator >> (T &v) const { v = **thiz(); ++*thiz(); return *thiz(); } - template - iter_t& operator << (const T v) { **thiz() = v; ++*thiz(); return *thiz(); } + iter_t& operator << (const T v) & { **thiz() = v; ++*thiz(); return *thiz(); } protected: hb_iter_t () {} From fa8c4ba81175f671c3f39f1586d0a1d9067d9f89 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 14:26:03 -0700 Subject: [PATCH 172/336] Minor --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index dc9cc8226..ccb7af988 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -393,7 +393,7 @@ struct hb_serialize_context_t { return _copy (src, hb_prioritize, hb_forward (ds)...); } template - hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } + hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } template Type *extend_size (Type &obj, unsigned int size) From e33ad252222481a6078a8bb423505e713b081313 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 15:46:24 -0700 Subject: [PATCH 173/336] [serialize] FeatureVariations subset->copy --- src/hb-ot-layout-common.hh | 6 +++--- src/hb-ot-layout-gsubgpos.hh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index a527b3966..153ee83e5 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1984,10 +1984,10 @@ struct FeatureVariations return (this+record.substitutions).find_substitute (feature_index); } - bool subset (hb_subset_context_t *c) const + FeatureVariations* copy (hb_serialize_context_t *c) const { - TRACE_SUBSET (this); - return_trace (c->serializer->embed (*this)); + TRACE_SERIALIZE (this); + return_trace (c->embed (*this)); } bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 0b4031499..5837e76d9 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2680,7 +2680,7 @@ struct GSUBGPOS out); if (version.to_int () >= 0x00010001u) - out->featureVars.serialize_subset (c, this+featureVars, out); + out->featureVars.serialize_copy (c->serializer, this+featureVars, out); return_trace (true); } From 95426ea983bde01fadf4681926cb77e3b3c0d40a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 15:56:51 -0700 Subject: [PATCH 174/336] Add comment --- src/hb-open-type.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 2990b0d58..2bfbee525 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -305,6 +305,7 @@ struct OffsetTo : Offset return ret; } + /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */ template bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts &&...ds) { From 7654ebe3a51c98b4d3bf6fb11779024f1c770962 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 16:53:03 -0700 Subject: [PATCH 175/336] Whitespace --- src/hb-algs.hh | 30 ++++++++++++++++++++---------- src/hb-iter.hh | 39 ++++++++++++++++++++++++++------------- src/hb-meta.hh | 11 ++++++----- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index ee604e88c..2d2fe31f0 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -38,13 +38,15 @@ struct { template T operator () (const T& v) const { return v; } -} HB_FUNCOBJ (hb_identity); +} +HB_FUNCOBJ (hb_identity); struct { template bool operator () (const T& v) const { return bool (v); } -} HB_FUNCOBJ (hb_bool); +} +HB_FUNCOBJ (hb_bool); struct { @@ -64,7 +66,8 @@ struct template auto operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize)) -} HB_FUNCOBJ (hb_hash); +} +HB_FUNCOBJ (hb_hash); struct { @@ -94,7 +97,8 @@ struct hb_prioritize, hb_forward (vs)...) ) -} HB_FUNCOBJ (hb_invoke); +} +HB_FUNCOBJ (hb_invoke); struct { @@ -119,7 +123,8 @@ struct hb_forward (v), hb_prioritize) ) -} HB_FUNCOBJ (hb_has); +} +HB_FUNCOBJ (hb_has); struct { @@ -145,7 +150,8 @@ struct hb_forward (v), hb_prioritize) ) -} HB_FUNCOBJ (hb_get); +} +HB_FUNCOBJ (hb_get); template @@ -170,24 +176,28 @@ struct { template auto operator () (const Pair& pair) const HB_AUTO_RETURN (pair.first) -} HB_FUNCOBJ (hb_first); +} +HB_FUNCOBJ (hb_first); struct { template auto operator () (const Pair& pair) const HB_AUTO_RETURN (pair.second) -} HB_FUNCOBJ (hb_second); +} +HB_FUNCOBJ (hb_second); struct { template auto operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a <= b ? a : b) -} HB_FUNCOBJ (hb_min); +} +HB_FUNCOBJ (hb_min); struct { template auto operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a >= b ? a : b) -} HB_FUNCOBJ (hb_max); +} +HB_FUNCOBJ (hb_max); /* diff --git a/src/hb-iter.hh b/src/hb-iter.hh index dc57e2be7..418ae9576 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -164,7 +164,8 @@ struct operator () (Type (&array)[length]) const { return hb_array_t (array, length); } -} HB_FUNCOBJ (hb_iter); +} +HB_FUNCOBJ (hb_iter); /* Mixin to fill in what the subclass doesn't provide. */ template @@ -360,7 +361,8 @@ struct hb_map_iter_factory_t operator () (Proj&& f) const { return hb_map_iter_factory_t (f); } -} HB_FUNCOBJ (hb_map); +} +HB_FUNCOBJ (hb_map); template @@ -408,7 +410,8 @@ struct hb_filter_iter_factory_t operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const { return hb_filter_iter_factory_t (p, f); } -} HB_FUNCOBJ (hb_filter); +} +HB_FUNCOBJ (hb_filter); template struct hb_reduce_t @@ -437,7 +440,8 @@ struct hb_reduce_t operator () (Redu&& r, InitT init_value) const { return hb_reduce_t (r, init_value); } -} HB_FUNCOBJ (hb_reduce); +} +HB_FUNCOBJ (hb_reduce); /* hb_zip() */ @@ -480,7 +484,8 @@ struct hb_zip_iter_t operator () (A& a, B &b) const { return hb_zip_iter_t (hb_iter (a), hb_iter (b)); } -} HB_FUNCOBJ (hb_zip); +} +HB_FUNCOBJ (hb_zip); /* hb_enumerate */ @@ -526,7 +531,8 @@ struct hb_enumerate_iter_t operator () (Iterable& it) const { return hb_enumerate_iter_t (hb_iter (it)); } -} HB_FUNCOBJ (hb_enumerate); +} +HB_FUNCOBJ (hb_enumerate); /* hb_apply() */ @@ -556,7 +562,8 @@ struct template hb_apply_t operator () (Appl *a) const { return hb_apply_t (*a); } -} HB_FUNCOBJ (hb_apply); +} +HB_FUNCOBJ (hb_apply); /* hb_sink() */ @@ -586,7 +593,8 @@ struct template hb_sink_t operator () (Sink *s) const { return hb_sink_t (*s); } -} HB_FUNCOBJ (hb_sink); +} +HB_FUNCOBJ (hb_sink); /* hb-drain: hb_sink to void / blackhole / /dev/null. */ @@ -600,7 +608,8 @@ struct for (; it; ++it) (void) *it; } -} HB_FUNCOBJ (hb_drain); +} +HB_FUNCOBJ (hb_drain); /* hb_unzip(): unzip and sink to two sinks. */ @@ -635,7 +644,8 @@ struct template hb_unzip_t operator () (Sink1 *s1, Sink2 *s2) const { return hb_unzip_t (*s1, *s2); } -} HB_FUNCOBJ (hb_unzip); +} +HB_FUNCOBJ (hb_unzip); /* hb-all, hb-any, hb-none. */ @@ -652,7 +662,8 @@ struct return false; return true; } -} HB_FUNCOBJ (hb_all); +} +HB_FUNCOBJ (hb_all); struct { template (arg))); #pragma GCC diagnostic pop } -} HB_FUNCOBJ (hb_addressof); +} +HB_FUNCOBJ (hb_addressof); template static inline T hb_declval (); #define hb_declval(T) (hb_declval ()) @@ -125,8 +126,8 @@ struct template auto operator () (T *v) const HB_AUTO_RETURN (*v) - -} HB_FUNCOBJ (hb_deref); +} +HB_FUNCOBJ (hb_deref); struct { @@ -135,8 +136,8 @@ struct template auto operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v)) - -} HB_FUNCOBJ (hb_ref); +} +HB_FUNCOBJ (hb_ref); template struct hb_reference_wrapper From 035b818e34bbd2d5c1f65328c9847c845d74d919 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 17:21:18 -0700 Subject: [PATCH 176/336] [meta] Fix addressof() --- src/hb-meta.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 132e644d5..6eb13155d 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -71,7 +71,7 @@ template using hb_type_identity = typename hb_match_identity::ty struct { template - T* operator () (const T& arg) const + T* operator () (T& arg) const { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" From 839618de3b3da285e8753b6ca6d767e9a483bfde Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 17:21:27 -0700 Subject: [PATCH 177/336] [serializer] Minor --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index ccb7af988..bb2637114 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -371,7 +371,7 @@ struct hb_serialize_context_t } template Type *embed (const Type &obj) - { return embed (&obj); } + { return embed (hb_addressof (obj)); } template auto _copy (const Type &src, hb_priority<1>, Ts &&...ds) HB_RETURN From 5c0f62adc969696b46c1ceb57cd3c2fa408eb94f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 17:23:46 -0700 Subject: [PATCH 178/336] [serializer] Accept pointer & reference in more methods --- src/hb-serialize.hh | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index bb2637114..21545a802 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -324,14 +324,11 @@ struct hb_serialize_context_t } template - Type *start_embed (const Type &_ HB_UNUSED) const - { return start_embed (); } + Type *start_embed (const Type *obj HB_UNUSED = nullptr) const + { return reinterpret_cast (this->head); } template - Type *start_embed (const Type *_ HB_UNUSED = nullptr) const - { - Type *ret = reinterpret_cast (this->head); - return ret; - } + Type *start_embed (const Type &obj) const + { return start_embed (hb_addressof (obj)); } /* Following two functions exist to allow setting breakpoint on. */ void err_ran_out_of_room () { this->ran_out_of_room = true; } @@ -391,25 +388,37 @@ struct hb_serialize_context_t template Type *copy (const Type &src, Ts &&...ds) { return _copy (src, hb_prioritize, hb_forward (ds)...); } + template + Type *copy (const Type *src, Ts &&...ds) + { return copy (*src, hb_forward (ds)...); } template hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } template - Type *extend_size (Type &obj, unsigned int size) + Type *extend_size (Type *obj, unsigned int size) { - assert (this->start <= (char *) &obj); - assert ((char *) &obj <= this->head); - assert ((char *) &obj + size >= this->head); - if (unlikely (!this->allocate_size (((char *) &obj) + size - this->head))) return nullptr; - return reinterpret_cast (&obj); + assert (this->start <= (char *) obj); + assert ((char *) obj <= this->head); + assert ((char *) obj + size >= this->head); + if (unlikely (!this->allocate_size (((char *) obj) + size - this->head))) return nullptr; + return reinterpret_cast (obj); } + template + Type *extend_size (Type &obj, unsigned int size) + { return extend_size (hb_addressof (obj), size); } template - Type *extend_min (Type &obj) { return extend_size (obj, obj.min_size); } + Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); } + template + Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); } template - Type *extend (Type &obj, Ts &&...ds) { return extend_size (obj, obj.get_size (hb_forward (ds)...)); } + Type *extend (Type *obj, Ts &&...ds) + { return extend_size (obj, obj->get_size (hb_forward (ds)...)); } + template + Type *extend (Type &obj, Ts &&...ds) + { return extend (hb_addressof (obj), hb_forward (ds)...); } /* Output routines. */ hb_bytes_t copy_bytes () const From 41248cce0e32653227a83eb4e42ccf793f040fc2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 20:54:31 -0700 Subject: [PATCH 179/336] Remove MIN/MAX in favor of hb_min/hb_max --- src/hb-aat-layout-common.hh | 8 ++++---- src/hb-aat-layout-feat-table.hh | 2 +- src/hb-aat-layout-kerx-table.hh | 2 +- src/hb-aat-layout-morx-table.hh | 18 +++++++++--------- src/hb-algs.hh | 14 +++++--------- src/hb-array.hh | 4 ++-- src/hb-blob.cc | 2 +- src/hb-buffer-serialize.cc | 32 ++++++++++++++++---------------- src/hb-buffer.cc | 4 ++-- src/hb-buffer.hh | 2 +- src/hb-common.cc | 20 ++++++++++---------- src/hb-coretext.cc | 6 +++--- src/hb-debug.hh | 2 +- src/hb-directwrite.cc | 2 +- src/hb-ft.cc | 2 +- src/hb-iter.hh | 2 +- src/hb-open-file.hh | 2 +- src/hb-open-type.hh | 2 +- src/hb-ot-cmap-table.hh | 8 ++++---- src/hb-ot-color-cbdt-table.hh | 6 +++--- src/hb-ot-color-cpal-table.hh | 2 +- src/hb-ot-color-sbix-table.hh | 2 +- src/hb-ot-glyf-table.hh | 14 +++++++------- src/hb-ot-hmtx-table.hh | 2 +- src/hb-ot-layout-gpos-table.hh | 2 +- src/hb-ot-layout-gsub-table.hh | 4 ++-- src/hb-ot-layout-gsubgpos.hh | 6 +++--- src/hb-ot-layout.cc | 2 +- src/hb-ot-map.cc | 8 ++++---- src/hb-ot-post-table.hh | 2 +- src/hb-ot-shape-complex-indic.cc | 8 ++++---- src/hb-ot-shape-complex-use.cc | 2 +- src/hb-ot-shape.cc | 4 ++-- src/hb-ot-tag.cc | 2 +- src/hb-ot-var-avar-table.hh | 2 +- src/hb-ot-var-fvar-table.hh | 18 +++++++++--------- src/hb-sanitize.hh | 4 ++-- src/hb-uniscribe.cc | 2 +- 38 files changed, 111 insertions(+), 115 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 95ac27128..ea24c9f0c 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -576,7 +576,7 @@ struct StateTable if (unlikely (stop > states)) return_trace (false); for (const HBUSHORT *p = states; stop < p; p--) - num_entries = MAX (num_entries, *(p - 1) + 1); + num_entries = hb_max (num_entries, *(p - 1) + 1); state_neg = min_state; } } @@ -597,7 +597,7 @@ struct StateTable if (unlikely (stop < states)) return_trace (false); for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++) - num_entries = MAX (num_entries, *p + 1); + num_entries = hb_max (num_entries, *p + 1); state_pos = max_state + 1; } } @@ -611,8 +611,8 @@ struct StateTable for (const Entry *p = &entries[entry]; p < stop; p++) { int newState = new_state (p->newState); - min_state = MIN (min_state, newState); - max_state = MAX (max_state, newState); + min_state = hb_min (min_state, newState); + max_state = hb_max (max_state, newState); } entry = num_entries; } diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh index ab23ee056..a20ef8640 100644 --- a/src/hb-aat-layout-feat-table.hh +++ b/src/hb-aat-layout-feat-table.hh @@ -165,7 +165,7 @@ struct feat unsigned int feature_count = featureNameCount; if (count && *count) { - unsigned int len = MIN (feature_count - start_offset, *count); + unsigned int len = hb_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; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index bb41fea9d..1b3f1f942 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -251,7 +251,7 @@ struct KerxSubTableFormat1 if (Format1EntryT::performAction (entry) && depth) { - unsigned int tuple_count = MAX (1u, table->header.tuple_count ()); + unsigned int tuple_count = hb_max (1u, table->header.tuple_count ()); unsigned int kern_idx = Format1EntryT::kernActionIndex (entry); kern_idx = Types::byteOffsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 4c4ea6206..7aa830d64 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -88,7 +88,7 @@ struct RearrangementSubtable start = buffer->idx; if (flags & MarkLast) - end = MIN (buffer->idx + 1, buffer->len); + end = hb_min (buffer->idx + 1, buffer->len); if ((flags & Verb) && start < end) { @@ -117,14 +117,14 @@ struct RearrangementSubtable }; unsigned int m = map[flags & Verb]; - unsigned int l = MIN (2, m >> 4); - unsigned int r = MIN (2, m & 0x0F); + unsigned int l = hb_min (2u, m >> 4); + unsigned int r = hb_min (2u, m & 0x0F); bool reverse_l = 3 == (m >> 4); bool reverse_r = 3 == (m & 0x0F); if (end - start >= l + r) { - buffer->merge_clusters (start, MIN (buffer->idx + 1, buffer->len)); + buffer->merge_clusters (start, hb_min (buffer->idx + 1, buffer->len)); buffer->merge_clusters (start, end); hb_glyph_info_t *info = buffer->info; @@ -261,13 +261,13 @@ struct ContextualSubtable } if (replacement) { - buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len)); + buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); buffer->info[mark].codepoint = *replacement; ret = true; } replacement = nullptr; - unsigned int idx = MIN (buffer->idx, buffer->len - 1); + unsigned int idx = hb_min (buffer->idx, buffer->len - 1); if (Types::extended) { if (entry.data.currentIndex != 0xFFFF) @@ -337,9 +337,9 @@ struct ContextualSubtable const EntryData &data = entries[i].data; if (data.markIndex != 0xFFFF) - num_lookups = MAX (num_lookups, 1 + data.markIndex); + num_lookups = hb_max (num_lookups, 1 + data.markIndex); if (data.currentIndex != 0xFFFF) - num_lookups = MAX (num_lookups, 1 + data.currentIndex); + num_lookups = hb_max (num_lookups, 1 + data.currentIndex); } return_trace (substitutionTables.sanitize (c, this, num_lookups)); @@ -744,7 +744,7 @@ struct InsertionSubtable buffer->move_to (end + count); - buffer->unsafe_to_break_from_outbuffer (mark, MIN (buffer->idx + 1, buffer->len)); + buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len)); } if (flags & SetMark) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 2d2fe31f0..eeac4b956 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -186,6 +186,10 @@ struct } HB_FUNCOBJ (hb_second); +/* Note. In min/max, we can use hb_type_identity for second argument. + * However, that would silently convert between different-signedness integers. + * Instead we accept two different types, such that compiler can err if + * comparing integers of different signedness. */ struct { template auto @@ -409,14 +413,6 @@ static inline unsigned char TOUPPER (unsigned char c) static inline unsigned char TOLOWER (unsigned char c) { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } -#undef MIN -template -static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } - -#undef MAX -template -static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } - static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) { return (a + (b - 1)) / b; } @@ -668,7 +664,7 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o { /* Pain because we don't know whether s is nul-terminated. */ char buf[64]; - len = MIN (ARRAY_LENGTH (buf) - 1, len); + len = hb_min (ARRAY_LENGTH (buf) - 1, len); strncpy (buf, s, len); buf[len] = '\0'; diff --git a/src/hb-array.hh b/src/hb-array.hh index 37ca63d35..2da8df0bb 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -143,7 +143,7 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> } void qsort (unsigned int start, unsigned int end) { - end = MIN (end, length); + end = hb_min (end, length); assert (start <= end); if (likely (start < end)) ::qsort (arrayZ + start, end - start, this->item_size, Type::cmp); @@ -166,7 +166,7 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> else count -= start_offset; if (seg_count) - count = *seg_count = MIN (count, *seg_count); + count = *seg_count = hb_min (count, *seg_count); return hb_array_t (arrayZ + start_offset, count); } hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 54637c727..699f66b1a 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -155,7 +155,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent, hb_blob_make_immutable (parent); blob = hb_blob_create (parent->data + offset, - MIN (length, parent->length - offset), + hb_min (length, parent->length - offset), HB_MEMORY_MODE_READONLY, hb_blob_reference (parent), _hb_blob_destroy); diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc index 6e265e84c..dcbdcea45 100644 --- a/src/hb-buffer-serialize.cc +++ b/src/hb-buffer-serialize.cc @@ -138,34 +138,34 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, *p++ = '"'; } else - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster)); } if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", x+pos[i].x_offset, y+pos[i].y_offset)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", pos[i].x_advance, pos[i].y_advance)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) { if (info[i].mask & HB_GLYPH_FLAG_DEFINED) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", extents.x_bearing, extents.y_bearing)); - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", extents.width, extents.height)); } @@ -224,37 +224,37 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, p += strlen (p); } else - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) { - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster)); } if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { if (x+pos[i].x_offset || y+pos[i].y_offset) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) { *p++ = '+'; - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); if (pos[i].y_advance) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); } } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) { if (info[i].mask & HB_GLYPH_FLAG_DEFINED) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) { hb_glyph_extents_t extents; hb_font_get_glyph_extents(font, info[i].codepoint, &extents); - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); + p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); } unsigned int l = p - b; @@ -380,7 +380,7 @@ static hb_bool_t parse_uint (const char *pp, const char *end, uint32_t *pv) { char buf[32]; - unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); strncpy (buf, pp, len); buf[len] = '\0'; @@ -401,7 +401,7 @@ static hb_bool_t parse_int (const char *pp, const char *end, int32_t *pv) { char buf[32]; - unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); strncpy (buf, pp, len); buf[len] = '\0'; diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 2dc02e9d6..d95404f5c 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -524,7 +524,7 @@ hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) - cluster = MIN (cluster, info[i].cluster); + cluster = hb_min (cluster, info[i].cluster); /* Extend end */ while (end < len && info[end - 1].cluster == info[end].cluster) @@ -555,7 +555,7 @@ hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int cluster = out_info[start].cluster; for (unsigned int i = start + 1; i < end; i++) - cluster = MIN (cluster, out_info[i].cluster); + cluster = hb_min (cluster, out_info[i].cluster); /* Extend start */ while (start && out_info[start - 1].cluster == out_info[start].cluster) diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh index 330f88bac..b2b190ace 100644 --- a/src/hb-buffer.hh +++ b/src/hb-buffer.hh @@ -379,7 +379,7 @@ struct hb_buffer_t unsigned int cluster) const { for (unsigned int i = start; i < end; i++) - cluster = MIN (cluster, infos[i].cluster); + cluster = hb_min (cluster, infos[i].cluster); return cluster; } void diff --git a/src/hb-common.cc b/src/hb-common.cc index 6db801cdd..70be6939b 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -356,7 +356,7 @@ hb_language_from_string (const char *str, int len) { /* NUL-terminate it. */ char strbuf[64]; - len = MIN (len, (int) sizeof (strbuf) - 1); + len = hb_min (len, (int) sizeof (strbuf) - 1); memcpy (strbuf, str, len); strbuf[len] = '\0'; item = lang_find_or_insert (strbuf); @@ -720,7 +720,7 @@ static bool parse_uint (const char **pp, const char *end, unsigned int *pv) { char buf[32]; - unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); strncpy (buf, *pp, len); buf[len] = '\0'; @@ -744,7 +744,7 @@ static bool parse_uint32 (const char **pp, const char *end, uint32_t *pv) { char buf[32]; - unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); strncpy (buf, *pp, len); buf[len] = '\0'; @@ -825,7 +825,7 @@ static bool parse_float (const char **pp, const char *end, float *pv) { char buf[32]; - unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); strncpy (buf, *pp, len); buf[len] = '\0'; @@ -1071,21 +1071,21 @@ hb_feature_to_string (hb_feature_t *feature, { s[len++] = '['; if (feature->start) - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); if (feature->end != feature->start + 1) { s[len++] = ':'; if (feature->end != (unsigned int) -1) - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end)); } s[len++] = ']'; } if (feature->value > 1) { s[len++] = '='; - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value)); } assert (len < ARRAY_LENGTH (s)); - len = MIN (len, size - 1); + len = hb_min (len, size - 1); memcpy (buf, s, len); buf[len] = '\0'; } @@ -1152,10 +1152,10 @@ hb_variation_to_string (hb_variation_t *variation, while (len && s[len - 1] == ' ') len--; s[len++] = '='; - len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value)); + len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value)); assert (len < ARRAY_LENGTH (s)); - len = MIN (len, size - 1); + len = hb_min (len, size - 1); memcpy (buf, s, len); buf[len] = '\0'; } diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 66f0fce1a..e0579bed8 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -771,7 +771,7 @@ resize_and_retry: feature.start < chars_len && feature.start < feature.end) { CFRange feature_range = CFRangeMake (feature.start, - MIN (feature.end, chars_len) - feature.start); + hb_min (feature.end, chars_len) - feature.start); if (feature.value) CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName); else @@ -1116,7 +1116,7 @@ resize_and_retry: unsigned int cluster = info[count - 1].cluster; for (unsigned int i = count - 1; i > 0; i--) { - cluster = MIN (cluster, info[i - 1].cluster); + cluster = hb_min (cluster, info[i - 1].cluster); info[i - 1].cluster = cluster; } } @@ -1125,7 +1125,7 @@ resize_and_retry: unsigned int cluster = info[0].cluster; for (unsigned int i = 1; i < count; i++) { - cluster = MIN (cluster, info[i].cluster); + cluster = hb_min (cluster, info[i].cluster); info[i].cluster = cluster; } } diff --git a/src/hb-debug.hh b/src/hb-debug.hh index e5328e916..57b3f1b04 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -161,7 +161,7 @@ _hb_debug_msg_va (const char *what, VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; fprintf (stderr, "%2u %s" VRBAR "%s", level, - bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level), + bars + sizeof (bars) - 1 - hb_min ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level), level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR); } else fprintf (stderr, " " VRBAR LBAR); diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 8f2e66025..6b2761e83 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -778,7 +778,7 @@ retry_getglyphs: { uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]]; - *p = MIN (*p, buffer->info[i].cluster); + *p = hb_min (*p, buffer->info[i].cluster); } for (unsigned int i = 1; i < glyphCount; i++) if (vis_clusters[i] == (uint32_t) -1) diff --git a/src/hb-ft.cc b/src/hb-ft.cc index f8dab8bc1..d70c38a7a 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -439,7 +439,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED, else { /* Make a nul-terminated version. */ char buf[128]; - len = MIN (len, (int) sizeof (buf) - 1); + len = hb_min (len, (int) sizeof (buf) - 1); strncpy (buf, name, len); buf[len] = '\0'; *glyph = FT_Get_Name_Index (ft_face, buf); diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 418ae9576..7358256c8 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -464,7 +464,7 @@ struct hb_zip_iter_t : __item_t__ __item__ () const { return __item_t__ (*a, *b); } __item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); } bool __more__ () const { return a && b; } - unsigned __len__ () const { return MIN (a.len (), b.len ()); } + unsigned __len__ () const { return hb_min (a.len (), b.len ()); } void __next__ () { ++a; ++b; } void __forward__ (unsigned n) { a += n; b += n; } void __prev__ () { --a; --b; } diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 0689facd0..5318c7fca 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -94,7 +94,7 @@ typedef struct OffsetTable if (start_offset >= tables.len) *table_count = 0; else - *table_count = MIN (*table_count, tables.len - start_offset); + *table_count = hb_min (*table_count, tables.len - start_offset); const TableRecord *sub_tables = tables.arrayZ + start_offset; unsigned int count = *table_count; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 2bfbee525..9458ceea7 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -921,7 +921,7 @@ struct BinSearchHeader { len = v; assert (len == v); - entrySelector = MAX (1u, hb_bit_storage (v)) - 1; + entrySelector = hb_max (1u, hb_bit_storage (v)) - 1; searchRange = 16 * (1u << entrySelector); rangeShift = v * 16 > searchRange ? 16 * v - searchRange diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 0a7d1ef67..b4c8c608b 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -93,7 +93,7 @@ struct CmapSubtableFormat4 this->length = get_sub_table_size (segments); this->segCountX2 = segments.length * 2; - this->entrySelector = MAX (1u, hb_bit_storage (segments.length)) - 1; + this->entrySelector = hb_max (1u, hb_bit_storage (segments.length)) - 1; this->searchRange = 2 * (1u << this->entrySelector); this->rangeShift = segments.length * 2 > this->searchRange ? 2 * segments.length - this->searchRange @@ -348,7 +348,7 @@ struct CmapSubtableFormat4 /* Some broken fonts have too long of a "length" value. * If that is the case, just change the value to truncate * the subtable at the end of the blob. */ - uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535, + uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535, (uintptr_t) (c->end - (char *) this)); if (!c->try_set (&length, new_length)) @@ -478,7 +478,7 @@ struct CmapSubtableLongSegmented { for (unsigned int i = 0; i < this->groups.len; i++) { out->add_range (this->groups[i].startCharCode, - MIN ((hb_codepoint_t) this->groups[i].endCharCode, + hb_min ((hb_codepoint_t) this->groups[i].endCharCode, (hb_codepoint_t) HB_UNICODE_MAX)); } } @@ -623,7 +623,7 @@ struct DefaultUVS : SortedArrayOf for (unsigned int i = 0; i < count; i++) { hb_codepoint_t first = arrayZ[i].startUnicodeValue; - hb_codepoint_t last = MIN ((hb_codepoint_t) (first + arrayZ[i].additionalCount), + hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount), (hb_codepoint_t) HB_UNICODE_MAX); out->add_range (first, last); } diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index b6dc364a1..96b14bd68 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -349,15 +349,15 @@ struct CBLC if (unlikely (!count)) return Null(BitmapSizeTable); - unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); + unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); if (!requested_ppem) requested_ppem = 1<<30; /* Choose largest strike. */ unsigned int best_i = 0; - unsigned int best_ppem = MAX (sizeTables[0].ppemX, sizeTables[0].ppemY); + unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY); for (unsigned int i = 1; i < count; i++) { - unsigned int ppem = MAX (sizeTables[i].ppemX, sizeTables[i].ppemY); + unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY); if ((requested_ppem <= ppem && ppem < best_ppem) || (requested_ppem > best_ppem && ppem > best_ppem)) { diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index 7df7059a8..9ec2957ea 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -144,7 +144,7 @@ struct CPAL { hb_array_t segment_colors = palette_colors.sub_array (start_offset, *color_count); /* Always return numColors colors per palette even if it has out-of-bounds start index. */ - unsigned int count = MIN (MAX (numColors - start_offset, 0), *color_count); + unsigned int count = hb_min ((unsigned) hb_max ((int) (numColors - start_offset), 0), *color_count); *color_count = count; for (unsigned int i = 0; i < count; i++) colors[i] = segment_colors[i]; /* Bound-checked read. */ diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 670c05504..f9739f9ef 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -175,7 +175,7 @@ struct sbix if (unlikely (!count)) return Null(SBIXStrike); - unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem); + unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem); if (!requested_ppem) requested_ppem = 1<<30; /* Choose largest strike. */ /* TODO Add DPI sensitivity as well? */ diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index b595e5efe..2a96c2e35 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -58,7 +58,7 @@ struct loca public: 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. */ + * defining it _MIN instead. */ }; @@ -241,7 +241,7 @@ struct glyf loca_table = hb_sanitize_context_t ().reference_table (face); glyf_table = hb_sanitize_context_t ().reference_table (face); - num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; + num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; } void fini () @@ -451,10 +451,10 @@ struct glyf const GlyphHeader &glyph_header = StructAtOffset (glyf_table, start_offset); - extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); - extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); - extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; - extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; + extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); + extents->y_bearing = hb_max (glyph_header.yMin, glyph_header.yMax); + extents->width = hb_max (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; + extents->height = hb_min (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; return true; } @@ -471,7 +471,7 @@ struct glyf public: 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. */ + * defining it _MIN instead. */ }; struct glyf_accelerator_t : glyf::accelerator_t {}; diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 5dff981ef..b3a97109b 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -240,7 +240,7 @@ struct hmtxvmtx return default_advance; } - return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance; + return table->longMetricZ[hb_min (glyph, (uint32_t) num_advances - 1)].advance; } unsigned int get_advance (hb_codepoint_t glyph, diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 556e4316d..4693f3818 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1287,7 +1287,7 @@ struct MarkLigPosFormat1 unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur()); unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (lig_id && lig_id == mark_id && mark_comp > 0) - comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1; + comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1; else comp_index = comp_count - 1; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index c5ebe44ec..5b25137c8 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -484,7 +484,7 @@ struct AlternateSet unsigned int shift = hb_ctz (lookup_mask); unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift); - /* If alt_index is MAX, randomize feature if it is the rand feature. */ + /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */ if (alt_index == HB_OT_MAP_MAX_VALUE && c->random) alt_index = c->random_number () % count + 1; @@ -792,7 +792,7 @@ struct LigatureSet if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false); for (unsigned int i = 0; i < ligatures.length; i++) { - unsigned int component_count = MAX (component_count_list[i] - 1, 0); + unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0); if (unlikely (!ligature[i].serialize (c, this) .serialize (c, ligatures[i], diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 5837e76d9..3c4bfa2c3 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -973,7 +973,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, if (this_comp == 0) this_comp = last_num_components; unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (this_comp, last_num_components); + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); } buffer->next_glyph (); @@ -995,7 +995,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, if (!this_comp) break; unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (this_comp, last_num_components); + hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); } else break; @@ -1173,7 +1173,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, else { /* NOTE: delta is negative. */ - delta = MAX (delta, (int) next - (int) count); + delta = hb_max (delta, (int) next - (int) count); next -= delta; } diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 1e2d159b5..817b28e68 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1735,7 +1735,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, unsigned int len = 0; if (char_count && characters && start_offset < cv_params.characters.len) { - len = MIN (cv_params.characters.len - start_offset, *char_count); + len = hb_min (cv_params.characters.len - start_offset, *char_count); for (unsigned int i = 0; i < len; ++i) characters[i] = cv_params.characters[start_offset + i]; } diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 846414c9b..92d70bb41 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -188,12 +188,12 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, feature_infos[j].default_value = feature_infos[i].default_value; } else { feature_infos[j].flags &= ~F_GLOBAL; - feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value); + feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value); /* Inherit default_value from j */ } feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK); - feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]); - feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]); + feature_infos[j].stage[0] = hb_min (feature_infos[j].stage[0], feature_infos[i].stage[0]); + feature_infos[j].stage[1] = hb_min (feature_infos[j].stage[1], feature_infos[i].stage[1]); } feature_infos.shrink (j + 1); } @@ -213,7 +213,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, bits_needed = 0; else /* Limit bits per feature. */ - bits_needed = MIN(HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value)); + bits_needed = hb_min (HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value)); if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) continue; /* Feature disabled, or not enough bits. */ diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 21aa94dad..12e08316a 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -131,7 +131,7 @@ struct post hb_bytes_t s = find_glyph_name (glyph); if (!s.length) return false; if (!buf_len) return true; - unsigned int len = MIN (buf_len - 1, s.length); + unsigned int len = hb_min (buf_len - 1, s.length); strncpy (buf, s.arrayZ, len); buf[len] = '\0'; return true; diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 6d46fe33c..7befbf630 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -645,7 +645,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Reorder characters */ for (unsigned int i = start; i < base; i++) - info[i].indic_position() = MIN (POS_PRE_C, (indic_position_t) info[i].indic_position()); + info[i].indic_position() = hb_min (POS_PRE_C, (indic_position_t) info[i].indic_position()); if (base < end) info[base].indic_position() = POS_BASE_C; @@ -801,7 +801,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, unsigned int j = start + info[i].syllable(); while (j != i) { - max = MAX (max, j); + max = hb_max (max, j); unsigned int next = start + info[j].syllable(); info[j].syllable() = 255; /* So we don't process j later again. */ j = next; @@ -1231,14 +1231,14 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* Note: this merge_clusters() is intentionally *after* the reordering. * Indic matra reordering is special and tricky... */ - buffer->merge_clusters (new_pos, MIN (end, base + 1)); + buffer->merge_clusters (new_pos, hb_min (end, base + 1)); new_pos--; } } else { for (unsigned int i = start; i < base; i++) if (info[i].indic_position () == POS_PRE_M) { - buffer->merge_clusters (i, MIN (end, base + 1)); + buffer->merge_clusters (i, hb_min (end, base + 1)); break; } } diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index ec4d4aa7e..cbaa519c4 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -294,7 +294,7 @@ setup_rphf_mask (const hb_ot_shape_plan_t *plan, foreach_syllable (buffer, start, end) { - unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start); + unsigned int limit = info[start].use_category() == USE_R ? 1 : hb_min (3u, end - start); for (unsigned int i = start; i < start + limit; i++) info[i].mask |= mask; } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 7fff3059e..03d9a68ae 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -962,12 +962,12 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR))) { - c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR, + c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR, (unsigned) HB_BUFFER_MAX_LEN_MIN); } if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR))) { - c->buffer->max_ops = MAX (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR, + c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR, (unsigned) HB_BUFFER_MAX_OPS_MIN); } diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index c57c688d4..4b42da42d 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -212,7 +212,7 @@ struct LangTag p = strchr (b, '-'); db = p ? (unsigned int) (p - b) : strlen (b); - return strncmp (a, b, MAX (da, db)); + return strncmp (a, b, hb_max (da, db)); } int cmp (const LangTag *that) const { return cmp (that->language); } diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh index c4a192dc9..57a3a6d16 100644 --- a/src/hb-ot-var-avar-table.hh +++ b/src/hb-ot-var-avar-table.hh @@ -123,7 +123,7 @@ struct avar void map_coords (int *coords, unsigned int coords_length) const { - unsigned int count = MIN (coords_length, axisCount); + unsigned int count = hb_min (coords_length, axisCount); const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 78cb3c867..3565185fd 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -122,8 +122,8 @@ struct fvar 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.); + info->min_value = hb_min (info->default_value, axis.minValue / 65536.); + info->max_value = hb_max (info->default_value, axis.maxValue / 65536.); } void get_axis_info (unsigned int axis_index, @@ -136,8 +136,8 @@ struct fvar 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->min_value = hb_min (info->default_value, axis.minValue / 65536.); + info->max_value = hb_max (info->default_value, axis.maxValue / 65536.); info->reserved = 0; } @@ -149,12 +149,12 @@ struct fvar { /* TODO Rewrite as hb_array_t<>::sub-array() */ unsigned int count = axisCount; - start_offset = MIN (start_offset, count); + start_offset = hb_min (start_offset, count); count -= start_offset; axes_array += start_offset; - count = MIN (count, *axes_count); + count = hb_min (count, *axes_count); *axes_count = count; for (unsigned int i = 0; i < count; i++) @@ -171,12 +171,12 @@ struct fvar { /* TODO Rewrite as hb_array_t<>::sub-array() */ unsigned int count = axisCount; - start_offset = MIN (start_offset, count); + start_offset = hb_min (start_offset, count); count -= start_offset; axes_array += start_offset; - count = MIN (count, *axes_count); + count = hb_min (count, *axes_count); *axes_count = count; for (unsigned int i = 0; i < count; i++) @@ -223,7 +223,7 @@ struct fvar hb_ot_var_axis_info_t axis; get_axis_info (axis_index, &axis); - v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */ + v = hb_max (hb_min (v, axis.max_value), axis.min_value); /* Clamp. */ if (v == axis.default_value) return 0; diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index 6799b7862..982723362 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -175,7 +175,7 @@ struct hb_sanitize_context_t : else { this->start = obj_start; - this->end = obj_start + MIN (this->end - obj_start, obj->get_size ()); + this->end = obj_start + hb_min (this->end - obj_start, obj->get_size ()); } } @@ -189,7 +189,7 @@ struct hb_sanitize_context_t : void start_processing () { reset_object (); - this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, + this->max_ops = hb_max ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; this->debug_depth = 0; diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index 4bbbf6122..ac4ff6366 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -967,7 +967,7 @@ retry: vis_clusters[i] = (uint32_t) -1; for (unsigned int i = 0; i < buffer->len; i++) { uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; - *p = MIN (*p, buffer->info[i].cluster); + *p = hb_min (*p, buffer->info[i].cluster); } for (unsigned int i = 1; i < glyphs_len; i++) if (vis_clusters[i] == (uint32_t) -1) From 2b9402a86a4e37e6386f8028bdf3789ae262a4c4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 20:55:33 -0700 Subject: [PATCH 180/336] Use universal references in hb_min/max --- src/hb-algs.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index eeac4b956..fe41702cf 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -193,13 +193,13 @@ HB_FUNCOBJ (hb_second); struct { template auto - operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a <= b ? a : b) + operator () (T&& a, T2&& b) const HB_AUTO_RETURN (a <= b ? a : b) } HB_FUNCOBJ (hb_min); struct { template auto - operator () (const T& a, const T2& b) const HB_AUTO_RETURN (a >= b ? a : b) + operator () (T&& a, T2&& b) const HB_AUTO_RETURN (a >= b ? a : b) } HB_FUNCOBJ (hb_max); From 83e3eabd84e2b53c696768d1357a6a259bcd3576 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 20:58:43 -0700 Subject: [PATCH 181/336] Whitespace --- src/hb-aat-layout-common.hh | 2 +- src/hb-aat-layout-kerx-table.hh | 2 +- src/hb-aat-layout-morx-table.hh | 2 +- src/hb-algs.hh | 6 +++--- src/hb-dispatch.hh | 2 +- src/hb-open-type.hh | 18 +++++++++--------- src/hb-ot-kern-table.hh | 4 ++-- src/hb-ot-layout-common.hh | 2 +- src/hb-ot-layout-gpos-table.hh | 16 ++++++++-------- src/hb-ot-layout-gsub-table.hh | 14 +++++++------- src/hb-ot-layout-gsubgpos.hh | 8 ++++---- src/hb-sanitize.hh | 6 +++--- src/hb-serialize.hh | 12 ++++++------ src/hb-subset.hh | 6 +++--- 14 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index ea24c9f0c..a8c4b7637 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -154,7 +154,7 @@ struct LookupSegmentArray valuesZ.sanitize (c, base, last - first + 1)); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 1b3f1f942..cec63ac6d 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -772,7 +772,7 @@ struct KerxSubTable unsigned int get_type () const { return u.header.coverage & u.header.SubtableType; } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 7aa830d64..81d78972a 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -884,7 +884,7 @@ struct ChainSubtable }; template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); diff --git a/src/hb-algs.hh b/src/hb-algs.hh index fe41702cf..23cb9b061 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -75,7 +75,7 @@ struct /* Pointer-to-member-function. */ template auto - impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN + impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals&&... vs) const HB_AUTO_RETURN ((hb_deref (hb_forward (v1)).*hb_forward (a)) (hb_forward (vs)...)) /* Pointer-to-member. */ @@ -85,13 +85,13 @@ struct /* Operator(). */ template auto - impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN + impl (Appl&& a, hb_priority<0>, Vals&&... vs) const HB_AUTO_RETURN (hb_deref (hb_forward (a)) (hb_forward (vs)...)) public: template auto - operator () (Appl&& a, Vals &&...vs) const HB_AUTO_RETURN + operator () (Appl&& a, Vals&&... vs) const HB_AUTO_RETURN ( impl (hb_forward (a), hb_prioritize, diff --git a/src/hb-dispatch.hh b/src/hb-dispatch.hh index 6b497823d..be4a90f4f 100644 --- a/src/hb-dispatch.hh +++ b/src/hb-dispatch.hh @@ -48,7 +48,7 @@ struct hb_dispatch_context_t template bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } template - return_t dispatch (const T &obj, Ts &&...ds) + return_t dispatch (const T &obj, Ts&&... ds) { return obj.dispatch (thiz (), hb_forward (ds)...); } static return_t no_dispatch_return_value () { return Context::default_return_value (); } static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; } diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9458ceea7..e2e562300 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -285,7 +285,7 @@ struct OffsetTo : Offset } template - bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts &&...ds) + bool serialize_subset (hb_subset_context_t *c, const Type &src, const void *base, Ts&&... ds) { *this = 0; if (has_null && &src == _hb_has_null::get_null ()) @@ -307,7 +307,7 @@ struct OffsetTo : Offset /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */ template - bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts &&...ds) + bool serialize_copy (hb_serialize_context_t *c, const Type &src, const void *base, Ts&&... ds) { *this = 0; if (has_null && &src == _hb_has_null::get_null ()) @@ -332,7 +332,7 @@ struct OffsetTo : Offset } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && @@ -465,7 +465,7 @@ struct UnsizedArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); @@ -511,7 +511,7 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace ((UnsizedOffsetArrayOf @@ -647,7 +647,7 @@ struct ArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); @@ -721,7 +721,7 @@ struct OffsetListOf : OffsetArrayOf } template - bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); return_trace (OffsetArrayOf::sanitize (c, this, hb_forward (ds)...)); @@ -823,7 +823,7 @@ struct ArrayOfM1 { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } template - bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); @@ -1028,7 +1028,7 @@ struct VarSizedBinSearchArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 1310b843c..436dad45d 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -122,7 +122,7 @@ struct KernSubTable } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); @@ -305,7 +305,7 @@ struct kern { return dispatch (c); } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 153ee83e5..17a03c85f 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -683,7 +683,7 @@ struct Lookup } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { unsigned int lookup_type = get_type (); TRACE_DISPATCH (this, lookup_type); diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 4693f3818..228820a17 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -577,7 +577,7 @@ struct SinglePosFormat2 struct SinglePos { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -908,7 +908,7 @@ struct PairPosFormat2 struct PairPos { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1093,7 +1093,7 @@ struct CursivePosFormat1 struct CursivePos { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1209,7 +1209,7 @@ struct MarkBasePosFormat1 struct MarkBasePos { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1334,7 +1334,7 @@ struct MarkLigPosFormat1 struct MarkLigPos { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1456,7 +1456,7 @@ struct MarkMarkPosFormat1 struct MarkMarkPos { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1508,7 +1508,7 @@ struct PosLookupSubTable }; template - typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { @@ -1582,7 +1582,7 @@ struct PosLookup : Lookup static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { return Lookup::dispatch (c, hb_forward (ds)...); } bool subset (hb_subset_context_t *c) const diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 5b25137c8..364ef189e 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -252,7 +252,7 @@ struct SingleSubst } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -441,7 +441,7 @@ struct MultipleSubst } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -615,7 +615,7 @@ struct AlternateSubst } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -946,7 +946,7 @@ struct LigatureSubst } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1114,7 +1114,7 @@ struct ReverseChainSingleSubstFormat1 struct ReverseChainSingleSubst { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -1154,7 +1154,7 @@ struct SubstLookupSubTable }; template - typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { @@ -1332,7 +1332,7 @@ struct SubstLookup : Lookup } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { return Lookup::dispatch (c, hb_forward (ds)...); } bool subset (hb_subset_context_t *c) const diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3c4bfa2c3..3d4a1bca8 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -1764,7 +1764,7 @@ struct ContextFormat3 struct Context { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -2475,7 +2475,7 @@ struct ChainContextFormat3 struct ChainContext { template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); @@ -2511,7 +2511,7 @@ struct ExtensionFormat1 } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, format); if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); @@ -2558,7 +2558,7 @@ struct Extension } template - typename context_t::return_t dispatch (context_t *c, Ts &&...ds) const + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { TRACE_DISPATCH (this, u.format); if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index 982723362..ac424c1d9 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -136,14 +136,14 @@ struct hb_sanitize_context_t : private: template auto - _dispatch (const T &obj, hb_priority<1>, Ts &&...ds) HB_AUTO_RETURN + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN ( obj.sanitize (this, hb_forward (ds)...) ) template auto - _dispatch (const T &obj, hb_priority<0>, Ts &&...ds) HB_AUTO_RETURN + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN ( obj.dispatch (this, hb_forward (ds)...) ) public: template auto - dispatch (const T &obj, Ts &&...ds) HB_AUTO_RETURN + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN ( _dispatch (obj, hb_prioritize, hb_forward (ds)...) ) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 21545a802..e0f79809f 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -134,7 +134,7 @@ struct hb_serialize_context_t template bool propagate_error (T &&obj) { return check_success (!hb_deref (obj).in_error ()); } - template bool propagate_error (T1 &&o1, Ts &&...os) + template bool propagate_error (T1 &&o1, Ts&&... os) { return propagate_error (hb_forward (o1)) && propagate_error (hb_forward (os)...); } @@ -371,7 +371,7 @@ struct hb_serialize_context_t { return embed (hb_addressof (obj)); } template auto - _copy (const Type &src, hb_priority<1>, Ts &&...ds) HB_RETURN + _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN (Type *, src.copy (this, hb_forward (ds)...)) template auto @@ -386,10 +386,10 @@ struct hb_serialize_context_t /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data * instead of memcpy(). */ template - Type *copy (const Type &src, Ts &&...ds) + Type *copy (const Type &src, Ts&&... ds) { return _copy (src, hb_prioritize, hb_forward (ds)...); } template - Type *copy (const Type *src, Ts &&...ds) + Type *copy (const Type *src, Ts&&... ds) { return copy (*src, hb_forward (ds)...); } template @@ -414,10 +414,10 @@ struct hb_serialize_context_t Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); } template - Type *extend (Type *obj, Ts &&...ds) + Type *extend (Type *obj, Ts&&... ds) { return extend_size (obj, obj->get_size (hb_forward (ds)...)); } template - Type *extend (Type &obj, Ts &&...ds) + Type *extend (Type &obj, Ts&&... ds) { return extend (hb_addressof (obj), hb_forward (ds)...); } /* Output routines. */ diff --git a/src/hb-subset.hh b/src/hb-subset.hh index 1c3f41fdd..b8dd07ab2 100644 --- a/src/hb-subset.hh +++ b/src/hb-subset.hh @@ -44,14 +44,14 @@ struct hb_subset_context_t : private: template auto - _dispatch (const T &obj, hb_priority<1>, Ts &&...ds) HB_AUTO_RETURN + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN ( obj.subset (this, hb_forward (ds)...) ) template auto - _dispatch (const T &obj, hb_priority<0>, Ts &&...ds) HB_AUTO_RETURN + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN ( obj.dispatch (this, hb_forward (ds)...) ) public: template auto - dispatch (const T &obj, Ts &&...ds) HB_AUTO_RETURN + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN ( _dispatch (obj, hb_prioritize, hb_forward (ds)...) ) hb_subset_plan_t *plan; From 1ad07080c3ea7f6a1b3cb247529ec0c78575a6d3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 21:00:23 -0700 Subject: [PATCH 182/336] Rename --- src/hb-algs.hh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 23cb9b061..7ed42d65f 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -74,28 +74,28 @@ struct private: /* Pointer-to-member-function. */ - template auto - impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals&&... vs) const HB_AUTO_RETURN - ((hb_deref (hb_forward (v1)).*hb_forward (a)) (hb_forward (vs)...)) + template auto + impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN + ((hb_deref (hb_forward (v)).*hb_forward (a)) (hb_forward (ds)...)) /* Pointer-to-member. */ - template auto - impl (Appl&& a, hb_priority<1>, Val &&v) const HB_AUTO_RETURN - ((hb_deref (hb_forward (v))).*hb_forward (a)) + template auto + impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN + ((hb_deref (hb_forward (v))).*hb_forward (a)) /* Operator(). */ - template auto - impl (Appl&& a, hb_priority<0>, Vals&&... vs) const HB_AUTO_RETURN - (hb_deref (hb_forward (a)) (hb_forward (vs)...)) + template auto + impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN + (hb_deref (hb_forward (a)) (hb_forward (ds)...)) public: - template auto - operator () (Appl&& a, Vals&&... vs) const HB_AUTO_RETURN + template auto + operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN ( impl (hb_forward (a), hb_prioritize, - hb_forward (vs)...) + hb_forward (ds)...) ) } HB_FUNCOBJ (hb_invoke); From 6fa1f38070e710b2f80a836bd633b6ab33e1bc80 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 21:33:26 -0700 Subject: [PATCH 183/336] [algs] Accept varargs in hb_min/max --- src/hb-algs.hh | 24 +++++++++++++++++++++--- src/test-algs.cc | 8 ++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 7ed42d65f..3b5e45f93 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -186,20 +186,38 @@ struct } HB_FUNCOBJ (hb_second); -/* Note. In min/max, we can use hb_type_identity for second argument. +/* Note. In min/max impl, we can use hb_type_identity for second argument. * However, that would silently convert between different-signedness integers. * Instead we accept two different types, such that compiler can err if * comparing integers of different signedness. */ struct { + private: template auto - operator () (T&& a, T2&& b) const HB_AUTO_RETURN (a <= b ? a : b) + impl (T&& a, T2&& b) const HB_AUTO_RETURN (a <= b ? a : b) + + public: + template auto + operator () (T&& a) const HB_AUTO_RETURN (a) + + template auto + operator () (T&& a, Ts&& ...ds) const HB_AUTO_RETURN + (impl (hb_forward (a), (*this) (hb_forward (ds)...))) } HB_FUNCOBJ (hb_min); struct { + private: template auto - operator () (T&& a, T2&& b) const HB_AUTO_RETURN (a >= b ? a : b) + impl (T&& a, T2&& b) const HB_AUTO_RETURN (a >= b ? a : b) + + public: + template auto + operator () (T&& a) const HB_AUTO_RETURN (a) + + template auto + operator () (T&& a, Ts&& ...ds) const HB_AUTO_RETURN + (impl (hb_forward (a), (*this) (hb_forward (ds)...))) } HB_FUNCOBJ (hb_max); diff --git a/src/test-algs.cc b/src/test-algs.cc index 163a79ad3..0a8fcbff7 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -62,5 +62,13 @@ main (int argc, char **argv) A a; hb_invoke (&A::a, a); + assert (1 == hb_min (3, 8, 1, 2)); + assert (8 == hb_max (3, 8, 1, 2)); + + int x = 1, y = 2; + int &z = hb_min (x, y); + z = 3; + assert (x == 3); + return 0; } From af571dbffc12e6bb7a3146762d12bb4ac3f19bdc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 21:39:20 -0700 Subject: [PATCH 184/336] [meta] Replace most hb_enable_if with hb_requires They do absolutely same thing. hb_requires is to encode constraints, whereas hb_enable_if is for more conditional enabling. --- src/hb-iter.hh | 63 +++++++++++++++++--------------------- src/hb-open-type.hh | 6 ++-- src/hb-ot-layout-common.hh | 6 ++-- src/test-iter.cc | 6 ++-- 4 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 7358256c8..5ad839e2a 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -281,11 +281,11 @@ struct hb_is_iterator_of { enum { /* Range-based 'for' for iterables. */ template + hb_requires (hb_is_iterable (Iterable))> static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ()) template + hb_requires (hb_is_iterable (Iterable))> static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ()) /* begin()/end() are NOT looked up non-ADL. So each namespace must declare them. @@ -293,11 +293,11 @@ static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable). namespace OT { template + hb_requires (hb_is_iterable (Iterable))> static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ()) template + hb_requires (hb_is_iterable (Iterable))> static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ()) } @@ -308,14 +308,14 @@ static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable). */ template + hb_requires (hb_is_iterator (Lhs))> static inline auto operator | (Lhs lhs, const Rhs &rhs) HB_AUTO_RETURN (rhs (lhs)) /* hb_map(), hb_filter(), hb_reduce() */ template + hb_requires (hb_is_iterator (Iter))> struct hb_map_iter_t : hb_iter_t, decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t)))> @@ -347,7 +347,7 @@ struct hb_map_iter_factory_t hb_map_iter_factory_t (Proj f) : f (f) {} template + hb_requires (hb_is_iterator (Iter))> hb_map_iter_t operator () (Iter it) const { return hb_map_iter_t (it, f); } @@ -365,7 +365,7 @@ struct HB_FUNCOBJ (hb_map); template + hb_requires (hb_is_iterator (Iter))> struct hb_filter_iter_t : hb_iter_with_fallback_t, typename Iter::item_t> @@ -394,7 +394,7 @@ struct hb_filter_iter_factory_t hb_filter_iter_factory_t (Pred p, Proj f) : p (p), f (f) {} template + hb_requires (hb_is_iterator (Iter))> hb_filter_iter_t operator () (Iter it) const { return hb_filter_iter_t (it, p, f); } @@ -419,7 +419,7 @@ struct hb_reduce_t hb_reduce_t (Redu r, InitT init_value) : r (r), init_value (init_value) {} template AccuT operator () (Iter it) const @@ -480,7 +480,7 @@ struct hb_zip_iter_t : struct { template + hb_requires (hb_is_iterable (A) && hb_is_iterable (B))> hb_zip_iter_t operator () (A& a, B &b) const { return hb_zip_iter_t (hb_iter (a), hb_iter (b)); } @@ -490,7 +490,7 @@ HB_FUNCOBJ (hb_zip); /* hb_enumerate */ template + hb_requires (hb_is_iterator (Iter))> struct hb_enumerate_iter_t : hb_iter_t, hb_pair_t> @@ -527,7 +527,7 @@ struct hb_enumerate_iter_t : struct { template + hb_requires (hb_is_iterable (Iterable))> hb_enumerate_iter_t operator () (Iterable& it) const { return hb_enumerate_iter_t (hb_iter (it)); } @@ -542,9 +542,8 @@ struct hb_apply_t hb_apply_t (Appl a) : a (a) {} template - void - operator () (Iter it) const + hb_requires (hb_is_iterator (Iter))> + void operator () (Iter it) const { for (; it; ++it) (void) hb_invoke (a, *it); @@ -573,9 +572,8 @@ struct hb_sink_t hb_sink_t (Sink&& s) : s (s) {} template - void - operator () (Iter it) const + hb_requires (hb_is_iterator (Iter))> + void operator () (Iter it) const { for (; it; ++it) s << *it; @@ -601,9 +599,8 @@ HB_FUNCOBJ (hb_sink); struct { template - void - operator () (Iter it) const + hb_requires (hb_is_iterator (Iter))> + void operator () (Iter it) const { for (; it; ++it) (void) *it; @@ -619,9 +616,8 @@ struct hb_unzip_t hb_unzip_t (Sink1&& s1, Sink2&& s2) : s1 (s1), s2 (s2) {} template - void - operator () (Iter it) const + hb_requires (hb_is_iterator (Iter))> + void operator () (Iter it) const { for (; it; ++it) { @@ -653,9 +649,8 @@ HB_FUNCOBJ (hb_unzip); struct { template - bool - operator () (Iterable&& c) const + hb_requires (hb_is_iterable (Iterable))> + bool operator () (Iterable&& c) const { for (auto it = hb_iter (c); it; ++it) if (!*it) @@ -667,9 +662,8 @@ HB_FUNCOBJ (hb_all); struct { template - bool - operator () (Iterable&& c) const + hb_requires (hb_is_iterable (Iterable))> + bool operator () (Iterable&& c) const { for (auto it = hb_iter (c); it; ++it) if (*it) @@ -681,9 +675,8 @@ HB_FUNCOBJ (hb_any); struct { template - bool - operator () (Iterable&& c) const + hb_requires (hb_is_iterable (Iterable))> + bool operator () (Iterable&& c) const { for (auto it = hb_iter (c); it; ++it) if (*it) @@ -698,7 +691,7 @@ HB_FUNCOBJ (hb_none); */ template + hb_requires (hb_is_iterable (C))> inline void hb_fill (C& c, const V &v) { diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index e2e562300..5c015af3e 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -419,7 +419,7 @@ struct UnsizedArrayOf return_trace (true); } template + hb_requires (hb_is_iterator_of (Iterator, const Type))> bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); @@ -600,7 +600,7 @@ struct ArrayOf return_trace (true); } template + hb_requires (hb_is_iterator_of (Iterator, const Type))> bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); @@ -880,7 +880,7 @@ struct SortedArrayOf : ArrayOf return_trace (ret); } template + hb_requires (hb_is_sorted_iterator_of (Iterator, const Type))> bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 17a03c85f..05f84d254 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -797,7 +797,7 @@ struct CoverageFormat1 } template + hb_requires (hb_is_sorted_iterator_of (Iterator, const GlyphID))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); @@ -866,7 +866,7 @@ struct CoverageFormat2 } template + hb_requires (hb_is_sorted_iterator_of (Iterator, const GlyphID))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); @@ -1030,7 +1030,7 @@ struct Coverage } template + hb_requires (hb_is_sorted_iterator_of (Iterator, const GlyphID))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); diff --git a/src/test-iter.cc b/src/test-iter.cc index afbcbe9b5..e8c6bda6b 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -65,7 +65,7 @@ struct some_array_t template + hb_requires (hb_is_iterator (Iter))> static void test_iterator_non_default_constructable (Iter it) { @@ -92,7 +92,7 @@ test_iterator_non_default_constructable (Iter it) } template + hb_requires (hb_is_iterator (Iter))> static void test_iterator (Iter it) { @@ -103,7 +103,7 @@ test_iterator (Iter it) } template + hb_requires (hb_is_iterable (Iterable))> static void test_iterable (const Iterable &lst = Null(Iterable)) { From e8bd5fc3fa2cc5c5f8f254629553902aed3496ba Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 22:29:40 -0700 Subject: [PATCH 185/336] [meta] Move hb_invoke from algs to meta --- src/hb-algs.hh | 31 ------------------------------- src/hb-meta.hh | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 3b5e45f93..77382458d 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -69,37 +69,6 @@ struct } HB_FUNCOBJ (hb_hash); -struct -{ - private: - - /* Pointer-to-member-function. */ - template auto - impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN - ((hb_deref (hb_forward (v)).*hb_forward (a)) (hb_forward (ds)...)) - - /* Pointer-to-member. */ - template auto - impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN - ((hb_deref (hb_forward (v))).*hb_forward (a)) - - /* Operator(). */ - template auto - impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN - (hb_deref (hb_forward (a)) (hb_forward (ds)...)) - - public: - - template auto - operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN - ( - impl (hb_forward (a), - hb_prioritize, - hb_forward (ds)...) - ) -} -HB_FUNCOBJ (hb_invoke); - struct { private: diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 6eb13155d..a47c8cabd 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -211,4 +211,36 @@ template <> struct hb_is_integer { enum { value = true }; }; #define hb_is_integer(T) hb_is_integer::value +struct +{ + private: + + /* Pointer-to-member-function. */ + template auto + impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN + ((hb_deref (hb_forward (v)).*hb_forward (a)) (hb_forward (ds)...)) + + /* Pointer-to-member. */ + template auto + impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN + ((hb_deref (hb_forward (v))).*hb_forward (a)) + + /* Operator(). */ + template auto + impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN + (hb_deref (hb_forward (a)) (hb_forward (ds)...)) + + public: + + template auto + operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN + ( + impl (hb_forward (a), + hb_prioritize, + hb_forward (ds)...) + ) +} +HB_FUNCOBJ (hb_invoke); + + #endif /* HB_META_HH */ From cf61acb9eaa2bb3fe479a9050116b4b96934e3ed Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 22:45:01 -0700 Subject: [PATCH 186/336] [iter] Accept rvalues to hb_enumerate() --- src/hb-iter.hh | 2 +- src/test-iter.cc | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 5ad839e2a..74cfbc862 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -529,7 +529,7 @@ struct template hb_enumerate_iter_t - operator () (Iterable& it) const + operator () (Iterable&& it) const { return hb_enumerate_iter_t (hb_iter (it)); } } HB_FUNCOBJ (hb_enumerate); diff --git a/src/test-iter.cc b/src/test-iter.cc index e8c6bda6b..bd99f83e6 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -157,6 +157,8 @@ main (int argc, char **argv) test_iterator (hb_zip (st, v)); test_iterator_non_default_constructable (hb_enumerate (st)); + test_iterator_non_default_constructable (hb_enumerate (hb_iter (st))); + test_iterator_non_default_constructable (hb_enumerate (hb_iter (st) + 1)); test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_identity)); From bdbfdc92b58d5c9f8654e430075dab543d1ba394 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 22:52:43 -0700 Subject: [PATCH 187/336] [iter] Add value and projection to hb_all/any/none Allows for eg, checking all values equal 2: hb_all (it, 2). --- src/hb-iter.hh | 24 ++++++++++++++++++------ src/test-iter.cc | 10 +++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 74cfbc862..192347dc0 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -649,11 +649,15 @@ HB_FUNCOBJ (hb_unzip); struct { template - bool operator () (Iterable&& c) const + bool operator () (Iterable&& c, + Val v = true, + Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (!*it) + if (!((Val) hb_get (hb_forward (f), *it) == v)) return false; return true; } @@ -662,11 +666,15 @@ HB_FUNCOBJ (hb_all); struct { template - bool operator () (Iterable&& c) const + bool operator () (Iterable&& c, + Val v = true, + Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (*it) + if (((Val) hb_get (hb_forward (f), *it) == v)) return true; return false; } @@ -675,11 +683,15 @@ HB_FUNCOBJ (hb_any); struct { template - bool operator () (Iterable&& c) const + bool operator () (Iterable&& c, + Val v = true, + Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (*it) + if (((Val) hb_get (hb_forward (f), *it) == v)) return false; return true; } diff --git a/src/test-iter.cc b/src/test-iter.cc index bd99f83e6..70952f3e2 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -140,6 +140,7 @@ main (int argc, char **argv) test_iterable (v); hb_set_t st; + st << 1 << 15 << 43; test_iterable (st); hb_sorted_array_t sa; (void) static_cast, hb_sorted_array_t::item_t>&> (sa); @@ -162,7 +163,14 @@ main (int argc, char **argv) test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_identity)); - hb_any (st); + assert (true == hb_all (st)); + assert (false == hb_all (st, 42u)); + assert (true == hb_any (st)); + assert (false == hb_any (st, 14)); + assert (true == hb_any (st, 15)); + assert (false == hb_none (st)); + assert (false == hb_none (st, 15)); + assert (true == hb_none (st, 17)); hb_array_t> pa; pa->as_array (); From 56d2d0294b836ea1e2dea9e242ae72c99387d00a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 23:08:49 -0700 Subject: [PATCH 188/336] [algs] Sprinkle hb_min/max with hb-forward salad Let's see if fixes MSVC fail. Though, the error doesn't make sense to me. hb-blob.cc c:\projects\harfbuzz\src\hb-algs.hh(166): error C2440: 'return': cannot convert from 'unsigned int' to 'unsigned int &&' [C:\projects\harfbuzz\build\harfbuzz.vcxproj] c:\projects\harfbuzz\src\hb-algs.hh(166): note: You cannot bind an lvalue to an rvalue reference c:\projects\harfbuzz\src\hb-algs.hh(174): note: see reference to function template instantiation 'T &&::impl(T &&,T2) const' being compiled with [ T=unsigned int, T2=unsigned int & ] --- src/hb-algs.hh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 77382458d..9e8a4aeba 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -163,11 +163,12 @@ struct { private: template auto - impl (T&& a, T2&& b) const HB_AUTO_RETURN (a <= b ? a : b) + impl (T&& a, T2&& b) const HB_AUTO_RETURN + (hb_forward (a) <= hb_forward (b) ? hb_forward (a) : hb_forward (b)) public: template auto - operator () (T&& a) const HB_AUTO_RETURN (a) + operator () (T&& a) const HB_AUTO_RETURN (hb_forward (a)) template auto operator () (T&& a, Ts&& ...ds) const HB_AUTO_RETURN @@ -178,11 +179,12 @@ struct { private: template auto - impl (T&& a, T2&& b) const HB_AUTO_RETURN (a >= b ? a : b) + impl (T&& a, T2&& b) const HB_AUTO_RETURN + (hb_forward (a) >= hb_forward (b) ? hb_forward (a) : hb_forward (b)) public: template auto - operator () (T&& a) const HB_AUTO_RETURN (a) + operator () (T&& a) const HB_AUTO_RETURN (hb_forward (a)) template auto operator () (T&& a, Ts&& ...ds) const HB_AUTO_RETURN From 2c7093ed01f417828d5521d983eae63042363197 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 23:10:59 -0700 Subject: [PATCH 189/336] More tests --- src/test-algs.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test-algs.cc b/src/test-algs.cc index 0a8fcbff7..d6f34d707 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -66,6 +66,9 @@ main (int argc, char **argv) assert (8 == hb_max (3, 8, 1, 2)); int x = 1, y = 2; + hb_min (x, 3); + hb_min (3, x, 4); + hb_min (3, x, 4 + 3); int &z = hb_min (x, y); z = 3; assert (x == 3); From c2c9d204fa5c2189e369726276a1c0e92e09a9ce Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 23:13:38 -0700 Subject: [PATCH 190/336] Fix double-promotion warnings Make it an error. --- src/hb-ot-var-fvar-table.hh | 12 ++++++------ src/hb.hh | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 3565185fd..c73348ef4 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -120,10 +120,10 @@ struct fvar const AxisRecord &axis = get_axes ()[axis_index]; info->tag = axis.axisTag; info->name_id = axis.axisNameID; - info->default_value = axis.defaultValue / 65536.; + info->default_value = axis.defaultValue / 65536.f; /* Ensure order, to simplify client math. */ - info->min_value = hb_min (info->default_value, axis.minValue / 65536.); - info->max_value = hb_max (info->default_value, axis.maxValue / 65536.); + info->min_value = hb_min (info->default_value, axis.minValue / 65536.f); + info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f); } void get_axis_info (unsigned int axis_index, @@ -134,10 +134,10 @@ struct fvar 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.; + info->default_value = axis.defaultValue / 65536.f; /* Ensure order, to simplify client math. */ - info->min_value = hb_min (info->default_value, axis.minValue / 65536.); - info->max_value = hb_max (info->default_value, axis.maxValue / 65536.); + info->min_value = hb_min (info->default_value, axis.minValue / 65536.f); + info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f); info->reserved = 0; } diff --git a/src/hb.hh b/src/hb.hh index 96db1f9d4..3d4b18033 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -65,6 +65,7 @@ #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" +#pragma GCC diagnostic error "-Wdouble-promotion" #pragma GCC diagnostic error "-Wformat-security" #pragma GCC diagnostic error "-Wimplicit-function-declaration" #pragma GCC diagnostic error "-Winit-self" From dfc57802450360f06026668b7b61495aaa2d1943 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 23:26:09 -0700 Subject: [PATCH 191/336] Fix more double-promotion errors WHy do only some of the clang bots catch this I have no idea :(. --- src/hb-aat-layout-trak-table.hh | 4 ++-- src/hb-font.hh | 2 +- src/hb-open-type.hh | 4 ++-- src/hb-ot-color-cbdt-table.hh | 12 ++++++------ src/hb-ot-color-sbix-table.hh | 10 +++++----- src/hb-ot-layout-gpos-table.hh | 20 ++++++++++---------- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index 2688270aa..2eace2aa0 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -133,8 +133,8 @@ struct TrackData if (size_table[size_index].to_float () >= csspx) break; - return round (interpolate_at (size_index ? size_index - 1 : 0, csspx, - *trackTableEntry, base)); + return roundf (interpolate_at (size_index ? size_index - 1 : 0, csspx, + *trackTableEntry, base)); } bool sanitize (hb_sanitize_context_t *c, const void *base) const diff --git a/src/hb-font.hh b/src/hb-font.hh index aaa0fd91c..4f5aa8a60 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -607,7 +607,7 @@ struct hb_font_t return (hb_position_t) (scaled / upem); } hb_position_t em_scalef (float v, int scale) - { return (hb_position_t) round (v * scale / face->get_upem ()); } + { return (hb_position_t) roundf (v * scale / face->get_upem ()); } float em_fscale (int16_t v, int scale) { return (float) v * scale / face->get_upem (); } }; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 5c015af3e..1129bd006 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -110,7 +110,7 @@ struct F2DOT14 : HBINT16 F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; } // 16384 means 1<<14 float to_float () const { return ((int32_t) v) / 16384.f; } - void set_float (float f) { v = round (f * 16384.f); } + void set_float (float f) { v = roundf (f * 16384.f); } public: DEFINE_SIZE_STATIC (2); }; @@ -121,7 +121,7 @@ struct Fixed : HBINT32 Fixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; } // 65536 means 1<<16 float to_float () const { return ((int32_t) v) / 65536.f; } - void set_float (float f) { v = round (f * 65536.f); } + void set_float (float f) { v = roundf (f * 65536.f); } public: DEFINE_SIZE_STATIC (4); }; diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 96b14bd68..7955cf651 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -442,12 +442,12 @@ struct CBDT } /* Convert to font units. */ - double x_scale = upem / (double) strike.ppemX; - double y_scale = upem / (double) strike.ppemY; - extents->x_bearing = round (extents->x_bearing * x_scale); - extents->y_bearing = round (extents->y_bearing * y_scale); - extents->width = round (extents->width * x_scale); - extents->height = round (extents->height * y_scale); + float x_scale = upem / (float) strike.ppemX; + float y_scale = upem / (float) strike.ppemY; + extents->x_bearing = roundf (extents->x_bearing * x_scale); + extents->y_bearing = roundf (extents->y_bearing * y_scale); + extents->width = roundf (extents->width * x_scale); + extents->height = roundf (extents->height * y_scale); return true; } diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index f9739f9ef..9b725c46e 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -242,11 +242,11 @@ struct sbix /* Convert to font units. */ if (strike_ppem) { - double scale = font->face->get_upem () / (double) strike_ppem; - extents->x_bearing = round (extents->x_bearing * scale); - extents->y_bearing = round (extents->y_bearing * scale); - extents->width = round (extents->width * scale); - extents->height = round (extents->height * scale); + float scale = font->face->get_upem () / (float) strike_ppem; + extents->x_bearing = roundf (extents->x_bearing * scale); + extents->y_bearing = roundf (extents->y_bearing * scale); + extents->width = roundf (extents->width * scale); + extents->height = roundf (extents->height * scale); } hb_blob_destroy (blob); diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 228820a17..45de78138 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -446,8 +446,8 @@ struct MarkArray : ArrayOf /* Array of MarkRecords--in Coverage orde glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); hb_glyph_position_t &o = buffer->cur_pos(); - o.x_offset = round (base_x - mark_x); - o.y_offset = round (base_y - mark_y); + o.x_offset = roundf (base_x - mark_x); + o.y_offset = roundf (base_y - mark_y); o.attach_type() = ATTACH_TYPE_MARK; o.attach_chain() = (int) glyph_pos - (int) buffer->idx; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; @@ -993,32 +993,32 @@ struct CursivePosFormat1 /* Main-direction adjustment */ switch (c->direction) { case HB_DIRECTION_LTR: - pos[i].x_advance = round (exit_x) + pos[i].x_offset; + pos[i].x_advance = roundf (exit_x) + pos[i].x_offset; - d = round (entry_x) + pos[j].x_offset; + d = roundf (entry_x) + pos[j].x_offset; pos[j].x_advance -= d; pos[j].x_offset -= d; break; case HB_DIRECTION_RTL: - d = round (exit_x) + pos[i].x_offset; + d = roundf (exit_x) + pos[i].x_offset; pos[i].x_advance -= d; pos[i].x_offset -= d; - pos[j].x_advance = round (entry_x) + pos[j].x_offset; + pos[j].x_advance = roundf (entry_x) + pos[j].x_offset; break; case HB_DIRECTION_TTB: - pos[i].y_advance = round (exit_y) + pos[i].y_offset; + pos[i].y_advance = roundf (exit_y) + pos[i].y_offset; - d = round (entry_y) + pos[j].y_offset; + d = roundf (entry_y) + pos[j].y_offset; pos[j].y_advance -= d; pos[j].y_offset -= d; break; case HB_DIRECTION_BTT: - d = round (exit_y) + pos[i].y_offset; + d = roundf (exit_y) + pos[i].y_offset; pos[i].y_advance -= d; pos[i].y_offset -= d; - pos[j].y_advance = round (entry_y); + pos[j].y_advance = roundf (entry_y); break; case HB_DIRECTION_INVALID: default: From 2ba984fcbbef4561d35c3a2c502610c38b26f4fb Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 7 May 2019 23:28:22 -0700 Subject: [PATCH 192/336] Fix signed comparison on 32bit --- src/hb-sanitize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index ac424c1d9..5ecd2d2bc 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -175,7 +175,7 @@ struct hb_sanitize_context_t : else { this->start = obj_start; - this->end = obj_start + hb_min (this->end - obj_start, obj->get_size ()); + this->end = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ()); } } From 0601a19d38b2b0fc5dd36fd821af634a49322ebf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 07:47:36 -0700 Subject: [PATCH 193/336] Fix a few more double-pomotion errors --- src/hb-coretext.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index e0579bed8..bf8e96c7b 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -55,13 +55,13 @@ coretext_font_size_from_ptem (float ptem) * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html */ ptem *= 96.f / 72.f; - return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem; + return (CGFloat) (ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem); } static float coretext_font_size_to_ptem (CGFloat size) { - size *= 72.f / 96.f; - return size <= 0.f ? 0 : size; + size *= 72. / 96.; + return size <= 0 ? 0 : size; } static void From 26adefd9eaf4bc1d80b1ffececf0d86f3308f9ee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 09:14:44 -0700 Subject: [PATCH 194/336] [algs] Try f[v] in hb_get() as last resort --- src/hb-algs.hh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 9e8a4aeba..b83ee6a78 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -100,14 +100,20 @@ struct private: template auto - impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN + impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN (hb_deref (hb_forward (f)).get (hb_forward (v))) + template auto + impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN + ( + hb_invoke (hb_forward (f), + hb_forward (v)) + ) + template auto impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN ( - hb_invoke (hb_forward (f), - hb_forward (v)) + hb_forward (f)[hb_forward (v)] ) public: From 4a101d8ffccd6f907f16ef190125ded5e27e0d8b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 09:16:33 -0700 Subject: [PATCH 195/336] Add hb_match --- src/hb-algs.hh | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index b83ee6a78..52d40923e 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -75,7 +75,7 @@ struct template auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref (hb_forward (p)).has (v)) + (hb_deref (hb_forward (p)).has (hb_forward (v))) template auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN @@ -95,6 +95,34 @@ struct } HB_FUNCOBJ (hb_has); +struct +{ + private: + + template auto + impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN + ( + hb_has (hb_forward (p), + hb_forward (v)) + ) + + template auto + impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN + ( + hb_forward (p) == hb_forward (v) + ) + + public: + + template auto + operator () (Pred&& p, Val &&v) const HB_RETURN (bool, + impl (hb_forward (p), + hb_forward (v), + hb_prioritize) + ) +} +HB_FUNCOBJ (hb_match); + struct { private: From fe14a4000a58528878bcc75fde0972de2b779316 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 09:32:19 -0700 Subject: [PATCH 196/336] Adjust hb_all/any/none --- src/hb-iter.hh | 18 +++++++++--------- src/test-iter.cc | 10 ++++++---- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 192347dc0..6954d431b 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -649,15 +649,15 @@ HB_FUNCOBJ (hb_unzip); struct { template bool operator () (Iterable&& c, - Val v = true, + Pred&& p = hb_bool, Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (!((Val) hb_get (hb_forward (f), *it) == v)) + if (!hb_match (hb_forward (p), hb_get (hb_forward (f), *it))) return false; return true; } @@ -666,15 +666,15 @@ HB_FUNCOBJ (hb_all); struct { template bool operator () (Iterable&& c, - Val v = true, + Pred&& p = hb_bool, Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (((Val) hb_get (hb_forward (f), *it) == v)) + if (hb_match (hb_forward (p), hb_get (hb_forward (f), *it))) return true; return false; } @@ -683,15 +683,15 @@ HB_FUNCOBJ (hb_any); struct { template bool operator () (Iterable&& c, - Val v = true, + Pred&& p = hb_bool, Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (((Val) hb_get (hb_forward (f), *it) == v)) + if (hb_match (hb_forward (p), hb_get (hb_forward (f), *it))) return false; return true; } diff --git a/src/test-iter.cc b/src/test-iter.cc index 70952f3e2..17a1972b3 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -166,11 +166,13 @@ main (int argc, char **argv) assert (true == hb_all (st)); assert (false == hb_all (st, 42u)); assert (true == hb_any (st)); - assert (false == hb_any (st, 14)); - assert (true == hb_any (st, 15)); + assert (false == hb_any (st, 14u)); + assert (true == hb_any (st, 14u, [] (unsigned _) { return _ - 1u; })); + assert (true == hb_any (st, [] (unsigned _) { return _ == 15u; })); + assert (true == hb_any (st, 15u)); assert (false == hb_none (st)); - assert (false == hb_none (st, 15)); - assert (true == hb_none (st, 17)); + assert (false == hb_none (st, 15u)); + assert (true == hb_none (st, 17u)); hb_array_t> pa; pa->as_array (); From 710d459acac88fd784d4ead0ba75b9aa623c48d4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 09:33:09 -0700 Subject: [PATCH 197/336] [iter] Default predicates to hb_identity instead of hb_bool The bool conversion happens after predicate is called automatically. --- src/hb-iter.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 6954d431b..aa5eb9cba 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -405,10 +405,10 @@ struct hb_filter_iter_factory_t }; struct { - template hb_filter_iter_factory_t - operator () (Pred&& p = hb_bool, Proj&& f = hb_identity) const + operator () (Pred&& p = hb_identity, Proj&& f = hb_identity) const { return hb_filter_iter_factory_t (p, f); } } HB_FUNCOBJ (hb_filter); @@ -649,11 +649,11 @@ HB_FUNCOBJ (hb_unzip); struct { template bool operator () (Iterable&& c, - Pred&& p = hb_bool, + Pred&& p = hb_identity, Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) @@ -666,11 +666,11 @@ HB_FUNCOBJ (hb_all); struct { template bool operator () (Iterable&& c, - Pred&& p = hb_bool, + Pred&& p = hb_identity, Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) @@ -683,11 +683,11 @@ HB_FUNCOBJ (hb_any); struct { template bool operator () (Iterable&& c, - Pred&& p = hb_bool, + Pred&& p = hb_identity, Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) From 8479eb5955c93cbc8951d0319b2fe43ff19cc403 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 09:48:55 -0700 Subject: [PATCH 198/336] [iter] Fix hb_sink() to accept rvalue --- src/hb-iter.hh | 2 +- src/test-iter.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index aa5eb9cba..a3390136c 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -569,7 +569,7 @@ HB_FUNCOBJ (hb_apply); template struct hb_sink_t { - hb_sink_t (Sink&& s) : s (s) {} + hb_sink_t (Sink s) : s (s) {} template diff --git a/src/test-iter.cc b/src/test-iter.cc index 17a1972b3..fe3c8f331 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -185,6 +185,10 @@ main (int argc, char **argv) | hb_sink (st) ; + + hb_iter (src) + | hb_sink (hb_array (dst)) + ; + + hb_iter (src) | hb_apply (&st) ; From 00946ca3aa45f109c455871ce89c5872fd243624 Mon Sep 17 00:00:00 2001 From: Roderick Sheeter Date: Wed, 8 May 2019 09:42:35 -0700 Subject: [PATCH 199/336] [docs] add sample commands for test exec --- README.md | 4 ++++ TESTING.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 TESTING.md diff --git a/README.md b/README.md index fd93be84f..b2eab567b 100644 --- a/README.md +++ b/README.md @@ -15,4 +15,8 @@ For bug reports, mailing list, and other information please visit: For license information, see the file COPYING. +For build information, see the file BUILD.md. + +For test execution, see the file TESTING.md. + Documentation: https://harfbuzz.github.io diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 000000000..91b6abd8b --- /dev/null +++ b/TESTING.md @@ -0,0 +1,47 @@ +## Build & Run + +Depending on what area you are working in change or add `HB_DEBUG_`. +Values defined in `hb-debug.hh`. + +```shell +# quick sanity check +time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ + && make -C test/api check || cat test/api/test-suite.log) + +# slower santiy check +time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ + && make -C src check \ + && make -C test/api check \ + && make -C test/subset check) + +# confirm you didn't break anything else +time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ + && make check) + +# often catches files you didn't add, e.g. test fonts to EXTRA_DIST +make distcheck +``` + +### Debug with GDB + +``` +cd ./util +../libtool --mode=execute gdb --args ./hb-subset ... +``` + +### Enable Debug Logging + +```shell +# make clean if you previously build w/o debug logging +make CPPFLAGS=-DHB_DEBUG_SUBSET=100 +``` + +## Build and Test via CMake + +Note: You'll need to first install ninja-build via apt-get. + +```shell +cd harfbuzz +mkdir buid +cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test +``` From 4063181791d6b3efb35e7c748dee12273e64ebd4 Mon Sep 17 00:00:00 2001 From: rsheeter Date: Wed, 8 May 2019 09:47:34 -0700 Subject: [PATCH 200/336] [docs] add fuzzer instructions (courtesy of Garret) --- TESTING.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/TESTING.md b/TESTING.md index 91b6abd8b..6bbf7bc5b 100644 --- a/TESTING.md +++ b/TESTING.md @@ -45,3 +45,13 @@ cd harfbuzz mkdir buid cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test ``` +## Test with the Fuzzer + +```shell +# push your changs to a branch on googlefonts/harfbuzz +# In a local copy of oss-fuzz, edit projects/harfbuzz/Dockerfile +# Change the git clone to pull your branch +sudo python infra/helper.py build_image harfbuzz +sudo python infra/helper.py build_fuzzers --sanitizer address harfbuzz +sudo python infra/helper.py run_fuzzer harfbuzz hb-subset-fuzzer +``` From d109c9e767ff3198d51e23a7ac8931d0bc4d5d72 Mon Sep 17 00:00:00 2001 From: rsheeter Date: Wed, 8 May 2019 09:53:29 -0700 Subject: [PATCH 201/336] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b2eab567b..c5f98404a 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ For bug reports, mailing list, and other information please visit: http://harfbuzz.org/ -For license information, see the file COPYING. +For license information, see the [COPYING](COPYING). -For build information, see the file BUILD.md. +For build information, see [BUILD](BUILD.md). -For test execution, see the file TESTING.md. +For test execution, see [TESTING](TESTING.md). Documentation: https://harfbuzz.github.io From fa576ce1874fd886688bf3f16b714d86aebb07ec Mon Sep 17 00:00:00 2001 From: rsheeter Date: Wed, 8 May 2019 09:53:58 -0700 Subject: [PATCH 202/336] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c5f98404a..ce0a04d1f 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ For bug reports, mailing list, and other information please visit: http://harfbuzz.org/ -For license information, see the [COPYING](COPYING). +For license information, see [COPYING](COPYING). -For build information, see [BUILD](BUILD.md). +For build information, see [BUILD.md](BUILD.md). -For test execution, see [TESTING](TESTING.md). +For test execution, see [TESTING.md](TESTING.md). Documentation: https://harfbuzz.github.io From a66598e0306fe80063c5d6a678bbca4a931bc4d4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 09:56:29 -0700 Subject: [PATCH 203/336] [iter] For ref-qualified variants --- src/hb-iter.hh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a3390136c..dc4738928 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -97,10 +97,12 @@ struct hb_iter_t item_t operator * () { return thiz()->__item__ (); } item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); } - iter_t& operator += (unsigned count) & { thiz()->__forward__ (count); return *thiz(); } + iter_t& operator += (unsigned count) & { thiz()->__forward__ (count); return *thiz(); } + iter_t operator += (unsigned count) && { thiz()->__forward__ (count); return *thiz(); } iter_t& operator ++ () & { thiz()->__next__ (); return *thiz(); } iter_t operator ++ () && { thiz()->__next__ (); return *thiz(); } - iter_t& operator -= (unsigned count) & { thiz()->__rewind__ (count); return *thiz(); } + iter_t& operator -= (unsigned count) & { thiz()->__rewind__ (count); return *thiz(); } + iter_t operator -= (unsigned count) && { thiz()->__rewind__ (count); return *thiz(); } iter_t& operator -- () & { thiz()->__prev__ (); return *thiz(); } iter_t operator -- () && { thiz()->__prev__ (); return *thiz(); } iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; } @@ -109,9 +111,13 @@ struct hb_iter_t iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; } iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } template - iter_t& operator >> (T &v) & { v = **thiz(); ++*thiz(); return *thiz(); } + iter_t& operator >> (T &v) & { v = **thiz(); ++*thiz(); return *thiz(); } template - iter_t& operator << (const T v) & { **thiz() = v; ++*thiz(); return *thiz(); } + iter_t operator >> (T &v) && { v = **thiz(); ++*thiz(); return *thiz(); } + template + iter_t& operator << (const T v) & { **thiz() = v; ++*thiz(); return *thiz(); } + template + iter_t operator << (const T v) && { **thiz() = v; ++*thiz(); return *thiz(); } protected: hb_iter_t () {} From aa4ac13f0be34bba66b00d04fd7806c474ff59c0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 10:02:30 -0700 Subject: [PATCH 204/336] [iter] Actually fix previous commit The iter objects shouldn't not be const. D'oh. --- src/hb-iter.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index dc4738928..23d2c271f 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -316,7 +316,7 @@ static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable). template static inline auto -operator | (Lhs lhs, const Rhs &rhs) HB_AUTO_RETURN (rhs (lhs)) +operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward (rhs) (hb_forward (lhs))) /* hb_map(), hb_filter(), hb_reduce() */ @@ -355,7 +355,7 @@ struct hb_map_iter_factory_t template hb_map_iter_t - operator () (Iter it) const + operator () (Iter it) { return hb_map_iter_t (it, f); } private: @@ -402,7 +402,7 @@ struct hb_filter_iter_factory_t template hb_filter_iter_t - operator () (Iter it) const + operator () (Iter it) { return hb_filter_iter_t (it, p, f); } private: @@ -428,7 +428,7 @@ struct hb_reduce_t hb_requires (hb_is_iterator (Iter)), typename AccuT = decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))> AccuT - operator () (Iter it) const + operator () (Iter it) { AccuT value = init_value; for (; it; ++it) @@ -549,7 +549,7 @@ struct hb_apply_t template - void operator () (Iter it) const + void operator () (Iter it) { for (; it; ++it) (void) hb_invoke (a, *it); @@ -579,7 +579,7 @@ struct hb_sink_t template - void operator () (Iter it) const + void operator () (Iter it) { for (; it; ++it) s << *it; @@ -619,11 +619,11 @@ HB_FUNCOBJ (hb_drain); template struct hb_unzip_t { - hb_unzip_t (Sink1&& s1, Sink2&& s2) : s1 (s1), s2 (s2) {} + hb_unzip_t (Sink1 s1, Sink2 s2) : s1 (s1), s2 (s2) {} template - void operator () (Iter it) const + void operator () (Iter it) { for (; it; ++it) { From 50dc3e7d9f4f290c7353313c5e5f888cb7c4846d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 10:35:02 -0700 Subject: [PATCH 205/336] Add hb_iota() --- src/hb-iter.hh | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ src/test-iter.cc | 10 ++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 23d2c271f..1a3e2ab3e 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -570,6 +570,57 @@ struct } HB_FUNCOBJ (hb_apply); +/* hb_iota() */ + +template +struct hb_iota_iter_t : + hb_iter_t, T> +{ + hb_iota_iter_t (T start, T end, S step) : v (start), end (end_for (start, end, step)), step (step) {} + + typedef T __item_t__; + static constexpr bool is_random_access_iterator = true; + static constexpr bool is_sorted_iterator = true; + __item_t__ __item__ () const { return v; } + __item_t__ __item_at__ (unsigned j) const { return v + j * step; } + bool __more__ () const { return v != end; } + unsigned __len__ () const { return (end - v) / step; } + void __next__ () { v += step; } + void __forward__ (unsigned n) { v += n * step; } + void __prev__ () { v -= step; } + void __rewind__ (unsigned n) { v -= n * step; } + hb_iota_iter_t __end__ () const { hb_iota_iter_t (end, end, step); } + bool operator != (const hb_iota_iter_t& o) const + { return v != o.v || end != o.end || step != o.step; } + + private: + static inline T end_for (T start, T end, S step) + { + auto res = (end - start) % step; + if (!res) + return end; + end += step - res; + return end; + } + + private: + T v; + T end; + S step; +}; +struct +{ + template hb_iota_iter_t + operator () (T end = (unsigned) -1) const + { return hb_iota_iter_t (0, end, 1u); } + + template hb_iota_iter_t + operator () (T start, T end, S&& step = 1u) const + { return hb_iota_iter_t (start, end, step); } +} +HB_FUNCOBJ (hb_iota); + + /* hb_sink() */ template diff --git a/src/test-iter.cc b/src/test-iter.cc index fe3c8f331..f29166fe8 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -236,5 +236,15 @@ main (int argc, char **argv) long vl; s >> vl; + hb_iota (); + assert (hb_iota (9).len () == 9); + assert (hb_iota (2, 9).len () == 7); + assert (hb_iota (2, 9, 3).len () == 3); + assert (hb_iota (2, 8, 3).len () == 2); + assert (hb_iota (2, 7, 3).len () == 2); + assert (hb_iota (-2, -9, -3).len () == 3); + assert (hb_iota (-2, -8, -3).len () == 2); + assert (hb_iota (-2, -7, -3).len () == 2); + return 0; } From 4c9e0c37a34e8355d752af39507b310f473bffa5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 10:40:39 -0700 Subject: [PATCH 206/336] [serialize] LangSys subset->copy --- src/hb-ot-layout-common.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 05f84d254..04b211ddb 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -229,10 +229,10 @@ struct LangSys return reqFeatureIndex;; } - bool subset (hb_subset_context_t *c) const + LangSys* copy (hb_serialize_context_t *c) const { - TRACE_SUBSET (this); - return_trace (c->serializer->embed (*this)); + TRACE_SERIALIZE (this); + return_trace (c->embed (*this)); } bool sanitize (hb_sanitize_context_t *c, @@ -279,10 +279,10 @@ struct Script TRACE_SUBSET (this); struct Script *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); - out->defaultLangSys.serialize_subset (c, this+defaultLangSys, out); + out->defaultLangSys.serialize_copy (c->serializer, this+defaultLangSys, out); unsigned int count = langSys.len; for (unsigned int i = 0; i < count; i++) - out->langSys.arrayZ[i].offset.serialize_subset (c, this+langSys[i].offset, out); + out->langSys.arrayZ[i].offset.serialize_copy (c->serializer, this+langSys[i].offset, out); return_trace (true); } From c93eeba9b21cb8f8ba64ebaf284bf9c8a8544886 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 10:56:09 -0700 Subject: [PATCH 207/336] [iter] Accept pointer in hb_map() --- src/hb-iter.hh | 4 ++-- src/test-iter.cc | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 1a3e2ab3e..5a76c9541 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -324,11 +324,11 @@ template struct hb_map_iter_t : hb_iter_t, - decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t)))> + decltype (hb_get (hb_declval (Proj), *hb_declval (Iter)))> { hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {} - typedef decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t))) __item_t__; + typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__; static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; __item_t__ __item__ () const { return hb_get (f.get (), *it); } __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); } diff --git a/src/test-iter.cc b/src/test-iter.cc index f29166fe8..1e721aecb 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -177,9 +177,14 @@ main (int argc, char **argv) hb_array_t> pa; pa->as_array (); + hb_map_t m; + + hb_iter (src) - | hb_map (hb_identity) + | hb_map (m) + | hb_map (&m) | hb_filter () + | hb_filter (st) + | hb_filter (&st) | hb_filter (hb_bool) | hb_filter (hb_bool, hb_identity) | hb_sink (st) From cdb61eb0431d426f7152f975e89ee3ba4431083f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 11:00:18 -0700 Subject: [PATCH 208/336] [iter] Accept pointer in hb_iter() and hb_iter_t() --- src/hb-iter.hh | 4 ++-- src/test-iter.cc | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 5a76c9541..141165028 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -148,7 +148,7 @@ struct hb_iter_t static_assert (true, "") /* Returns iterator type of a type. */ -#define hb_iter_t(Iterable) decltype (hb_declval (Iterable).iter ()) +#define hb_iter_t(Iterable) decltype (hb_deref (hb_declval (Iterable)).iter ()) template struct hb_array_t; @@ -158,7 +158,7 @@ struct template hb_iter_t (T) operator () (T&& c) const - { return c.iter (); } + { return hb_deref (hb_forward (c)).iter (); } /* Specialization for C arrays. */ diff --git a/src/test-iter.cc b/src/test-iter.cc index 1e721aecb..ac2c30e09 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -179,6 +179,9 @@ main (int argc, char **argv) hb_map_t m; + hb_iter (st); + hb_iter (&st); + + hb_iter (src) | hb_map (m) | hb_map (&m) From 750d5af48e38627c3c84a2f3857a7ee602221e24 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 12:01:55 -0700 Subject: [PATCH 209/336] Make compiler happy with -Og --- src/hb-cff-interp-cs-common.hh | 2 +- src/hb-ot-cmap-table.hh | 6 +++--- src/hb-ot-glyf-table.hh | 2 +- src/hb-subset-glyf.cc | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh index 71bc29282..2f892f84c 100644 --- a/src/hb-cff-interp-cs-common.hh +++ b/src/hb-cff-interp-cs-common.hh @@ -160,7 +160,7 @@ struct cs_interp_env_t : interp_env_t void callSubr (const biased_subrs_t& biasedSubrs, cs_type_t type) { - unsigned int subr_num; + unsigned int subr_num = 0; if (unlikely (!popSubrNum (biasedSubrs, subr_num) || callStack.get_count () >= kMaxCallLimit)) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index b4c8c608b..cec78d77c 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -142,7 +142,7 @@ struct CmapSubtableFormat4 for (unsigned int j = 0; j < num_codepoints; j++) { hb_codepoint_t cp = segments[i].start_code + j; - hb_codepoint_t new_gid; + hb_codepoint_t new_gid = 0; if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) return_trace (false); glyph_id_array[j] = new_gid; @@ -183,7 +183,7 @@ struct CmapSubtableFormat4 hb_codepoint_t cp = HB_SET_VALUE_INVALID; while (plan->unicodes->next (&cp)) { - hb_codepoint_t new_gid; + hb_codepoint_t new_gid = 0; if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) { DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); @@ -542,7 +542,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented hb_codepoint_t cp = HB_SET_VALUE_INVALID; while (plan->unicodes->next (&cp)) { - hb_codepoint_t new_gid; + hb_codepoint_t new_gid = 0; if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) { DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 2a96c2e35..f7629eca3 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -283,7 +283,7 @@ struct glyf /* based on FontTools _g_l_y_f.py::trim */ bool remove_padding (unsigned int start_offset, - unsigned int *end_offset) const + unsigned int *end_offset) const { if (*end_offset - start_offset < GlyphHeader::static_size) return true; diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index d40233187..0647ee4e7 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -108,7 +108,7 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, hb_codepoint_t next_glyph = HB_SET_VALUE_INVALID; while (plan->glyphset ()->next (&next_glyph)) { - unsigned int start_offset, end_offset; + unsigned int start_offset = 0, end_offset = 0; if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) && glyf.remove_padding (start_offset, &end_offset)))) { @@ -211,7 +211,7 @@ _write_glyf_and_loca_prime (const hb_subset_plan_t *plan, } - unsigned int start_offset, end_offset; + unsigned int start_offset = 0, end_offset = 0; if (unlikely (!(glyf.get_offsets (old_gid, &start_offset, &end_offset) && glyf.remove_padding (start_offset, &end_offset)))) end_offset = start_offset = 0; From bad16066392e4dbdd8490a4b1c70d1dcddcc8ec8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 12:11:52 -0700 Subject: [PATCH 210/336] [map] Make .has() optionally return value --- src/hb-map.hh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index f27ca9cae..13099afc4 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -181,7 +181,12 @@ struct hb_hashmap_t static constexpr V SENTINEL = vINVALID; typedef V value_t; value_t operator [] (K k) const { return get (k); } - bool has (K k) const { return (*this)[k] != SENTINEL; } + bool has (K k, V *vp = nullptr) const + { + V v = (*this)[k]; + if (vp) *vp = v; + return v != SENTINEL; + } /* Projection. */ V operator () (K k) const { return get (k); } From 5875d775e1253c0e14b900539c28c2de881da7aa Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 12:25:34 -0700 Subject: [PATCH 211/336] [iter] Rename hb_iter_t() to hb_iter_type<> and add hb_item_type<> --- src/hb-iter.hh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 141165028..5aa138fbc 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -147,16 +147,18 @@ struct hb_iter_t using Name::operator <<; \ static_assert (true, "") -/* Returns iterator type of a type. */ -#define hb_iter_t(Iterable) decltype (hb_deref (hb_declval (Iterable)).iter ()) +/* Returns iterator / item type of a type. */ +template +using hb_iter_type = decltype (hb_deref (hb_declval (Iterable)).iter ()); +template +using hb_item_type = decltype (*hb_deref (hb_declval (Iterable)).iter ()); template struct hb_array_t; struct { - template - hb_iter_t (T) + template hb_iter_type operator () (T&& c) const { return hb_deref (hb_forward (c)).iter (); } @@ -487,9 +489,9 @@ struct { template - hb_zip_iter_t + hb_zip_iter_t, hb_iter_type> operator () (A& a, B &b) const - { return hb_zip_iter_t (hb_iter (a), hb_iter (b)); } + { return hb_zip_iter_t, hb_iter_type> (hb_iter (a), hb_iter (b)); } } HB_FUNCOBJ (hb_zip); @@ -534,9 +536,9 @@ struct { template - hb_enumerate_iter_t + hb_enumerate_iter_t> operator () (Iterable&& it) const - { return hb_enumerate_iter_t (hb_iter (it)); } + { return hb_enumerate_iter_t> (hb_iter (it)); } } HB_FUNCOBJ (hb_enumerate); From 503748d8a80dd5db450c8c4dc109f2b97049d989 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 12:45:02 -0700 Subject: [PATCH 212/336] [name] Sanitize records for reals Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14641 --- src/hb-ot-name-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 4e4da74bc..1c8f54406 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -220,7 +220,6 @@ struct name { TRACE_SANITIZE (this); const void *string_pool = (this+stringOffset).arrayZ; - /* TODO: Move to run-time?! */ return_trace (nameRecordZ.sanitize (c, count, string_pool)); } @@ -230,7 +229,8 @@ struct name return_trace (c->check_struct (this) && likely (format == 0 || format == 1) && c->check_array (nameRecordZ.arrayZ, count) && - c->check_range (this, stringOffset)); + c->check_range (this, stringOffset) && + sanitize_records (c)); } struct accelerator_t From 02ae2591d930563cec8c3c63086afb0a3a12c4aa Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Wed, 8 May 2019 13:44:03 -0700 Subject: [PATCH 213/336] initialize return param subr_num in popSubrNum also snake_cased popSubrtNum and other surrounding function names --- src/hb-cff-interp-cs-common.hh | 15 ++++++++------- src/hb-subset-cff1.cc | 4 ++-- src/hb-subset-cff2.cc | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh index 2f892f84c..61bdba5f5 100644 --- a/src/hb-cff-interp-cs-common.hh +++ b/src/hb-cff-interp-cs-common.hh @@ -147,8 +147,9 @@ struct cs_interp_env_t : interp_env_t return callStack.in_error () || SUPER::in_error (); } - bool popSubrNum (const biased_subrs_t& biasedSubrs, unsigned int &subr_num) + bool pop_subr_num (const biased_subrs_t& biasedSubrs, unsigned int &subr_num) { + subr_num = 0; int n = SUPER::argStack.pop_int (); n += biasedSubrs.get_bias (); if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.get_count ()))) @@ -158,11 +159,11 @@ struct cs_interp_env_t : interp_env_t return true; } - void callSubr (const biased_subrs_t& biasedSubrs, cs_type_t type) + void call_subr (const biased_subrs_t& biasedSubrs, cs_type_t type) { unsigned int subr_num = 0; - if (unlikely (!popSubrNum (biasedSubrs, subr_num) + if (unlikely (!pop_subr_num (biasedSubrs, subr_num) || callStack.get_count () >= kMaxCallLimit)) { SUPER::set_error (); @@ -175,7 +176,7 @@ struct cs_interp_env_t : interp_env_t SUPER::str_ref = context.str_ref; } - void returnFromSubr () + void return_from_subr () { if (unlikely (SUPER::str_ref.in_error ())) SUPER::set_error (); @@ -254,7 +255,7 @@ struct cs_opset_t : opset_t switch (op) { case OpCode_return: - env.returnFromSubr (); + env.return_from_subr (); break; case OpCode_endchar: OPSET::check_width (op, env, param); @@ -267,11 +268,11 @@ struct cs_opset_t : opset_t break; case OpCode_callsubr: - env.callSubr (env.localSubrs, CSType_LocalSubr); + env.call_subr (env.localSubrs, CSType_LocalSubr); break; case OpCode_callgsubr: - env.callSubr (env.globalSubrs, CSType_GlobalSubr); + env.call_subr (env.globalSubrs, CSType_GlobalSubr); break; case OpCode_hstem: diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index 39bf5acdd..a69dd93ae 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -351,7 +351,7 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_tadd_op (op, env.str_ref); param.current_parsed_str->set_parsed (); - env.returnFromSubr (); + env.return_from_subr (); param.set_current_str (env, false); break; @@ -382,7 +382,7 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_tadd_call_op (op, str_ref, env.context.subr_num); hb_set_add (closure, env.context.subr_num); param.set_current_str (env, true); diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index f033fbde1..caee17550 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -183,7 +183,7 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_tset_parsed (); - env.returnFromSubr (); + env.return_from_subr (); param.set_current_str (env, false); break; @@ -213,7 +213,7 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_tadd_call_op (op, str_ref, env.context.subr_num); hb_set_add (closure, env.context.subr_num); param.set_current_str (env, true); From df237d2fe78086ad16bdbd2cc60639ae9ce909d6 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Wed, 8 May 2019 14:17:14 -0700 Subject: [PATCH 214/336] [test] Add https://crbug.com/oss-fuzz/14641 testcase As 503748d fix --- ...e-minimized-hb-subset-fuzzer-5676773460672512 | Bin 0 -> 2172 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512 new file mode 100644 index 0000000000000000000000000000000000000000..4fc920bf52021ee6fe169c056bed6c5e089d326a GIT binary patch literal 2172 zcmeHHF=!J}82&DaN!o;_YN$(t2g#BK<24aMs356L?37~D=%6%5O?yMmMyV1(G*E0u z7o8j&+?+ZH3OWetCgSGepdezW3W5a>di~x@Okzn%ZHqei!@Ya&fB*ge_ul_~2L-?) zpcTZ#f&Q294`jy=CrmC!H`>TXM{~_^+I~!lJhUEDFYmQ!m&IV)(m7#VFe~xI#Been zAFTPeJ%0WQS9QSDD`h~|e9aQ>i#maS`B|^FfrG%CS{)S_16+u8UkAKLW=hwlxp9nN zF7O=++^o?c5v$kPv6~sKhPC@+u;M?|RVXoUvm^DN-Xx}|(EmPmQs++kxZ^H1w6qR Date: Wed, 8 May 2019 11:40:31 -0700 Subject: [PATCH 215/336] [map] add iteration --- src/hb-map.hh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/hb-map.hh b/src/hb-map.hh index 13099afc4..2b25c2e61 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -62,6 +62,7 @@ struct hb_hashmap_t bool is_unused () const { return key == kINVALID; } bool is_tombstone () const { return key != kINVALID && value == vINVALID; } bool is_real () const { return key != kINVALID && value != vINVALID; } + hb_pair_t get_pair() const { return hb_pair (key, value); } }; hb_object_header_t header; @@ -206,6 +207,16 @@ struct hb_hashmap_t unsigned int get_population () const { return population; } + /* + * Iterator + */ + auto iter() const HB_AUTO_RETURN + ( + + hb_array_t (items, mask + 1) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::get_pair) + ) + protected: unsigned int bucket_for (K key) const From ba60512813caafc2006b26214e95bbfe1c0e460a Mon Sep 17 00:00:00 2001 From: rsheeter Date: Wed, 8 May 2019 12:09:10 -0700 Subject: [PATCH 216/336] [map] add a test for iteration --- src/hb-map.hh | 2 +- src/test-iter.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 2b25c2e61..5a4f5c371 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -62,7 +62,7 @@ struct hb_hashmap_t bool is_unused () const { return key == kINVALID; } bool is_tombstone () const { return key != kINVALID && value == vINVALID; } bool is_real () const { return key != kINVALID && value != vINVALID; } - hb_pair_t get_pair() const { return hb_pair (key, value); } + hb_pair_t get_pair() const { return hb_pair_t (key, value); } }; hb_object_header_t header; diff --git a/src/test-iter.cc b/src/test-iter.cc index ac2c30e09..7e7732018 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -206,6 +206,10 @@ main (int argc, char **argv) | hb_reduce ([&] (int acc, int value) -> int { return acc; }, 2) ; + using map_pair_t = decltype (*hb_iter (m)); + + hb_iter (m) + | hb_map ([] (map_pair_t p) { return p.first * p.second; }); + unsigned int temp1 = 10; unsigned int temp2 = 0; hb_map_t *result = From 492af0f1bf1d7198b474fda2faca451908af267f Mon Sep 17 00:00:00 2001 From: rsheeter Date: Wed, 8 May 2019 12:47:18 -0700 Subject: [PATCH 217/336] [map] add keys() --- src/hb-map.hh | 9 ++++++++- src/test-iter.cc | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 5a4f5c371..4a1f75e65 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -212,11 +212,18 @@ struct hb_hashmap_t */ auto iter() const HB_AUTO_RETURN ( - + hb_array_t (items, mask + 1) + + hb_array (items, mask + 1) | hb_filter (&item_t::is_real) | hb_map (&item_t::get_pair) ) + auto keys() const HB_AUTO_RETURN + ( + + iter() + | hb_map (&hb_pair_t::first) + ) + // | hb_map ([&] (item_t i) { return i.key; }) + protected: unsigned int bucket_for (K key) const diff --git a/src/test-iter.cc b/src/test-iter.cc index 7e7732018..63851a34e 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -210,6 +210,10 @@ main (int argc, char **argv) + hb_iter (m) | hb_map ([] (map_pair_t p) { return p.first * p.second; }); + using map_key_t = decltype (*m.keys()); + + hb_iter (m.keys ()) + | hb_filter ([] (map_key_t k) { return k < 42; }); + unsigned int temp1 = 10; unsigned int temp2 = 0; hb_map_t *result = From b827181ba1f539c990e1bd8fdd3559f1589c8d28 Mon Sep 17 00:00:00 2001 From: rsheeter Date: Wed, 8 May 2019 13:51:11 -0700 Subject: [PATCH 218/336] [map] tweak test-iter.cc --- src/hb-map.hh | 1 - src/test-iter.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 4a1f75e65..36dfc3e5c 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -222,7 +222,6 @@ struct hb_hashmap_t + iter() | hb_map (&hb_pair_t::first) ) - // | hb_map ([&] (item_t i) { return i.key; }) protected: diff --git a/src/test-iter.cc b/src/test-iter.cc index 63851a34e..273ba6c4f 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -206,7 +206,7 @@ main (int argc, char **argv) | hb_reduce ([&] (int acc, int value) -> int { return acc; }, 2) ; - using map_pair_t = decltype (*hb_iter (m)); + using map_pair_t = hb_item_type; + hb_iter (m) | hb_map ([] (map_pair_t p) { return p.first * p.second; }); From 7166bd563447a64eda05c66668bd4a178292bd79 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 14:24:57 -0700 Subject: [PATCH 219/336] Minor --- src/hb-open-type.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 1129bd006..9d388ff3f 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -427,7 +427,7 @@ struct UnsizedArrayOf if (unlikely (!serialize (c, count))) return_trace (false); /* TODO Umm. Just exhaust the iterator instead? Being extra * cautious right now.. */ - for (unsigned i = 0; i < count; i++, items++) + for (unsigned i = 0; i < count; i++, ++items) arrayZ[i] = *items; return_trace (true); } @@ -608,7 +608,7 @@ struct ArrayOf if (unlikely (!serialize (c, count))) return_trace (false); /* TODO Umm. Just exhaust the iterator instead? Being extra * cautious right now.. */ - for (unsigned i = 0; i < count; i++, items++) + for (unsigned i = 0; i < count; i++, ++items) arrayZ[i] = *items; return_trace (true); } From a17f0fa3a10a25959561582ae63ef2e5208647e2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 14:44:11 -0700 Subject: [PATCH 220/336] [meta] Capture rvalue-references in is_reference / remove_reference --- src/hb-meta.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index a47c8cabd..421eb0638 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -93,6 +93,7 @@ template using hb_remove_const = typename hb_match_const::type; #define hb_is_const(T) hb_match_const::value template struct hb_match_reference { typedef T type; enum { value = false }; }; template struct hb_match_reference { typedef T type; enum { value = true }; }; +template struct hb_match_reference { typedef T type; enum { value = true }; }; template using hb_remove_reference = typename hb_match_reference::type; #define hb_is_reference(T) hb_match_reference::value template struct hb_match_pointer { typedef T type; enum { value = false }; }; From f5705d7656817cbfdbc4479b1cb0be3af6f4abdf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 14:46:55 -0700 Subject: [PATCH 221/336] Whitespace --- src/hb-map.hh | 10 +++++----- src/test-iter.cc | 11 +++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 36dfc3e5c..0e57f9732 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -210,16 +210,16 @@ struct hb_hashmap_t /* * Iterator */ - auto iter() const HB_AUTO_RETURN + auto iter () const HB_AUTO_RETURN ( + hb_array (items, mask + 1) | hb_filter (&item_t::is_real) | hb_map (&item_t::get_pair) ) - auto keys() const HB_AUTO_RETURN + auto keys () const HB_AUTO_RETURN ( - + iter() + + iter() | hb_map (&hb_pair_t::first) ) @@ -233,9 +233,9 @@ struct hb_hashmap_t while (!items[i].is_unused ()) { if (items[i] == key) - return i; + return i; if (tombstone == (unsigned) -1 && items[i].is_tombstone ()) - tombstone = i; + tombstone = i; i = (i + ++step) & mask; } return tombstone == (unsigned) -1 ? i : tombstone; diff --git a/src/test-iter.cc b/src/test-iter.cc index 273ba6c4f..69f2de978 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -208,11 +208,14 @@ main (int argc, char **argv) using map_pair_t = hb_item_type; + hb_iter (m) - | hb_map ([] (map_pair_t p) { return p.first * p.second; }); + | hb_map ([] (map_pair_t p) { return p.first * p.second; }) + ; - using map_key_t = decltype (*m.keys()); - + hb_iter (m.keys ()) - | hb_filter ([] (map_key_t k) { return k < 42; }); + m.keys (); + using map_key_t = decltype (*m.keys()); + + hb_iter (m.keys ()) + | hb_filter ([] (map_key_t k) { return k < 42; }) + ; unsigned int temp1 = 10; unsigned int temp2 = 0; From 5ceaafa5de8dff51fe91f7008a12ec9c304a1376 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 14:59:25 -0700 Subject: [PATCH 222/336] [algs] Fix identity return type --- src/hb-algs.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 52d40923e..d377772e0 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -36,15 +36,15 @@ struct { - template T - operator () (const T& v) const { return v; } + template auto + operator () (T&& v) const HB_AUTO_RETURN ( hb_forward (v) ) } HB_FUNCOBJ (hb_identity); struct { template bool - operator () (const T& v) const { return bool (v); } + operator () (T&& v) const { return bool (hb_forward (v)); } } HB_FUNCOBJ (hb_bool); From 3c69505b3a7850b68a931849a2badb84b6b36d51 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 15:05:10 -0700 Subject: [PATCH 223/336] [map] Fix iter --- src/hb-map.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 0e57f9732..a5dedac57 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -212,7 +212,7 @@ struct hb_hashmap_t */ auto iter () const HB_AUTO_RETURN ( - + hb_array (items, mask + 1) + + hb_array (items, mask ? mask + 1 : 0) | hb_filter (&item_t::is_real) | hb_map (&item_t::get_pair) ) From a30482718491e3455365167e1c85981c8c0f542b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 15:08:10 -0700 Subject: [PATCH 224/336] [map] Add .values() iterator --- src/hb-map.hh | 6 +++++- src/test-iter.cc | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index a5dedac57..1c2fe145f 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -216,12 +216,16 @@ struct hb_hashmap_t | hb_filter (&item_t::is_real) | hb_map (&item_t::get_pair) ) - auto keys () const HB_AUTO_RETURN ( + iter() | hb_map (&hb_pair_t::first) ) + auto values () const HB_AUTO_RETURN + ( + + iter() + | hb_map (&hb_pair_t::second) + ) protected: diff --git a/src/test-iter.cc b/src/test-iter.cc index 69f2de978..0a0e4d102 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -215,6 +215,14 @@ main (int argc, char **argv) using map_key_t = decltype (*m.keys()); + hb_iter (m.keys ()) | hb_filter ([] (map_key_t k) { return k < 42; }) + | hb_drain + ; + + m.values (); + using map_value_t = decltype (*m.values()); + + hb_iter (m.values ()) + | hb_filter ([] (map_value_t k) { return k < 42; }) + | hb_drain ; unsigned int temp1 = 10; From 372c5b97bfa3b744de1d017cf662607eb8a2fa6e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 15:28:39 -0700 Subject: [PATCH 225/336] [map] Fix bots Older compilers don't like calling iter() from return-type decltype() ../src/hb-map.hh:226:12: error: cannot call member function 'decltype ((((+ hb_array(((const hb_hashmap_t*)this)->hb_hashmap_t::items, (((const hb_hashmap_t*)this)->hb_hashmap_t::mask ? (((const hb_hashmap_t*)this)->hb_hashmap_t::mask + 1) : 0))) | hb_filter((& hb_hashmap_t::item_t:: is_real))) | hb_map((& hb_hashmap_t::item_t:: get_pair)))) hb_hashmap_t::iter() const [with K = const hb_serialize_context_t::object_t*; V = unsigned int; K kINVALID = 0u; V vINVALID = 0u; decltype ((((+ hb_array(((const hb_hashmap_t*)this)->hb_hashmap_t::items, (((const hb_hashmap_t*)this)->hb_hashmap_t::mask ? (((const hb_hashmap_t*)this)->hb_hashmap_t::mask + 1) : 0))) | hb_filter((& hb_hashmap_t::item_t:: is_real))) | hb_map((& hb_hashmap_t::item_t:: get_pair)))) = hb_map_iter_t::item_t>, bool (hb_hashmap_t::item_t::*)() const, const&, 0u>, hb_pair_t (hb_hashmap_t::item_t::*)() const, 0u>]' without object + iter() ^ ../src/hb-meta.hh:58:41: note: in definition of macro 'HB_AUTO_RETURN' #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); } ^ --- src/hb-map.hh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 1c2fe145f..6eac8c3d3 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -218,13 +218,15 @@ struct hb_hashmap_t ) auto keys () const HB_AUTO_RETURN ( - + iter() - | hb_map (&hb_pair_t::first) + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::key) ) auto values () const HB_AUTO_RETURN ( - + iter() - | hb_map (&hb_pair_t::second) + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::value) ) protected: From 27b2093009745b6c30663605f45ac95deb1562cc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 15:32:57 -0700 Subject: [PATCH 226/336] [map] Return rvalues from keys()/values() --- src/hb-algs.hh | 7 +++++++ src/hb-map.hh | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index d377772e0..0db2184cf 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -41,6 +41,13 @@ struct } HB_FUNCOBJ (hb_identity); +struct +{ + template hb_remove_reference + operator () (T&& v) const { return v; } +} +HB_FUNCOBJ (hb_rvalue); + struct { template bool diff --git a/src/hb-map.hh b/src/hb-map.hh index 6eac8c3d3..2f0659562 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -221,12 +221,14 @@ struct hb_hashmap_t + hb_array (items, mask ? mask + 1 : 0) | hb_filter (&item_t::is_real) | hb_map (&item_t::key) + | hb_map (hb_rvalue) ) auto values () const HB_AUTO_RETURN ( + hb_array (items, mask ? mask + 1 : 0) | hb_filter (&item_t::is_real) | hb_map (&item_t::value) + | hb_map (hb_rvalue) ) protected: From d5decf9bf77db914b67ffc446379df621516e362 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Tue, 7 May 2019 15:47:38 -0700 Subject: [PATCH 227/336] [subset] Move hdmx to subset2. --- src/hb-ot-hdmx-table.hh | 38 +++++++------------------------------- src/hb-subset.cc | 2 +- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 847b32657..abf4440a6 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -157,40 +157,16 @@ struct hdmx return_trace (true); } - static size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan) + + bool subset (hb_subset_context_t *c) const { - return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->num_output_glyphs ()); - } + TRACE_SUBSET (this); - bool subset (hb_subset_plan_t *plan) const - { - size_t dest_size = get_subsetted_size (this, plan); - hdmx *dest = (hdmx *) malloc (dest_size); - if (unlikely (!dest)) - { - DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for hdmx subset output.", (unsigned long) dest_size); - return false; - } + hdmx *hdmx_prime = c->serializer->start_embed (); + if (unlikely (!hdmx_prime)) return_trace (false); - hb_serialize_context_t c (dest, dest_size); - hdmx *hdmx_prime = c.start_serialize (); - if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan)) - { - free (dest); - DEBUG_MSG(SUBSET, nullptr, "Failed to serialize write new hdmx."); - return false; - } - c.end_serialize (); - - hb_blob_t *hdmx_prime_blob = hb_blob_create ((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); - bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob); - hb_blob_destroy (hdmx_prime_blob); - - return result; + hdmx_prime->serialize (c->serializer, this, c->plan); + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 800bd35c8..f4fc77172 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -159,7 +159,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset (plan); break; case HB_OT_TAG_hdmx: - result = _subset (plan); + result = _subset2 (plan); break; case HB_OT_TAG_name: result = _subset2 (plan); From e8ef0e627c493af700e254bdd2767f8955f2d03f Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Tue, 7 May 2019 17:23:02 -0700 Subject: [PATCH 228/336] [subset] WIP convert hdmx subsetting to use iterators. --- src/hb-ot-hdmx-table.hh | 117 +++++++++++++++--------------------- test/api/test-subset-hdmx.c | 23 ------- 2 files changed, 49 insertions(+), 91 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index abf4440a6..560fb14d0 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -41,71 +41,30 @@ namespace OT { struct DeviceRecord { - struct SubsetView - { - const DeviceRecord *source_device_record; - unsigned int sizeDeviceRecord; - hb_subset_plan_t *subset_plan; - - void init (const DeviceRecord *source_device_record, - unsigned int sizeDeviceRecord, - hb_subset_plan_t *subset_plan) - { - this->source_device_record = source_device_record; - this->sizeDeviceRecord = sizeDeviceRecord; - this->subset_plan = subset_plan; - } - - unsigned int len () const - { return this->subset_plan->num_output_glyphs (); } - - const HBUINT8* operator [] (unsigned int new_gid) const - { - if (unlikely (new_gid >= len ())) return nullptr; - - hb_codepoint_t old_gid; - if (!this->subset_plan->old_gid_for_new_gid (new_gid, &old_gid)) - return &Null(HBUINT8); - - if (old_gid >= sizeDeviceRecord - DeviceRecord::min_size) - return nullptr; - return &(this->source_device_record->widthsZ[old_gid]); - } - }; - - static unsigned int get_size (unsigned int count) + static unsigned int get_size (unsigned count) { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); } - bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) + template + bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it) { TRACE_SERIALIZE (this); - unsigned int size = get_size (subset_view.len ()); - if (unlikely (!c->allocate_size (size))) - { - DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.", - size); - return_trace (false); - } + unsigned length = it.len (); - this->pixelSize = subset_view.source_device_record->pixelSize; - this->maxWidth = subset_view.source_device_record->maxWidth; + if (unlikely (!c->extend (*this, length))) return_trace (false); - for (unsigned int i = 0; i < subset_view.len (); i++) - { - const HBUINT8 *width = subset_view[i]; - if (!width) - { - DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i); - return_trace (false); - } - widthsZ[i] = *width; - } + this->pixelSize = pixelSize; + this->maxWidth = + + it + | hb_reduce (hb_max, 0u); + + + it + | hb_sink (widthsZ.as_array (length)); return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, unsigned int sizeDeviceRecord) const + bool sanitize (hb_sanitize_context_t *c, unsigned sizeDeviceRecord) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && @@ -135,26 +94,25 @@ struct hdmx return StructAtOffset (&this->firstDeviceRecord, i * sizeDeviceRecord); } - bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan) + template + bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min ((*this)))) return_trace (false); - this->version = source_hdmx->version; - this->numRecords = source_hdmx->numRecords; - this->sizeDeviceRecord = DeviceRecord::get_size (plan->num_output_glyphs ()); + this->version = version; + this->numRecords = it.len (); + this->sizeDeviceRecord = + it ? DeviceRecord::get_size ((*it).second.len ()) : DeviceRecord::get_size (0); - for (unsigned int i = 0; i < source_hdmx->numRecords; i++) - { - DeviceRecord::SubsetView subset_view; - subset_view.init (&(*source_hdmx)[i], source_hdmx->sizeDeviceRecord, plan); + using pair_t = decltype (*it); + + it + | hb_apply ([&] (const pair_t& _) { + c->start_embed ()->serialize (c, _.first, _.second); + }); - if (!c->start_embed ()->serialize (c, subset_view)) - return_trace (false); - } - - return_trace (true); + return_trace (c->successful); } @@ -165,10 +123,33 @@ struct hdmx hdmx *hdmx_prime = c->serializer->start_embed (); if (unlikely (!hdmx_prime)) return_trace (false); - hdmx_prime->serialize (c->serializer, this, c->plan); + auto it = + + hb_iota ((unsigned) numRecords) + | hb_map ([&] (unsigned _) { + const DeviceRecord *device_record = + &StructAtOffset (&firstDeviceRecord, + _ * sizeDeviceRecord); + auto row = + + hb_iota (c->plan->num_output_glyphs ()) + | hb_map (c->plan->reverse_glyph_map) + | hb_map ([=] (hb_codepoint_t _) { + if (c->plan->is_empty_glyph (_)) + return Null(HBUINT8); + return device_record->widthsZ.as_array (get_num_glyphs ()) [_]; + }) + ; + return hb_pair ((unsigned) device_record->pixelSize, +row); + }); + + hdmx_prime->serialize (c->serializer, version, it); return_trace (true); } + unsigned get_num_glyphs () const + { + return sizeDeviceRecord - DeviceRecord::min_size; + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c index 44e579ace..7178833bc 100644 --- a/test/api/test-subset-hdmx.c +++ b/test/api/test-subset-hdmx.c @@ -91,28 +91,6 @@ test_subset_hdmx_invalid (void) hb_face_destroy (face); } -static void -test_subset_hdmx_fails_sanitize (void) -{ - hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016"); - - hb_subset_input_t *input = hb_subset_input_create_or_fail (); - hb_set_t *codepoints = hb_subset_input_unicode_set (input); - hb_face_t *subset; - - hb_set_add (codepoints, 'a'); - hb_set_add (codepoints, 'b'); - hb_set_add (codepoints, 'c'); - - subset = hb_subset (face, input); - g_assert (subset); - g_assert (subset == hb_face_get_empty ()); - - hb_subset_input_destroy (input); - hb_face_destroy (subset); - hb_face_destroy (face); -} - static void test_subset_hdmx_noop (void) { @@ -140,7 +118,6 @@ main (int argc, char **argv) hb_test_add (test_subset_hdmx_simple_subset); hb_test_add (test_subset_hdmx_multiple_device_records); hb_test_add (test_subset_hdmx_invalid); - hb_test_add (test_subset_hdmx_fails_sanitize); hb_test_add (test_subset_hdmx_noop); return hb_test_run(); From b710176ce28e863a01797987d7ce37d19aaf2fd3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 15:46:51 -0700 Subject: [PATCH 229/336] [hdmx] Touch up --- src/hb-ot-hdmx-table.hh | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 560fb14d0..35d27f7fa 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -44,7 +44,8 @@ struct DeviceRecord static unsigned int get_size (unsigned count) { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); } - template + template bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it) { TRACE_SERIALIZE (this); @@ -94,7 +95,8 @@ struct hdmx return StructAtOffset (&this->firstDeviceRecord, i * sizeDeviceRecord); } - template + template bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it) { TRACE_SERIALIZE (this); @@ -103,14 +105,13 @@ struct hdmx this->version = version; this->numRecords = it.len (); - this->sizeDeviceRecord = - it ? DeviceRecord::get_size ((*it).second.len ()) : DeviceRecord::get_size (0); + this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0); - using pair_t = decltype (*it); + it - | hb_apply ([&] (const pair_t& _) { + | hb_apply ([&] (const hb_item_type& _) { c->start_embed ()->serialize (c, _.first, _.second); - }); + }) + ; return_trace (c->successful); } @@ -125,21 +126,24 @@ struct hdmx auto it = + hb_iota ((unsigned) numRecords) - | hb_map ([&] (unsigned _) { + | hb_map ([&] (unsigned _) + { const DeviceRecord *device_record = &StructAtOffset (&firstDeviceRecord, _ * sizeDeviceRecord); auto row = + hb_iota (c->plan->num_output_glyphs ()) | hb_map (c->plan->reverse_glyph_map) - | hb_map ([=] (hb_codepoint_t _) { + | hb_map ([=] (hb_codepoint_t _) + { if (c->plan->is_empty_glyph (_)) return Null(HBUINT8); return device_record->widthsZ.as_array (get_num_glyphs ()) [_]; }) ; return hb_pair ((unsigned) device_record->pixelSize, +row); - }); + }) + ; hdmx_prime->serialize (c->serializer, version, it); return_trace (true); From 4c94bc63d914fac7e11940eb165b6cf1039ba5a1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 15:57:33 -0700 Subject: [PATCH 230/336] Move hb_invoke() back to hb-algs.hh --- src/hb-algs.hh | 32 ++++++++++++++++++++++++++++++++ src/hb-meta.hh | 32 -------------------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 0db2184cf..6adbade15 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -76,6 +76,38 @@ struct } HB_FUNCOBJ (hb_hash); + +struct +{ + private: + + /* Pointer-to-member-function. */ + template auto + impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN + ((hb_deref (hb_forward (v)).*hb_forward (a)) (hb_forward (ds)...)) + + /* Pointer-to-member. */ + template auto + impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN + ((hb_deref (hb_forward (v))).*hb_forward (a)) + + /* Operator(). */ + template auto + impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN + (hb_deref (hb_forward (a)) (hb_forward (ds)...)) + + public: + + template auto + operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN + ( + impl (hb_forward (a), + hb_prioritize, + hb_forward (ds)...) + ) +} +HB_FUNCOBJ (hb_invoke); + struct { private: diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 421eb0638..4e5e5d94f 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -212,36 +212,4 @@ template <> struct hb_is_integer { enum { value = true }; }; #define hb_is_integer(T) hb_is_integer::value -struct -{ - private: - - /* Pointer-to-member-function. */ - template auto - impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN - ((hb_deref (hb_forward (v)).*hb_forward (a)) (hb_forward (ds)...)) - - /* Pointer-to-member. */ - template auto - impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN - ((hb_deref (hb_forward (v))).*hb_forward (a)) - - /* Operator(). */ - template auto - impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN - (hb_deref (hb_forward (a)) (hb_forward (ds)...)) - - public: - - template auto - operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN - ( - impl (hb_forward (a), - hb_prioritize, - hb_forward (ds)...) - ) -} -HB_FUNCOBJ (hb_invoke); - - #endif /* HB_META_HH */ From afb013f350b0022ae6c05f140aeba23d5de34101 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 16:16:43 -0700 Subject: [PATCH 231/336] Fix msan issue hb_identity returns rvalue-reference if input is rvalue. That, can leak the reference and cause in bad access to temporaries after they are destructed. This is unfortunately unfixable given the desired transparency of hb_identity :(. Just don't use it with hb_map(). --- src/test-iter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 0a0e4d102..944c234f5 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -161,7 +161,7 @@ main (int argc, char **argv) test_iterator_non_default_constructable (hb_enumerate (hb_iter (st))); test_iterator_non_default_constructable (hb_enumerate (hb_iter (st) + 1)); test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); - test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_identity)); + test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_rvalue)); assert (true == hb_all (st)); assert (false == hb_all (st, 42u)); From e8b45c19330d8718cd6d7aef0ca2db0539a53294 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 16:37:38 -0700 Subject: [PATCH 232/336] [array] Add .copy() --- src/hb-array.hh | 11 +++++++++++ src/hb-open-type.hh | 10 ++++------ src/hb-serialize.hh | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 2da8df0bb..8902e7aaf 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -176,6 +176,17 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> void free () { ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; } + template + hb_array_t copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto* out = c->template start_embed (arrayZ); + if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ()); + for (unsigned i = 0; i < length; i++) + out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ + return_trace (hb_array_t (out, length)); + } + template bool sanitize (hb_sanitize_context_t *c) const { return c->check_array (arrayZ, length); } diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9d388ff3f..cacb1a7b8 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -436,9 +436,7 @@ struct UnsizedArrayOf { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); - if (unlikely (!out->serialize (c, count))) return_trace (nullptr); - for (unsigned i = 0; i < count; i++) - out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ + if (unlikely (!as_array (count).copy (c))) return_trace (nullptr); return_trace (out); } @@ -618,9 +616,9 @@ struct ArrayOf TRACE_SERIALIZE (this); auto *out = c->start_embed (this); unsigned count = len; - if (unlikely (!out->serialize (c, count))) return_trace (nullptr); - for (unsigned i = 0; i < count; i++) - out->arrayZ[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ + if (unlikely (!c->extend_min (out))) return_trace (nullptr); + c->check_assign (out->len, len); + if (unlikely (!as_array ().copy (c))) return_trace (nullptr); return_trace (out); } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index e0f79809f..76f701608 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -323,7 +323,7 @@ struct hb_serialize_context_t allocate_size (alignment - l); } - template + template Type *start_embed (const Type *obj HB_UNUSED = nullptr) const { return reinterpret_cast (this->head); } template From e2a51ff7264940312197184318f5ad4ec971492f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 16:41:39 -0700 Subject: [PATCH 233/336] Remove unused var --- src/hb-open-type.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index cacb1a7b8..5fa1164db 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -615,7 +615,6 @@ struct ArrayOf { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); - unsigned count = len; if (unlikely (!c->extend_min (out))) return_trace (nullptr); c->check_assign (out->len, len); if (unlikely (!as_array ().copy (c))) return_trace (nullptr); From 3476445420d0e6432c09710b6667205453799129 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 8 May 2019 21:14:01 -0700 Subject: [PATCH 234/336] Remove unnecessary template keyword Should fix MSVC. --- src/hb-array.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 8902e7aaf..a320685e2 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -180,7 +180,7 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> hb_array_t copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); - auto* out = c->template start_embed (arrayZ); + auto* out = c->start_embed (arrayZ); if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ()); for (unsigned i = 0; i < length; i++) out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */ From 71537f93e0ce27121012bf1e81270b6b03b22224 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 10:46:49 -0700 Subject: [PATCH 235/336] [iota] end -> end_ to not shadow --- src/hb-iter.hh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 5aa138fbc..974855467 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -578,36 +578,36 @@ template struct hb_iota_iter_t : hb_iter_t, T> { - hb_iota_iter_t (T start, T end, S step) : v (start), end (end_for (start, end, step)), step (step) {} + hb_iota_iter_t (T start, T end_, S step) : v (start), end_ (end__for (start, end_, step)), step (step) {} typedef T __item_t__; static constexpr bool is_random_access_iterator = true; static constexpr bool is_sorted_iterator = true; __item_t__ __item__ () const { return v; } __item_t__ __item_at__ (unsigned j) const { return v + j * step; } - bool __more__ () const { return v != end; } - unsigned __len__ () const { return (end - v) / step; } + bool __more__ () const { return v != end_; } + unsigned __len__ () const { return (end_ - v) / step; } void __next__ () { v += step; } void __forward__ (unsigned n) { v += n * step; } void __prev__ () { v -= step; } void __rewind__ (unsigned n) { v -= n * step; } - hb_iota_iter_t __end__ () const { hb_iota_iter_t (end, end, step); } + hb_iota_iter_t __end___ () const { hb_iota_iter_t (end_, end_, step); } bool operator != (const hb_iota_iter_t& o) const - { return v != o.v || end != o.end || step != o.step; } + { return v != o.v || end_ != o.end_ || step != o.step; } private: - static inline T end_for (T start, T end, S step) + static inline T end__for (T start, T end_, S step) { - auto res = (end - start) % step; + auto res = (end_ - start) % step; if (!res) - return end; - end += step - res; - return end; + return end_; + end_ += step - res; + return end_; } private: T v; - T end; + T end_; S step; }; struct From 05867d9f5315c7e4f49e5873a5aba6bba7121f04 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:00:43 -0700 Subject: [PATCH 236/336] [meta] Add hb_int_max() --- src/hb-meta.hh | 91 +++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 4e5e5d94f..74a4457c3 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -47,7 +47,7 @@ template using hb_head_tt = typename _hb_head_tt::type; /* Bool! For when we need to evaluate type-dependent expressions * in a template argument. */ -template struct hb_bool_tt { enum { value = b }; }; +template struct hb_bool_tt { static constexpr bool value = b; }; typedef hb_bool_tt hb_true_t; typedef hb_bool_tt hb_false_t; @@ -87,17 +87,17 @@ HB_FUNCOBJ (hb_addressof); template static inline T hb_declval (); #define hb_declval(T) (hb_declval ()) -template struct hb_match_const { typedef T type; enum { value = false }; }; -template struct hb_match_const { typedef T type; enum { value = true }; }; +template struct hb_match_const { typedef T type; static constexpr bool value = false; }; +template struct hb_match_const { typedef T type; static constexpr bool value = true; }; template using hb_remove_const = typename hb_match_const::type; #define hb_is_const(T) hb_match_const::value -template struct hb_match_reference { typedef T type; enum { value = false }; }; -template struct hb_match_reference { typedef T type; enum { value = true }; }; -template struct hb_match_reference { typedef T type; enum { value = true }; }; +template struct hb_match_reference { typedef T type; static constexpr bool value = false; }; +template struct hb_match_reference { typedef T type; static constexpr bool value = true; }; +template struct hb_match_reference { typedef T type; static constexpr bool value = true; }; template using hb_remove_reference = typename hb_match_reference::type; #define hb_is_reference(T) hb_match_reference::value -template struct hb_match_pointer { typedef T type; enum { value = false }; }; -template struct hb_match_pointer { typedef T type; enum { value = true }; }; +template struct hb_match_pointer { typedef T type; static constexpr bool value = false; }; +template struct hb_match_pointer { typedef T type; static constexpr bool value = true; }; template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value @@ -173,42 +173,63 @@ template struct hb_is_same : hb_true_t {}; #define hb_is_same(T, T2) hb_is_same::value template struct hb_is_signed; -template <> struct hb_is_signed { enum { value = CHAR_MIN < 0 }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { static constexpr bool value = CHAR_MIN < 0; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = false; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = false; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = false; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = false; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = false; }; #define hb_is_signed(T) hb_is_signed::value -template struct hb_int_min { static constexpr T value = 0; }; -template <> struct hb_int_min { static constexpr char value = CHAR_MIN; }; -template <> struct hb_int_min { static constexpr int value = INT_MIN; }; -template <> struct hb_int_min { static constexpr long value = LONG_MIN; }; +template struct hb_int_min; +template <> struct hb_int_min { static constexpr char value = CHAR_MIN; }; +template <> struct hb_int_min { static constexpr signed char value = SCHAR_MIN; }; +template <> struct hb_int_min { static constexpr unsigned char value = 0; }; +template <> struct hb_int_min { static constexpr signed short value = SHRT_MIN; }; +template <> struct hb_int_min { static constexpr unsigned short value = 0; }; +template <> struct hb_int_min { static constexpr signed int value = INT_MIN; }; +template <> struct hb_int_min { static constexpr unsigned int value = 0; }; +template <> struct hb_int_min { static constexpr signed long value = LONG_MIN; }; +template <> struct hb_int_min { static constexpr unsigned long value = 0; }; +template <> struct hb_int_min { static constexpr signed long long value = LLONG_MIN; }; +template <> struct hb_int_min { static constexpr unsigned long long value = 0; }; #define hb_int_min(T) hb_int_min::value +template struct hb_int_max; +template <> struct hb_int_max { static constexpr char value = CHAR_MAX; }; +template <> struct hb_int_max { static constexpr signed char value = SCHAR_MAX; }; +template <> struct hb_int_max { static constexpr unsigned char value = UCHAR_MAX; }; +template <> struct hb_int_max { static constexpr signed short value = SHRT_MAX; }; +template <> struct hb_int_max { static constexpr unsigned short value = USHRT_MAX; }; +template <> struct hb_int_max { static constexpr signed int value = INT_MAX; }; +template <> struct hb_int_max { static constexpr unsigned int value = UINT_MAX; }; +template <> struct hb_int_max { static constexpr signed long value = LONG_MAX; }; +template <> struct hb_int_max { static constexpr unsigned long value = ULONG_MAX; }; +template <> struct hb_int_max { static constexpr signed long long value = LLONG_MAX; }; +template <> struct hb_int_max { static constexpr unsigned long long value = ULLONG_MAX; }; +#define hb_int_max(T) hb_int_max::value template struct hb_signedness_int; template <> struct hb_signedness_int { typedef unsigned int value; }; template <> struct hb_signedness_int { typedef signed int value; }; #define hb_signedness_int(T) hb_signedness_int::value -template struct hb_is_integer { enum { value = false }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; -template <> struct hb_is_integer { enum { value = true }; }; +template struct hb_is_integer { static constexpr bool value = false;}; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; +template <> struct hb_is_integer { static constexpr bool value = true; }; #define hb_is_integer(T) hb_is_integer::value From 7675d0d3a6cc13ade1a2047019ef7fac8c373a3c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:02:56 -0700 Subject: [PATCH 237/336] [iter] Add hb_range() hb_range() is like Python range. hb_iota() has slightly different API. Ie. it takes a start, instead of end. --- src/hb-iter.hh | 33 ++++++++++++++++++++------------- src/test-iter.cc | 19 +++++++++++-------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 974855467..2557d3abc 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -572,13 +572,13 @@ struct } HB_FUNCOBJ (hb_apply); -/* hb_iota() */ +/* hb_iota()/hb_range() */ template -struct hb_iota_iter_t : - hb_iter_t, T> +struct hb_counter_iter_t : + hb_iter_t, T> { - hb_iota_iter_t (T start, T end_, S step) : v (start), end_ (end__for (start, end_, step)), step (step) {} + hb_counter_iter_t (T start, T end_, S step) : v (start), end_ (end__for (start, end_, step)), step (step) {} typedef T __item_t__; static constexpr bool is_random_access_iterator = true; @@ -591,8 +591,8 @@ struct hb_iota_iter_t : void __forward__ (unsigned n) { v += n * step; } void __prev__ () { v -= step; } void __rewind__ (unsigned n) { v -= n * step; } - hb_iota_iter_t __end___ () const { hb_iota_iter_t (end_, end_, step); } - bool operator != (const hb_iota_iter_t& o) const + hb_counter_iter_t __end___ () const { hb_counter_iter_t (end_, end_, step); } + bool operator != (const hb_counter_iter_t& o) const { return v != o.v || end_ != o.end_ || step != o.step; } private: @@ -612,15 +612,22 @@ struct hb_iota_iter_t : }; struct { - template hb_iota_iter_t - operator () (T end = (unsigned) -1) const - { return hb_iota_iter_t (0, end, 1u); } - - template hb_iota_iter_t - operator () (T start, T end, S&& step = 1u) const - { return hb_iota_iter_t (start, end, step); } + template hb_counter_iter_t + operator () (T start = 0u, S&& step = 1u) const + { return hb_counter_iter_t (start, hb_int_max (T), step); } } HB_FUNCOBJ (hb_iota); +struct +{ + template hb_counter_iter_t + operator () (T end = (unsigned) -1) const + { return hb_counter_iter_t (0, end, 1u); } + + template hb_counter_iter_t + operator () (T start, T end, S&& step = 1u) const + { return hb_counter_iter_t (start, end, step); } +} +HB_FUNCOBJ (hb_range); /* hb_sink() */ diff --git a/src/test-iter.cc b/src/test-iter.cc index 944c234f5..8f197898e 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -264,14 +264,17 @@ main (int argc, char **argv) s >> vl; hb_iota (); - assert (hb_iota (9).len () == 9); - assert (hb_iota (2, 9).len () == 7); - assert (hb_iota (2, 9, 3).len () == 3); - assert (hb_iota (2, 8, 3).len () == 2); - assert (hb_iota (2, 7, 3).len () == 2); - assert (hb_iota (-2, -9, -3).len () == 3); - assert (hb_iota (-2, -8, -3).len () == 2); - assert (hb_iota (-2, -7, -3).len () == 2); + hb_iota (3); + hb_iota (3, 2); + hb_range (); + assert (hb_range (9).len () == 9); + assert (hb_range (2, 9).len () == 7); + assert (hb_range (2, 9, 3).len () == 3); + assert (hb_range (2, 8, 3).len () == 2); + assert (hb_range (2, 7, 3).len () == 2); + assert (hb_range (-2, -9, -3).len () == 3); + assert (hb_range (-2, -8, -3).len () == 2); + assert (hb_range (-2, -7, -3).len () == 2); return 0; } From 2c24ea37b1ef63f79fcc24752dd180ce53540eda Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:07:38 -0700 Subject: [PATCH 238/336] [iter] Take start value in hb_enumerate() Also rewrite it via composition. --- src/hb-iter.hh | 61 +++++++++++------------------------------------- src/test-iter.cc | 1 + 2 files changed, 14 insertions(+), 48 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2557d3abc..885c122e2 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -490,58 +490,11 @@ struct template hb_zip_iter_t, hb_iter_type> - operator () (A& a, B &b) const + operator () (A&& a, B&& b) const { return hb_zip_iter_t, hb_iter_type> (hb_iter (a), hb_iter (b)); } } HB_FUNCOBJ (hb_zip); -/* hb_enumerate */ - -template -struct hb_enumerate_iter_t : - hb_iter_t, - hb_pair_t> -{ - hb_enumerate_iter_t (const Iter& it) : i (0), it (it) {} - - typedef hb_pair_t __item_t__; - static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - static constexpr bool is_sorted_iterator = true; - __item_t__ __item__ () const { return __item_t__ (+i, *it); } - __item_t__ __item_at__ (unsigned j) const { return __item_t__ (i + j, it[j]); } - bool __more__ () const { return bool (it); } - unsigned __len__ () const { return it.len (); } - void __next__ () { ++i; ++it; } - void __forward__ (unsigned n) { i += n; it += n; } - void __prev__ () { --i; --it; } - void __rewind__ (unsigned n) { i -= n; it -= n; } - hb_enumerate_iter_t __end__ () const - { - if (is_random_access_iterator) - return *this + this->len (); - /* Above expression loops twice. Following loops once. */ - auto it = *this; - while (it) ++it; - return it; - } - bool operator != (const hb_enumerate_iter_t& o) const - { return i != o.i || it != o.it; } - - private: - unsigned i; - Iter it; -}; -struct -{ - template - hb_enumerate_iter_t> - operator () (Iterable&& it) const - { return hb_enumerate_iter_t> (hb_iter (it)); } -} -HB_FUNCOBJ (hb_enumerate); - /* hb_apply() */ template @@ -629,6 +582,18 @@ struct } HB_FUNCOBJ (hb_range); +/* hb_enumerate */ + +struct +{ + template + auto operator () (Iterable&& it, Index start = 0u) const HB_AUTO_RETURN + ( hb_zip (hb_iota (start), it) ) +} +HB_FUNCOBJ (hb_enumerate); + /* hb_sink() */ diff --git a/src/test-iter.cc b/src/test-iter.cc index 8f197898e..e6c5d45c0 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -158,6 +158,7 @@ main (int argc, char **argv) test_iterator (hb_zip (st, v)); test_iterator_non_default_constructable (hb_enumerate (st)); + test_iterator_non_default_constructable (hb_enumerate (st, -5)); test_iterator_non_default_constructable (hb_enumerate (hb_iter (st))); test_iterator_non_default_constructable (hb_enumerate (hb_iter (st) + 1)); test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); From 5d263556b95047bced88e4a6252178d2fc0f9a19 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:08:25 -0700 Subject: [PATCH 239/336] [iter] Fix --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 885c122e2..b74a395f5 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -544,7 +544,7 @@ struct hb_counter_iter_t : void __forward__ (unsigned n) { v += n * step; } void __prev__ () { v -= step; } void __rewind__ (unsigned n) { v -= n * step; } - hb_counter_iter_t __end___ () const { hb_counter_iter_t (end_, end_, step); } + hb_counter_iter_t __end__ () const { hb_counter_iter_t (end_, end_, step); } bool operator != (const hb_counter_iter_t& o) const { return v != o.v || end_ != o.end_ || step != o.step; } From 64f0899a9f5e5aff65c5a78fa796ceae6f35c008 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:10:31 -0700 Subject: [PATCH 240/336] [iter] Bug fix --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index b74a395f5..ff30b170b 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -544,7 +544,7 @@ struct hb_counter_iter_t : void __forward__ (unsigned n) { v += n * step; } void __prev__ () { v -= step; } void __rewind__ (unsigned n) { v -= n * step; } - hb_counter_iter_t __end__ () const { hb_counter_iter_t (end_, end_, step); } + hb_counter_iter_t __end__ () const { return hb_counter_iter_t (end_, end_, step); } bool operator != (const hb_counter_iter_t& o) const { return v != o.v || end_ != o.end_ || step != o.step; } From 087327af1eac8c3a16115904557cbf3ab0f28072 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:14:06 -0700 Subject: [PATCH 241/336] [iter] Minor --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index ff30b170b..1f3c81976 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -536,7 +536,7 @@ struct hb_counter_iter_t : typedef T __item_t__; static constexpr bool is_random_access_iterator = true; static constexpr bool is_sorted_iterator = true; - __item_t__ __item__ () const { return v; } + __item_t__ __item__ () const { return +v; } __item_t__ __item_at__ (unsigned j) const { return v + j * step; } bool __more__ () const { return v != end_; } unsigned __len__ () const { return (end_ - v) / step; } From 46837910e628248edc09e45e212532a3493905da Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:20:41 -0700 Subject: [PATCH 242/336] [iter] Allow negative step in hb_iota() --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 1f3c81976..a9981258e 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -567,7 +567,7 @@ struct { template hb_counter_iter_t operator () (T start = 0u, S&& step = 1u) const - { return hb_counter_iter_t (start, hb_int_max (T), step); } + { return hb_counter_iter_t (start, step >= 0 ? hb_int_max (T) : hb_int_min (T), step); } } HB_FUNCOBJ (hb_iota); struct From 57d545932f539d06c52862310ecdfe79c143bb6b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:23:41 -0700 Subject: [PATCH 243/336] [test-iter] Don't walk past end That's not legal. --- src/test-iter.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index e6c5d45c0..2f6ed7471 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -82,8 +82,10 @@ test_iterator_non_default_constructable (Iter it) (void) _; it += it.len (); - it = it + 10; - it = 10 + it; + if (0) + it = it + 10; + if (0) + it = 10 + it; assert (*it == it[0]); From 12dd56f8573cb86169580d5ac31b986208805c03 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:25:02 -0700 Subject: [PATCH 244/336] [iter] Minor --- src/hb-iter.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a9981258e..30181564b 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -531,7 +531,7 @@ template struct hb_counter_iter_t : hb_iter_t, T> { - hb_counter_iter_t (T start, T end_, S step) : v (start), end_ (end__for (start, end_, step)), step (step) {} + hb_counter_iter_t (T start, T end_, S step) : v (start), end_ (end_for (start, end_, step)), step (step) {} typedef T __item_t__; static constexpr bool is_random_access_iterator = true; @@ -549,8 +549,10 @@ struct hb_counter_iter_t : { return v != o.v || end_ != o.end_ || step != o.step; } private: - static inline T end__for (T start, T end_, S step) + static inline T end_for (T start, T end_, S step) { + if (!step) + return end_; auto res = (end_ - start) % step; if (!res) return end_; From 57a5256fbcef6e5d29fc40cf019cc4b2c29c9dcf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:30:27 -0700 Subject: [PATCH 245/336] [iter] Minor --- src/hb-iter.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 30181564b..d5933986d 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -190,7 +190,7 @@ struct hb_iter_fallback_mixin_t item_t __item_at__ (unsigned i) const { return *(*thiz() + i); } /* Termination: Implement __more__(), or __len__() if random-access. */ - bool __more__ () const { return thiz()->len (); } + bool __more__ () const { return bool (thiz()->len ()); } unsigned __len__ () const { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } @@ -471,7 +471,7 @@ struct hb_zip_iter_t : B::is_sorted_iterator; __item_t__ __item__ () const { return __item_t__ (*a, *b); } __item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); } - bool __more__ () const { return a && b; } + bool __more__ () const { return bool (a) && bool (b); } unsigned __len__ () const { return hb_min (a.len (), b.len ()); } void __next__ () { ++a; ++b; } void __forward__ (unsigned n) { a += n; b += n; } From 5da3c9c33f02010a3fc57cf0e1d07955af681e7c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 11:30:31 -0700 Subject: [PATCH 246/336] [iter] Fix hb_zip() end condition We should compare-equal to end if either iterator's end reaches, not if both reach at the same time. Fixes infinite-loop in test which was happening after hb_enumerate() switched to using hb_zip(). --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index d5933986d..750331265 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -479,7 +479,7 @@ struct hb_zip_iter_t : void __rewind__ (unsigned n) { a -= n; b -= n; } hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); } bool operator != (const hb_zip_iter_t& o) const - { return a != o.a || b != o.b; } + { return a != o.a && b != o.b; } private: A a; From 4f2ad75a839708de71e7341f23c2d4b72059fc58 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 12:07:45 -0700 Subject: [PATCH 247/336] [enumerate] Fix hb_enumerate() len for step=0 --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 750331265..13b82604a 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -539,7 +539,7 @@ struct hb_counter_iter_t : __item_t__ __item__ () const { return +v; } __item_t__ __item_at__ (unsigned j) const { return v + j * step; } bool __more__ () const { return v != end_; } - unsigned __len__ () const { return (end_ - v) / step; } + unsigned __len__ () const { return !step ? UINT_MAX : (end_ - v) / step; } void __next__ () { v += step; } void __forward__ (unsigned n) { v += n * step; } void __prev__ () { v -= step; } From 00195a22ce5198345cb39825a45863cef7d8f7fc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 12:14:36 -0700 Subject: [PATCH 248/336] [hdmx] Adjust to hb_iota() behavior change Use hb_range() instead. --- src/hb-ot-hdmx-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index 35d27f7fa..dc36d0ab5 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -125,14 +125,14 @@ struct hdmx if (unlikely (!hdmx_prime)) return_trace (false); auto it = - + hb_iota ((unsigned) numRecords) + + hb_range ((unsigned) numRecords) | hb_map ([&] (unsigned _) { const DeviceRecord *device_record = &StructAtOffset (&firstDeviceRecord, _ * sizeDeviceRecord); auto row = - + hb_iota (c->plan->num_output_glyphs ()) + + hb_range (c->plan->num_output_glyphs ()) | hb_map (c->plan->reverse_glyph_map) | hb_map ([=] (hb_codepoint_t _) { From c9b287a867d6130a0cc745d7fd3ccfa4dcb4c32e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 12:43:57 -0700 Subject: [PATCH 249/336] Add hb_lidentity(), and rename hb_rvalue() to hb_ridentity() --- src/hb-algs.hh | 15 +++++++++++++-- src/hb-map.hh | 4 ++-- src/test-iter.cc | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 6adbade15..53bfa1fc5 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -36,17 +36,28 @@ struct { + /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ template auto operator () (T&& v) const HB_AUTO_RETURN ( hb_forward (v) ) } HB_FUNCOBJ (hb_identity); - struct { + /* Like identity(), but only retains lvalue-references. Rvalues are returned as rvalues. */ + template T& + operator () (T& v) const { return v; } + template hb_remove_reference operator () (T&& v) const { return v; } } -HB_FUNCOBJ (hb_rvalue); +HB_FUNCOBJ (hb_lidentity); +struct +{ + /* Like identity(), but always returns rvalue. */ + template hb_remove_reference + operator () (T&& v) const { return v; } +} +HB_FUNCOBJ (hb_ridentity); struct { diff --git a/src/hb-map.hh b/src/hb-map.hh index 2f0659562..9dc178880 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -221,14 +221,14 @@ struct hb_hashmap_t + hb_array (items, mask ? mask + 1 : 0) | hb_filter (&item_t::is_real) | hb_map (&item_t::key) - | hb_map (hb_rvalue) + | hb_map (hb_ridentity) ) auto values () const HB_AUTO_RETURN ( + hb_array (items, mask ? mask + 1 : 0) | hb_filter (&item_t::is_real) | hb_map (&item_t::value) - | hb_map (hb_rvalue) + | hb_map (hb_ridentity) ) protected: diff --git a/src/test-iter.cc b/src/test-iter.cc index 2f6ed7471..0d41e76f3 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -164,7 +164,7 @@ main (int argc, char **argv) test_iterator_non_default_constructable (hb_enumerate (hb_iter (st))); test_iterator_non_default_constructable (hb_enumerate (hb_iter (st) + 1)); test_iterator_non_default_constructable (hb_iter (st) | hb_filter ()); - test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_rvalue)); + test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_lidentity)); assert (true == hb_all (st)); assert (false == hb_all (st, 42u)); From 98eec3dd5f527cc562d98784429db0c7269e82a8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 13:15:36 -0700 Subject: [PATCH 250/336] Add hb_pair_t(,) macro as alternative to hb_pair_t<,> Just so it's easier to use it in other macros. --- src/hb-algs.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 53bfa1fc5..f211242db 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -222,6 +222,7 @@ struct hb_pair_t T1 first; T2 second; }; +#define hb_pair_t(T1,T2) hb_pair_t template static inline hb_pair_t hb_pair (T1&& a, T2&& b) { return hb_pair_t (a, b); } From 971020eca7c5d576816b93431607f1e63e9584a4 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 8 May 2019 16:31:52 -0700 Subject: [PATCH 251/336] Add sink support for hb_hashmap_t and a reverse call to hb_pair_t. --- src/hb-algs.hh | 5 +++++ src/hb-map.hh | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index f211242db..ca7075538 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -217,6 +217,11 @@ struct hb_pair_t hb_pair_t (T1 a, T2 b) : first (a), second (b) {} hb_pair_t (const pair_t& o) : first (o.first), second (o.second) {} + hb_pair_t reverse () const + { + return hb_pair_t (second, first); + } + bool operator == (const pair_t& o) const { return first == o.first && second == o.second; } T1 first; diff --git a/src/hb-map.hh b/src/hb-map.hh index 9dc178880..942a301e4 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -231,6 +231,10 @@ struct hb_hashmap_t | hb_map (hb_ridentity) ) + /* Sink interface. */ + hb_hashmap_t& operator << (const hb_pair_t& v) + { set (v.first, v.second); return *this; } + protected: unsigned int bucket_for (K key) const From 5e3cbed048b19ee579277ab4c56167a15d13104e Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 8 May 2019 16:33:03 -0700 Subject: [PATCH 252/336] [subset] Switch building of glyph maps in subset plan to use iterators. --- src/hb-algs.hh | 4 +--- src/hb-subset-plan.cc | 52 +++++++++++++++++++++---------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index ca7075538..dbb0805fc 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -218,9 +218,7 @@ struct hb_pair_t hb_pair_t (const pair_t& o) : first (o.first), second (o.second) {} hb_pair_t reverse () const - { - return hb_pair_t (second, first); - } + { return hb_pair_t (second, first); } bool operator == (const pair_t& o) const { return first == o.first && second == o.second; } diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 901347b9f..66976fa95 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -153,36 +153,36 @@ _populate_gids_to_retain (hb_face_t *face, } static void -_create_old_gid_to_new_gid_map (const hb_face_t *face, - bool retain_gids, - hb_set_t *all_gids_to_retain, - hb_map_t *glyph_map, /* OUT */ - hb_map_t *reverse_glyph_map, /* OUT */ - unsigned int *num_glyphs /* OUT */) +_create_old_gid_to_new_gid_map (const hb_face_t *face, + bool retain_gids, + const hb_set_t *all_gids_to_retain, + hb_map_t *glyph_map, /* OUT */ + hb_map_t *reverse_glyph_map, /* OUT */ + unsigned int *num_glyphs /* OUT */) { - hb_codepoint_t gid = HB_SET_VALUE_INVALID; - unsigned int length = 0; - for (unsigned int i = 0; all_gids_to_retain->next (&gid); i++) { - if (!retain_gids) - { - glyph_map->set (gid, i); - reverse_glyph_map->set (i, gid); - } - else - { - glyph_map->set (gid, gid); - reverse_glyph_map->set (gid, gid); - } - ++length; - } - if (!retain_gids || length == 0) - { - *num_glyphs = length; - } - else + if (!retain_gids) { + + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0) + | hb_sink (reverse_glyph_map) + ; + *num_glyphs = reverse_glyph_map->get_population (); + } else { + + hb_iter (all_gids_to_retain) + | hb_map ([=] (hb_codepoint_t _) { + return hb_pair_t (_, _); + }) + | hb_sink (reverse_glyph_map); + ; + + // TODO(grieger): Should we discard glyphs past the max glyph to keep? + // *num_glyphs = + hb_iter (all_gids_to_retain) | hb_reduce (hb_max, 0); *num_glyphs = face->get_num_glyphs (); } + + + reverse_glyph_map->iter () + | hb_map (&hb_pair_t::reverse) + | hb_sink (glyph_map) + ; } /** From 70a49f2e4a9ab05fe04d1949bbf7a128d14a1284 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 14:35:15 -0700 Subject: [PATCH 253/336] [meta] Add hb_conditional<> and hb_is_convertible() --- src/Makefile.am | 6 ++++- src/hb-meta.hh | 56 +++++++++++++++++++++++++++++++------- src/test-meta.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 src/test-meta.cc diff --git a/src/Makefile.am b/src/Makefile.am index 9b5512f20..fc772e0ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -384,7 +384,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) -COMPILED_TESTS = test-algs test-iter test-ot-tag test-unicode-ranges +COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS) check_PROGRAMS += $(COMPILED_TESTS) @@ -398,6 +398,10 @@ test_iter_SOURCES = test-iter.cc hb-static.cc test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_iter_LDADD = $(COMPILED_TESTS_LDADD) +test_meta_SOURCES = test-meta.cc hb-static.cc +test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) +test_meta_LDADD = $(COMPILED_TESTS_LDADD) + test_ot_tag_SOURCES = hb-ot-tag.cc test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS) test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 74a4457c3..b2344f78c 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -52,6 +52,18 @@ typedef hb_bool_tt hb_true_t; typedef hb_bool_tt hb_false_t; +/* Basic type SFINAE. */ + +template struct hb_enable_if {}; +template struct hb_enable_if { typedef T type; }; +#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr +/* Concepts/Requires alias: */ +#define hb_requires(Cond) hb_enable_if((Cond)) + +template struct hb_is_same : hb_false_t {}; +template struct hb_is_same : hb_true_t {}; +#define hb_is_same(T, T2) hb_is_same::value + /* Function overloading SFINAE and priority. */ #define HB_RETURN(Ret, E) -> hb_head_tt { return (E); } @@ -110,6 +122,40 @@ template using hb_decay = hb_remove_const>; hb_is_reference (A) >= hb_is_reference (B)) + +template +struct _hb_conditional { typedef T type; }; +template +struct _hb_conditional { typedef F type; }; +template +using hb_conditional = typename _hb_conditional::type; + + +template +struct hb_is_convertible +{ + private: + static constexpr bool from_void = hb_is_same (void, hb_decay); + static constexpr bool to_void = hb_is_same (void, hb_decay ); + static constexpr bool either_void = from_void || to_void; + static constexpr bool both_void = from_void && to_void; + + static hb_true_t impl2 (hb_conditional); + + template + static auto impl (hb_priority<1>) HB_AUTO_RETURN ( impl2 (hb_declval (T)) ) + template + static hb_false_t impl (hb_priority<0>); + public: + static constexpr bool value = both_void || + (!either_void && + decltype (impl> (hb_prioritize))::value); +}; + + +#define hb_is_convertible(From,To) hb_is_convertible::value + + /* std::move and std::forward */ template @@ -162,16 +208,6 @@ struct hb_reference_wrapper }; -template struct hb_enable_if {}; -template struct hb_enable_if { typedef T type; }; -#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr -/* Concepts/Requires alias: */ -#define hb_requires(Cond) hb_enable_if((Cond)) - -template struct hb_is_same : hb_false_t {}; -template struct hb_is_same : hb_true_t {}; -#define hb_is_same(T, T2) hb_is_same::value - template struct hb_is_signed; template <> struct hb_is_signed { static constexpr bool value = CHAR_MIN < 0; }; template <> struct hb_is_signed { static constexpr bool value = true; }; diff --git a/src/test-meta.cc b/src/test-meta.cc new file mode 100644 index 000000000..a7cfef5a4 --- /dev/null +++ b/src/test-meta.cc @@ -0,0 +1,70 @@ +/* + * Copyright © 2019 Facebook, 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. + * + * Facebook Author(s): Behdad Esfahbod + */ + +#include "hb.hh" +#include "hb-meta.hh" + + +int +main (int argc, char **argv) +{ + + static_assert (hb_is_convertible (void, void)); + static_assert (hb_is_convertible (void, const void)); + static_assert (hb_is_convertible (const void, void)); + + static_assert (hb_is_convertible (int, int)); + static_assert (hb_is_convertible (char, int)); + static_assert (hb_is_convertible (long, int)); + + static_assert (hb_is_convertible (int, int)); + + static_assert (hb_is_convertible (const int, int)); + static_assert (hb_is_convertible (int, const int)); + static_assert (hb_is_convertible (const int, const int)); + + static_assert (hb_is_convertible (int&, int)); + static_assert (!hb_is_convertible (int, int&)); + + static_assert (hb_is_convertible (int, const int&)); + static_assert (!hb_is_convertible (const int, int&)); + static_assert (hb_is_convertible (const int, const int&)); + static_assert (hb_is_convertible (int&, const int)); + static_assert (hb_is_convertible (const int&, int)); + static_assert (hb_is_convertible (const int&, const int)); + + static_assert (hb_is_convertible (int&, long)); + static_assert (!hb_is_convertible (int&, long&)); + + static_assert (hb_is_convertible (int *, int *)); + static_assert (hb_is_convertible (int *, const int *)); + static_assert (!hb_is_convertible (const int *, int *)); + static_assert (!hb_is_convertible (int *, long *)); + static_assert (hb_is_convertible (int *, void *)); + static_assert (!hb_is_convertible (void *, int *)); + + return 0; +} From 726002a6a615e2d213186d402cca4e8d7e7a7f58 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 14:53:02 -0700 Subject: [PATCH 254/336] [iter] Make hb_is_iterator_of() check is_convertible Instead of is_cr_convertible. --- src/hb-array.hh | 8 ++++---- src/hb-iter.hh | 2 +- src/hb-meta.hh | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index a320685e2..1fc07eb69 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -47,12 +47,12 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} template + hb_enable_if (hb_is_cr_convertible(U, Type))> hb_array_t (const hb_array_t &o) : hb_iter_with_fallback_t, Type&> (), arrayZ (o.arrayZ), length (o.length) {} template + hb_enable_if (hb_is_cr_convertible(U, Type))> hb_array_t& operator = (const hb_array_t &o) { arrayZ = o.arrayZ; length = o.length; return *this; } @@ -228,12 +228,12 @@ struct hb_sorted_array_t : template hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} template + hb_enable_if (hb_is_cr_convertible(U, Type))> hb_sorted_array_t (const hb_array_t &o) : hb_iter_t, Type&> (), hb_array_t (o) {} template + hb_enable_if (hb_is_cr_convertible(U, Type))> hb_sorted_array_t& operator = (const hb_array_t &o) { hb_array_t (*this) = o; return *this; } diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 13b82604a..2c1e31b64 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -266,7 +266,7 @@ static inline char _hb_is_iterator_of (hb_priority<0>, const void *) { return 0; template + hb_enable_if (hb_is_convertible (Item2, Item))> static inline int _hb_is_iterator_of (hb_priority<2>, hb_iter_t *) { return 0; } template diff --git a/src/hb-meta.hh b/src/hb-meta.hh index b2344f78c..9c8dfedc9 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -116,10 +116,10 @@ template using hb_remove_pointer = typename hb_match_pointer::ty /* TODO Add feature-parity to std::decay. */ template using hb_decay = hb_remove_const>; -#define hb_is_cr_convertible_to(A, B) ( \ - hb_is_same (hb_decay, hb_decay) && \ - hb_is_const (A) <= hb_is_const (B) && \ - hb_is_reference (A) >= hb_is_reference (B)) +#define hb_is_cr_convertible(From, To) ( \ + hb_is_same (hb_decay, hb_decay) && \ + hb_is_const (From) <= hb_is_const (To) && \ + hb_is_reference (From) >= hb_is_reference (To)) From 3686c3b65c017cf8689b67db440b4cddd399538b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 15:09:07 -0700 Subject: [PATCH 255/336] Adjust is_cr_convertible If To is const& then From doesn't need to be &. --- src/hb-meta.hh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 9c8dfedc9..bcd541e7a 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -116,10 +116,16 @@ template using hb_remove_pointer = typename hb_match_pointer::ty /* TODO Add feature-parity to std::decay. */ template using hb_decay = hb_remove_const>; -#define hb_is_cr_convertible(From, To) ( \ - hb_is_same (hb_decay, hb_decay) && \ - hb_is_const (From) <= hb_is_const (To) && \ - hb_is_reference (From) >= hb_is_reference (To)) +#define hb_is_cr_convertible(From, To) \ + ( \ + hb_is_same (hb_decay, hb_decay) && \ + ( \ + hb_is_const (From) <= hb_is_const (To) && \ + hb_is_reference (From) >= hb_is_reference (To) \ + ) || ( \ + hb_is_const (To) && hb_is_reference (To) \ + ) \ + ) From ceda1f03b7b06248ffd056eb7b2400088bb4a121 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 15:19:42 -0700 Subject: [PATCH 256/336] Fix compile NameRecord is not copy-constructible, so should be iterator of const-reference. --- src/hb-meta.hh | 2 -- src/hb-ot-name-table.hh | 2 +- src/test-meta.cc | 12 ++++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index bcd541e7a..b906c5539 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -157,8 +157,6 @@ struct hb_is_convertible (!either_void && decltype (impl> (hb_prioritize))::value); }; - - #define hb_is_convertible(From,To) hb_is_convertible::value diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 1c8f54406..04995c441 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -170,7 +170,7 @@ struct name { return min_size + count * nameRecordZ.item_size; } template + hb_requires (hb_is_iterator_of (Iterator, const NameRecord &))> bool serialize (hb_serialize_context_t *c, Iterator it, const void *src_string_pool) diff --git a/src/test-meta.cc b/src/test-meta.cc index a7cfef5a4..d2976b614 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -55,6 +55,18 @@ main (int argc, char **argv) static_assert (hb_is_convertible (int&, const int)); static_assert (hb_is_convertible (const int&, int)); static_assert (hb_is_convertible (const int&, const int)); + static_assert (hb_is_convertible (const int&, const int)); + + struct X {}; + + static_assert (hb_is_convertible (const X &, const X)); + static_assert (hb_is_convertible (X &, const X)); + static_assert (hb_is_convertible (X &, const X &)); + static_assert (hb_is_convertible (X, const X &)); + static_assert (hb_is_convertible (const X, const X &)); + static_assert (!hb_is_convertible (const X, X &)); + static_assert (!hb_is_convertible (X, X &)); + static_assert (hb_is_convertible (X &, X &)); static_assert (hb_is_convertible (int&, long)); static_assert (!hb_is_convertible (int&, long&)); From 69d9114b5372c1fcea5f20e75a187158c31c52f8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 15:24:14 -0700 Subject: [PATCH 257/336] [meta] Rewrite hb_is_cr_converitble --- src/hb-meta.hh | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index b906c5539..58852091f 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -116,18 +116,6 @@ template using hb_remove_pointer = typename hb_match_pointer::ty /* TODO Add feature-parity to std::decay. */ template using hb_decay = hb_remove_const>; -#define hb_is_cr_convertible(From, To) \ - ( \ - hb_is_same (hb_decay, hb_decay) && \ - ( \ - hb_is_const (From) <= hb_is_const (To) && \ - hb_is_reference (From) >= hb_is_reference (To) \ - ) || ( \ - hb_is_const (To) && hb_is_reference (To) \ - ) \ - ) - - template struct _hb_conditional { typedef T type; }; @@ -159,6 +147,16 @@ struct hb_is_convertible }; #define hb_is_convertible(From,To) hb_is_convertible::value +template +struct hb_is_cr_convertible +{ + public: + static constexpr bool value = + hb_is_same (hb_decay, hb_decay) && + (!hb_is_const (From) || hb_is_const (To)) && + (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To)); +}; +#define hb_is_cr_convertible(From,To) hb_is_cr_convertible::value /* std::move and std::forward */ From 790315e0dbc0ce796f0081a60953f74bd3fbdb63 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 15:31:24 -0700 Subject: [PATCH 258/336] [algs] Implement implicit casting between compatible pair types --- src/hb-algs.hh | 5 +++++ src/test-algs.cc | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index dbb0805fc..bbf748e3b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -217,6 +217,11 @@ struct hb_pair_t hb_pair_t (T1 a, T2 b) : first (a), second (b) {} hb_pair_t (const pair_t& o) : first (o.first), second (o.second) {} + template + operator hb_pair_t () { return hb_pair_t (first, second); } + hb_pair_t reverse () const { return hb_pair_t (second, first); } diff --git a/src/test-algs.cc b/src/test-algs.cc index d6f34d707..774414ad1 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -73,5 +73,8 @@ main (int argc, char **argv) z = 3; assert (x == 3); + hb_pair_t xp = hb_pair_t (nullptr, 0); + xp = hb_pair_t (nullptr, 1); + return 0; } From 489f3c35bddb22cfe40c45d3a5c1cb6d88ccaf1f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 15:39:32 -0700 Subject: [PATCH 259/336] Fix bot --- src/test-meta.cc | 70 ++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/test-meta.cc b/src/test-meta.cc index d2976b614..9037e9ce4 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -32,51 +32,51 @@ int main (int argc, char **argv) { - static_assert (hb_is_convertible (void, void)); - static_assert (hb_is_convertible (void, const void)); - static_assert (hb_is_convertible (const void, void)); + static_assert (hb_is_convertible (void, void), ""); + static_assert (hb_is_convertible (void, const void), ""); + static_assert (hb_is_convertible (const void, void), ""); - static_assert (hb_is_convertible (int, int)); - static_assert (hb_is_convertible (char, int)); - static_assert (hb_is_convertible (long, int)); + static_assert (hb_is_convertible (int, int), ""); + static_assert (hb_is_convertible (char, int), ""); + static_assert (hb_is_convertible (long, int), ""); - static_assert (hb_is_convertible (int, int)); + static_assert (hb_is_convertible (int, int), ""); - static_assert (hb_is_convertible (const int, int)); - static_assert (hb_is_convertible (int, const int)); - static_assert (hb_is_convertible (const int, const int)); + static_assert (hb_is_convertible (const int, int), ""); + static_assert (hb_is_convertible (int, const int), ""); + static_assert (hb_is_convertible (const int, const int), ""); - static_assert (hb_is_convertible (int&, int)); - static_assert (!hb_is_convertible (int, int&)); + static_assert (hb_is_convertible (int&, int), ""); + static_assert (!hb_is_convertible (int, int&), ""); - static_assert (hb_is_convertible (int, const int&)); - static_assert (!hb_is_convertible (const int, int&)); - static_assert (hb_is_convertible (const int, const int&)); - static_assert (hb_is_convertible (int&, const int)); - static_assert (hb_is_convertible (const int&, int)); - static_assert (hb_is_convertible (const int&, const int)); - static_assert (hb_is_convertible (const int&, const int)); + static_assert (hb_is_convertible (int, const int&), ""); + static_assert (!hb_is_convertible (const int, int&), ""); + static_assert (hb_is_convertible (const int, const int&), ""); + static_assert (hb_is_convertible (int&, const int), ""); + static_assert (hb_is_convertible (const int&, int), ""); + static_assert (hb_is_convertible (const int&, const int), ""); + static_assert (hb_is_convertible (const int&, const int), ""); struct X {}; - static_assert (hb_is_convertible (const X &, const X)); - static_assert (hb_is_convertible (X &, const X)); - static_assert (hb_is_convertible (X &, const X &)); - static_assert (hb_is_convertible (X, const X &)); - static_assert (hb_is_convertible (const X, const X &)); - static_assert (!hb_is_convertible (const X, X &)); - static_assert (!hb_is_convertible (X, X &)); - static_assert (hb_is_convertible (X &, X &)); + static_assert (hb_is_convertible (const X &, const X), ""); + static_assert (hb_is_convertible (X &, const X), ""); + static_assert (hb_is_convertible (X &, const X &), ""); + static_assert (hb_is_convertible (X, const X &), ""); + static_assert (hb_is_convertible (const X, const X &), ""); + static_assert (!hb_is_convertible (const X, X &), ""); + static_assert (!hb_is_convertible (X, X &), ""); + static_assert (hb_is_convertible (X &, X &), ""); - static_assert (hb_is_convertible (int&, long)); - static_assert (!hb_is_convertible (int&, long&)); + static_assert (hb_is_convertible (int&, long), ""); + static_assert (!hb_is_convertible (int&, long&), ""); - static_assert (hb_is_convertible (int *, int *)); - static_assert (hb_is_convertible (int *, const int *)); - static_assert (!hb_is_convertible (const int *, int *)); - static_assert (!hb_is_convertible (int *, long *)); - static_assert (hb_is_convertible (int *, void *)); - static_assert (!hb_is_convertible (void *, int *)); + static_assert (hb_is_convertible (int *, int *), ""); + static_assert (hb_is_convertible (int *, const int *), ""); + static_assert (!hb_is_convertible (const int *, int *), ""); + static_assert (!hb_is_convertible (int *, long *), ""); + static_assert (hb_is_convertible (int *, void *), ""); + static_assert (!hb_is_convertible (void *, int *), ""); return 0; } From 322627ae1daa16f62f7a91c3c3ed02eb5b708ca5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 16:08:10 -0700 Subject: [PATCH 260/336] Whitespace --- src/hb-array.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 1fc07eb69..003fc5bed 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -44,7 +44,8 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> */ hb_array_t () : arrayZ (nullptr), length (0) {} hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} - template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} + template + hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} template @@ -225,7 +226,8 @@ struct hb_sorted_array_t : hb_sorted_array_t () : hb_array_t () {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t (array_, length_) {} - template hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} + template + hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} template From 42901d7af91b4c5cffee9752f653447e4f4bd4f7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 16:22:08 -0700 Subject: [PATCH 261/336] Minor --- src/hb-meta.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 58852091f..88b7f2fc1 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -137,7 +137,7 @@ struct hb_is_convertible static hb_true_t impl2 (hb_conditional); template - static auto impl (hb_priority<1>) HB_AUTO_RETURN ( impl2 (hb_declval (T)) ) + static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T))); template static hb_false_t impl (hb_priority<0>); public: From ed972d5d73ba0592e1ba92426adf2a8f67acf9c9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 16:58:28 -0700 Subject: [PATCH 262/336] [iter] Rewrite test functions Notably, add hb_is_source_of(,) and hb_is_sink_of(,) to replace most uses of hb_is_iterator_of(,). --- src/hb-iter.hh | 69 ++++++++++++++++++++++++-------------- src/hb-open-type.hh | 7 ++-- src/hb-ot-layout-common.hh | 6 ++-- src/hb-ot-name-table.hh | 2 +- src/test-iter.cc | 2 +- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2c1e31b64..131ffb9e7 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -237,6 +237,21 @@ struct hb_iter_with_fallback_t : * Meta-programming predicates. */ +/* hb_is_iterator() / hb_is_iterator_of() */ + +template +struct hb_is_iterator_of +{ + template + static hb_true_t impl (hb_priority<2>, hb_iter_t> *); + static hb_false_t impl (hb_priority<0>, const void *); + + public: + static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value; +}; +#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of::value +#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) + /* hb_is_iterable() */ template @@ -251,39 +266,41 @@ struct hb_is_iterable static hb_false_t impl (hb_priority<0>); public: - - enum { value = decltype (impl (hb_prioritize))::value }; + static constexpr bool value = decltype (impl (hb_prioritize))::value; }; #define hb_is_iterable(Iterable) hb_is_iterable::value -/* TODO Add hb_is_iterable_of(). - * TODO Add random_access / sorted variants. */ - -/* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ - -template -static inline char _hb_is_iterator_of (hb_priority<0>, const void *) { return 0; } -template -static inline int _hb_is_iterator_of (hb_priority<2>, hb_iter_t *) { return 0; } +/* hb_is_source_of() / hb_is_sink_of() */ template -struct hb_is_iterator_of { enum { - value = sizeof (int) == sizeof (_hb_is_iterator_of (hb_prioritize, hb_declval (Iter*))) }; }; -#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of::value -#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) +struct hb_is_source_of +{ + private: + template + static hb_true_t impl (hb_priority<2>); + static hb_false_t impl (hb_priority<0>); -#define hb_is_random_access_iterator_of(Iter, Item) \ - hb_is_iterator_of (Iter, Item) && Iter::is_random_access_iterator -#define hb_is_random_access_iterator(Iter) \ - hb_is_random_access_iterator_of (Iter, typename Iter::item_t) + public: + static constexpr bool value = decltype (impl (hb_prioritize))::value; +}; +#define hb_is_source_of(Iter, Item) hb_is_source_of::value -#define hb_is_sorted_iterator_of(Iter, Item) \ - hb_is_iterator_of (Iter, Item) && Iter::is_sorted_iterator -#define hb_is_sorted_iterator(Iter) \ - hb_is_sorted_iterator_of (Iter, typename Iter::item_t) +template +struct hb_is_sink_of +{ + private: + static auto impl (hb_priority<2>) -> decltype (hb_declval (Iter) << hb_declval (Item), hb_true_t ()); + static hb_false_t impl (hb_priority<0>); + + public: + static constexpr bool value = decltype (impl (hb_prioritize))::value; +}; +#define hb_is_sink_of(Iter, Item) hb_is_sink_of::value + +/* This is commonly used, so define: */ +#define hb_is_sorted_source_of(Iter, Item) \ + (hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator) /* Range-based 'for' for iterables. */ diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 5fa1164db..a7e10ed74 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -419,7 +419,7 @@ struct UnsizedArrayOf return_trace (true); } template + hb_requires (hb_is_source_of (Iterator, Type))> bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); @@ -598,7 +598,7 @@ struct ArrayOf return_trace (true); } template + hb_requires (hb_is_source_of (Iterator, Type))> bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); @@ -877,7 +877,7 @@ struct SortedArrayOf : ArrayOf return_trace (ret); } template + hb_requires (hb_is_sorted_source_of (Iterator, Type))> bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); @@ -885,7 +885,6 @@ struct SortedArrayOf : ArrayOf return_trace (ret); } - template Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 04b211ddb..d4f0c77fb 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -797,7 +797,7 @@ struct CoverageFormat1 } template + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); @@ -866,7 +866,7 @@ struct CoverageFormat2 } template + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); @@ -1030,7 +1030,7 @@ struct Coverage } template + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 04995c441..f2f5a1a53 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -170,7 +170,7 @@ struct name { return min_size + count * nameRecordZ.item_size; } template + hb_requires (hb_is_source_of (Iterator, const NameRecord &))> bool serialize (hb_serialize_context_t *c, Iterator it, const void *src_string_pool) diff --git a/src/test-iter.cc b/src/test-iter.cc index 0d41e76f3..d9e2a97f1 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -127,7 +127,7 @@ main (int argc, char **argv) array_iter_t s2 (v); /* Implicit conversion from vector. */ array_iter_t t (dst); - static_assert (hb_is_random_access_iterator (array_iter_t), ""); + static_assert (array_iter_t::is_random_access_iterator, ""); some_array_t a (src); From 1b58bf22ca70908bb578910757795ee32d48b65a Mon Sep 17 00:00:00 2001 From: rsheeter Date: Thu, 9 May 2019 20:06:29 -0700 Subject: [PATCH 263/336] Update TESTING.md --- TESTING.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/TESTING.md b/TESTING.md index 6bbf7bc5b..a690afe92 100644 --- a/TESTING.md +++ b/TESTING.md @@ -5,18 +5,18 @@ Values defined in `hb-debug.hh`. ```shell # quick sanity check -time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ - && make -C test/api check || cat test/api/test-suite.log) +time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ + && {make -j4 -C test/api check || cat test/api/test-suite.log}) -# slower santiy check -time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ - && make -C src check \ - && make -C test/api check \ - && make -C test/subset check) +# slower sanity check +time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ + && make -j4 -C src check \ + && make -j4 -C test/api check \ + && make -j4 -C test/subset check) # confirm you didn't break anything else -time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ - && make check) +time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ + && make -j4 check) # often catches files you didn't add, e.g. test fonts to EXTRA_DIST make distcheck From 98974ac16f5caf282c9c7cf0c417b494efd6af1d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 11:18:52 -0700 Subject: [PATCH 264/336] [iter] Adjust is_source_of / is_sink_of There are two cases that we accept. Encode both. --- src/hb-iter.hh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 131ffb9e7..cdc4fdceb 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -279,6 +279,8 @@ struct hb_is_source_of template static hb_true_t impl (hb_priority<2>); + template + static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_t ()); static hb_false_t impl (hb_priority<0>); public: @@ -290,7 +292,11 @@ template struct hb_is_sink_of { private: - static auto impl (hb_priority<2>) -> decltype (hb_declval (Iter) << hb_declval (Item), hb_true_t ()); + template + static hb_true_t impl (hb_priority<2>); + template + static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_t ()); static hb_false_t impl (hb_priority<0>); public: From 30e4ae6bd19bf297b029205b5f86c1a0ae14943d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 11:26:39 -0700 Subject: [PATCH 265/336] [meta] Add hb_is_base_of --- src/hb-meta.hh | 7 +++++++ src/test-meta.cc | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 88b7f2fc1..645eb5439 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -147,6 +147,13 @@ struct hb_is_convertible }; #define hb_is_convertible(From,To) hb_is_convertible::value +template +struct hb_is_base_of +{ + static constexpr bool value = hb_is_convertible (hb_decay *, hb_decay *); +}; +#define hb_is_base_of(Base,Derived) hb_is_base_of::value + template struct hb_is_cr_convertible { diff --git a/src/test-meta.cc b/src/test-meta.cc index 9037e9ce4..716e99cd7 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -78,5 +78,21 @@ main (int argc, char **argv) static_assert (hb_is_convertible (int *, void *), ""); static_assert (!hb_is_convertible (void *, int *), ""); + struct Y : X {}; + + static_assert (hb_is_base_of (void, void)); + static_assert (hb_is_base_of (void, int)); + static_assert (!hb_is_base_of (int, void)); + + static_assert (hb_is_base_of (int, int)); + static_assert (hb_is_base_of (const int, int)); + static_assert (hb_is_base_of (int, const int)); + + static_assert (hb_is_base_of (X, X)); + static_assert (hb_is_base_of (X, Y)); + static_assert (hb_is_base_of (const X, Y)); + static_assert (hb_is_base_of (X, const Y)); + static_assert (!hb_is_base_of (Y, X)); + return 0; } From 1d870cce68f7033f6d3967ce4e9ba622a6fafe79 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 11:32:59 -0700 Subject: [PATCH 266/336] Fix bot Any way to catch these? --- src/test-meta.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/test-meta.cc b/src/test-meta.cc index 716e99cd7..6fb8e4f19 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -80,19 +80,19 @@ main (int argc, char **argv) struct Y : X {}; - static_assert (hb_is_base_of (void, void)); - static_assert (hb_is_base_of (void, int)); - static_assert (!hb_is_base_of (int, void)); + static_assert (hb_is_base_of (void, void), ""); + static_assert (hb_is_base_of (void, int), ""); + static_assert (!hb_is_base_of (int, void), ""); - static_assert (hb_is_base_of (int, int)); - static_assert (hb_is_base_of (const int, int)); - static_assert (hb_is_base_of (int, const int)); + static_assert (hb_is_base_of (int, int), ""); + static_assert (hb_is_base_of (const int, int), ""); + static_assert (hb_is_base_of (int, const int), ""); - static_assert (hb_is_base_of (X, X)); - static_assert (hb_is_base_of (X, Y)); - static_assert (hb_is_base_of (const X, Y)); - static_assert (hb_is_base_of (X, const Y)); - static_assert (!hb_is_base_of (Y, X)); + static_assert (hb_is_base_of (X, X), ""); + static_assert (hb_is_base_of (X, Y), ""); + static_assert (hb_is_base_of (const X, Y), ""); + static_assert (hb_is_base_of (X, const Y), ""); + static_assert (!hb_is_base_of (Y, X), ""); return 0; } From 6d63e27ca41b12ba2e8fb22fd6bc44417651c518 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 11:53:02 -0700 Subject: [PATCH 267/336] Generate tarball in .xz instead of .bz2 Fixes https://github.com/harfbuzz/harfbuzz/issues/1662 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 98e9c32d8..8444e3bf2 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([src/harfbuzz.pc.in]) AC_CONFIG_HEADERS([config.h]) -AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability]) +AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-xz no-dist-gzip -Wall no-define color-tests -Wno-portability]) AM_SILENT_RULES([yes]) AX_CODE_COVERAGE From cd9bc732a75c716121a86e39ab588d2e0af58eba Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 13:17:41 -0700 Subject: [PATCH 268/336] [gsubgpos] Minor --- src/hb-ot-layout-gsubgpos.hh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3d4a1bca8..3fb6829b3 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2504,11 +2504,7 @@ struct ExtensionFormat1 template const X& get_subtable () const - { - unsigned int offset = extensionOffset; - if (unlikely (!offset)) return Null(typename T::SubTable); - return StructAtOffset (this, offset); - } + { return this + (LOffsetTo&) extensionOffset; } template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const @@ -2523,7 +2519,6 @@ struct ExtensionFormat1 { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - extensionOffset != 0 && extensionLookupType != T::SubTable::Extension); } @@ -2532,7 +2527,7 @@ struct ExtensionFormat1 HBUINT16 extensionLookupType; /* Lookup type of subtable referenced * by ExtensionOffset (i.e. the * extension subtable). */ - HBUINT32 extensionOffset; /* Offset to the extension subtable, + Offset32 extensionOffset; /* Offset to the extension subtable, * of lookup type subtable. */ public: DEFINE_SIZE_STATIC (8); From 5d4437fad0f99508ebd5c026a3d927f5d649615e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 13:43:29 -0700 Subject: [PATCH 269/336] Minor --- src/hb-ot-layout-common.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index d4f0c77fb..eca70ad62 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -762,7 +762,6 @@ struct Lookup return_trace (false); } return_trace (true); - return_trace (true); } private: From ac737f8c9e7cbc81cdb5a0542a2494671f236895 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 13:51:12 -0700 Subject: [PATCH 270/336] Minor again --- src/hb-ot-layout-gsubgpos.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3fb6829b3..93f8f6ea1 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2504,7 +2504,7 @@ struct ExtensionFormat1 template const X& get_subtable () const - { return this + (LOffsetTo&) extensionOffset; } + { return this + CastR> (extensionOffset); } template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const From 5d773ec60029e1a6edec45c27ea918d9be4ea806 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 13:53:15 -0700 Subject: [PATCH 271/336] Minor --- src/hb-ot-layout-gsubgpos.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 93f8f6ea1..9d7481b5f 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2671,7 +2671,7 @@ struct GSUBGPOS /* TODO Use intersects() to count how many subtables survive? */ CastR> (out->lookupList) .serialize_subset (c, - this+CastR> (lookupList), + this+CastR> (lookupList), out); if (version.to_int () >= 0x00010001u) From 9c0c3589f31106d1898f8922cc9a2e18cb054989 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 13:56:50 -0700 Subject: [PATCH 272/336] Minor --- src/hb-ot-layout-common.hh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index eca70ad62..ac9145151 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -647,10 +647,6 @@ struct Lookup { unsigned int get_subtable_count () const { return subTable.len; } - template - const TSubTable& get_subtable (unsigned int i) const - { return this+CastR> (subTable)[i]; } - template const OffsetArrayOf& get_subtables () const { return CastR> (subTable); } @@ -658,6 +654,13 @@ struct Lookup OffsetArrayOf& get_subtables () { return CastR> (subTable); } + template + const TSubTable& get_subtable (unsigned int i) const + { return this+get_subtables ()[i]; } + template + TSubTable& get_subtable (unsigned int i) + { return this+get_subtables ()[i]; } + unsigned int get_size () const { const HBUINT16 &markFilteringSet = StructAfter (subTable); @@ -745,8 +748,7 @@ struct Lookup if (!markFilteringSet.sanitize (c)) return_trace (false); } - if (unlikely (!CastR> (subTable) - .sanitize (c, this, get_type ()))) + if (unlikely (!get_subtables ().sanitize (c, this, get_type ()))) return_trace (false); if (unlikely (get_type () == TSubTable::Extension)) From 25a5b287f220802728cd3312692f368c45d22862 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 16:01:39 -0700 Subject: [PATCH 273/336] Fix sanitize fail of extension sublookups Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=960331 --- src/hb-ot-layout-common.hh | 10 ++++++++-- src/hb-sanitize.hh | 2 ++ ...case-minimized-harfbuzz_fuzzer-5702671124791296 | Bin 0 -> 94 bytes 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index ac9145151..478e66c02 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -751,12 +751,18 @@ struct Lookup if (unlikely (!get_subtables ().sanitize (c, this, get_type ()))) return_trace (false); - if (unlikely (get_type () == TSubTable::Extension)) + if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type * itself (but we already checked for that). - * This is specially important if one has a reverse type! */ + * This is specially important if one has a reverse type! + * + * We only do this if sanitizer edit_count is zero. Otherwise, + * some of the subtables might have become insane after they + * were sanity-checked by the edits of subsequent subtables. + * https://bugs.chromium.org/p/chromium/issues/detail?id=960331 + */ unsigned int type = get_subtable (0).u.extension.get_type (); unsigned int count = get_subtable_count (); for (unsigned int i = 1; i < count; i++) diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index 5ecd2d2bc..5f5b4bdc9 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -211,6 +211,8 @@ struct hb_sanitize_context_t : this->start = this->end = nullptr; } + unsigned get_edit_count () { return edit_count; } + bool check_range (const void *base, unsigned int len) const { diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 new file mode 100644 index 0000000000000000000000000000000000000000..9ecc7f16be2128be18d43f5b2173514ec21ce879 GIT binary patch literal 94 zcmZQzWME)m24bxfyaDbEj0`SXZW4cif>sR1?!lo>(sw1R2 Date: Fri, 10 May 2019 16:52:43 -0700 Subject: [PATCH 274/336] Update TESTING.md --- TESTING.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/TESTING.md b/TESTING.md index a690afe92..ba9e32f2c 100644 --- a/TESTING.md +++ b/TESTING.md @@ -6,7 +6,7 @@ Values defined in `hb-debug.hh`. ```shell # quick sanity check time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ - && {make -j4 -C test/api check || cat test/api/test-suite.log}) + && (make -j4 -C test/api check || cat test/api/test-suite.log)) # slower sanity check time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ @@ -22,6 +22,13 @@ time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \ make distcheck ``` +### Run tests with asan + +```shell +./configure CC=clang CXX=clang++ CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address +# make/run tests as usual +``` + ### Debug with GDB ``` From 99ed6e29d86bbf391c12ee1f980b8af9dc35615e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 16:07:51 -0700 Subject: [PATCH 275/336] [serialize] Fix a TODO --- src/hb-ot-layout-common.hh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 478e66c02..2fd97cf4e 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1043,12 +1043,16 @@ struct Coverage TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - /* TODO(iter) Port to non-random-access iterator interface. */ - unsigned int count = glyphs.len (); - unsigned int num_ranges = 1; - for (unsigned int i = 1; i < count; i++) - if (glyphs[i - 1] + 1 != glyphs[i]) - num_ranges++; + unsigned count = 0; + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + count++; + } u.format = count * 2 < num_ranges * 3 ? 1 : 2; switch (u.format) From 2ade0086286963ae2c65d44b94e63cb3836ce36b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 16:21:03 -0700 Subject: [PATCH 276/336] [serialize] More rewrite --- src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 2fd97cf4e..06062ea1b 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -884,30 +884,36 @@ struct CoverageFormat2 rangeRecord.len = 0; return_trace (true); } - /* TODO(iter) Port to non-random-access iterator interface. */ - unsigned int count = glyphs.len (); - unsigned int num_ranges = 1; - for (unsigned int i = 1; i < count; i++) - if (glyphs[i - 1] + 1 != glyphs[i]) - num_ranges++; - rangeRecord.len = num_ranges; - if (unlikely (!c->extend (rangeRecord))) return_trace (false); + /* TODO(iter) Write more efficiently? */ - unsigned int range = 0; - rangeRecord[range].start = glyphs[0]; - rangeRecord[range].value = 0; - for (unsigned int i = 1; i < count; i++) + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) { - if (glyphs[i - 1] + 1 != glyphs[i]) - { - rangeRecord[range].end = glyphs[i - 1]; - range++; - rangeRecord[range].start = glyphs[i]; - rangeRecord[range].value = i; - } + if (last + 1 != g) + num_ranges++; + last = g; } - rangeRecord[range].end = glyphs[count - 1]; + + if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false); + + unsigned count = 0; + unsigned range = (unsigned) -1; + last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + { + range++; + rangeRecord[range].start = g; + rangeRecord[range].value = count; + } + rangeRecord[range].end = g; + last = g; + count++; + } + return_trace (true); } From a27a31b9ee2601a05575cb581dc227caa73742c4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 16:26:19 -0700 Subject: [PATCH 277/336] Minor --- src/hb-ot-layout-common.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 06062ea1b..40349a01d 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1224,7 +1224,7 @@ struct ClassDefFormat1 hb_codepoint_t glyph_max = +glyphs | hb_reduce (hb_max, 0u); startGlyph = glyph_min; - classValue.len = glyph_max - glyph_min + 1; + c->check_assign (classValue.len, glyph_max - glyph_min + 1); if (unlikely (!c->extend (classValue))) return_trace (false); for (unsigned int i = 0; i < glyphs.length; i++) From 4d67743ffd99ed9f2278ab21adfac7eb314c0df0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 16:35:31 -0700 Subject: [PATCH 278/336] [subset] Use more auto typing --- src/hb-ot-layout-common.hh | 8 ++++---- src/hb-ot-layout-gdef-table.hh | 2 +- src/hb-ot-layout-gsubgpos.hh | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 40349a01d..017895891 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -138,7 +138,7 @@ struct RecordListOf : RecordArrayOf bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct RecordListOf *out = c->serializer->embed (*this); + auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); unsigned int count = this->len; for (unsigned int i = 0; i < count; i++) @@ -277,7 +277,7 @@ struct Script bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct Script *out = c->serializer->embed (*this); + auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); out->defaultLangSys.serialize_copy (c->serializer, this+defaultLangSys, out); unsigned int count = langSys.len; @@ -559,7 +559,7 @@ struct Feature bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct Feature *out = c->serializer->embed (*this); + auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); out->featureParams = 0; /* TODO(subset) FeatureParams. */ return_trace (true); @@ -722,7 +722,7 @@ struct Lookup bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct Lookup *out = c->serializer->embed (*this); + auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); /* Subset the actual subtables. */ diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 5d9a3ec78..ac1bddb2e 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -439,7 +439,7 @@ struct GDEF bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct GDEF *out = c->serializer->embed (*this); + auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); out->glyphClassDef.serialize_subset (c, this+glyphClassDef, out); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 9d7481b5f..182f9a06b 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -849,7 +849,7 @@ static inline bool match_input (hb_ot_apply_context_t *c, if (ligbase == LIGBASE_NOT_CHECKED) { bool found = false; - const hb_glyph_info_t *out = buffer->out_info; + const auto *out = buffer->out_info; unsigned int j = buffer->out_len; while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id) { @@ -2661,7 +2661,7 @@ struct GSUBGPOS bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct GSUBGPOS *out = c->serializer->embed (*this); + auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); out->scriptList.serialize_subset (c, this+scriptList, out); From 2fb3a8327ab35248a0c7877c48422718cfbe375d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 18:40:29 -0700 Subject: [PATCH 279/336] [vector] Simplify arrayZ Was turned into function when we had static ones and wanted to be move-safe... Not the case anymore. --- src/hb-coretext.cc | 2 +- src/hb-ot-cff-common.hh | 2 +- src/hb-uniscribe.cc | 10 +++--- src/hb-vector.hh | 71 +++++++++++++++++++---------------------- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index bf8e96c7b..383428570 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -598,7 +598,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, } else { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ ()); + active_features.remove (feature - active_features.arrayZ); } } } diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index e7ac0bac2..5d80943b7 100644 --- a/src/hb-ot-cff-common.hh +++ b/src/hb-ot-cff-common.hh @@ -167,7 +167,7 @@ struct CFFIndex byteArray.resize (buffArray.length); for (unsigned int i = 0; i < byteArray.length; i++) { - byteArray[i] = byte_str_t (buffArray[i].arrayZ (), buffArray[i].length); + byteArray[i] = byte_str_t (buffArray[i].arrayZ, buffArray[i].length); } bool result = this->serialize (c, offSize_, byteArray); byteArray.fini (); diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index ac4ff6366..4e004416b 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -698,7 +698,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, { active_feature_t *feature = active_features.find (&event->feature); if (feature) - active_features.remove (feature - active_features.arrayZ ()); + active_features.remove (feature - active_features.arrayZ); } } @@ -889,8 +889,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ (), - range_properties.arrayZ (), + range_char_counts.arrayZ, + range_properties.arrayZ, range_properties.length, pchars + chars_offset, item_chars_len, @@ -930,8 +930,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ (), - range_properties.arrayZ (), + range_char_counts.arrayZ, + range_properties.arrayZ, range_properties.length, pchars + chars_offset, log_clusters + chars_offset, diff --git a/src/hb-vector.hh b/src/hb-vector.hh index e0b7fb0cb..3c6347b3f 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -49,35 +49,34 @@ struct hb_vector_t { allocated = o.allocated; length = o.length; - arrayZ_ = o.arrayZ_; + arrayZ = o.arrayZ; o.init (); } ~hb_vector_t () { fini (); } - unsigned int length; private: int allocated; /* == -1 means allocation failed. */ - Type *arrayZ_; public: + unsigned int length; + public: + Type *arrayZ; void init () { allocated = length = 0; - arrayZ_ = nullptr; + arrayZ = nullptr; } void fini () { - if (arrayZ_) - free (arrayZ_); + free (arrayZ); init (); } void fini_deep () { - Type *array = arrayZ(); unsigned int count = length; for (unsigned int i = 0; i < count; i++) - array[i].fini (); + arrayZ[i].fini (); fini (); } @@ -95,33 +94,30 @@ struct hb_vector_t fini (); allocated = o.allocated; length = o.length; - arrayZ_ = o.arrayZ_; + arrayZ = o.arrayZ; o.init (); return *this; } hb_bytes_t as_bytes () const - { return hb_bytes_t ((const char *) arrayZ(), length * item_size); } + { return hb_bytes_t ((const char *) arrayZ, length * item_size); } bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); } uint32_t hash () const { return as_array ().hash (); } - const Type * arrayZ () const { return arrayZ_; } - Type * arrayZ () { return arrayZ_; } - Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= length)) return Crap (Type); - return arrayZ()[i]; + return arrayZ[i]; } const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; if (unlikely (i >= length)) return Null(Type); - return arrayZ()[i]; + return arrayZ[i]; } Type& tail () { return (*this)[length - 1]; } @@ -134,8 +130,8 @@ struct hb_vector_t template hb_vector_t& operator << (T&& v) { push (hb_forward (v)); return *this; } - hb_array_t< Type> as_array () { return hb_array (arrayZ(), length); } - hb_array_t as_array () const { return hb_array (arrayZ(), length); } + hb_array_t< Type> as_array () { return hb_array (arrayZ, length); } + hb_array_t as_array () const { return hb_array (arrayZ, length); } /* Iterator. */ typedef hb_array_t iter_t; @@ -155,21 +151,21 @@ struct hb_vector_t { return as_array ().sub_array (start_offset, count);} hb_sorted_array_t as_sorted_array () - { return hb_sorted_array (arrayZ(), length); } + { return hb_sorted_array (arrayZ, length); } hb_sorted_array_t as_sorted_array () const - { return hb_sorted_array (arrayZ(), length); } + { return hb_sorted_array (arrayZ, length); } - template explicit operator T * () { return arrayZ(); } - template explicit operator const T * () const { return arrayZ(); } + template explicit operator T * () { return arrayZ; } + template explicit operator const T * () const { return arrayZ; } - Type * operator + (unsigned int i) { return arrayZ() + i; } - const Type * operator + (unsigned int i) const { return arrayZ() + i; } + Type * operator + (unsigned int i) { return arrayZ + i; } + const Type * operator + (unsigned int i) const { return arrayZ + i; } Type *push () { if (unlikely (!resize (length + 1))) return &Crap(Type); - return &arrayZ()[length - 1]; + return &arrayZ[length - 1]; } template Type *push (T&& v) @@ -202,7 +198,7 @@ struct hb_vector_t (new_allocated < (unsigned) allocated) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type)); if (likely (!overflows)) - new_array = (Type *) realloc (arrayZ_, new_allocated * sizeof (Type)); + new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type)); if (unlikely (!new_array)) { @@ -210,7 +206,7 @@ struct hb_vector_t return false; } - arrayZ_ = new_array; + arrayZ = new_array; allocated = new_allocated; return true; @@ -223,7 +219,7 @@ struct hb_vector_t return false; if (size > length) - memset (arrayZ() + length, 0, (size - length) * sizeof (*arrayZ())); + memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ)); length = size; return true; @@ -232,16 +228,15 @@ struct hb_vector_t Type pop () { if (!length) return Null(Type); - return hb_move (arrayZ()[--length]); /* Does this move actually work? */ + return hb_move (arrayZ[--length]); /* Does this move actually work? */ } void remove (unsigned int i) { if (unlikely (i >= length)) return; - Type *array = arrayZ(); - memmove (static_cast (&array[i]), - static_cast (&array[i + 1]), + memmove (static_cast (&arrayZ[i]), + static_cast (&arrayZ[i + 1]), (length - i - 1) * sizeof (Type)); length--; } @@ -256,19 +251,17 @@ struct hb_vector_t template Type *find (T v) { - Type *array = arrayZ(); for (unsigned int i = 0; i < length; i++) - if (array[i] == v) - return &array[i]; + if (arrayZ[i] == v) + return &arrayZ[i]; return nullptr; } template const Type *find (T v) const { - const Type *array = arrayZ(); for (unsigned int i = 0; i < length; i++) - if (array[i] == v) - return &array[i]; + if (arrayZ[i] == v) + return &arrayZ[i]; return nullptr; } @@ -288,8 +281,8 @@ struct hb_vector_t template struct hb_sorted_vector_t : hb_vector_t { - hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ(), this->length); } - hb_sorted_array_t as_array () const { return hb_sorted_array (this->arrayZ(), this->length); } + hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); } + hb_sorted_array_t as_array () const { return hb_sorted_array (this->arrayZ, this->length); } /* Iterator. */ typedef hb_sorted_array_t const_iter_t; From 9574de7a3e763b9c5eacf65b4b8c148724c00b82 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 19:29:32 -0700 Subject: [PATCH 280/336] [meta] Add add_const, add_pointer, add_lvalue_reference, add_rvalue_reference --- src/hb-meta.hh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 645eb5439..4cf846653 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -102,17 +102,28 @@ template static inline T hb_declval (); template struct hb_match_const { typedef T type; static constexpr bool value = false; }; template struct hb_match_const { typedef T type; static constexpr bool value = true; }; template using hb_remove_const = typename hb_match_const::type; +template using hb_add_const = const T; #define hb_is_const(T) hb_match_const::value template struct hb_match_reference { typedef T type; static constexpr bool value = false; }; template struct hb_match_reference { typedef T type; static constexpr bool value = true; }; template struct hb_match_reference { typedef T type; static constexpr bool value = true; }; template using hb_remove_reference = typename hb_match_reference::type; +template auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity; +template auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity; +template using hb_add_lvalue_reference = decltype (_hb_try_add_lvalue_reference (hb_prioritize)); +template auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity; +template auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity; +template using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference (hb_prioritize)); #define hb_is_reference(T) hb_match_reference::value template struct hb_match_pointer { typedef T type; static constexpr bool value = false; }; template struct hb_match_pointer { typedef T type; static constexpr bool value = true; }; template using hb_remove_pointer = typename hb_match_pointer::type; +template auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity*>; +template auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity; +template using hb_add_pointer = decltype (_hb_try_add_pointer (hb_prioritize)); #define hb_is_pointer(T) hb_match_pointer::value + /* TODO Add feature-parity to std::decay. */ template using hb_decay = hb_remove_const>; From e0315b4aadb3fbc6b618de56d643471e8d1f7859 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 19:48:02 -0700 Subject: [PATCH 281/336] [meta] is_integer -> is_integral --- src/hb-algs.hh | 2 +- src/hb-map.hh | 4 ++-- src/hb-meta.hh | 26 +++++++++++++------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index bbf748e3b..24bdeb190 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,7 +73,7 @@ struct impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) template auto + hb_enable_if (hb_is_integral (T))> auto impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN ( /* Knuth's multiplicative method: */ diff --git a/src/hb-map.hh b/src/hb-map.hh index 942a301e4..26e4930a5 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -43,8 +43,8 @@ struct hb_hashmap_t hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - static_assert (hb_is_integer (K) || hb_is_pointer (K), ""); - static_assert (hb_is_integer (V) || hb_is_pointer (V), ""); + static_assert (hb_is_integral (K) || hb_is_pointer (K), ""); + static_assert (hb_is_integral (V) || hb_is_pointer (V), ""); /* TODO If key type is a pointer, keep hash in item_t and use to: * 1. avoid rehashing when resizing table, and diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 4cf846653..290b41cc2 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -274,19 +274,19 @@ template <> struct hb_signedness_int { typedef unsigned int value; }; template <> struct hb_signedness_int { typedef signed int value; }; #define hb_signedness_int(T) hb_signedness_int::value -template struct hb_is_integer { static constexpr bool value = false;}; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -template <> struct hb_is_integer { static constexpr bool value = true; }; -#define hb_is_integer(T) hb_is_integer::value +template struct hb_is_integral { static constexpr bool value = false;}; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +#define hb_is_integral(T) hb_is_integral::value #endif /* HB_META_HH */ From 25bb7e005d96c367731fd8d129d764d101b1200f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 19:49:26 -0700 Subject: [PATCH 282/336] [meta] Add is_signed for floating point types --- src/hb-meta.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 290b41cc2..f13b256ee 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -240,6 +240,9 @@ template <> struct hb_is_signed { static constexpr bool value = tr template <> struct hb_is_signed { static constexpr bool value = false; }; template <> struct hb_is_signed { static constexpr bool value = true; }; template <> struct hb_is_signed { static constexpr bool value = false; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; +template <> struct hb_is_signed { static constexpr bool value = true; }; #define hb_is_signed(T) hb_is_signed::value template struct hb_int_min; From 3919ca41b5e657764c7f75dfdc21cf8ca20bd66f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 19:56:36 -0700 Subject: [PATCH 283/336] [meta] Add is_floating_point --- src/hb-meta.hh | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index f13b256ee..d995607f4 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -228,6 +228,25 @@ struct hb_reference_wrapper }; +template struct hb_is_integral { static constexpr bool value = false;}; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; +template <> struct hb_is_integral { static constexpr bool value = true; }; + +template struct hb_is_floating_point { static constexpr bool value = false;}; +template <> struct hb_is_floating_point { static constexpr bool value = true; }; +template <> struct hb_is_floating_point { static constexpr bool value = true; }; +template <> struct hb_is_floating_point { static constexpr bool value = true; }; + +#define hb_is_integral(T) hb_is_integral::value template struct hb_is_signed; template <> struct hb_is_signed { static constexpr bool value = CHAR_MIN < 0; }; template <> struct hb_is_signed { static constexpr bool value = true; }; @@ -277,19 +296,5 @@ template <> struct hb_signedness_int { typedef unsigned int value; }; template <> struct hb_signedness_int { typedef signed int value; }; #define hb_signedness_int(T) hb_signedness_int::value -template struct hb_is_integral { static constexpr bool value = false;}; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -#define hb_is_integral(T) hb_is_integral::value - #endif /* HB_META_HH */ From 38e3a8bd531ef3d35ca0fbcfad09db3f83345038 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:03:14 -0700 Subject: [PATCH 284/336] [meta] bool_tt -> bool_constant --- src/hb-meta.hh | 6 +++--- src/hb-null.hh | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index d995607f4..e5eae564d 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -47,9 +47,9 @@ template using hb_head_tt = typename _hb_head_tt::type; /* Bool! For when we need to evaluate type-dependent expressions * in a template argument. */ -template struct hb_bool_tt { static constexpr bool value = b; }; -typedef hb_bool_tt hb_true_t; -typedef hb_bool_tt hb_false_t; +template struct hb_bool_constant { static constexpr bool value = b; }; +typedef hb_bool_constant hb_true_t; +typedef hb_bool_constant hb_false_t; /* Basic type SFINAE. */ diff --git a/src/hb-null.hh b/src/hb-null.hh index 562c4abc0..fea881af6 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 @@ -67,7 +67,7 @@ template struct _hb_static_size { enum { value = sizeof (T) }; }; template -struct _hb_static_size> +struct _hb_static_size> { enum { value = T::static_size }; }; template From 61d150c916d181cc3f333d0378108e08210370ad Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:06:31 -0700 Subject: [PATCH 285/336] [meta] Add integral_constant, true_t -> true_type, false_t -> false_type --- src/hb-iter.hh | 20 ++++++++++---------- src/hb-meta.hh | 17 ++++++++--------- src/hb-null.hh | 4 ++-- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index cdc4fdceb..a0beb2cdd 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -243,8 +243,8 @@ template struct hb_is_iterator_of { template - static hb_true_t impl (hb_priority<2>, hb_iter_t> *); - static hb_false_t impl (hb_priority<0>, const void *); + static hb_true_type impl (hb_priority<2>, hb_iter_t> *); + static hb_false_type impl (hb_priority<0>, const void *); public: static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value; @@ -260,10 +260,10 @@ struct hb_is_iterable private: template - static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_t ()); + static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_type ()); template - static hb_false_t impl (hb_priority<0>); + static hb_false_type impl (hb_priority<0>); public: static constexpr bool value = decltype (impl (hb_prioritize))::value; @@ -278,10 +278,10 @@ struct hb_is_source_of private: template - static hb_true_t impl (hb_priority<2>); + static hb_true_type impl (hb_priority<2>); template - static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_t ()); - static hb_false_t impl (hb_priority<0>); + static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ()); + static hb_false_type impl (hb_priority<0>); public: static constexpr bool value = decltype (impl (hb_prioritize))::value; @@ -294,10 +294,10 @@ struct hb_is_sink_of private: template - static hb_true_t impl (hb_priority<2>); + static hb_true_type impl (hb_priority<2>); template - static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_t ()); - static hb_false_t impl (hb_priority<0>); + static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_type ()); + static hb_false_type impl (hb_priority<0>); public: static constexpr bool value = decltype (impl (hb_prioritize))::value; diff --git a/src/hb-meta.hh b/src/hb-meta.hh index e5eae564d..f00924599 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -45,11 +45,10 @@ template using hb_void_tt = typename _hb_void_tt::type; template struct _hb_head_tt { typedef Head type; }; template using hb_head_tt = typename _hb_head_tt::type; -/* Bool! For when we need to evaluate type-dependent expressions - * in a template argument. */ -template struct hb_bool_constant { static constexpr bool value = b; }; -typedef hb_bool_constant hb_true_t; -typedef hb_bool_constant hb_false_t; +template struct hb_integral_constant { static constexpr T value = v; }; +template using hb_bool_constant = hb_integral_constant; +using hb_true_type = hb_bool_constant; +using hb_false_type = hb_bool_constant; /* Basic type SFINAE. */ @@ -60,8 +59,8 @@ template struct hb_enable_if { typedef T ty /* Concepts/Requires alias: */ #define hb_requires(Cond) hb_enable_if((Cond)) -template struct hb_is_same : hb_false_t {}; -template struct hb_is_same : hb_true_t {}; +template struct hb_is_same : hb_false_type {}; +template struct hb_is_same : hb_true_type {}; #define hb_is_same(T, T2) hb_is_same::value /* Function overloading SFINAE and priority. */ @@ -145,12 +144,12 @@ struct hb_is_convertible static constexpr bool either_void = from_void || to_void; static constexpr bool both_void = from_void && to_void; - static hb_true_t impl2 (hb_conditional); + static hb_true_type impl2 (hb_conditional); template static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T))); template - static hb_false_t impl (hb_priority<0>); + static hb_false_type impl (hb_priority<0>); public: static constexpr bool value = both_void || (!either_void && diff --git a/src/hb-null.hh b/src/hb-null.hh index fea881af6..79da71513 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -55,7 +55,7 @@ struct _hb_null_size> template struct hb_null_size -{ enum { value = _hb_null_size::value }; }; +{ enum { value = _hb_null_size::value }; }; #define hb_null_size(T) hb_null_size::value /* These doesn't belong here, but since is copy/paste from above, put it here. */ @@ -72,7 +72,7 @@ struct _hb_static_size> template struct hb_static_size -{ enum { value = _hb_static_size::value }; }; +{ enum { value = _hb_static_size::value }; }; #define hb_static_size(T) hb_static_size::value From 5a171ed3a69313e10df6e42a03affb5e8bfe8e95 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:11:29 -0700 Subject: [PATCH 286/336] [null] Modernize template work --- src/hb-null.hh | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 79da71513..725db5024 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -47,15 +47,12 @@ */ template -struct _hb_null_size -{ enum { value = sizeof (T) }; }; +struct _hb_null_size : hb_integral_constant {}; template -struct _hb_null_size> -{ enum { value = T::null_size }; }; +struct _hb_null_size> : hb_integral_constant {}; template -struct hb_null_size -{ enum { value = _hb_null_size::value }; }; +using hb_null_size = _hb_null_size; #define hb_null_size(T) hb_null_size::value /* These doesn't belong here, but since is copy/paste from above, put it here. */ @@ -64,15 +61,11 @@ struct hb_null_size * Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */ template -struct _hb_static_size -{ enum { value = sizeof (T) }; }; +struct _hb_static_size : hb_integral_constant {}; template -struct _hb_static_size> -{ enum { value = T::static_size }; }; - +struct _hb_static_size> : hb_integral_constant {}; template -struct hb_static_size -{ enum { value = _hb_static_size::value }; }; +using hb_static_size = _hb_static_size; #define hb_static_size(T) hb_static_size::value From b4ad6af9c4ec30c462078bd93ae12653619c5fea Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:15:03 -0700 Subject: [PATCH 287/336] [meta] Rewrite is_base_of --- src/hb-meta.hh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index f00924599..ef6d98912 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -158,10 +158,7 @@ struct hb_is_convertible #define hb_is_convertible(From,To) hb_is_convertible::value template -struct hb_is_base_of -{ - static constexpr bool value = hb_is_convertible (hb_decay *, hb_decay *); -}; +using hb_is_base_of = hb_is_convertible *, hb_decay *>; #define hb_is_base_of(Base,Derived) hb_is_base_of::value template From c3a456a26e8e5f8bc483b326f1928e9c603a7216 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:17:30 -0700 Subject: [PATCH 288/336] [meta] Rewrite is_cr_convertible --- src/hb-meta.hh | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index ef6d98912..334a44a2a 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -162,14 +162,11 @@ using hb_is_base_of = hb_is_convertible *, hb_decay *>; #define hb_is_base_of(Base,Derived) hb_is_base_of::value template -struct hb_is_cr_convertible -{ - public: - static constexpr bool value = - hb_is_same (hb_decay, hb_decay) && - (!hb_is_const (From) || hb_is_const (To)) && - (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To)); -}; +using hb_is_cr_convertible = hb_bool_constant< + hb_is_same (hb_decay, hb_decay) && + (!hb_is_const (From) || hb_is_const (To)) && + (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To)) +>; #define hb_is_cr_convertible(From,To) hb_is_cr_convertible::value /* std::move and std::forward */ From e939d88bd72e0db0ebe357649b7a0fa3447c0bf4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:20:51 -0700 Subject: [PATCH 289/336] [meta] Rewrite is_integral / is_floating_point, add is_arithmetic --- src/hb-meta.hh | 49 +++++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 334a44a2a..6f141e02e 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -221,25 +221,38 @@ struct hb_reference_wrapper }; -template struct hb_is_integral { static constexpr bool value = false;}; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; -template <> struct hb_is_integral { static constexpr bool value = true; }; - -template struct hb_is_floating_point { static constexpr bool value = false;}; -template <> struct hb_is_floating_point { static constexpr bool value = true; }; -template <> struct hb_is_floating_point { static constexpr bool value = true; }; -template <> struct hb_is_floating_point { static constexpr bool value = true; }; - +template +using hb_is_integral = hb_bool_constant< + hb_is_same (hb_decay, char) || + hb_is_same (hb_decay, signed char) || + hb_is_same (hb_decay, unsigned char) || + hb_is_same (hb_decay, signed int) || + hb_is_same (hb_decay, unsigned int) || + hb_is_same (hb_decay, signed short) || + hb_is_same (hb_decay, unsigned short) || + hb_is_same (hb_decay, signed long) || + hb_is_same (hb_decay, unsigned long) || + hb_is_same (hb_decay, signed long long) || + hb_is_same (hb_decay, unsigned long long) || + false +>; #define hb_is_integral(T) hb_is_integral::value +template +using hb_is_floating_point = hb_bool_constant< + hb_is_same (hb_decay, float) || + hb_is_same (hb_decay, double) || + hb_is_same (hb_decay, long double) || + false +>; +#define hb_is_floating_point(T) hb_is_floating_point::value +template +using hb_is_arithmetic = hb_bool_constant< + hb_is_integral (T) || + hb_is_floating_point (T) || + false +>; +#define hb_is_arighmetic(T) hb_is_arighmetic::value + template struct hb_is_signed; template <> struct hb_is_signed { static constexpr bool value = CHAR_MIN < 0; }; template <> struct hb_is_signed { static constexpr bool value = true; }; From ce300f4fb68a25d46d165e8b0a4825482c83a966 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:26:29 -0700 Subject: [PATCH 290/336] [meta] Rewrite is_signed, add is_unsigned --- src/hb-meta.hh | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 6f141e02e..7b4d0263a 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -251,24 +251,19 @@ using hb_is_arithmetic = hb_bool_constant< hb_is_floating_point (T) || false >; -#define hb_is_arighmetic(T) hb_is_arighmetic::value +#define hb_is_arithmetic(T) hb_is_arithmetic::value -template struct hb_is_signed; -template <> struct hb_is_signed { static constexpr bool value = CHAR_MIN < 0; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = false; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = false; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = false; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = false; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = false; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; -template <> struct hb_is_signed { static constexpr bool value = true; }; + +template +using hb_is_signed = hb_conditional, + hb_false_type>; #define hb_is_signed(T) hb_is_signed::value +template +using hb_is_unsigned = hb_conditional, + hb_false_type>; +#define hb_is_unsigned(T) hb_is_unsigned::value template struct hb_int_min; template <> struct hb_int_min { static constexpr char value = CHAR_MIN; }; From 707ff5b59d3903b60312a028f2ba5d74c18db101 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:31:20 -0700 Subject: [PATCH 291/336] Minor --- src/hb-meta.hh | 5 ----- src/hb-open-type.hh | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 7b4d0263a..71698f941 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -292,10 +292,5 @@ template <> struct hb_int_max { static constexpr signed long template <> struct hb_int_max { static constexpr unsigned long long value = ULLONG_MAX; }; #define hb_int_max(T) hb_int_max::value -template struct hb_signedness_int; -template <> struct hb_signedness_int { typedef unsigned int value; }; -template <> struct hb_signedness_int { typedef signed int value; }; -#define hb_signedness_int(T) hb_signedness_int::value - #endif /* HB_META_HH */ diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index a7e10ed74..9e17b5c88 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -57,7 +57,7 @@ template struct IntType { typedef Type type; - typedef typename hb_signedness_int (hb_is_signed (Type)) wide_type; + typedef hb_conditional wide_type; IntType& operator = (wide_type i) { v = i; return *this; } operator wide_type () const { return v; } From 149c3db8a2d41894b5d65f4c4b7c20757f6de6dd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:34:52 -0700 Subject: [PATCH 292/336] [meta] Minor --- src/hb-meta.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 71698f941..7ddfd13a4 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -35,7 +35,7 @@ */ /* Void! For when we need a expression-type of void. */ -struct hb_void_t { typedef void value; }; +struct hb_void_t {}; /* Void meta-function ala std::void_t * https://en.cppreference.com/w/cpp/types/void_t */ From 7df3ecfb4069d275cd277c71165962bb5769364a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:43:26 -0700 Subject: [PATCH 293/336] [meta] hb_void_t -> hb_empty_t --- src/hb-debug.hh | 6 +++--- src/hb-meta.hh | 2 +- src/hb-ot-layout-gsub-table.hh | 2 +- src/hb-ot-layout-gsubgpos.hh | 18 +++++++++--------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hb-debug.hh b/src/hb-debug.hh index 57b3f1b04..a03170b08 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -249,8 +249,8 @@ struct hb_printer_t { }; template <> -struct hb_printer_t { - const char *print (hb_void_t) { return ""; } +struct hb_printer_t { + const char *print (hb_empty_t) { return ""; } }; @@ -266,7 +266,7 @@ static inline void _hb_warn_no_return (bool returned) } } template <> -/*static*/ inline void _hb_warn_no_return (bool returned HB_UNUSED) +/*static*/ inline void _hb_warn_no_return (bool returned HB_UNUSED) {} template diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 7ddfd13a4..b8964c047 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -35,7 +35,7 @@ */ /* Void! For when we need a expression-type of void. */ -struct hb_void_t {}; +struct hb_empty_t {}; /* Void meta-function ala std::void_t * https://en.cppreference.com/w/cpp/types/void_t */ diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 364ef189e..a6e9a7534 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1319,7 +1319,7 @@ struct SubstLookup : Lookup HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) { if (!c->should_visit_lookup (lookup_index)) - return hb_void_t (); + return hb_empty_t (); hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 182f9a06b..5946db7c4 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -59,13 +59,13 @@ struct hb_intersects_context_t : }; struct hb_closure_context_t : - hb_dispatch_context_t + hb_dispatch_context_t { const char *get_name () { return "CLOSURE"; } typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); template - return_t dispatch (const T &obj) { obj.closure (this); return hb_void_t (); } - static return_t default_return_value () { return hb_void_t (); } + return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); } + static return_t default_return_value () { return hb_empty_t (); } void recurse (unsigned int lookup_index) { if (unlikely (nesting_level_left == 0 || !recurse_func)) @@ -151,13 +151,13 @@ struct hb_would_apply_context_t : struct hb_collect_glyphs_context_t : - hb_dispatch_context_t + hb_dispatch_context_t { const char *get_name () { return "COLLECT_GLYPHS"; } typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); template - return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_void_t (); } - static return_t default_return_value () { return hb_void_t (); } + return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_empty_t (); } + static return_t default_return_value () { return hb_empty_t (); } void recurse (unsigned int lookup_index) { if (unlikely (nesting_level_left == 0 || !recurse_func)) @@ -610,7 +610,7 @@ struct hb_ot_apply_context_t : struct hb_get_subtables_context_t : - hb_dispatch_context_t + hb_dispatch_context_t { template HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c) @@ -652,9 +652,9 @@ struct hb_get_subtables_context_t : { hb_applicable_t *entry = array.push(); entry->init (obj, apply_to); - return hb_void_t (); + return hb_empty_t (); } - static return_t default_return_value () { return hb_void_t (); } + static return_t default_return_value () { return hb_empty_t (); } hb_get_subtables_context_t (array_t &array_) : array (array_), From caa3f92e91062ff78b657aec23569b099de48640 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:43:51 -0700 Subject: [PATCH 294/336] [meta] void_tt -> void_t --- src/hb-meta.hh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index b8964c047..4cdb77d83 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -37,10 +37,9 @@ /* Void! For when we need a expression-type of void. */ struct hb_empty_t {}; -/* Void meta-function ala std::void_t - * https://en.cppreference.com/w/cpp/types/void_t */ -template struct _hb_void_tt { typedef void type; }; -template using hb_void_tt = typename _hb_void_tt::type; +/* https://en.cppreference.com/w/cpp/types/void_t */ +template struct _hb_void_t { typedef void type; }; +template using hb_void_t = typename _hb_void_t::type; template struct _hb_head_tt { typedef Head type; }; template using hb_head_tt = typename _hb_head_tt::type; @@ -67,7 +66,7 @@ template struct hb_is_same : hb_true_type {}; #define HB_RETURN(Ret, E) -> hb_head_tt { return (E); } #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); } -#define HB_VOID_RETURN(E) -> hb_void_tt { (E); } +#define HB_VOID_RETURN(E) -> hb_void_t { (E); } template struct hb_priority : hb_priority {}; template <> struct hb_priority<0> {}; From 5252677e53ff4473701172bbbd4e953ac6b08e6f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:49:52 -0700 Subject: [PATCH 295/336] [meta] Rewrite hb_int_min/max --- src/hb-meta.hh | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 4cdb77d83..16f39ebcb 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -265,30 +265,30 @@ using hb_is_unsigned = hb_conditional::value template struct hb_int_min; -template <> struct hb_int_min { static constexpr char value = CHAR_MIN; }; -template <> struct hb_int_min { static constexpr signed char value = SCHAR_MIN; }; -template <> struct hb_int_min { static constexpr unsigned char value = 0; }; -template <> struct hb_int_min { static constexpr signed short value = SHRT_MIN; }; -template <> struct hb_int_min { static constexpr unsigned short value = 0; }; -template <> struct hb_int_min { static constexpr signed int value = INT_MIN; }; -template <> struct hb_int_min { static constexpr unsigned int value = 0; }; -template <> struct hb_int_min { static constexpr signed long value = LONG_MIN; }; -template <> struct hb_int_min { static constexpr unsigned long value = 0; }; -template <> struct hb_int_min { static constexpr signed long long value = LLONG_MIN; }; -template <> struct hb_int_min { static constexpr unsigned long long value = 0; }; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; +template <> struct hb_int_min : hb_integral_constant {}; #define hb_int_min(T) hb_int_min::value template struct hb_int_max; -template <> struct hb_int_max { static constexpr char value = CHAR_MAX; }; -template <> struct hb_int_max { static constexpr signed char value = SCHAR_MAX; }; -template <> struct hb_int_max { static constexpr unsigned char value = UCHAR_MAX; }; -template <> struct hb_int_max { static constexpr signed short value = SHRT_MAX; }; -template <> struct hb_int_max { static constexpr unsigned short value = USHRT_MAX; }; -template <> struct hb_int_max { static constexpr signed int value = INT_MAX; }; -template <> struct hb_int_max { static constexpr unsigned int value = UINT_MAX; }; -template <> struct hb_int_max { static constexpr signed long value = LONG_MAX; }; -template <> struct hb_int_max { static constexpr unsigned long value = ULONG_MAX; }; -template <> struct hb_int_max { static constexpr signed long long value = LLONG_MAX; }; -template <> struct hb_int_max { static constexpr unsigned long long value = ULLONG_MAX; }; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; +template <> struct hb_int_max : hb_integral_constant {}; #define hb_int_max(T) hb_int_max::value From f9a96a0a97f59a0b31ee0f901d1c21dde6b3cfaf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 20:56:16 -0700 Subject: [PATCH 296/336] [meta] More rewrites --- src/hb-meta.hh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 16f39ebcb..15c38bbc8 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -75,8 +75,8 @@ template <> struct hb_priority<0> {}; #define HB_FUNCOBJ(x) static_const x HB_UNUSED -template struct hb_match_identity { typedef T type; }; -template using hb_type_identity = typename hb_match_identity::type; +template struct hb_type_identity_t { typedef T type; }; +template using hb_type_identity = typename hb_type_identity_t::type; struct { @@ -97,14 +97,14 @@ HB_FUNCOBJ (hb_addressof); template static inline T hb_declval (); #define hb_declval(T) (hb_declval ()) -template struct hb_match_const { typedef T type; static constexpr bool value = false; }; -template struct hb_match_const { typedef T type; static constexpr bool value = true; }; +template struct hb_match_const : hb_type_identity_t, hb_bool_constant{}; +template struct hb_match_const : hb_type_identity_t, hb_bool_constant {}; template using hb_remove_const = typename hb_match_const::type; template using hb_add_const = const T; #define hb_is_const(T) hb_match_const::value -template struct hb_match_reference { typedef T type; static constexpr bool value = false; }; -template struct hb_match_reference { typedef T type; static constexpr bool value = true; }; -template struct hb_match_reference { typedef T type; static constexpr bool value = true; }; +template struct hb_match_reference : hb_type_identity_t, hb_bool_constant{}; +template struct hb_match_reference : hb_type_identity_t, hb_bool_constant {}; +template struct hb_match_reference : hb_type_identity_t, hb_bool_constant {}; template using hb_remove_reference = typename hb_match_reference::type; template auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity; template auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity; @@ -113,8 +113,8 @@ template auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_t template auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity; template using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference (hb_prioritize)); #define hb_is_reference(T) hb_match_reference::value -template struct hb_match_pointer { typedef T type; static constexpr bool value = false; }; -template struct hb_match_pointer { typedef T type; static constexpr bool value = true; }; +template struct hb_match_pointer : hb_type_identity_t, hb_bool_constant{}; +template struct hb_match_pointer : hb_type_identity_t, hb_bool_constant {}; template using hb_remove_pointer = typename hb_match_pointer::type; template auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity*>; template auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity; From 40fb36a39de5dd3ee9a4c84f1f76205b6bb68660 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:01:19 -0700 Subject: [PATCH 297/336] [meta] Minor --- src/hb-meta.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 15c38bbc8..f67623136 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -41,8 +41,8 @@ struct hb_empty_t {}; template struct _hb_void_t { typedef void type; }; template using hb_void_t = typename _hb_void_t::type; -template struct _hb_head_tt { typedef Head type; }; -template using hb_head_tt = typename _hb_head_tt::type; +template struct _hb_head_t { typedef Head type; }; +template using hb_head_t = typename _hb_head_t::type; template struct hb_integral_constant { static constexpr T value = v; }; template using hb_bool_constant = hb_integral_constant; @@ -64,7 +64,7 @@ template struct hb_is_same : hb_true_type {}; /* Function overloading SFINAE and priority. */ -#define HB_RETURN(Ret, E) -> hb_head_tt { return (E); } +#define HB_RETURN(Ret, E) -> hb_head_t { return (E); } #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); } #define HB_VOID_RETURN(E) -> hb_void_t { (E); } From c0485e32a320e17dd0634b2cc8b4dd8c4fdc65e0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:03:14 -0700 Subject: [PATCH 298/336] Use hb_void_t<> the way it's supposed to be used --- src/hb-null.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 725db5024..674b4dffc 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -46,13 +46,13 @@ * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol */ -template +template struct _hb_null_size : hb_integral_constant {}; template -struct _hb_null_size> : hb_integral_constant {}; +struct _hb_null_size> : hb_integral_constant {}; template -using hb_null_size = _hb_null_size; +using hb_null_size = _hb_null_size; #define hb_null_size(T) hb_null_size::value /* These doesn't belong here, but since is copy/paste from above, put it here. */ @@ -60,12 +60,12 @@ using hb_null_size = _hb_null_size; /* hb_static_size (T) * Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */ -template +template struct _hb_static_size : hb_integral_constant {}; template -struct _hb_static_size> : hb_integral_constant {}; +struct _hb_static_size> : hb_integral_constant {}; template -using hb_static_size = _hb_static_size; +using hb_static_size = _hb_static_size; #define hb_static_size(T) hb_static_size::value From 19e08a146712dacd11359370c91a7bad55bc6f62 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:25:07 -0700 Subject: [PATCH 299/336] [iter] Adjust source_of/sink_of --- src/hb-iter.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a0beb2cdd..194a421ff 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -277,7 +277,7 @@ struct hb_is_source_of { private: template + hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference>))> static hb_true_type impl (hb_priority<2>); template static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ()); @@ -293,7 +293,7 @@ struct hb_is_sink_of { private: template + hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference))> static hb_true_type impl (hb_priority<2>); template static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_type ()); From b14745278ad16fe7f4e838b685029e3fdda516ca Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:42:59 -0700 Subject: [PATCH 300/336] [met]a Add is_constructible, ... --- src/hb-meta.hh | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ src/test-meta.cc | 23 +++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index f67623136..0ab717940 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -292,4 +292,77 @@ template <> struct hb_int_max : hb_integral_constant::value +template +struct _hb_is_constructible : hb_false_type {}; +template +struct _hb_is_constructible, Ts...> : hb_true_type {}; +template +using hb_is_constructible = _hb_is_constructible; +#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value + +template +using hb_is_default_constructible = hb_is_constructible; +#define hb_is_default_constructible(T) hb_is_default_constructible::value + +template +using hb_is_copy_constructible = hb_is_constructible>>; +#define hb_is_copy_constructible(T) hb_is_copy_constructible::value + +template +using hb_is_move_constructible = hb_is_constructible>>; +#define hb_is_move_constructible(T) hb_is_move_constructible::value + +template +struct _hb_is_assignable : hb_false_type {}; +template +struct _hb_is_assignable> : hb_true_type {}; +template +using hb_is_assignable = _hb_is_assignable; +#define hb_is_assignable(T,U) hb_is_assignable::value + +template +using hb_is_copy_assignable = hb_is_assignable, + hb_add_lvalue_reference>>; +#define hb_is_copy_assignable(T) hb_is_copy_assignable::value + +template +using hb_is_move_assignable = hb_is_assignable, + hb_add_rvalue_reference>; +#define hb_is_move_assignable(T) hb_is_move_assignable::value + +/* Trivial versions. */ + +template union hb_trivial { T value; }; + +/* Don't know how to do the following. */ +//template +//using hb_is_trivially_constructible= hb_is_constructible, hb_trivial...>; +//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value + +template +using hb_is_trivially_default_constructible= hb_is_default_constructible>; +#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible::value + +template +using hb_is_trivially_copy_constructible= hb_is_copy_constructible>; +#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible::value + +template +using hb_is_trivially_move_constructible= hb_is_move_constructible>; +#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible::value + +/* Don't know how to do the following. */ +//template +//using hb_is_trivially_assignable= hb_is_assignable, hb_trivial>; +//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable::value + +template +using hb_is_trivially_copy_assignable= hb_is_copy_assignable>; +#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable::value + +template +using hb_is_trivially_move_assignable= hb_is_move_assignable>; +#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable::value + + #endif /* HB_META_HH */ diff --git a/src/test-meta.cc b/src/test-meta.cc index 6fb8e4f19..af1ca2e09 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -27,6 +27,8 @@ #include "hb.hh" #include "hb-meta.hh" +#include + int main (int argc, char **argv) @@ -94,5 +96,26 @@ main (int argc, char **argv) static_assert (hb_is_base_of (X, const Y), ""); static_assert (!hb_is_base_of (Y, X), ""); + static_assert (hb_is_constructible (int), ""); + static_assert (hb_is_constructible (int, int), ""); + static_assert (hb_is_constructible (int, char), ""); + static_assert (hb_is_constructible (int, long), ""); + static_assert (!hb_is_constructible (int, X), ""); + static_assert (!hb_is_constructible (int, int, int), ""); + static_assert (hb_is_constructible (X), ""); + static_assert (!hb_is_constructible (X, int), ""); + static_assert (hb_is_constructible (X, X), ""); + static_assert (!hb_is_constructible (X, X, X), ""); + static_assert (hb_is_constructible (X, Y), ""); + static_assert (!hb_is_constructible (Y, X), ""); + + static_assert (hb_is_trivially_default_constructible (X), ""); + static_assert (hb_is_trivially_default_constructible (Y), ""); + static_assert (hb_is_trivially_copy_constructible (X), ""); + static_assert (hb_is_trivially_copy_constructible (Y), ""); + static_assert (hb_is_trivially_move_constructible (X), ""); + static_assert (hb_is_trivially_move_constructible (Y), ""); + /* TODO Add more meaningful tests. */ + return 0; } From 086772e409759e8f1edd0e34f6f25374e51e9e10 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:49:25 -0700 Subject: [PATCH 301/336] [meta] Add is_destructible --- src/hb-meta.hh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 0ab717940..47cefa869 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -292,6 +292,15 @@ template <> struct hb_int_max : hb_integral_constant::value + +template +struct _hb_is_destructible : hb_false_type {}; +template +struct _hb_is_destructible> : hb_true_type {}; +template +using hb_is_destructible = _hb_is_destructible; +#define hb_is_destructible(T) hb_is_destructible::value + template struct _hb_is_constructible : hb_false_type {}; template @@ -334,6 +343,11 @@ using hb_is_move_assignable = hb_is_assignable, template union hb_trivial { T value; }; +/* Don't know how to do the following. */ +//template +//using hb_is_trivially_destructible= hb_is_destructible>; +//#define hb_is_trivially_destructible(T) hb_is_trivially_destructible::value + /* Don't know how to do the following. */ //template //using hb_is_trivially_constructible= hb_is_constructible, hb_trivial...>; From 72cb5b8e52b7103c18adcb82cbcd4b91a2c85474 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:50:15 -0700 Subject: [PATCH 302/336] Remove accidentally included include --- src/test-meta.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test-meta.cc b/src/test-meta.cc index af1ca2e09..ffc3147dd 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -27,9 +27,6 @@ #include "hb.hh" #include "hb-meta.hh" -#include - - int main (int argc, char **argv) { From f2398f34c019a55d4f0e1a7031961714afadf2b3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 21:59:57 -0700 Subject: [PATCH 303/336] [meta] Add is_trivially_destructible --- src/hb-meta.hh | 6 +++--- src/test-meta.cc | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 47cefa869..f69a567c2 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -344,9 +344,9 @@ using hb_is_move_assignable = hb_is_assignable, template union hb_trivial { T value; }; /* Don't know how to do the following. */ -//template -//using hb_is_trivially_destructible= hb_is_destructible>; -//#define hb_is_trivially_destructible(T) hb_is_trivially_destructible::value +template +using hb_is_trivially_destructible= hb_is_destructible>; +#define hb_is_trivially_destructible(T) hb_is_trivially_destructible::value /* Don't know how to do the following. */ //template diff --git a/src/test-meta.cc b/src/test-meta.cc index ffc3147dd..ab7f6ad11 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -27,6 +27,8 @@ #include "hb.hh" #include "hb-meta.hh" +#include + int main (int argc, char **argv) { @@ -57,6 +59,7 @@ main (int argc, char **argv) static_assert (hb_is_convertible (const int&, const int), ""); struct X {}; + struct Y : X {}; static_assert (hb_is_convertible (const X &, const X), ""); static_assert (hb_is_convertible (X &, const X), ""); @@ -77,8 +80,6 @@ main (int argc, char **argv) static_assert (hb_is_convertible (int *, void *), ""); static_assert (!hb_is_convertible (void *, int *), ""); - struct Y : X {}; - static_assert (hb_is_base_of (void, void), ""); static_assert (hb_is_base_of (void, int), ""); static_assert (!hb_is_base_of (int, void), ""); @@ -112,6 +113,8 @@ main (int argc, char **argv) static_assert (hb_is_trivially_copy_constructible (Y), ""); static_assert (hb_is_trivially_move_constructible (X), ""); static_assert (hb_is_trivially_move_constructible (Y), ""); + static_assert (hb_is_trivially_destructible (Y), ""); + /* TODO Add more meaningful tests. */ return 0; From 7162a97bca6e0dde3d277701a3bf15688deef61d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 22:03:03 -0700 Subject: [PATCH 304/336] [meta] Add hb_is_trivially_copyable() --- src/hb-meta.hh | 11 +++++++++++ src/test-meta.cc | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index f69a567c2..a1e93d750 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -378,5 +378,16 @@ template using hb_is_trivially_move_assignable= hb_is_move_assignable>; #define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable::value +template +using hb_is_trivially_copyable= hb_bool_constant< + hb_is_trivially_destructible (T) && + (!hb_is_move_assignable (T) || hb_is_trivially_move_assignable (T)) && + (!hb_is_move_constructible (T) || hb_is_trivially_move_constructible (T)) && + (!hb_is_copy_assignable (T) || hb_is_trivially_copy_assignable (T)) && + (!hb_is_copy_constructible (T) || hb_is_trivially_copy_constructible (T)) && + true +>; +#define hb_is_trivially_copyable(T) hb_is_trivially_copyable::value + #endif /* HB_META_HH */ diff --git a/src/test-meta.cc b/src/test-meta.cc index ab7f6ad11..f03be3064 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -115,6 +115,10 @@ main (int argc, char **argv) static_assert (hb_is_trivially_move_constructible (Y), ""); static_assert (hb_is_trivially_destructible (Y), ""); + static_assert (hb_is_trivially_copyable (int), ""); + static_assert (hb_is_trivially_copyable (X), ""); + static_assert (hb_is_trivially_copyable (Y), ""); + /* TODO Add more meaningful tests. */ return 0; From 0ff7954f9f09f80654ac91c16712154744a0dd2d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 22:04:40 -0700 Subject: [PATCH 305/336] [meta] Add hb_is_trivial --- src/hb-meta.hh | 7 +++++++ src/test-meta.cc | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index a1e93d750..df8ebd175 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -389,5 +389,12 @@ using hb_is_trivially_copyable= hb_bool_constant< >; #define hb_is_trivially_copyable(T) hb_is_trivially_copyable::value +template +using hb_is_trivial= hb_bool_constant< + hb_is_trivially_copyable (T) && + hb_is_trivially_default_constructible (T) +>; +#define hb_is_trivial(T) hb_is_trivial::value + #endif /* HB_META_HH */ diff --git a/src/test-meta.cc b/src/test-meta.cc index f03be3064..ffd360b0d 100644 --- a/src/test-meta.cc +++ b/src/test-meta.cc @@ -119,6 +119,10 @@ main (int argc, char **argv) static_assert (hb_is_trivially_copyable (X), ""); static_assert (hb_is_trivially_copyable (Y), ""); + static_assert (hb_is_trivial (int), ""); + static_assert (hb_is_trivial (X), ""); + static_assert (hb_is_trivial (Y), ""); + /* TODO Add more meaningful tests. */ return 0; From 23168c3981f7c80883663fa69c608caee98d3d99 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 22:11:51 -0700 Subject: [PATCH 306/336] [sanitize] Use hb_is_trivially_copyable() --- src/hb-open-type.hh | 64 ++++++--------------------------------------- 1 file changed, 8 insertions(+), 56 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 9e17b5c88..3fc49400c 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -445,20 +445,8 @@ struct UnsizedArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - /* Note: for structs that do not reference other structs, - * we do not need to call their sanitize() as we already did - * a bound check on the aggregate array size. We just include - * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize() as well as an - * assignment opreator. This ensures that they do not - * reference other structs via offsets. - */ - if (false) - { - arrayZ[0].sanitize (c); - Type v; - v = arrayZ[0]; - } + static_assert ((hb_void_t (), true), ""); + static_assert (hb_is_trivially_copyable (Type), ""); return_trace (true); } @@ -626,20 +614,8 @@ struct ArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - /* Note: for structs that do not reference other structs, - * we do not need to call their sanitize() as we already did - * a bound check on the aggregate array size. We just include - * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize() as well as an - * assignment opreator. This ensures that they do not - * reference other structs via offsets. - */ - if (false) - { - arrayZ[0].sanitize (c); - Type v; - v = arrayZ[0]; - } + static_assert ((hb_void_t (), true), ""); + static_assert (hb_is_trivially_copyable (Type), ""); return_trace (true); } @@ -765,20 +741,8 @@ struct HeadlessArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - /* Note: for structs that do not reference other structs, - * we do not need to call their sanitize() as we already did - * a bound check on the aggregate array size. We just include - * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize() as well as an - * assignment opreator. This ensures that they do not - * reference other structs via offsets. - */ - if (false) - { - arrayZ[0].sanitize (c); - Type v; - v = arrayZ[0]; - } + static_assert ((hb_void_t (), true), ""); + static_assert (hb_is_trivially_copyable (Type), ""); return_trace (true); } @@ -1006,20 +970,8 @@ struct VarSizedBinSearchArrayOf TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - /* Note: for structs that do not reference other structs, - * we do not need to call their sanitize() as we already did - * a bound check on the aggregate array size. We just include - * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize() as well as an - * assignment opreator. This ensures that they do not - * reference other structs via offsets. - */ - if (false) - { - (*this)[0].sanitize (c); - Type v; - v = (*this)[0]; - } + static_assert ((hb_void_t (), true), ""); + static_assert (hb_is_trivially_copyable (Type), ""); return_trace (true); } From 4dcf65328f04a11594fc190fd7e976afa54455e9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 22:23:24 -0700 Subject: [PATCH 307/336] [sanitize] Simplify --- src/hb-open-type.hh | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 3fc49400c..13b1245de 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -440,21 +440,12 @@ struct UnsizedArrayOf return_trace (out); } - bool sanitize (hb_sanitize_context_t *c, unsigned int count) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - - static_assert ((hb_void_t (), true), ""); - static_assert (hb_is_trivially_copyable (Type), ""); - - return_trace (true); - } template bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); + if (hb_is_trivially_copyable (Type)) return_trace (true); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) return_trace (false); @@ -609,21 +600,12 @@ struct ArrayOf return_trace (out); } - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - - static_assert ((hb_void_t (), true), ""); - static_assert (hb_is_trivially_copyable (Type), ""); - - return_trace (true); - } template bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); + if (hb_is_trivially_copyable (Type)) return_trace (true); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) @@ -736,14 +718,16 @@ struct HeadlessArrayOf return_trace (true); } - bool sanitize (hb_sanitize_context_t *c) const + template + bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - - static_assert ((hb_void_t (), true), ""); - static_assert (hb_is_trivially_copyable (Type), ""); - + if (hb_is_trivially_copyable (Type)) return_trace (true); + unsigned int count = lenP1 ? lenP1 - 1 : 0; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) + return_trace (false); return_trace (true); } @@ -965,21 +949,12 @@ struct VarSizedBinSearchArrayOf unsigned int get_size () const { return header.static_size + header.nUnits * header.unitSize; } - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - - static_assert ((hb_void_t (), true), ""); - static_assert (hb_is_trivially_copyable (Type), ""); - - return_trace (true); - } template bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); + if (hb_is_trivially_copyable (Type)) return_trace (true); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, hb_forward (ds)...))) From 9bfe22af6113ee8cd24cb9ee091f0841c27bbf98 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 22:44:19 -0700 Subject: [PATCH 308/336] [sanitize] Fix previous commit --- src/hb-open-type.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 13b1245de..57b22a8e3 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -445,7 +445,7 @@ struct UnsizedArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - if (hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) return_trace (false); @@ -605,7 +605,7 @@ struct ArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) @@ -723,7 +723,7 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); unsigned int count = lenP1 ? lenP1 - 1 : 0; for (unsigned int i = 0; i < count; i++) if (unlikely (!c->dispatch (arrayZ[i], hb_forward (ds)...))) @@ -954,7 +954,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, hb_forward (ds)...))) From 227d85e138d4c785c2d658e225ed35f5acd1235f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:15:58 -0700 Subject: [PATCH 309/336] Minor --- src/hb-atomic.hh | 2 +- src/hb-debug.hh | 2 +- src/hb-font.cc | 2 +- src/hb-ot-font.cc | 4 ++-- src/hb-ot-layout.cc | 6 +++--- src/hb-ot-name-table.hh | 2 +- src/hb-ot-shape-complex-arabic.cc | 2 +- src/hb-ot-shape-complex-hebrew.cc | 2 +- src/hb-ot-shape-complex-thai.cc | 2 +- src/hb-ot-shape-complex-vowel-constraints.cc | 2 +- src/hb-ot-shape-fallback.cc | 6 +++--- src/hb-subset.cc | 4 ++-- src/hb-warning.cc | 4 ++-- src/hb.hh | 10 +++++----- 14 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/hb-atomic.hh b/src/hb-atomic.hh index 8307a549d..a82ce6cf3 100644 --- a/src/hb-atomic.hh +++ b/src/hb-atomic.hh @@ -107,7 +107,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) static inline void _hb_memory_barrier () { -#if !defined(MemoryBarrier) +#ifndef MemoryBarrier /* MinGW has a convoluted history of supporting MemoryBarrier. */ LONG dummy = 0; InterlockedExchange (&dummy, 1); diff --git a/src/hb-debug.hh b/src/hb-debug.hh index a03170b08..e6d06e310 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -63,7 +63,7 @@ extern HB_INTERNAL hb_atomic_int_t _hb_options; static inline hb_options_t hb_options () { -#if defined(HB_NO_GETENV) +#ifdef HB_NO_GETENV return hb_options_t (); #endif /* Make a local copy, so we can access bitfield threadsafely. */ diff --git a/src/hb-font.cc b/src/hb-font.cc index 20daefd27..c00f33329 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1347,7 +1347,7 @@ hb_font_create (hb_face_t *face) { hb_font_t *font = _hb_font_create (face); -#if !defined(HB_NO_OT_FONT) +#ifndef HB_NO_OT_FONT /* Install our in-house, very lightweight, funcs. */ hb_ot_font_set_funcs (font); #endif diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 77e42cc53..5051fa0ea 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -183,13 +183,13 @@ hb_ot_get_glyph_extents (hb_font_t *font, bool ret = ot_face->sbix->get_extents (font, glyph, extents); if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); -#if !defined(HB_NO_OT_FONT_CFF) +#ifndef HB_NO_OT_FONT_CFF if (!ret) ret = ot_face->cff1->get_extents (glyph, extents); if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents); #endif -#if !defined(HB_NO_OT_FONT_BITMAP) +#ifndef HB_NO_OT_FONT_BITMAP if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents); #endif diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 817b28e68..cd603d8d0 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -138,7 +138,7 @@ bool OT::GDEF::is_blacklisted (hb_blob_t *blob, hb_face_t *face) const { -#if defined(HB_NO_OT_LAYOUT_BLACKLIST) +#ifdef HB_NO_OT_LAYOUT_BLACKLIST return false; #endif /* The ugly business of blacklisting individual fonts' tables happen here! @@ -384,7 +384,7 @@ bool OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED, hb_face_t *face) const { -#if defined(HB_NO_OT_LAYOUT_BLACKLIST) +#ifdef HB_NO_OT_LAYOUT_BLACKLIST return false; #endif /* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts, @@ -412,7 +412,7 @@ bool OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED, hb_face_t *face HB_UNUSED) const { -#if defined(HB_NO_OT_LAYOUT_BLACKLIST) +#ifdef HB_NO_OT_LAYOUT_BLACKLIST return false; #endif return false; diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index f2f5a1a53..e7e32ecf8 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -60,7 +60,7 @@ struct NameRecord if (p == 1) return _hb_ot_name_language_for_mac_code (l); -#if !defined(HB_NO_NAME_TABLE_AAT) +#ifndef HB_NO_NAME_TABLE_AAT if (p == 0) return _hb_aat_language_get (face, l); #endif diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index 4daf2a666..3212e0c96 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -383,7 +383,7 @@ arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { -#if defined(HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK) +#ifdef HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK return; #endif diff --git a/src/hb-ot-shape-complex-hebrew.cc b/src/hb-ot-shape-complex-hebrew.cc index db8801814..14989730f 100644 --- a/src/hb-ot-shape-complex-hebrew.cc +++ b/src/hb-ot-shape-complex-hebrew.cc @@ -70,7 +70,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, bool found = (bool) c->unicode->compose (a, b, ab); -#if defined(HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK) +#ifdef HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK return found; #endif diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc index 130ea1c98..22d4aa3ab 100644 --- a/src/hb-ot-shape-complex-thai.cc +++ b/src/hb-ot-shape-complex-thai.cc @@ -218,7 +218,7 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font) { -#if defined(HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK) +#ifdef HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK return; #endif diff --git a/src/hb-ot-shape-complex-vowel-constraints.cc b/src/hb-ot-shape-complex-vowel-constraints.cc index 2eb313ae4..912ee35b4 100644 --- a/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/src/hb-ot-shape-complex-vowel-constraints.cc @@ -34,7 +34,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, hb_font_t *font HB_UNUSED) { -#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS) +#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS return; #endif if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index b10eec666..42b728fd1 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -166,7 +166,7 @@ _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { -#if defined(HB_NO_OT_SHAPE_FALLBACK) +#ifdef HB_NO_OT_SHAPE_FALLBACK return; #endif @@ -438,7 +438,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, bool adjust_offsets_when_zeroing) { -#if defined(HB_NO_OT_SHAPE_FALLBACK) +#ifdef HB_NO_OT_SHAPE_FALLBACK return; #endif @@ -481,7 +481,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { -#if defined(HB_NO_OT_SHAPE_FALLBACK) +#ifdef HB_NO_OT_SHAPE_FALLBACK return; #endif diff --git a/src/hb-subset.cc b/src/hb-subset.cc index f4fc77172..aa6934bc3 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -206,7 +206,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset (plan); break; -#if !defined(HB_NO_SUBSET_LAYOUT) +#ifndef HB_NO_SUBSET_LAYOUT case HB_OT_TAG_GDEF: result = _subset2 (plan); break; @@ -247,7 +247,7 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) case HB_OT_TAG_GDEF: case HB_OT_TAG_GPOS: case HB_OT_TAG_GSUB: -#if defined(HB_NO_SUBSET_LAYOUT) +#ifdef HB_NO_SUBSET_LAYOUT return true; #endif return plan->drop_layout; diff --git a/src/hb-warning.cc b/src/hb-warning.cc index 9fb410038..60c7445b7 100644 --- a/src/hb-warning.cc +++ b/src/hb-warning.cc @@ -26,12 +26,12 @@ #include "hb.hh" -#if defined(HB_ATOMIC_INT_NIL) +#ifdef HB_ATOMIC_INT_NIL #error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe" #error "Check hb-atomic.hh for possible resolutions." #endif -#if defined(HB_MUTEX_IMPL_NIL) +#ifdef HB_MUTEX_IMPL_NIL #error "Could not find any system to define mutex macros, library WILL NOT be thread-safe" #error "Check hb-mutex.hh for possible resolutions." #endif diff --git a/src/hb.hh b/src/hb.hh index 3d4b18033..0aa55af16 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -30,7 +30,7 @@ #define HB_HH #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC -#if defined(_MSC_VER) +#ifdef _MSC_VER #pragma warning( disable: 4068 ) /* Unknown pragma */ #endif #if defined(__GNUC__) || defined(__clang__) @@ -203,7 +203,7 @@ extern "C" void hb_free_impl(void *ptr); #define realloc hb_realloc_impl #define free hb_free_impl -#if defined(hb_memalign_impl) +#ifdef hb_memalign_impl extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); #define posix_memalign hb_memalign_impl #else @@ -315,7 +315,7 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); # define HB_FALLTHROUGH /* FALLTHROUGH */ #endif -#if defined(__clang__) +#ifdef __clang__ /* Disable certain sanitizer errors. */ /* https://github.com/harfbuzz/harfbuzz/issues/1247 */ #define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow"))) @@ -445,12 +445,12 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); * * https://bugs.chromium.org/p/chromium/issues/detail?id=860184 */ -#if !defined(HB_VECTOR_SIZE) +#ifndef HB_VECTOR_SIZE # define HB_VECTOR_SIZE 0 #endif /* The `vector_size' attribute was introduced in gcc 3.1. */ -#if !defined(HB_VECTOR_SIZE) +#ifndef HB_VECTOR_SIZE # if defined( __GNUC__ ) && ( __GNUC__ >= 4 ) # define HB_VECTOR_SIZE 128 # else From 62dfe7aea23c95f4550543085071990e20ee4d54 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:17:15 -0700 Subject: [PATCH 310/336] [cff] Minor --- src/hb-subset-cff1.cc | 2 +- src/hb-subset-cff2.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index a69dd93ae..ab3ad0936 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -1064,7 +1064,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan, return true; } -static bool +static inline bool _hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc, const char *data, hb_subset_plan_t *plan, diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index caee17550..9a03c3ed9 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -571,7 +571,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan, return true; } -static bool +static inline bool _hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc, const char *data, hb_subset_plan_t *plan, From 2c93f0dee31b2277567ccbee041539732b9bd26d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:31:05 -0700 Subject: [PATCH 311/336] Add HB_NO_AAT Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-aat-layout.cc | 58 +++++++++++++++++++++++++++++++++++++++++ src/hb-aat-map.cc | 8 ++++++ src/hb-ot-kern-table.hh | 14 ++++++++++ src/hb-ot-shape.cc | 28 +++++++++++++++++++- 4 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 1966ded32..20c82aeff 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -135,6 +135,10 @@ static const hb_aat_feature_mapping_t feature_mappings[] = const hb_aat_feature_mapping_t * hb_aat_layout_find_feature_mapping (hb_tag_t tag) { +#ifdef HB_NO_AAT + return nullptr; +#endif + return (const hb_aat_feature_mapping_t *) bsearch (&tag, feature_mappings, ARRAY_LENGTH (feature_mappings), @@ -147,6 +151,8 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) * hb_aat_apply_context_t */ +/* Note: This context is used for kerning, even without AAT. */ + AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, hb_font_t *font_, hb_buffer_t *buffer_, @@ -183,6 +189,10 @@ void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) { +#ifdef HB_NO_AAT + return; +#endif + const AAT::morx& morx = *mapper->face->table.morx; if (morx.has_data ()) { @@ -209,6 +219,10 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) { +#ifdef HB_NO_AAT + return false; +#endif + return face->table.morx->has_data () || face->table.mort->has_data (); } @@ -218,6 +232,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { +#ifdef HB_NO_AAT + return; +#endif + hb_blob_t *morx_blob = font->face->table.morx.get_blob (); const AAT::morx& morx = *morx_blob->as (); if (morx.has_data ()) @@ -240,6 +258,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, void hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer) { +#ifdef HB_NO_AAT + return; +#endif + unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; hb_glyph_position_t *pos = buffer->pos; @@ -257,6 +279,10 @@ is_deleted_glyph (const hb_glyph_info_t *info) void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { +#ifdef HB_NO_AAT + return; +#endif + hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph); } @@ -270,6 +296,10 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) hb_bool_t hb_aat_layout_has_positioning (hb_face_t *face) { +#ifdef HB_NO_AAT + return false; +#endif + return face->table.kerx->has_data (); } @@ -278,6 +308,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { +#ifdef HB_NO_AAT + return; +#endif + hb_blob_t *kerx_blob = font->face->table.kerx.get_blob (); const AAT::kerx& kerx = *kerx_blob->as (); @@ -297,6 +331,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_bool_t hb_aat_layout_has_tracking (hb_face_t *face) { +#ifdef HB_NO_AAT + return false; +#endif + return face->table.trak->has_data (); } @@ -305,6 +343,10 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { +#ifdef HB_NO_AAT + return; +#endif + const AAT::trak& trak = *font->face->table.trak; AAT::hb_aat_apply_context_t c (plan, font, buffer); @@ -328,6 +370,12 @@ hb_aat_layout_get_feature_types (hb_face_t *face, unsigned int *feature_count, /* IN/OUT. May be NULL. */ hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) { +#ifdef HB_NO_AAT + if (feature_count) + *feature_count = 0; + return 0; +#endif + return face->table.feat->get_feature_types (start_offset, feature_count, features); } @@ -344,6 +392,10 @@ hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature_type) { +#ifdef HB_NO_AAT + return HB_OT_NAME_ID_INVALID; +#endif + return face->table.feat->get_feature_name_id (feature_type); } @@ -372,5 +424,11 @@ hb_aat_layout_feature_type_get_selector_infos (hb_face_t hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ unsigned int *default_index /* OUT. May be NULL. */) { +#ifdef HB_NO_AAT + if (selector_count) + *selector_count = 0; + return 0; +#endif + return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index); } diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index 98c5d7fe4..618ec8f5a 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -34,6 +34,10 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned int value) { +#ifdef HB_NO_AAT + return; +#endif + if (tag == HB_TAG ('a','a','l','t')) { feature_info_t *info = features.push(); @@ -53,6 +57,10 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, void hb_aat_map_builder_t::compile (hb_aat_map_t &m) { +#ifdef HB_NO_AAT + return; +#endif + /* Sort features and merge duplicates */ if (features.length) { diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 436dad45d..e862718fb 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -128,9 +128,13 @@ struct KernSubTable TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { case 0: return_trace (c->dispatch (u.format0)); +#ifndef HB_NO_AAT case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward (ds)...) : c->default_return_value ()); +#endif case 2: return_trace (c->dispatch (u.format2)); +#ifndef HB_NO_AAT case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward (ds)...) : c->default_return_value ()); +#endif default: return_trace (c->default_return_value ()); } } @@ -278,7 +282,9 @@ struct kern { switch (get_type ()) { case 0: return u.ot.has_state_machine (); +#ifndef HB_NO_AAT case 1: return u.aat.has_state_machine (); +#endif default:return false; } } @@ -287,7 +293,9 @@ struct kern { switch (get_type ()) { case 0: return u.ot.has_cross_stream (); +#ifndef HB_NO_AAT case 1: return u.aat.has_cross_stream (); +#endif default:return false; } } @@ -296,7 +304,9 @@ struct kern { switch (get_type ()) { case 0: return u.ot.get_h_kerning (left, right); +#ifndef HB_NO_AAT case 1: return u.aat.get_h_kerning (left, right); +#endif default:return 0; } } @@ -311,7 +321,9 @@ struct kern TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { case 0: return_trace (c->dispatch (u.ot, hb_forward (ds)...)); +#ifndef HB_NO_AAT case 1: return_trace (c->dispatch (u.aat, hb_forward (ds)...)); +#endif default: return_trace (c->default_return_value ()); } } @@ -328,7 +340,9 @@ struct kern HBUINT32 version32; HBUINT16 major; KernOT ot; +#ifndef HB_NO_AAT KernAAT aat; +#endif } u; public: DEFINE_SIZE_UNION (4, version32); diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 03d9a68ae..0d8acc3a5 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -58,6 +58,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, static bool _hb_apply_morx (hb_face_t *face) { +#ifdef HB_NO_AAT + return false; +#endif + if (hb_options ().aat && hb_aat_layout_has_substitution (face)) return true; @@ -83,8 +87,10 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; +#ifndef HB_NO_AAT if (apply_morx) shaper = &_hb_ot_complex_shaper_default; +#endif } void @@ -94,8 +100,10 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, key); +#ifndef HB_NO_AAT if (apply_morx) aat_map.compile (plan.aat_map); +#endif plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); @@ -130,12 +138,18 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, * Decide who does positioning. GPOS, kerx, kern, or fallback. */ - if (hb_options ().aat && hb_aat_layout_has_positioning (face)) + if (0) + ; +#ifndef HB_NO_AAT + else if (hb_options ().aat && hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; +#endif else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face)) plan.apply_gpos = true; +#ifndef HB_NO_AAT else if (hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; +#endif if (!plan.apply_kerx && !has_gpos_kern) { @@ -202,9 +216,11 @@ void hb_ot_shape_plan_t::substitute (hb_font_t *font, hb_buffer_t *buffer) const { +#ifndef HB_NO_AAT if (unlikely (apply_morx)) hb_aat_layout_substitute (this, font, buffer); else +#endif map.substitute (this, font, buffer); } @@ -214,15 +230,19 @@ hb_ot_shape_plan_t::position (hb_font_t *font, { if (this->apply_gpos) map.position (this, font, buffer); +#ifndef HB_NO_AAT else if (this->apply_kerx) hb_aat_layout_position (this, font, buffer); +#endif else if (this->apply_kern) hb_ot_layout_kern (this, font, buffer); else _hb_ot_shape_fallback_kern (this, font, buffer); +#ifndef HB_NO_AAT if (this->apply_trak) hb_aat_layout_track (this, font, buffer); +#endif } @@ -318,6 +338,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, feature->value); } +#ifndef HB_NO_AAT if (planner->apply_morx) { hb_aat_map_builder_t *aat_map = &planner->aat_map; @@ -327,6 +348,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, aat_map->add_feature (feature->tag, feature->value); } } +#endif if (planner->shaper->override_features) planner->shaper->override_features (planner); @@ -761,8 +783,10 @@ static inline void hb_ot_substitute_post (const hb_ot_shape_context_t *c) { hb_ot_hide_default_ignorables (c->buffer, c->font); +#ifndef HB_NO_AAT if (c->plan->apply_morx) hb_aat_layout_remove_deleted_glyphs (c->buffer); +#endif if (c->plan->shaper->postprocess_glyphs) c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); @@ -896,8 +920,10 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) /* Finish off. Has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c->buffer); +#ifndef HB_NO_AAT if (c->plan->apply_morx) hb_aat_layout_zero_width_deleted_glyphs (c->buffer); +#endif hb_ot_layout_position_finish_offsets (c->font, c->buffer); /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ From 5ea8ad5c48f9baabc4ccf81dce4aee1067c401f6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:36:42 -0700 Subject: [PATCH 312/336] [subset] Add HB_NO_SUBSET_CFF Doesn't fully prune all the relevant code. To be fixed later. Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-subset.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index aa6934bc3..a8ec14f57 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -196,6 +196,8 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_post: result = _subset (plan); break; + +#ifndef HB_NO_SUBSET_CFF case HB_OT_TAG_cff1: result = _subset (plan); break; @@ -205,6 +207,7 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_VORG: result = _subset (plan); break; +#endif #ifndef HB_NO_SUBSET_LAYOUT case HB_OT_TAG_GDEF: From 31c591d69f6a7605088883db59149e83c80d019c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:39:53 -0700 Subject: [PATCH 313/336] [cff] Prune more code if HB_NO_OT_FONT_CFF Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-ot-cff1-table.cc | 5 +++++ src/hb-ot-cff2-table.cc | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 1d97e5444..2844f3ca4 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -305,6 +305,11 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { +#ifdef HB_NO_OT_FONT_CFF + /* XXX Remove check when this code moves to .hh file. */ + return true; +#endif + bounds_t bounds; if (!_get_bounds (this, glyph, bounds)) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index d2463d785..a1aaef636 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -99,6 +99,11 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { +#ifdef HB_NO_OT_FONT_CFF + /* XXX Remove check when this code moves to .hh file. */ + return true; +#endif + if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false; unsigned int num_coords; From d43af339e7a7f5dab1690703a78d2690baefbd59 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:46:22 -0700 Subject: [PATCH 314/336] [subset] More HB_NO_SUBSET_LAYOUT Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-subset-plan.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 66976fa95..009faeb95 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -32,7 +32,7 @@ #include "hb-ot-glyf-table.hh" #include "hb-ot-cff1-table.hh" -static void +static inline void _add_gid_and_children (const OT::glyf::accelerator_t &glyf, hb_codepoint_t gid, hb_set_t *gids_to_retain) @@ -53,7 +53,7 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf, } } -static void +static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, hb_codepoint_t gid, hb_set_t *gids_to_retain) @@ -66,7 +66,7 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff, } } -static void +static inline void _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) { hb_set_t lookup_indices; @@ -81,7 +81,7 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) gids_to_retain); } -static void +static inline void _remove_invalid_gids (hb_set_t *glyphs, unsigned int num_glyphs) { @@ -126,9 +126,11 @@ _populate_gids_to_retain (hb_face_t *face, initial_gids_to_retain->add (gid); } +#ifndef HB_NO_SUBSET_LAYOUT if (close_over_gsub) // Add all glyphs needed for GSUB substitutions. _gsub_closure (face, initial_gids_to_retain); +#endif // Populate a full set of glyphs to retain by adding all referenced // composite glyphs. @@ -137,14 +139,15 @@ _populate_gids_to_retain (hb_face_t *face, while (initial_gids_to_retain->next (&gid)) { _add_gid_and_children (glyf, gid, all_gids_to_retain); +#ifndef HB_NO_SUBSET_CFF if (cff.is_valid ()) _add_cff_seac_components (cff, gid, all_gids_to_retain); +#endif } hb_set_destroy (initial_gids_to_retain); _remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ()); - cff.fini (); glyf.fini (); cmap.fini (); From e6582de12f1af9ab5e3122d762a3e12438a66b6b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:53:38 -0700 Subject: [PATCH 315/336] Add hb-config.hh --- src/Makefile.sources | 1 + src/hb-config.hh | 36 ++++++++++++++++++++++++++++++++++++ src/hb.hh | 7 ++++--- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/hb-config.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index e61315be6..0615a8bfc 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -31,6 +31,7 @@ HB_BASE_sources = \ hb-cff1-interp-cs.hh \ hb-cff2-interp-cs.hh \ hb-common.cc \ + hb-config.hh \ hb-debug.hh \ hb-dispatch.hh \ hb-face.cc \ diff --git a/src/hb-config.hh b/src/hb-config.hh new file mode 100644 index 000000000..385ea4828 --- /dev/null +++ b/src/hb-config.hh @@ -0,0 +1,36 @@ +/* + * Copyright © 2019 Facebook, 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. + * + * Facebook Author(s): Behdad Esfahbod + */ + +#ifndef HB_CONFIG_HH +#define HB_CONFIG_HH + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + + +#endif /* HB_CONFIG_HH */ diff --git a/src/hb.hh b/src/hb.hh index 0aa55af16..e4c7271bd 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -29,6 +29,7 @@ #ifndef HB_HH #define HB_HH + #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC #ifdef _MSC_VER #pragma warning( disable: 4068 ) /* Unknown pragma */ @@ -129,9 +130,9 @@ #endif #endif -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif + +#include "hb-config.hh" + /* * Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to From 799c6a5081e5058260199eeeb2091ee2c1dfefff Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 10 May 2019 23:55:22 -0700 Subject: [PATCH 316/336] [config] Add some --- src/hb-aat-layout.cc | 26 +++++++++++++------------- src/hb-aat-map.cc | 4 ++-- src/hb-config.hh | 18 ++++++++++++++++++ src/hb-ot-kern-table.hh | 14 +++++++------- src/hb-ot-shape.cc | 22 +++++++++++----------- 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 20c82aeff..22cbd7338 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -135,7 +135,7 @@ static const hb_aat_feature_mapping_t feature_mappings[] = const hb_aat_feature_mapping_t * hb_aat_layout_find_feature_mapping (hb_tag_t tag) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return nullptr; #endif @@ -189,7 +189,7 @@ void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -219,7 +219,7 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return false; #endif @@ -232,7 +232,7 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -258,7 +258,7 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, void hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -279,7 +279,7 @@ is_deleted_glyph (const hb_glyph_info_t *info) void hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -296,7 +296,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) hb_bool_t hb_aat_layout_has_positioning (hb_face_t *face) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return false; #endif @@ -308,7 +308,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -331,7 +331,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_bool_t hb_aat_layout_has_tracking (hb_face_t *face) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return false; #endif @@ -343,7 +343,7 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -370,7 +370,7 @@ hb_aat_layout_get_feature_types (hb_face_t *face, unsigned int *feature_count, /* IN/OUT. May be NULL. */ hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT if (feature_count) *feature_count = 0; return 0; @@ -392,7 +392,7 @@ hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature_type) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return HB_OT_NAME_ID_INVALID; #endif @@ -424,7 +424,7 @@ hb_aat_layout_feature_type_get_selector_infos (hb_face_t hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */ unsigned int *default_index /* OUT. May be NULL. */) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT if (selector_count) *selector_count = 0; return 0; diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc index 618ec8f5a..d57ee849d 100644 --- a/src/hb-aat-map.cc +++ b/src/hb-aat-map.cc @@ -34,7 +34,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned int value) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif @@ -57,7 +57,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, void hb_aat_map_builder_t::compile (hb_aat_map_t &m) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return; #endif diff --git a/src/hb-config.hh b/src/hb-config.hh index 385ea4828..03f1ba247 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -33,4 +33,22 @@ + + +/* Closure. */ + +#ifdef HB_NO_AAT +#define HB_NO_SHAPE_AAT +#endif + +#ifdef HB_NO_BITMAP +#define HB_NO_OT_FONT_BITMAP +#endif + +#ifdef HB_NO_CFF +#define HB_NO_OT_FONT_CFF +#define HB_NO_SUBSET_CFF +#endif + + #endif /* HB_CONFIG_HH */ diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index e862718fb..ae2bcc92d 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -128,11 +128,11 @@ struct KernSubTable TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { case 0: return_trace (c->dispatch (u.format0)); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward (ds)...) : c->default_return_value ()); #endif case 2: return_trace (c->dispatch (u.format2)); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward (ds)...) : c->default_return_value ()); #endif default: return_trace (c->default_return_value ()); @@ -282,7 +282,7 @@ struct kern { switch (get_type ()) { case 0: return u.ot.has_state_machine (); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT case 1: return u.aat.has_state_machine (); #endif default:return false; @@ -293,7 +293,7 @@ struct kern { switch (get_type ()) { case 0: return u.ot.has_cross_stream (); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT case 1: return u.aat.has_cross_stream (); #endif default:return false; @@ -304,7 +304,7 @@ struct kern { switch (get_type ()) { case 0: return u.ot.get_h_kerning (left, right); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT case 1: return u.aat.get_h_kerning (left, right); #endif default:return 0; @@ -321,7 +321,7 @@ struct kern TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { case 0: return_trace (c->dispatch (u.ot, hb_forward (ds)...)); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT case 1: return_trace (c->dispatch (u.aat, hb_forward (ds)...)); #endif default: return_trace (c->default_return_value ()); @@ -340,7 +340,7 @@ struct kern HBUINT32 version32; HBUINT16 major; KernOT ot; -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT KernAAT aat; #endif } u; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 0d8acc3a5..09b8a582a 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -58,7 +58,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, static bool _hb_apply_morx (hb_face_t *face) { -#ifdef HB_NO_AAT +#ifdef HB_NO_SHAPE_AAT return false; #endif @@ -87,7 +87,7 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE; script_fallback_mark_positioning = shaper->fallback_position; -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (apply_morx) shaper = &_hb_ot_complex_shaper_default; #endif @@ -100,7 +100,7 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, key); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (apply_morx) aat_map.compile (plan.aat_map); #endif @@ -140,13 +140,13 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (0) ; -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT else if (hb_options ().aat && hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; #endif else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face)) plan.apply_gpos = true; -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT else if (hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; #endif @@ -216,7 +216,7 @@ void hb_ot_shape_plan_t::substitute (hb_font_t *font, hb_buffer_t *buffer) const { -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (unlikely (apply_morx)) hb_aat_layout_substitute (this, font, buffer); else @@ -230,7 +230,7 @@ hb_ot_shape_plan_t::position (hb_font_t *font, { if (this->apply_gpos) map.position (this, font, buffer); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT else if (this->apply_kerx) hb_aat_layout_position (this, font, buffer); #endif @@ -239,7 +239,7 @@ hb_ot_shape_plan_t::position (hb_font_t *font, else _hb_ot_shape_fallback_kern (this, font, buffer); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (this->apply_trak) hb_aat_layout_track (this, font, buffer); #endif @@ -338,7 +338,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, feature->value); } -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (planner->apply_morx) { hb_aat_map_builder_t *aat_map = &planner->aat_map; @@ -783,7 +783,7 @@ static inline void hb_ot_substitute_post (const hb_ot_shape_context_t *c) { hb_ot_hide_default_ignorables (c->buffer, c->font); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (c->plan->apply_morx) hb_aat_layout_remove_deleted_glyphs (c->buffer); #endif @@ -920,7 +920,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) /* Finish off. Has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); hb_ot_zero_width_default_ignorables (c->buffer); -#ifndef HB_NO_AAT +#ifndef HB_NO_SHAPE_AAT if (c->plan->apply_morx) hb_aat_layout_zero_width_deleted_glyphs (c->buffer); #endif From 784df8eba1aaf20d2db464f8b3ea0984f7ea1308 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:04:59 -0700 Subject: [PATCH 317/336] [config] Flesh out more Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 03f1ba247..00a18e2d8 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -32,7 +32,16 @@ #endif +#ifdef HB_TINY +#define HB_MINI +#define HB_NO_BITMAP +#define HB_NO_CFF +#endif +#ifdef HB_MINI +#define HB_NO_AAT +#define HB_NO_FALLBACK +#endif /* Closure. */ @@ -50,5 +59,13 @@ #define HB_NO_SUBSET_CFF #endif +#ifdef HB_NO_FALLBACK +#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK +#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK +#define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK +#define HB_NO_OT_SHAPE_FALLBACK +#define HB_NO_OT_SHAPE_FALLBACK +#endif + #endif /* HB_CONFIG_HH */ From 0bfd14c0ed2f95f00d0b94d396c777399afa4d68 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:06:57 -0700 Subject: [PATCH 318/336] [config] Fix tests --- src/hb-config.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 00a18e2d8..6c7a4eb0c 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -27,6 +27,9 @@ #ifndef HB_CONFIG_HH #define HB_CONFIG_HH +#if 0 /* Make test happy. */ +#include "hb.hh" +#endif #ifdef HAVE_CONFIG_H #include "config.h" #endif From 484f6e8215038006a945da67d245f14db3eeeb2e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:13:35 -0700 Subject: [PATCH 319/336] [config] Add HB_LEAN Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 5 +++++ src/hb-ot-math.cc | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 6c7a4eb0c..b13215abf 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -36,9 +36,14 @@ #ifdef HB_TINY +#define HB_LEAN #define HB_MINI +#endif + +#ifdef HB_LEAN #define HB_NO_BITMAP #define HB_NO_CFF +#define HB_NO_MATH #endif #ifdef HB_MINI diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index bd31bf565..b06824a6e 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -58,6 +58,10 @@ hb_bool_t hb_ot_math_has_data (hb_face_t *face) { +#ifdef HB_NO_MATH + return false; +#endif + return face->table.MATH->has_data (); } @@ -80,6 +84,10 @@ hb_position_t hb_ot_math_get_constant (hb_font_t *font, hb_ot_math_constant_t constant) { +#ifdef HB_NO_MATH + return 0; +#endif + return font->face->table.MATH->get_constant(constant, font); } @@ -96,6 +104,10 @@ hb_position_t hb_ot_math_get_glyph_italics_correction (hb_font_t *font, hb_codepoint_t glyph) { +#ifdef HB_NO_MATH + return 0; +#endif + return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font); } @@ -112,6 +124,10 @@ hb_position_t hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, hb_codepoint_t glyph) { +#ifdef HB_NO_MATH + return 0; +#endif + return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font); } @@ -128,6 +144,10 @@ hb_bool_t hb_ot_math_is_glyph_extended_shape (hb_face_t *face, hb_codepoint_t glyph) { +#ifdef HB_NO_MATH + return false; +#endif + return face->table.MATH->get_glyph_info().is_extended_shape (glyph); } @@ -154,6 +174,10 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font, hb_ot_math_kern_t kern, hb_position_t correction_height) { +#ifdef HB_NO_MATH + return 0; +#endif + return font->face->table.MATH->get_glyph_info().get_kerning (glyph, kern, correction_height, @@ -187,6 +211,12 @@ hb_ot_math_get_glyph_variants (hb_font_t *font, unsigned int *variants_count, /* IN/OUT */ hb_ot_math_glyph_variant_t *variants /* OUT */) { +#ifdef HB_NO_MATH + if (variants_count) + *variants_count = 0; + return 0; +#endif + return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font, start_offset, variants_count, @@ -211,6 +241,10 @@ hb_position_t hb_ot_math_get_min_connector_overlap (hb_font_t *font, hb_direction_t direction) { +#ifdef HB_NO_MATH + return 0; +#endif + return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font); } @@ -243,6 +277,12 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font, hb_ot_math_glyph_part_t *parts, /* OUT */ hb_position_t *italics_correction /* OUT */) { +#ifdef HB_NO_MATH + if (parts_count) + *parts_count = 0; + return 0; +#endif + return font->face->table.MATH->get_variants().get_glyph_parts (glyph, direction, font, From 771f1b21d1d7128440d6b4488705456d43dbc0e7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:16:18 -0700 Subject: [PATCH 320/336] [config] Adjust --- src/hb-config.hh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index b13215abf..7e5abd0a2 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -48,10 +48,9 @@ #ifdef HB_MINI #define HB_NO_AAT -#define HB_NO_FALLBACK +#define HB_NO_LEGACY #endif - /* Closure. */ #ifdef HB_NO_AAT @@ -67,12 +66,15 @@ #define HB_NO_SUBSET_CFF #endif -#ifdef HB_NO_FALLBACK +#ifdef HB_NO_LEGACY +#define HB_NO_OT_LAYOUT_BLACKLIST +#define HB_NO_OT_SHAPE_FALLBACK +#endif + +#ifdef HB_NO_OT_SHAPE_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK -#define HB_NO_OT_SHAPE_FALLBACK -#define HB_NO_OT_SHAPE_FALLBACK #endif From 5a48611ccd045de5782ad2fd5f6718357fe232a2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:19:03 -0700 Subject: [PATCH 321/336] [config] Add HB_NO_OT_LAYOUT_UNUSED Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 1 + src/hb-ot-layout.cc | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 7e5abd0a2..bd1becb79 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -44,6 +44,7 @@ #define HB_NO_BITMAP #define HB_NO_CFF #define HB_NO_MATH +#define HB_NO_OT_LAYOUT_UNUSED #endif #ifdef HB_MINI diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index cd603d8d0..25ad22625 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -335,6 +335,12 @@ hb_ot_layout_get_attach_points (hb_face_t *face, unsigned int *point_count /* IN/OUT */, unsigned int *point_array /* OUT */) { +#ifdef HB_NO_OT_LAYOUT_UNUSED + if (point_count) + *point_count = 0; + return 0; +#endif + return face->table.GDEF->table->get_attach_points (glyph, start_offset, point_count, @@ -364,6 +370,12 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) { +#ifdef HB_NO_OT_LAYOUT_UNUSED + if (caret_count) + *caret_count = 0; + return 0; +#endif + unsigned int result_caret_count = 0; unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array); if (result) From fca27860417812d51e40f040de97c10177b1250e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:37:01 -0700 Subject: [PATCH 322/336] [config] Make HB_DISABLE_DEPRECATED actually compile Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 7 +++++++ src/hb-font.cc | 8 ++++++++ src/hb-font.hh | 12 ++++++++++-- src/hb-graphite2.cc | 2 ++ src/hb-icu.cc | 2 +- src/hb-ot-layout.cc | 7 ++++++- src/hb-ot-shape-fallback.cc | 4 ++++ src/hb-ot-tag.cc | 4 ++++ src/hb-ot-var-fvar-table.hh | 6 ++++++ src/hb-ot-var.cc | 2 ++ src/hb-set.cc | 2 ++ src/hb-unicode.cc | 6 ++++++ src/hb-unicode.hh | 10 +++++++--- 13 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index bd1becb79..087e669c9 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -41,6 +41,7 @@ #endif #ifdef HB_LEAN +#define HB_DISABLE_DEPRECATED #define HB_NO_BITMAP #define HB_NO_CFF #define HB_NO_MATH @@ -54,6 +55,12 @@ /* Closure. */ +#ifdef HB_DISABLE_DEPRECATED +#define HB_IF_NOT_DEPRECATED(x) +#else +#define HB_IF_NOT_DEPRECATED(x) x +#endif + #ifdef HB_NO_AAT #define HB_NO_SHAPE_AAT #endif diff --git a/src/hb-font.cc b/src/hb-font.cc index c00f33329..19ee353eb 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -336,6 +336,7 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font, return ret; } +#ifndef HB_DISABLE_DEPRECATED static hb_position_t hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, @@ -373,6 +374,7 @@ hb_font_get_glyph_v_kerning_default (hb_font_t *font, { return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); } +#endif static hb_bool_t hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, @@ -925,6 +927,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font, return font->get_glyph_v_origin (glyph, x, y); } +#ifndef HB_DISABLE_DEPRECATED /** * hb_font_get_glyph_h_kerning: * @font: a font. @@ -964,6 +967,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, { return font->get_glyph_v_kerning (top_glyph, bottom_glyph); } +#endif /** * hb_font_get_glyph_extents: @@ -1173,6 +1177,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); } +#ifndef HB_DISABLE_DEPRECATED /** * hb_font_get_glyph_kerning_for_direction: * @font: a font. @@ -1195,6 +1200,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, { return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); } +#endif /** * hb_font_get_glyph_extents_for_origin: @@ -1916,6 +1922,7 @@ hb_font_get_var_coords_normalized (hb_font_t *font, } +#ifndef HB_DISABLE_DEPRECATED /* * Deprecated get_glyph_func(): */ @@ -2038,3 +2045,4 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, trampoline, trampoline_destroy); } +#endif diff --git a/src/hb-font.hh b/src/hb-font.hh index 4f5aa8a60..95551bfd2 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -51,8 +51,8 @@ HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \ HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \ + HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning)) \ + HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \ HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ HB_FONT_FUNC_IMPLEMENT (glyph_name) \ @@ -304,17 +304,25 @@ struct hb_font_t hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) { +#ifdef HB_DISABLE_DEPRECATED + return 0; +#else return klass->get.f.glyph_h_kerning (this, user_data, left_glyph, right_glyph, klass->user_data.glyph_h_kerning); +#endif } hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) { +#ifdef HB_DISABLE_DEPRECATED + return 0; +#else return klass->get.f.glyph_v_kerning (this, user_data, top_glyph, bottom_glyph, klass->user_data.glyph_v_kerning); +#endif } hb_bool_t get_glyph_extents (hb_codepoint_t glyph, diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index fdb545342..5b1ba4515 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -202,6 +202,7 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED { } +#ifndef HB_DISABLE_DEPRECATED /** * hb_graphite2_font_get_gr_font: * @@ -213,6 +214,7 @@ hb_graphite2_font_get_gr_font (hb_font_t *font HB_UNUSED) { return nullptr; } +#endif /* diff --git a/src/hb-icu.cc b/src/hb-icu.cc index c26c91d48..99305ae55 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -236,7 +236,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, /* We don't ifdef-out the fallback code such that compiler always * sees it and makes sure it's compilable. */ - UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1]; + UChar utf16[2], normalized[2 * 19/*HB_UNICODE_MAX_DECOMPOSITION_LEN*/ + 1]; unsigned int len; hb_bool_t ret, err; UErrorCode icu_err; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 25ad22625..acc996158 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -512,6 +512,7 @@ hb_ot_layout_table_find_script (hb_face_t *face, return false; } +#ifndef HB_DISABLE_DEPRECATED /** * hb_ot_layout_table_choose_script: * @face: #hb_face_t to work upon @@ -533,6 +534,7 @@ hb_ot_layout_table_choose_script (hb_face_t *face, for (t = script_tags; *t; t++); return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script); } +#endif /** * hb_ot_layout_table_select_script: @@ -684,6 +686,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, } +#ifndef HB_DISABLE_DEPRECATED /** * hb_ot_layout_script_find_language: * @face: #hb_face_t to work upon @@ -697,6 +700,8 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, * * Return value: true if the language tag is found, false otherwise * + * Since: ?? + * Deprecated: ?? **/ hb_bool_t hb_ot_layout_script_find_language (hb_face_t *face, @@ -712,6 +717,7 @@ hb_ot_layout_script_find_language (hb_face_t *face, &language_tag, language_index); } +#endif /** @@ -728,7 +734,6 @@ hb_ot_layout_script_find_language (hb_face_t *face, * * Return value: true if the language tag is found, false otherwise * - * * Since: 2.0.0 **/ hb_bool_t diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 42b728fd1..573af8ec6 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -456,6 +456,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, } +#ifndef HB_DISABLE_DEPRECATED struct hb_ot_shape_fallback_kern_driver_t { hb_ot_shape_fallback_kern_driver_t (hb_font_t *font_, @@ -474,6 +475,7 @@ struct hb_ot_shape_fallback_kern_driver_t hb_font_t *font; hb_direction_t direction; }; +#endif /* Performs font-assisted kerning. */ void @@ -485,6 +487,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, return; #endif +#ifndef HB_DISABLE_DEPRECATED if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ? !font->has_glyph_h_kerning_func () : !font->has_glyph_v_kerning_func ()) @@ -501,6 +504,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, if (reverse) buffer->reverse (); +#endif } diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc index 4b42da42d..ad3635bda 100644 --- a/src/hb-ot-tag.cc +++ b/src/hb-ot-tag.cc @@ -113,6 +113,7 @@ hb_ot_new_tag_to_script (hb_tag_t tag) return HB_SCRIPT_UNKNOWN; } +#ifndef HB_DISABLE_DEPRECATED void hb_ot_tags_from_script (hb_script_t script, hb_tag_t *script_tag_1, @@ -124,6 +125,7 @@ hb_ot_tags_from_script (hb_script_t script, *script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT; *script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT; } +#endif /* * Complete list at: @@ -230,6 +232,7 @@ struct LangTag /*{"??", {HB_TAG('Y','I','C',' ')}},*/ /* Yi Classic */ /*{"zh?", {HB_TAG('Z','H','P',' ')}},*/ /* Chinese Phonetic */ +#ifndef HB_DISABLE_DEPRECATED hb_tag_t hb_ot_tag_from_language (hb_language_t language) { @@ -238,6 +241,7 @@ hb_ot_tag_from_language (hb_language_t language) hb_ot_tags_from_script_and_language (HB_SCRIPT_UNKNOWN, language, nullptr, nullptr, &count, tags); return count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_LANGUAGE; } +#endif static void hb_ot_tags_from_language (const char *lang_str, diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index c73348ef4..aa89dce26 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -114,6 +114,7 @@ struct fvar unsigned int get_axis_count () const { return axisCount; } +#ifndef HB_DISABLE_DEPRECATED void get_axis_deprecated (unsigned int axis_index, hb_ot_var_axis_t *info) const { @@ -125,6 +126,7 @@ struct fvar info->min_value = hb_min (info->default_value, axis.minValue / 65536.f); info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f); } +#endif void get_axis_info (unsigned int axis_index, hb_ot_var_axis_info_t *info) const @@ -141,6 +143,7 @@ struct fvar info->reserved = 0; } +#ifndef HB_DISABLE_DEPRECATED unsigned int get_axes_deprecated (unsigned int start_offset, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */) const @@ -162,6 +165,7 @@ struct fvar } return axisCount; } +#endif unsigned int get_axis_infos (unsigned int start_offset, unsigned int *axes_count /* IN/OUT */, @@ -185,6 +189,7 @@ struct fvar return axisCount; } +#ifndef HB_DISABLE_DEPRECATED bool find_axis_deprecated (hb_tag_t tag, unsigned int *axis_index, hb_ot_var_axis_t *info) const @@ -203,6 +208,7 @@ struct fvar *axis_index = HB_OT_VAR_NO_AXIS_INDEX; return false; } +#endif bool find_axis_info (hb_tag_t tag, hb_ot_var_axis_info_t *info) const diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index e327fb762..25a246a21 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -75,6 +75,7 @@ hb_ot_var_get_axis_count (hb_face_t *face) return face->table.fvar->get_axis_count (); } +#ifndef HB_DISABLE_DEPRECATED /** * hb_ot_var_get_axes: * @@ -104,6 +105,7 @@ hb_ot_var_find_axis (hb_face_t *face, { return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info); } +#endif /** * hb_ot_var_get_axis_infos: diff --git a/src/hb-set.cc b/src/hb-set.cc index 068236264..fa9868809 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -389,6 +389,7 @@ hb_set_symmetric_difference (hb_set_t *set, set->symmetric_difference (other); } +#ifndef HB_DISABLE_DEPRECATED /** * hb_set_invert: * @set: a set. @@ -403,6 +404,7 @@ void hb_set_invert (hb_set_t *set HB_UNUSED) { } +#endif /** * hb_set_get_population: diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index d32cace64..94106faee 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -60,6 +60,7 @@ hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED; } +#ifndef HB_DISABLE_DEPRECATED static unsigned int hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t unicode HB_UNUSED, @@ -67,6 +68,7 @@ hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, { return 1; } +#endif static hb_unicode_general_category_t hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, @@ -113,6 +115,7 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, } +#ifndef HB_DISABLE_DEPRECATED static unsigned int hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, hb_codepoint_t u HB_UNUSED, @@ -121,6 +124,7 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED { return 0; } +#endif extern "C" hb_unicode_funcs_t *hb_glib_get_unicode_funcs (); @@ -425,6 +429,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, return ufuncs->decompose (ab, a, b); } +#ifndef HB_DISABLE_DEPRECATED /** * hb_unicode_decompose_compatibility: * @ufuncs: Unicode functions. @@ -445,6 +450,7 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, { return ufuncs->decompose_compatibility (u, decomposed); } +#endif /* See hb-unicode.hh for details. */ diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh index 82ebb1064..80624c0ec 100644 --- a/src/hb-unicode.hh +++ b/src/hb-unicode.hh @@ -42,19 +42,19 @@ extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256]; #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \ HB_UNICODE_FUNC_IMPLEMENT (combining_class) \ - HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \ + HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (eastasian_width)) \ HB_UNICODE_FUNC_IMPLEMENT (general_category) \ HB_UNICODE_FUNC_IMPLEMENT (mirroring) \ HB_UNICODE_FUNC_IMPLEMENT (script) \ HB_UNICODE_FUNC_IMPLEMENT (compose) \ HB_UNICODE_FUNC_IMPLEMENT (decompose) \ - HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \ + HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility)) \ /* ^--- Add new callbacks here */ /* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */ #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \ HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \ - HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \ + HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width)) \ HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \ HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \ HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \ @@ -89,7 +89,11 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE unsigned int decompose_compatibility (hb_codepoint_t u, hb_codepoint_t *decomposed) { +#ifdef HB_DISABLE_DEPRECATED + unsigned int ret = 0; +#else unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility); +#endif if (ret == 1 && u == decomposed[0]) { decomposed[0] = 0; return 0; From 42a21284778f3203d96133f74b0f846cd1567958 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:44:22 -0700 Subject: [PATCH 323/336] [config] Disbale getenv() and atexit() if HB_LEAN Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 087e669c9..2eada9877 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -42,8 +42,10 @@ #ifdef HB_LEAN #define HB_DISABLE_DEPRECATED +#define HB_NO_ATEXIT #define HB_NO_BITMAP #define HB_NO_CFF +#define HB_NO_GETENV #define HB_NO_MATH #define HB_NO_OT_LAYOUT_UNUSED #endif From b63a8e173cbc5a81f2ca4a0a82f20b9dafaedb30 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:47:20 -0700 Subject: [PATCH 324/336] [config Add HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS to LEAN Already I don't like the inflexibility of this approach :(. Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 2eada9877..6393f56e2 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -85,6 +85,7 @@ #define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK +#define HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS #endif From 81b79dfc397599182f43d63bf9346eee28e2d220 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 00:53:52 -0700 Subject: [PATCH 325/336] [config] Add HB_NO_COLOR to HB_LEAN Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 1 + src/hb-ot-color.cc | 49 ++++++++++++++++++++++++++++++++++++++++++---- src/hb-ot-color.h | 2 +- src/hb-ot-layout.h | 2 +- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index 6393f56e2..ae7ca17da 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -45,6 +45,7 @@ #define HB_NO_ATEXIT #define HB_NO_BITMAP #define HB_NO_CFF +#define HB_NO_COLOR #define HB_NO_GETENV #define HB_NO_MATH #define HB_NO_OT_LAYOUT_UNUSED diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 791135b10..5341a53f2 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -66,6 +66,9 @@ hb_bool_t hb_ot_color_has_palettes (hb_face_t *face) { +#ifdef HB_NO_COLOR + return false; +#endif return face->table.CPAL->has_data (); } @@ -81,6 +84,9 @@ hb_ot_color_has_palettes (hb_face_t *face) unsigned int hb_ot_color_palette_get_count (hb_face_t *face) { +#ifdef HB_NO_COLOR + return 0; +#endif return face->table.CPAL->get_palette_count (); } @@ -101,6 +107,9 @@ hb_ot_name_id_t hb_ot_color_palette_get_name_id (hb_face_t *face, unsigned int palette_index) { +#ifdef HB_NO_COLOR + return HB_OT_NAME_ID_INVALID; +#endif return face->table.CPAL->get_palette_name_id (palette_index); } @@ -117,6 +126,9 @@ hb_ot_name_id_t hb_ot_color_palette_color_get_name_id (hb_face_t *face, unsigned int color_index) { +#ifdef HB_NO_COLOR + return HB_OT_NAME_ID_INVALID; +#endif return face->table.CPAL->get_color_name_id (color_index); } @@ -133,6 +145,9 @@ hb_ot_color_palette_flags_t hb_ot_color_palette_get_flags (hb_face_t *face, unsigned int palette_index) { +#ifdef HB_NO_COLOR + return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; +#endif return face->table.CPAL->get_palette_flags (palette_index); } @@ -167,6 +182,11 @@ hb_ot_color_palette_get_colors (hb_face_t *face, unsigned int *colors_count /* IN/OUT. May be NULL. */, hb_color_t *colors /* OUT. May be NULL. */) { +#ifdef HB_NO_COLOR + if (colors_count) + *colors_count = 0; + return 0; +#endif return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors); } @@ -186,6 +206,9 @@ hb_ot_color_palette_get_colors (hb_face_t *face, hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { +#ifdef HB_NO_COLOR + return false; +#endif return face->table.COLR->has_data (); } @@ -194,9 +217,9 @@ hb_ot_color_has_layers (hb_face_t *face) * @face: a font face. * @glyph: a layered color glyph id. * @start_offset: starting offset of layers. - * @count: (inout) (optional): gets number of layers available to be written on buffer + * @layer_count: (inout) (optional): gets number of layers available to be written on buffer * and returns number of written layers. - * @layers: (array length=count) (out) (optional): layers buffer to buffer. + * @layers: (array length=layer_count) (out) (optional): layers buffer to buffer. * * Returns: Total number of layers a layered color glyph have. * @@ -206,10 +229,15 @@ unsigned int hb_ot_color_glyph_get_layers (hb_face_t *face, hb_codepoint_t glyph, unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ + unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) { - return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers); +#ifdef HB_NO_COLOR + if (layer_count) + *layer_count = 0; + return 0; +#endif + return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers); } @@ -230,6 +258,9 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, hb_bool_t hb_ot_color_has_svg (hb_face_t *face) { +#ifdef HB_NO_COLOR + return false; +#endif return face->table.SVG->has_data (); } @@ -247,6 +278,9 @@ hb_ot_color_has_svg (hb_face_t *face) hb_blob_t * hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) { +#ifdef HB_NO_COLOR + return hb_blob_get_empty (); +#endif return face->table.SVG->reference_blob_for_glyph (glyph); } @@ -268,6 +302,9 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) hb_bool_t hb_ot_color_has_png (hb_face_t *face) { +#ifdef HB_NO_COLOR + return false; +#endif return face->table.CBDT->has_data () || face->table.sbix->has_data (); } @@ -287,6 +324,10 @@ hb_ot_color_has_png (hb_face_t *face) hb_blob_t * hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) { +#ifdef HB_NO_COLOR + return hb_blob_get_empty (); +#endif + hb_blob_t *blob = hb_blob_get_empty (); if (font->face->table.sbix->has_data ()) diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 49646bf3a..0d7daa5d3 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -110,7 +110,7 @@ HB_EXTERN unsigned int hb_ot_color_glyph_get_layers (hb_face_t *face, hb_codepoint_t glyph, unsigned int start_offset, - unsigned int *count, /* IN/OUT. May be NULL. */ + unsigned int *layer_count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */); /* diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 359ee1b6f..3b9a78eaf 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -94,7 +94,7 @@ HB_EXTERN hb_bool_t hb_ot_layout_has_glyph_classes (hb_face_t *face); /** - * hb_ot_layout_get_glyph_class: + * hb_ot_layout_glyph_class_t: * @HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: Glyphs not matching the other classifications * @HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: Spacing, single characters, capable of accepting marks * @HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: Glyphs that represent ligation of multiple characters From 9c921e6c32ab5ac4c524f554b7a7841eeeb0908f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 01:08:51 -0700 Subject: [PATCH 326/336] [config] Enable HB_NO_NAME_TABLE_AAT Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index ae7ca17da..8d71a1102 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -48,6 +48,7 @@ #define HB_NO_COLOR #define HB_NO_GETENV #define HB_NO_MATH +#define HB_NO_NAME_TABLE_AAT #define HB_NO_OT_LAYOUT_UNUSED #endif @@ -65,6 +66,7 @@ #endif #ifdef HB_NO_AAT +#define HB_NO_NAME_TABLE_AAT #define HB_NO_SHAPE_AAT #endif From 4381bb2de7a554a148302836b86a5d73264abeae Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 01:14:04 -0700 Subject: [PATCH 327/336] [config] Comment --- src/hb-config.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 8d71a1102..09f71155b 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -38,6 +38,7 @@ #ifdef HB_TINY #define HB_LEAN #define HB_MINI +//#define HB_NO_MT /* Let user choose */ #endif #ifdef HB_LEAN From 1fc077211771c752768f63f178116d2b8f2f7d03 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 01:24:23 -0700 Subject: [PATCH 328/336] [config] HB_NO_OT_NAME_LANGUAGE AAT --- src/hb-config.hh | 4 ++-- src/hb-ot-name-language-static.hh | 3 +++ src/hb-ot-name-table.hh | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index 09f71155b..40a0baef1 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -49,7 +49,7 @@ #define HB_NO_COLOR #define HB_NO_GETENV #define HB_NO_MATH -#define HB_NO_NAME_TABLE_AAT +#define HB_NO_OT_NAME_LANGUAGE #define HB_NO_OT_LAYOUT_UNUSED #endif @@ -67,7 +67,7 @@ #endif #ifdef HB_NO_AAT -#define HB_NO_NAME_TABLE_AAT +#define HB_NO_OT_NAME_LANGUAGE_AAT #define HB_NO_SHAPE_AAT #endif diff --git a/src/hb-ot-name-language-static.hh b/src/hb-ot-name-language-static.hh index fac317856..580e7637b 100644 --- a/src/hb-ot-name-language-static.hh +++ b/src/hb-ot-name-language-static.hh @@ -430,6 +430,9 @@ _hb_ot_name_language_for (unsigned int code, const hb_ot_language_map_t *array, unsigned int len) { +#ifdef HB_NO_OT_NAME_LANGUAGE + return HB_LANGUAGE_INVALID; +#endif const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) hb_bsearch (&code, array, diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index e7e32ecf8..332f48533 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -51,6 +51,7 @@ struct NameRecord { hb_language_t language (hb_face_t *face) const { +#ifndef HB_NO_OT_NAME_LANGUAGE unsigned int p = platformID; unsigned int l = languageID; @@ -60,11 +61,12 @@ struct NameRecord if (p == 1) return _hb_ot_name_language_for_mac_code (l); -#ifndef HB_NO_NAME_TABLE_AAT +#ifndef HB_NO_OT_NAME_LANGUAGE_AAT if (p == 0) return _hb_aat_language_get (face, l); #endif +#endif return HB_LANGUAGE_INVALID; } From 0e78d4ddaec5f29d6652cc4185cbcca98c3a2927 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 01:27:50 -0700 Subject: [PATCH 329/336] [config] Add HB_NO_NAME Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-config.hh | 6 +++++- src/hb-ot-name.cc | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index 40a0baef1..86f7b0105 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -49,7 +49,7 @@ #define HB_NO_COLOR #define HB_NO_GETENV #define HB_NO_MATH -#define HB_NO_OT_NAME_LANGUAGE +#define HB_NO_NAME #define HB_NO_OT_LAYOUT_UNUSED #endif @@ -85,6 +85,10 @@ #define HB_NO_OT_SHAPE_FALLBACK #endif +#ifdef HB_NO_NAME +#define HB_NO_OT_NAME_LANGUAGE +#endif + #ifdef HB_NO_OT_SHAPE_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK #define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index 907ae6ab5..f7cd427ac 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -58,6 +58,11 @@ const hb_ot_name_entry_t * hb_ot_name_list_names (hb_face_t *face, unsigned int *num_entries /* OUT */) { +#ifdef HB_NO_NAME + if (num_entries) + *num_entries = 0; + return 0; +#endif const OT::name_accelerator_t &name = *face->table.name; if (num_entries) *num_entries = name.names.length; return (const hb_ot_name_entry_t *) name.names; @@ -167,6 +172,11 @@ hb_ot_name_get_utf8 (hb_face_t *face, unsigned int *text_size /* IN/OUT */, char *text /* OUT */) { +#ifdef HB_NO_NAME + if (text_size) + *text_size = 0; + return 0; +#endif return hb_ot_name_get_utf (face, name_id, language, text_size, (hb_utf8_t::codepoint_t *) text); } @@ -194,6 +204,11 @@ hb_ot_name_get_utf16 (hb_face_t *face, unsigned int *text_size /* IN/OUT */, uint16_t *text /* OUT */) { +#ifdef HB_NO_NAME + if (text_size) + *text_size = 0; + return 0; +#endif return hb_ot_name_get_utf (face, name_id, language, text_size, text); } @@ -220,5 +235,10 @@ hb_ot_name_get_utf32 (hb_face_t *face, unsigned int *text_size /* IN/OUT */, uint32_t *text /* OUT */) { +#ifdef HB_NO_NAME + if (text_size) + *text_size = 0; + return 0; +#endif return hb_ot_name_get_utf (face, name_id, language, text_size, text); } From 7f45ce42dbf11366e904f48db45cf5405e4e94df Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 01:28:31 -0700 Subject: [PATCH 330/336] [config] Rename --- src/hb-config.hh | 2 +- src/hb-ot-layout.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index 86f7b0105..836d0cdb1 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -50,7 +50,7 @@ #define HB_NO_GETENV #define HB_NO_MATH #define HB_NO_NAME -#define HB_NO_OT_LAYOUT_UNUSED +#define HB_NO_LAYOUT_UNUSED #endif #ifdef HB_MINI diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index acc996158..f5c11d8b3 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -335,7 +335,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, unsigned int *point_count /* IN/OUT */, unsigned int *point_array /* OUT */) { -#ifdef HB_NO_OT_LAYOUT_UNUSED +#ifdef HB_NO_LAYOUT_UNUSED if (point_count) *point_count = 0; return 0; @@ -370,7 +370,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) { -#ifdef HB_NO_OT_LAYOUT_UNUSED +#ifdef HB_NO_LAYOUT_UNUSED if (caret_count) *caret_count = 0; return 0; From 79126df3070f00193fe3caefe9deb62c4520e048 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 11:23:31 -0700 Subject: [PATCH 331/336] [iter] Add hb_map_sorted() and hb_map_retains_sorting() --- src/hb-iter.hh | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 194a421ff..77edd1a0a 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -345,16 +345,24 @@ operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward (rhs) (hb_forw /* hb_map(), hb_filter(), hb_reduce() */ -template struct hb_map_iter_t : - hb_iter_t, + hb_iter_t, decltype (hb_get (hb_declval (Proj), *hb_declval (Iter)))> { hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {} typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__; static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; + static constexpr bool is_sorted_iterator = + Sorted == SORTED ? true : Sorted == RETAINS_SORTING ? Iter::is_sorted_iterator : false; __item_t__ __item__ () const { return hb_get (f.get (), *it); } __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); } bool __more__ () const { return bool (it); } @@ -372,16 +380,16 @@ struct hb_map_iter_t : hb_reference_wrapper f; }; -template +template struct hb_map_iter_factory_t { hb_map_iter_factory_t (Proj f) : f (f) {} template - hb_map_iter_t + hb_map_iter_t operator () (Iter it) - { return hb_map_iter_t (it, f); } + { return hb_map_iter_t (it, f); } private: Proj f; @@ -389,11 +397,27 @@ struct hb_map_iter_factory_t struct { template - hb_map_iter_factory_t + hb_map_iter_factory_t operator () (Proj&& f) const - { return hb_map_iter_factory_t (f); } + { return hb_map_iter_factory_t (f); } } HB_FUNCOBJ (hb_map); +struct +{ + template + hb_map_iter_factory_t + operator () (Proj&& f) const + { return hb_map_iter_factory_t (f); } +} +HB_FUNCOBJ (hb_map_retains_sorting); +struct +{ + template + hb_map_iter_factory_t + operator () (Proj&& f) const + { return hb_map_iter_factory_t (f); } +} +HB_FUNCOBJ (hb_map_sorted); template From b854d4ff46602104343201361919f30169144cf1 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Fri, 10 May 2019 22:51:49 -0400 Subject: [PATCH 332/336] [array] Fix rewinding --- src/hb-array.hh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 003fc5bed..705bc6a46 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -42,20 +42,20 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> /* * Constructors. */ - hb_array_t () : arrayZ (nullptr), length (0) {} - hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} + hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {} + hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {} template - hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} + hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {} template hb_array_t (const hb_array_t &o) : hb_iter_with_fallback_t, Type&> (), - arrayZ (o.arrayZ), length (o.length) {} + arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {} template hb_array_t& operator = (const hb_array_t &o) - { arrayZ = o.arrayZ; length = o.length; return *this; } + { arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; } /* * Iterator implementation. @@ -72,17 +72,20 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> if (unlikely (n > length)) n = length; length -= n; + backwards_length += n; arrayZ += n; } void __rewind__ (unsigned n) { - if (unlikely (n > length)) - n = length; - length -= n; + if (unlikely (n > backwards_length)) + n = backwards_length; + length += n; + backwards_length -= n; + arrayZ -= n; } unsigned __len__ () const { return length; } bool operator != (const hb_array_t& o) const - { return arrayZ != o.arrayZ || length != o.length; } + { return arrayZ != o.arrayZ || length != o.length || backwards_length != o.backwards_length; } /* Extra operators. */ @@ -199,6 +202,7 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> public: Type *arrayZ; unsigned int length; + unsigned int backwards_length; }; template inline hb_array_t hb_array (T *array, unsigned int length) From c1c122e7b3f60dc7b5a224c68d2acb106fda8b49 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Sat, 11 May 2019 11:38:06 -0400 Subject: [PATCH 333/336] [iter] Fix filter rewinding --- src/hb-iter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 77edd1a0a..1b5c427df 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -433,7 +433,7 @@ struct hb_filter_iter_t : __item_t__ __item__ () const { return *it; } bool __more__ () const { return bool (it); } void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } - void __prev__ () { --it; } + void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); } hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); } bool operator != (const hb_filter_iter_t& o) const { return it != o.it || p != o.p || f != o.f; } From 606841b07017ac80dea2fc5ada25b5976f2f9192 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 11:54:30 -0700 Subject: [PATCH 334/336] [iter] Check for more before forwarding/rewinding past ends --- src/hb-iter.hh | 4 ++-- src/test-iter.cc | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 1b5c427df..dcc49ee5d 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -196,11 +196,11 @@ struct hb_iter_fallback_mixin_t /* Advancing: Implement __next__(), or __forward__() if random-access. */ void __next__ () { *thiz() += 1; } - void __forward__ (unsigned n) { while (n--) ++*thiz(); } + void __forward__ (unsigned n) { while (*thiz() && n--) ++*thiz(); } /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */ void __prev__ () { *thiz() -= 1; } - void __rewind__ (unsigned n) { while (n--) --*thiz(); } + void __rewind__ (unsigned n) { while (*thiz() && n--) --*thiz(); } /* Range-based for: Implement __end__() if can be done faster, * and operator!=. */ diff --git a/src/test-iter.cc b/src/test-iter.cc index d9e2a97f1..f834640ff 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -82,10 +82,8 @@ test_iterator_non_default_constructable (Iter it) (void) _; it += it.len (); - if (0) - it = it + 10; - if (0) - it = 10 + it; + it = it + 10; + it = 10 + it; assert (*it == it[0]); From 32d3c06b61f2f4252f4403b55c6ba07fbb572149 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 11:59:18 -0700 Subject: [PATCH 335/336] Disable sbix if no-color or no-ot-font-bitmap Part of https://github.com/harfbuzz/harfbuzz/issues/1652 --- src/hb-ot-font.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 5051fa0ea..f5a676bb1 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -180,19 +180,20 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; - bool ret = ot_face->sbix->get_extents (font, glyph, extents); - if (!ret) - ret = ot_face->glyf->get_extents (glyph, extents); + bool ret = false; + +#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) + if (!ret) ot_face->sbix->get_extents (font, glyph, extents); +#endif + if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); #ifndef HB_NO_OT_FONT_CFF - if (!ret) - ret = ot_face->cff1->get_extents (glyph, extents); - if (!ret) - ret = ot_face->cff2->get_extents (font, glyph, extents); + if (!ret) ret = ot_face->cff1->get_extents (glyph, extents); + if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents); #endif -#ifndef HB_NO_OT_FONT_BITMAP - if (!ret) - ret = ot_face->CBDT->get_extents (font, glyph, extents); +#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) + if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents); #endif + // TODO Hook up side-bearings variations. extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); From a6048e4cd013987ecb846e0683a7cf6f0caa65f9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 11 May 2019 12:11:22 -0700 Subject: [PATCH 336/336] Fix build --- src/hb-ot-font.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index f5a676bb1..3344c4b6b 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -183,7 +183,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, bool ret = false; #if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR) - if (!ret) ot_face->sbix->get_extents (font, glyph, extents); + if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents); #endif if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); #ifndef HB_NO_OT_FONT_CFF