From 371010c5f95ff13132821d707468d457dbaea7a7 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Tue, 30 Nov 2021 12:14:06 +0200 Subject: [PATCH] HarfBuzz: Update to version 3.1.2 --- thirdparty/README.md | 2 +- thirdparty/harfbuzz/src/hb-array.hh | 24 ++++++++++---- thirdparty/harfbuzz/src/hb-map.hh | 22 ++++++++----- .../harfbuzz/src/hb-ot-color-colr-table.hh | 22 ++++++++++--- .../harfbuzz/src/hb-ot-layout-common.hh | 10 +++--- .../harfbuzz/src/hb-ot-layout-gsubgpos.hh | 21 +++++++------ thirdparty/harfbuzz/src/hb-ot-layout.cc | 4 +-- .../harfbuzz/src/hb-ot-post-table-v2subset.hh | 31 ++++++++++++------- thirdparty/harfbuzz/src/hb-sanitize.hh | 15 +++++++++ thirdparty/harfbuzz/src/hb-serialize.hh | 4 ++- thirdparty/harfbuzz/src/hb-set.hh | 6 ++-- thirdparty/harfbuzz/src/hb-subset-plan.cc | 20 +++++++++--- thirdparty/harfbuzz/src/hb-subset-plan.hh | 4 +-- thirdparty/harfbuzz/src/hb-version.h | 4 +-- 14 files changed, 130 insertions(+), 59 deletions(-) diff --git a/thirdparty/README.md b/thirdparty/README.md index 03e9885bd00..eea947dadbb 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -201,7 +201,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 3.1.1 (cd5c6cd0419ac5e4de975d6c476fb760bf06d2ce, 2021) +- Version: 3.1.2 (8aed5c21a31eece6a9f3cd775fda8facb6c28b9b, 2021) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index dd61509b2e4..0beffb078f2 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -51,13 +51,19 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> * Constructors. */ hb_array_t () = default; - hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} + hb_array_t (const hb_array_t&) = default; + ~hb_array_t () = default; + hb_array_t& operator= (const hb_array_t&) = default; + hb_array_t& operator= (hb_array_t&&) = default; + + constexpr hb_array_t (std::nullptr_t) : hb_array_t () {} + constexpr hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} template - hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {} + constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {} template - hb_array_t (const hb_array_t &o) : + constexpr hb_array_t (const hb_array_t &o) : hb_iter_with_fallback_t (), arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {} template (array_, length_) {} + hb_sorted_array_t (const hb_sorted_array_t&) = default; + ~hb_sorted_array_t () = default; + hb_sorted_array_t& operator= (const hb_sorted_array_t&) = default; + hb_sorted_array_t& operator= (hb_sorted_array_t&&) = default; + + constexpr hb_sorted_array_t (std::nullptr_t) : hb_sorted_array_t () {} + constexpr 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_) {} + constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} template - hb_sorted_array_t (const hb_array_t &o) : + constexpr hb_sorted_array_t (const hb_array_t &o) : hb_iter_t (), hb_array_t (o) {} template ::value ? hb_int_min (K) : (K) -1, - V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed::value ? hb_int_min (V) : (V) -1> + typename k_invalid_t = K, + typename v_invalid_t = V, + k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed::value ? hb_int_min (K) : (K) -1, + v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed::value ? hb_int_min (V) : (V) -1> struct hb_hashmap_t { static constexpr K INVALID_KEY = kINVALID; @@ -62,8 +64,10 @@ struct hb_hashmap_t hb_copy (o, *this); } - static_assert (std::is_integral::value || hb_is_pointer (K), ""); - static_assert (std::is_integral::value || hb_is_pointer (V), ""); + static_assert (std::is_trivially_copyable::value, ""); + static_assert (std::is_trivially_copyable::value, ""); + static_assert (std::is_trivially_destructible::value, ""); + static_assert (std::is_trivially_destructible::value, ""); struct item_t { @@ -347,20 +351,24 @@ struct hb_hashmap_t */ struct hb_map_t : hb_hashmap_t { using hashmap = hb_hashmap_t; hb_map_t () = default; ~hb_map_t () = default; - hb_map_t (hb_map_t& o) = default; - hb_map_t& operator= (const hb_map_t& other) = default; - hb_map_t& operator= (hb_map_t&& other) = default; + hb_map_t (hb_map_t&) = default; + hb_map_t& operator= (const hb_map_t&) = default; + hb_map_t& operator= (hb_map_t&&) = default; hb_map_t (std::initializer_list> lst) : hashmap (lst) {} template diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index 03476faba7f..a3c55fa8f40 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -38,8 +38,8 @@ */ #define HB_OT_TAG_COLR HB_TAG('C','O','L','R') -#ifndef COLRV1_MAX_NESTING_LEVEL -#define COLRV1_MAX_NESTING_LEVEL 100 +#ifndef HB_COLRV1_MAX_NESTING_LEVEL +#define HB_COLRV1_MAX_NESTING_LEVEL 100 #endif #ifndef COLRV1_ENABLE_SUBSETTING @@ -102,7 +102,7 @@ struct hb_colrv1_closure_context_t : hb_set_t *glyphs_, hb_set_t *layer_indices_, hb_set_t *palette_indices_, - unsigned nesting_level_left_ = COLRV1_MAX_NESTING_LEVEL) : + unsigned nesting_level_left_ = HB_COLRV1_MAX_NESTING_LEVEL) : base (base_), glyphs (glyphs_), layer_indices (layer_indices_), @@ -985,7 +985,7 @@ struct ClipList for (const hb_codepoint_t _ : gids.iter ()) { if (_ == start_gid) continue; - + offset = gid_offset_map.get (_); if (_ == prev_gid + 1 && offset == prev_offset) { @@ -1027,7 +1027,7 @@ struct ClipList const hb_set_t& glyphset = *c->plan->_glyphset; const hb_map_t &glyph_map = *c->plan->glyph_map; - + hb_map_t new_gid_offset_map; hb_set_t new_gids; for (const ClipRecord& record : clips.iter ()) @@ -1062,6 +1062,18 @@ struct ClipList struct Paint { + + template + bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const + { + TRACE_SANITIZE (this); + + if (unlikely (!c->check_start_recursion (HB_COLRV1_MAX_NESTING_LEVEL))) + return_trace (c->no_dispatch_return_value ()); + + return_trace (c->end_recursion (this->dispatch (c, std::forward (ds)...))); + } + template typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 5d98278bedc..882c3ae96f4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -98,7 +98,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, struct hb_prune_langsys_context_t { hb_prune_langsys_context_t (const void *table_, - hb_hashmap_t *script_langsys_map_, + hb_hashmap_t *script_langsys_map_, const hb_map_t *duplicate_feature_map_, hb_set_t *new_collected_feature_indexes_) :table (table_), @@ -137,7 +137,7 @@ struct hb_prune_langsys_context_t public: const void *table; - hb_hashmap_t *script_langsys_map; + hb_hashmap_t *script_langsys_map; const hb_map_t *duplicate_feature_map; hb_set_t *new_feature_indexes; @@ -179,14 +179,14 @@ struct hb_subset_layout_context_t : hb_subset_context_t *subset_context; const hb_tag_t table_tag; const hb_map_t *lookup_index_map; - const hb_hashmap_t *script_langsys_map; + const hb_hashmap_t *script_langsys_map; const hb_map_t *feature_index_map; unsigned cur_script_index; hb_subset_layout_context_t (hb_subset_context_t *c_, hb_tag_t tag_, hb_map_t *lookup_map_, - hb_hashmap_t *script_langsys_map_, + hb_hashmap_t *script_langsys_map_, hb_map_t *feature_index_map_) : subset_context (c_), table_tag (tag_), @@ -1357,7 +1357,7 @@ struct Lookup if (unlikely (!get_subtables ().sanitize (c, this, get_type ()))) return_trace (false); - if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) + if (unlikely (get_type () == TSubTable::Extension && subtables && !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 diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index c0ed2bcc03d..6bc06b50eda 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -163,7 +163,7 @@ struct hb_closure_context_t : hb_set_t *glyphs_, hb_set_t *cur_intersected_glyphs_, hb_map_t *done_lookups_glyph_count_, - hb_hashmap_t *done_lookups_glyph_set_, + hb_hashmap_t *done_lookups_glyph_set_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), @@ -192,7 +192,7 @@ struct hb_closure_context_t : private: hb_map_t *done_lookups_glyph_count; - hb_hashmap_t *done_lookups_glyph_set; + hb_hashmap_t *done_lookups_glyph_set; unsigned int lookup_count; }; @@ -1642,9 +1642,8 @@ struct Rule const hb_map_t *klass_map = nullptr) const { TRACE_SUBSET (this); - - const hb_array_t input = inputZ.as_array ((inputCount ? inputCount - 1 : 0)); - if (!input.length) return_trace (false); + if (unlikely (!inputCount)) return_trace (false); + const hb_array_t input = inputZ.as_array (inputCount - 1); const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map; if (!hb_all (input, mapping)) return_trace (false); @@ -3631,7 +3630,7 @@ struct GSUBGPOS } void prune_langsys (const hb_map_t *duplicate_feature_map, - hb_hashmap_t *script_langsys_map, + hb_hashmap_t *script_langsys_map, hb_set_t *new_feature_indexes /* OUT */) const { hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes); @@ -3689,7 +3688,7 @@ struct GSUBGPOS hb_map_t *duplicate_feature_map /* OUT */) const { if (feature_indices->is_empty ()) return; - hb_hashmap_t unique_features; + hb_hashmap_t unique_features; //find out duplicate features after subset for (unsigned i : feature_indices->iter ()) { @@ -3784,8 +3783,12 @@ struct GSUBGPOS // http://lists.freedesktop.org/archives/harfbuzz/2012-November/002660.html continue; - if (f.featureParams.is_null () - && !f.intersects_lookup_indexes (lookup_indices) + + if (!f.featureParams.is_null () && + tag == HB_TAG ('s', 'i', 'z', 'e')) + continue; + + if (!f.intersects_lookup_indexes (lookup_indices) #ifndef HB_NO_VAR && !alternate_feature_indices.has (i) #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index fbdedd0e209..4e1d23eba5c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -1493,7 +1493,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, { hb_set_t cur_intersected_glyphs; hb_map_t done_lookups_glyph_count; - hb_hashmap_t done_lookups_glyph_set; + hb_hashmap_t done_lookups_glyph_set; OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); @@ -1522,7 +1522,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, { hb_set_t cur_intersected_glyphs; hb_map_t done_lookups_glyph_count; - hb_hashmap_t done_lookups_glyph_set; + hb_hashmap_t done_lookups_glyph_set; OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set); const OT::GSUB& gsub = *face->table.GSUB->table; diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh index 94450eb53ad..504de2de740 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh @@ -79,6 +79,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const post::accelerator_t _post; _post.init (c->plan->source); + hb_hashmap_t glyph_name_to_new_index; for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) { hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); @@ -90,22 +91,28 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const else { hb_bytes_t s = _post.find_glyph_name (old_gid); - int standard_glyph_index = -1; - for (unsigned i = 0; i < format1_names_length; i++) + new_index = glyph_name_to_new_index.get (s); + if (new_index == (unsigned)-1) { - if (s == format1_names (i)) + int standard_glyph_index = -1; + for (unsigned i = 0; i < format1_names_length; i++) { - standard_glyph_index = i; - break; + if (s == format1_names (i)) + { + standard_glyph_index = i; + break; + } } + + if (standard_glyph_index == -1) + { + new_index = 258 + i; + i++; + } + else + { new_index = standard_glyph_index; } + glyph_name_to_new_index.set (s, new_index); } - if (standard_glyph_index == -1) - { - new_index = 258 + i; - i++; - } - else - { new_index = standard_glyph_index; } old_new_index_map.set (old_index, new_index); } old_gid_new_index_map.set (old_gid, new_index); diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 2e536c7a814..65c2772201d 100644 --- a/thirdparty/harfbuzz/src/hb-sanitize.hh +++ b/thirdparty/harfbuzz/src/hb-sanitize.hh @@ -123,6 +123,7 @@ struct hb_sanitize_context_t : hb_sanitize_context_t () : start (nullptr), end (nullptr), max_ops (0), max_subtables (0), + recursion_depth (0), writable (false), edit_count (0), blob (nullptr), num_glyphs (65536), @@ -205,6 +206,7 @@ struct hb_sanitize_context_t : (unsigned) HB_SANITIZE_MAX_OPS_MAX); this->edit_count = 0; this->debug_depth = 0; + this->recursion_depth = 0; DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1, "start [%p..%p] (%lu bytes)", @@ -278,6 +280,18 @@ struct hb_sanitize_context_t : return this->check_range (base, a, b, hb_static_size (T)); } + bool check_start_recursion (int max_depth) + { + if (unlikely (recursion_depth >= max_depth)) return false; + return ++recursion_depth; + } + + bool end_recursion (bool result) + { + recursion_depth--; + return result; + } + template bool check_struct (const Type *obj) const { return likely (this->check_range (obj, obj->min_size)); } @@ -389,6 +403,7 @@ struct hb_sanitize_context_t : const char *start, *end; mutable int max_ops, max_subtables; private: + int recursion_depth; bool writable; unsigned int edit_count; hb_blob_t *blob; diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index 57689916f67..d22ae06087f 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -652,7 +652,9 @@ struct hb_serialize_context_t hb_vector_t packed; /* Map view of packed objects. */ - hb_hashmap_t packed_map; + hb_hashmap_t packed_map; }; #endif /* HB_SERIALIZE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index 88414271897..af02e9e12b2 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -157,9 +157,9 @@ struct hb_set_t : hb_sparseset_t { hb_set_t () = default; ~hb_set_t () = default; - hb_set_t (hb_set_t& o) = default; - hb_set_t& operator= (const hb_set_t& other) = default; - hb_set_t& operator= (hb_set_t&& other) = default; + hb_set_t (hb_set_t&) = default; + hb_set_t& operator= (const hb_set_t&) = default; + hb_set_t& operator= (hb_set_t&&) = default; hb_set_t (std::initializer_list lst) : hb_sparseset_t (lst) {} template diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 1e195ff6606..53f8664d92e 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -41,7 +41,7 @@ #include "hb-ot-math-table.hh" -typedef hb_hashmap_t script_langsys_map; +typedef hb_hashmap_t script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, @@ -100,11 +100,23 @@ static void _collect_layout_indices (hb_face_t *face, if (!features.alloc (table.get_feature_count () + 1)) return; + hb_set_t visited_features; + bool retain_all_features = true; for (unsigned i = 0; i < table.get_feature_count (); i++) { hb_tag_t tag = table.get_feature_tag (i); - if (tag && layout_features_to_retain->has (tag)) - features.push (tag); + if (!tag) continue; + if (!layout_features_to_retain->has (tag)) + { + retain_all_features = false; + continue; + } + + if (visited_features.has (tag)) + continue; + + features.push (tag); + visited_features.add (tag); } if (!features) @@ -113,7 +125,7 @@ static void _collect_layout_indices (hb_face_t *face, // The collect function needs a null element to signal end of the array. features.push (0); - if (features.get_size () == table.get_feature_count () + 1) + if (retain_all_features) { // Looking for all features, trigger the faster collection method. layout_collect_func (face, diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index c30feeb42f2..c0232480bff 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -84,8 +84,8 @@ struct hb_subset_plan_t hb_map_t *gpos_lookups; //active langsys we'd like to retain - hb_hashmap_t *gsub_langsys; - hb_hashmap_t *gpos_langsys; + hb_hashmap_t *gsub_langsys; + hb_hashmap_t *gpos_langsys; //active features after removing redundant langsys and prune_features hb_map_t *gsub_features; diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 1a4f0bf62ad..c9fefa1df60 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -53,14 +53,14 @@ HB_BEGIN_DECLS * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 1 +#define HB_VERSION_MICRO 2 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "3.1.1" +#define HB_VERSION_STRING "3.1.2" /** * HB_VERSION_ATLEAST: