diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh | 206 |
1 files changed, 137 insertions, 69 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh index 65f499a00d..f2a58028e3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh @@ -37,7 +37,7 @@ #ifndef HB_MAX_NESTING_LEVEL -#define HB_MAX_NESTING_LEVEL 6 +#define HB_MAX_NESTING_LEVEL 64 #endif #ifndef HB_MAX_CONTEXT_LENGTH #define HB_MAX_CONTEXT_LENGTH 64 @@ -60,6 +60,10 @@ #define HB_MAX_LANGSYS 2000 #endif +#ifndef HB_MAX_LANGSYS_FEATURE_COUNT +#define HB_MAX_LANGSYS_FEATURE_COUNT 50000 +#endif + #ifndef HB_MAX_FEATURES #define HB_MAX_FEATURES 750 #endif @@ -68,8 +72,8 @@ #define HB_MAX_FEATURE_INDICES 1500 #endif -#ifndef HB_MAX_LOOKUP_INDICES -#define HB_MAX_LOOKUP_INDICES 20000 +#ifndef HB_MAX_LOOKUP_VISIT_COUNT +#define HB_MAX_LOOKUP_VISIT_COUNT 35000 #endif @@ -89,7 +93,7 @@ static inline void ClassDef_serialize (hb_serialize_context_t *c, static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, const hb_map_t &gid_klass_map, - hb_sorted_vector_t<HBGlyphID> &glyphs, + hb_sorted_vector_t<HBGlyphID16> &glyphs, const hb_set_t &klasses, bool use_class_zero, hb_map_t *klass_map /*INOUT*/); @@ -98,54 +102,33 @@ 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<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_, + hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_, const hb_map_t *duplicate_feature_map_, hb_set_t *new_collected_feature_indexes_) :table (table_), script_langsys_map (script_langsys_map_), duplicate_feature_map (duplicate_feature_map_), new_feature_indexes (new_collected_feature_indexes_), - script_count (0),langsys_count (0) {} - - bool visitedScript (const void *s) - { - if (script_count++ > HB_MAX_SCRIPTS) - return true; - - return visited (s, visited_script); - } - - bool visitedLangsys (const void *l) - { - if (langsys_count++ > HB_MAX_LANGSYS) - return true; + script_count (0),langsys_feature_count (0) {} - return visited (l, visited_langsys); - } + bool visitScript () + { return script_count++ < HB_MAX_SCRIPTS; } - private: - template <typename T> - bool visited (const T *p, hb_set_t &visited_set) + bool visitLangsys (unsigned feature_count) { - hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table); - if (visited_set.has (delta)) - return true; - - visited_set.add (delta); - return false; + langsys_feature_count += feature_count; + return langsys_feature_count < HB_MAX_LANGSYS_FEATURE_COUNT; } public: const void *table; - hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map; + hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map; const hb_map_t *duplicate_feature_map; hb_set_t *new_feature_indexes; private: - hb_set_t visited_script; - hb_set_t visited_langsys; unsigned script_count; - unsigned langsys_count; + unsigned langsys_feature_count; }; struct hb_subset_layout_context_t : @@ -173,20 +156,20 @@ struct hb_subset_layout_context_t : bool visitLookupIndex() { lookup_index_count++; - return lookup_index_count < HB_MAX_LOOKUP_INDICES; + return lookup_index_count < HB_MAX_LOOKUP_VISIT_COUNT; } hb_subset_context_t *subset_context; const hb_tag_t table_tag; const hb_map_t *lookup_index_map; - const hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map; + const hb_hashmap_t<unsigned, hb_set_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<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_, + hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_, hb_map_t *feature_index_map_) : subset_context (c_), table_tag (tag_), @@ -237,9 +220,9 @@ struct subset_offset_array_t template <typename T> bool operator () (T&& offset) { + auto snap = subset_context->serializer->snapshot (); auto *o = out.serialize_append (subset_context->serializer); if (unlikely (!o)) return false; - auto snap = subset_context->serializer->snapshot (); bool ret = o->serialize_subset (subset_context, offset, base); if (!ret) { @@ -268,9 +251,9 @@ struct subset_offset_array_arg_t template <typename T> bool operator () (T&& offset) { + auto snap = subset_context->serializer->snapshot (); auto *o = out.serialize_append (subset_context->serializer); if (unlikely (!o)) return false; - auto snap = subset_context->serializer->snapshot (); bool ret = o->serialize_subset (subset_context, offset, base, arg); if (!ret) { @@ -346,6 +329,43 @@ struct } HB_FUNCOBJ (subset_record_array); + +template<typename OutputArray> +struct serialize_math_record_array_t +{ + serialize_math_record_array_t (hb_serialize_context_t *serialize_context_, + OutputArray& out_, + const void *base_) : serialize_context (serialize_context_), + out (out_), base (base_) {} + + template <typename T> + bool operator () (T&& record) + { + if (!serialize_context->copy (record, base)) return false; + out.len++; + return true; + } + + private: + hb_serialize_context_t *serialize_context; + OutputArray &out; + const void *base; +}; + +/* + * Helper to serialize an array of MATH records. + */ +struct +{ + template<typename OutputArray> + serialize_math_record_array_t<OutputArray> + operator () (hb_serialize_context_t *serialize_context, OutputArray& out, + const void *base) const + { return serialize_math_record_array_t<OutputArray> (serialize_context, out, base); } + +} +HB_FUNCOBJ (serialize_math_record_array); + /* * * OpenType Layout Common Table Formats @@ -508,8 +528,8 @@ struct RangeRecord bool collect_coverage (set_t *glyphs) const { return glyphs->add_range (first, last); } - HBGlyphID first; /* First GlyphID in the range */ - HBGlyphID last; /* Last GlyphID in the range */ + HBGlyphID16 first; /* First GlyphID in the range */ + HBGlyphID16 last; /* Last GlyphID in the range */ HBUINT16 value; /* Value */ public: DEFINE_SIZE_STATIC (6); @@ -606,11 +626,14 @@ struct LangSys | hb_map (feature_index_map) ; - if (iter.len () != o_iter.len ()) - return false; + for (; iter && o_iter; iter++, o_iter++) + { + unsigned a = *iter; + unsigned b = *o_iter; + if (a != b) return false; + } - for (const auto _ : + hb_zip (iter, o_iter)) - if (_.first != _.second) return false; + if (iter || o_iter) return false; return true; } @@ -618,7 +641,6 @@ struct LangSys void collect_features (hb_prune_langsys_context_t *c) const { if (!has_required_feature () && !get_feature_count ()) return; - if (c->visitedLangsys (this)) return; if (has_required_feature () && c->duplicate_feature_map->has (reqFeatureIndex)) c->new_feature_indexes->add (get_required_feature_index ()); @@ -696,7 +718,7 @@ struct Script unsigned script_index) const { if (!has_default_lang_sys () && !get_lang_sys_count ()) return; - if (c->visitedScript (this)) return; + if (!c->visitScript ()) return; if (!c->script_langsys_map->has (script_index)) { @@ -713,11 +735,14 @@ struct Script { //only collect features from non-redundant langsys const LangSys& d = get_default_lang_sys (); - d.collect_features (c); + if (c->visitLangsys (d.get_feature_count ())) { + d.collect_features (c); + } for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) { const LangSys& l = this+_.first.offset; + if (!c->visitLangsys (l.get_feature_count ())) continue; if (l.compare (d, c->duplicate_feature_map)) continue; l.collect_features (c); @@ -729,6 +754,7 @@ struct Script for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) { const LangSys& l = this+_.first.offset; + if (!c->visitLangsys (l.get_feature_count ())) continue; l.collect_features (c); c->script_langsys_map->get (script_index)->add (_.second); } @@ -808,7 +834,7 @@ struct FeatureParamsSize if (unlikely (!c->check_struct (this))) return_trace (false); /* This subtable has some "history", if you will. Some earlier versions of - * Adobe tools calculated the offset of the FeatureParams sutable from the + * Adobe tools calculated the offset of the FeatureParams subtable from the * beginning of the FeatureList table! Now, that is dealt with in the * Feature implementation. But we still need to be able to tell junk from * real data. Note: We don't check that the nameID actually exists. @@ -1249,7 +1275,7 @@ struct Lookup 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<TSubTable> (i).dispatch (c, lookup_type, hb_forward<Ts> (ds)...); + typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...); if (c->stop_sublookup_iteration (r)) return_trace (r); } @@ -1299,7 +1325,7 @@ struct Lookup outMarkFilteringSet = markFilteringSet; } - return_trace (true); + return_trace (out->subTable.len); } template <typename TSubTable> @@ -1320,7 +1346,7 @@ struct Lookup if (unlikely (!get_subtables<TSubTable> ().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 @@ -1454,7 +1480,7 @@ struct CoverageFormat1 protected: HBUINT16 coverageFormat; /* Format identifier--format = 1 */ - SortedArray16Of<HBGlyphID> + SortedArray16Of<HBGlyphID16> glyphArray; /* Array of GlyphIDs--in numerical order */ public: DEFINE_SIZE_ARRAY (4, glyphArray); @@ -1832,7 +1858,7 @@ Coverage_serialize (hb_serialize_context_t *c, static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, const hb_map_t &gid_klass_map, - hb_sorted_vector_t<HBGlyphID> &glyphs, + hb_sorted_vector_t<HBGlyphID16> &glyphs, const hb_set_t &klasses, bool use_class_zero, hb_map_t *klass_map /*INOUT*/) @@ -1859,7 +1885,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, auto it = + glyphs.iter () - | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, unsigned> + | hb_map_retains_sorting ([&] (const HBGlyphID16& gid) -> hb_pair_t<hb_codepoint_t, unsigned> { unsigned new_klass = klass_map->get (gid_klass_map[gid]); return hb_pair ((hb_codepoint_t)gid, new_klass); @@ -1926,7 +1952,7 @@ struct ClassDefFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_sorted_vector_t<HBGlyphID> glyphs; + hb_sorted_vector_t<HBGlyphID16> glyphs; hb_set_t orig_klasses; hb_map_t gid_org_klass_map; @@ -2044,9 +2070,25 @@ struct ClassDefFormat1 intersect_glyphs->add (startGlyph + i); } + void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const + { + if (glyphs->is_empty ()) return; + hb_codepoint_t end_glyph = startGlyph + classValue.len - 1; + if (glyphs->get_min () < startGlyph || + glyphs->get_max () > end_glyph) + intersect_classes->add (0); + + for (const auto& _ : + hb_enumerate (classValue)) + { + hb_codepoint_t g = startGlyph + _.first; + if (glyphs->has (g)) + intersect_classes->add (_.second); + } + } + protected: HBUINT16 classFormat; /* Format identifier--format = 1 */ - HBGlyphID startGlyph; /* First GlyphID of the classValueArray */ + HBGlyphID16 startGlyph; /* First GlyphID of the classValueArray */ Array16Of<HBUINT16> classValue; /* Array of Class Values--one per GlyphID */ public: @@ -2128,7 +2170,7 @@ struct ClassDefFormat2 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_sorted_vector_t<HBGlyphID> glyphs; + hb_sorted_vector_t<HBGlyphID16> glyphs; hb_set_t orig_klasses; hb_map_t gid_org_klass_map; @@ -2277,6 +2319,31 @@ struct ClassDefFormat2 } } + void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const + { + if (glyphs->is_empty ()) return; + + unsigned count = rangeRecord.len; + hb_codepoint_t g = HB_SET_VALUE_INVALID; + for (unsigned int i = 0; i < count; i++) + { + if (!hb_set_next (glyphs, &g)) + break; + if (g < rangeRecord[i].first) + { + intersect_classes->add (0); + break; + } + g = rangeRecord[i].last; + } + if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) + intersect_classes->add (0); + + for (const RangeRecord& record : rangeRecord.iter ()) + if (record.intersects (glyphs)) + intersect_classes->add (record.value); + } + protected: HBUINT16 classFormat; /* Format identifier--format = 2 */ SortedArray16Of<RangeRecord> @@ -2429,6 +2496,16 @@ struct ClassDef } } + void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const + { + switch (u.format) { + case 1: return u.format1.intersected_classes (glyphs, intersect_classes); + case 2: return u.format2.intersected_classes (glyphs, intersect_classes); + default:return; + } + } + + protected: union { HBUINT16 format; /* Format identifier */ @@ -2543,7 +2620,7 @@ struct VarRegionList public: HBUINT16 axisCount; - HBUINT16 regionCount; + HBUINT15 regionCount; protected: UnsizedArrayOf<VarRegionAxis> axesZ; @@ -2838,8 +2915,6 @@ struct VariationStore hb_vector_t<hb_inc_bimap_t> inner_maps; inner_maps.resize ((unsigned) dataSets.len); - for (unsigned i = 0; i < inner_maps.length; i++) - inner_maps[i].init (); for (unsigned idx : c->plan->layout_variation_indices->iter ()) { @@ -2847,18 +2922,11 @@ struct VariationStore uint16_t minor = idx & 0xFFFF; if (major >= inner_maps.length) - { - for (unsigned i = 0; i < inner_maps.length; i++) - inner_maps[i].fini (); return_trace (false); - } inner_maps[major].add (minor); } varstore_prime->serialize (c->serializer, this, inner_maps.as_array ()); - for (unsigned i = 0; i < inner_maps.length; i++) - inner_maps[i].fini (); - return_trace ( !c->serializer->in_error() && varstore_prime->dataSets); @@ -2947,7 +3015,7 @@ struct Condition 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, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } |