diff options
Diffstat (limited to 'thirdparty/harfbuzz/src')
85 files changed, 4278 insertions, 2193 deletions
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh index cd36fc8953..b52844e75d 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh @@ -82,7 +82,7 @@ struct BaselineTableFormat2Part } protected: - HBGlyphID stdGlyph; /* The specific glyph index number in this + HBGlyphID16 stdGlyph; /* The specific glyph index number in this * font that is used to set the baseline values. * This is the standard glyph. * This glyph must contain a set of control points @@ -105,7 +105,7 @@ struct BaselineTableFormat3Part } protected: - HBGlyphID stdGlyph; /* ditto */ + HBGlyphID16 stdGlyph; /* ditto */ HBUINT16 ctlPoints[32]; /* ditto */ Lookup<HBUINT16> lookupTable; /* Lookup table that maps glyphs to their diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index e70ce97174..1dcbe92904 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -96,8 +96,8 @@ struct LookupSegmentSingle return_trace (c->check_struct (this) && value.sanitize (c, base)); } - HBGlyphID last; /* Last GlyphID in this segment */ - HBGlyphID first; /* First GlyphID in this segment */ + HBGlyphID16 last; /* Last GlyphID in this segment */ + HBGlyphID16 first; /* First GlyphID in this segment */ T value; /* The lookup value (only one) */ public: DEFINE_SIZE_STATIC (4 + T::static_size); @@ -162,11 +162,11 @@ struct LookupSegmentArray TRACE_SANITIZE (this); return_trace (c->check_struct (this) && first <= last && - valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...)); + valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...)); } - HBGlyphID last; /* Last GlyphID in this segment */ - HBGlyphID first; /* First GlyphID in this segment */ + HBGlyphID16 last; /* Last GlyphID in this segment */ + HBGlyphID16 first; /* First GlyphID in this segment */ NNOffset16To<UnsizedArrayOf<T>> valuesZ; /* A 16-bit offset from the start of * the table to the data. */ @@ -225,7 +225,7 @@ struct LookupSingle return_trace (c->check_struct (this) && value.sanitize (c, base)); } - HBGlyphID glyph; /* Last GlyphID */ + HBGlyphID16 glyph; /* Last GlyphID */ T value; /* The lookup value (only one) */ public: DEFINE_SIZE_STATIC (2 + T::static_size); @@ -287,7 +287,7 @@ struct LookupFormat8 protected: HBUINT16 format; /* Format identifier--format = 8 */ - HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */ HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last * glyph minus the value of firstGlyph plus 1). */ UnsizedArrayOf<T> @@ -329,7 +329,7 @@ struct LookupFormat10 protected: HBUINT16 format; /* Format identifier--format = 8 */ HBUINT16 valueSize; /* Byte size of each value. */ - HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */ HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last * glyph minus the value of firstGlyph plus 1). */ UnsizedArrayOf<HBUINT8> @@ -661,7 +661,7 @@ struct ClassTable return_trace (c->check_struct (this) && classArray.sanitize (c)); } protected: - HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */ Array16Of<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus * firstGlyph). */ public: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh index 556d4ad75b..d745c11431 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh @@ -100,7 +100,7 @@ struct UnconditionalAddGlyphAction protected: ActionSubrecordHeader header; - HBGlyphID addGlyph; /* Glyph that should be added if the distance factor + HBGlyphID16 addGlyph; /* Glyph that should be added if the distance factor * is growing. */ public: @@ -121,11 +121,11 @@ struct ConditionalAddGlyphAction HBFixed substThreshold; /* Distance growth factor (in ems) at which * this glyph is replaced and the growth factor * recalculated. */ - HBGlyphID addGlyph; /* Glyph to be added as kashida. If this value is + HBGlyphID16 addGlyph; /* Glyph to be added as kashida. If this value is * 0xFFFF, no extra glyph will be added. Note that * generally when a glyph is added, justification * will need to be redone. */ - HBGlyphID substGlyph; /* Glyph to be substituted for this glyph if the + HBGlyphID16 substGlyph; /* Glyph to be substituted for this glyph if the * growth factor equals or exceeds the value of * substThreshold. */ public: @@ -170,7 +170,7 @@ struct RepeatedAddGlyphAction ActionSubrecordHeader header; HBUINT16 flags; /* Currently unused; set to 0. */ - HBGlyphID glyph; /* Glyph that should be added if the distance factor + HBGlyphID16 glyph; /* Glyph that should be added if the distance factor * is growing. */ public: DEFINE_SIZE_STATIC (10); diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh index d0eacf0e61..0354b47d5a 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh @@ -82,8 +82,8 @@ struct KernPair } protected: - HBGlyphID left; - HBGlyphID right; + HBGlyphID16 left; + HBGlyphID16 right; FWORD value; public: DEFINE_SIZE_STATIC (6); @@ -775,11 +775,11 @@ struct KerxSubTable unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case 0: return_trace (c->dispatch (u.format0, hb_forward<Ts> (ds)...)); - case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); - case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); - case 4: return_trace (c->dispatch (u.format4, hb_forward<Ts> (ds)...)); - case 6: return_trace (c->dispatch (u.format6, hb_forward<Ts> (ds)...)); + case 0: return_trace (c->dispatch (u.format0, std::forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + case 6: return_trace (c->dispatch (u.format6, std::forward<Ts> (ds)...)); default: return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index a807bdcfc5..2f99510925 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -243,21 +243,21 @@ struct ContextualSubtable if (buffer->idx == buffer->len && !mark_set) return; - const HBGlyphID *replacement; + const HBGlyphID16 *replacement; replacement = nullptr; if (Types::extended) { if (entry.data.markIndex != 0xFFFF) { - const Lookup<HBGlyphID> &lookup = subs[entry.data.markIndex]; + const Lookup<HBGlyphID16> &lookup = subs[entry.data.markIndex]; replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs); } } else { unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint; - const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs; + const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; if (!replacement->sanitize (&c->sanitizer) || !*replacement) replacement = nullptr; @@ -278,14 +278,14 @@ struct ContextualSubtable { if (entry.data.currentIndex != 0xFFFF) { - const Lookup<HBGlyphID> &lookup = subs[entry.data.currentIndex]; + const Lookup<HBGlyphID16> &lookup = subs[entry.data.currentIndex]; replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs); } } else { unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint; - const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs; + const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; if (!replacement->sanitize (&c->sanitizer) || !*replacement) replacement = nullptr; @@ -315,7 +315,7 @@ struct ContextualSubtable bool has_glyph_classes; unsigned int mark; const ContextualSubtable *table; - const UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false> &subs; + const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false> &subs; }; bool apply (hb_aat_apply_context_t *c) const @@ -359,7 +359,7 @@ struct ContextualSubtable protected: StateTable<Types, EntryData> machine; - NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false>, HBUINT> + NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false>, HBUINT> substitutionTables; public: DEFINE_SIZE_STATIC (20); @@ -531,7 +531,7 @@ struct LigatureSubtable if (action & (LigActionStore | LigActionLast)) { ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); - const HBGlyphID &ligatureData = ligature[ligature_idx]; + const HBGlyphID16 &ligatureData = ligature[ligature_idx]; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break; hb_codepoint_t lig = ligatureData; @@ -565,7 +565,7 @@ struct LigatureSubtable const LigatureSubtable *table; const UnsizedArrayOf<HBUINT32> &ligAction; const UnsizedArrayOf<HBUINT16> &component; - const UnsizedArrayOf<HBGlyphID> &ligature; + const UnsizedArrayOf<HBGlyphID16> &ligature; unsigned int match_length; unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; }; @@ -597,7 +597,7 @@ struct LigatureSubtable ligAction; /* Offset to the ligature action table. */ NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT> component; /* Offset to the component table. */ - NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT> + NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT> ligature; /* Offset to the actual ligature lists. */ public: DEFINE_SIZE_STATIC (28); @@ -620,7 +620,7 @@ struct NoncontextualSubtable unsigned int count = c->buffer->len; for (unsigned int i = 0; i < count; i++) { - const HBGlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs); + const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs); if (replacement) { info[i].codepoint = *replacement; @@ -641,7 +641,7 @@ struct NoncontextualSubtable } protected: - Lookup<HBGlyphID> substitute; + Lookup<HBGlyphID16> substitute; public: DEFINE_SIZE_MIN (2); }; @@ -744,7 +744,7 @@ struct InsertionSubtable unsigned int count = (flags & MarkedInsertCount); if (unlikely ((buffer->max_ops -= count) <= 0)) return; unsigned int start = entry.data.markedInsertIndex; - const HBGlyphID *glyphs = &insertionAction[start]; + const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; bool before = flags & MarkedInsertBefore; @@ -772,7 +772,7 @@ struct InsertionSubtable unsigned int count = (flags & CurrentInsertCount) >> 5; if (unlikely ((buffer->max_ops -= count) <= 0)) return; unsigned int start = entry.data.currentInsertIndex; - const HBGlyphID *glyphs = &insertionAction[start]; + const HBGlyphID16 *glyphs = &insertionAction[start]; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; bool before = flags & CurrentInsertBefore; @@ -810,7 +810,7 @@ struct InsertionSubtable private: hb_aat_apply_context_t *c; unsigned int mark; - const UnsizedArrayOf<HBGlyphID> &insertionAction; + const UnsizedArrayOf<HBGlyphID16> &insertionAction; }; bool apply (hb_aat_apply_context_t *c) const @@ -836,7 +836,7 @@ struct InsertionSubtable protected: StateTable<Types, EntryData> machine; - NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT> + NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT> insertionAction; /* Byte offset from stateHeader to the start of * the insertion glyph table. */ public: @@ -906,11 +906,11 @@ struct ChainSubtable unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case Rearrangement: return_trace (c->dispatch (u.rearrangement, hb_forward<Ts> (ds)...)); - case Contextual: return_trace (c->dispatch (u.contextual, hb_forward<Ts> (ds)...)); - case Ligature: return_trace (c->dispatch (u.ligature, hb_forward<Ts> (ds)...)); - case Noncontextual: return_trace (c->dispatch (u.noncontextual, hb_forward<Ts> (ds)...)); - case Insertion: return_trace (c->dispatch (u.insertion, hb_forward<Ts> (ds)...)); + case Rearrangement: return_trace (c->dispatch (u.rearrangement, std::forward<Ts> (ds)...)); + case Contextual: return_trace (c->dispatch (u.contextual, std::forward<Ts> (ds)...)); + case Ligature: return_trace (c->dispatch (u.ligature, std::forward<Ts> (ds)...)); + case Noncontextual: return_trace (c->dispatch (u.noncontextual, std::forward<Ts> (ds)...)); + case Insertion: return_trace (c->dispatch (u.insertion, std::forward<Ts> (ds)...)); default: return_trace (c->default_return_value ()); } } @@ -1038,12 +1038,12 @@ struct Chain goto skip; if (reverse) - c->buffer->reverse (); + _hb_ot_layout_reverse_graphemes (c->buffer); subtable->apply (c); if (reverse) - c->buffer->reverse (); + _hb_ot_layout_reverse_graphemes (c->buffer); (void) c->buffer->message (c->font, "end chainsubtable %d", c->lookup_index); diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index bbe097fe01..446d87e28b 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -34,6 +34,9 @@ #include "hb-null.hh" #include "hb-number.hh" +#include <algorithm> +#include <initializer_list> +#include <new> /* * Flags @@ -125,7 +128,7 @@ struct BEInt<Type, 2> template <typename Type> struct BEInt<Type, 3> { - static_assert (!hb_is_signed (Type), ""); + static_assert (!std::is_signed<Type>::value, ""); public: BEInt () = default; constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), @@ -179,7 +182,7 @@ struct { /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ template <typename T> constexpr auto - operator () (T&& v) const HB_AUTO_RETURN ( hb_forward<T> (v) ) + operator () (T&& v) const HB_AUTO_RETURN ( std::forward<T> (v) ) } HB_FUNCOBJ (hb_identity); struct @@ -203,7 +206,7 @@ HB_FUNCOBJ (hb_ridentity); struct { template <typename T> constexpr bool - operator () (T&& v) const { return bool (hb_forward<T> (v)); } + operator () (T&& v) const { return bool (std::forward<T> (v)); } } HB_FUNCOBJ (hb_bool); @@ -215,7 +218,7 @@ struct impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) template <typename T, - hb_enable_if (hb_is_integral (T))> constexpr auto + hb_enable_if (std::is_integral<T>::value)> constexpr auto impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN ( /* Knuth's multiplicative method: */ @@ -237,26 +240,26 @@ struct /* Pointer-to-member-function. */ template <typename Appl, typename T, typename ...Ts> auto impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN - ((hb_deref (hb_forward<T> (v)).*hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...)) + ((hb_deref (std::forward<T> (v)).*std::forward<Appl> (a)) (std::forward<Ts> (ds)...)) /* Pointer-to-member. */ template <typename Appl, typename T> auto impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN - ((hb_deref (hb_forward<T> (v))).*hb_forward<Appl> (a)) + ((hb_deref (std::forward<T> (v))).*std::forward<Appl> (a)) /* Operator(). */ template <typename Appl, typename ...Ts> auto impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN - (hb_deref (hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...)) + (hb_deref (std::forward<Appl> (a)) (std::forward<Ts> (ds)...)) public: template <typename Appl, typename ...Ts> auto operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN ( - impl (hb_forward<Appl> (a), + impl (std::forward<Appl> (a), hb_prioritize, - hb_forward<Ts> (ds)...) + std::forward<Ts> (ds)...) ) } HB_FUNCOBJ (hb_invoke); @@ -275,9 +278,9 @@ struct hb_partial_t hb_declval (V), hb_declval (Ts)...)) { - return hb_invoke (hb_forward<Appl> (a), - hb_forward<V> (v), - hb_forward<Ts> (ds)...); + return hb_invoke (std::forward<Appl> (a), + std::forward<V> (v), + std::forward<Ts> (ds)...); } template <typename T0, typename ...Ts, unsigned P = Pos, @@ -287,10 +290,10 @@ struct hb_partial_t hb_declval (V), hb_declval (Ts)...)) { - return hb_invoke (hb_forward<Appl> (a), - hb_forward<T0> (d0), - hb_forward<V> (v), - hb_forward<Ts> (ds)...); + return hb_invoke (std::forward<Appl> (a), + std::forward<T0> (d0), + std::forward<V> (v), + std::forward<Ts> (ds)...); } private: @@ -324,14 +327,14 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN #define HB_PARTIALIZE(Pos) \ template <typename _T> \ decltype(auto) operator () (_T&& _v) const \ - { return hb_partial<Pos> (this, hb_forward<_T> (_v)); } \ + { return hb_partial<Pos> (this, std::forward<_T> (_v)); } \ static_assert (true, "") #else /* https://github.com/harfbuzz/harfbuzz/issues/1724 */ #define HB_PARTIALIZE(Pos) \ template <typename _T> \ auto operator () (_T&& _v) const HB_AUTO_RETURN \ - (hb_partial<Pos> (+this, hb_forward<_T> (_v))) \ + (hb_partial<Pos> (+this, std::forward<_T> (_v))) \ static_assert (true, "") #endif @@ -343,22 +346,22 @@ struct template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN ( - hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v)) + hb_deref (std::forward<Pred> (p)).has (std::forward<Val> (v)) ) template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN ( - hb_invoke (hb_forward<Pred> (p), - hb_forward<Val> (v)) + hb_invoke (std::forward<Pred> (p), + std::forward<Val> (v)) ) public: template <typename Pred, typename Val> auto operator () (Pred&& p, Val &&v) const HB_RETURN (bool, - impl (hb_forward<Pred> (p), - hb_forward<Val> (v), + impl (std::forward<Pred> (p), + std::forward<Val> (v), hb_prioritize) ) } @@ -371,22 +374,22 @@ struct template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN ( - hb_has (hb_forward<Pred> (p), - hb_forward<Val> (v)) + hb_has (std::forward<Pred> (p), + std::forward<Val> (v)) ) template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN ( - hb_forward<Pred> (p) == hb_forward<Val> (v) + std::forward<Pred> (p) == std::forward<Val> (v) ) public: template <typename Pred, typename Val> auto operator () (Pred&& p, Val &&v) const HB_RETURN (bool, - impl (hb_forward<Pred> (p), - hb_forward<Val> (v), + impl (std::forward<Pred> (p), + std::forward<Val> (v), hb_prioritize) ) } @@ -399,20 +402,20 @@ struct template <typename Proj, typename Val> auto impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN ( - hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v)) + hb_deref (std::forward<Proj> (f)).get (std::forward<Val> (v)) ) template <typename Proj, typename Val> auto impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN ( - hb_invoke (hb_forward<Proj> (f), - hb_forward<Val> (v)) + hb_invoke (std::forward<Proj> (f), + std::forward<Val> (v)) ) template <typename Proj, typename Val> auto impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN ( - hb_forward<Proj> (f)[hb_forward<Val> (v)] + std::forward<Proj> (f)[std::forward<Val> (v)] ) public: @@ -420,8 +423,8 @@ struct template <typename Proj, typename Val> auto operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN ( - impl (hb_forward<Proj> (f), - hb_forward<Val> (v), + impl (std::forward<Proj> (f), + std::forward<Val> (v), hb_prioritize) ) } @@ -434,19 +437,19 @@ struct template <typename T1, typename T2> auto impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN ( - hb_forward<T2> (v2).cmp (hb_forward<T1> (v1)) == 0 + std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0 ) template <typename T1, typename T2> auto impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN ( - hb_forward<T1> (v1).cmp (hb_forward<T2> (v2)) == 0 + std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0 ) template <typename T1, typename T2> auto impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN ( - hb_forward<T1> (v1) == hb_forward<T2> (v2) + std::forward<T1> (v1) == std::forward<T2> (v2) ) public: @@ -454,8 +457,8 @@ struct template <typename T1, typename T2> auto operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN ( - impl (hb_forward<T1> (v1), - hb_forward<T2> (v2), + impl (std::forward<T1> (v1), + std::forward<T2> (v2), hb_prioritize) ) } @@ -515,24 +518,34 @@ struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a <= b ? hb_forward<T> (a) : hb_forward<T2> (b)) + (a <= b ? std::forward<T> (a) : std::forward<T2> (b)) } HB_FUNCOBJ (hb_min); struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a >= b ? hb_forward<T> (a) : hb_forward<T2> (b)) + (a >= b ? std::forward<T> (a) : std::forward<T2> (b)) } HB_FUNCOBJ (hb_max); struct { template <typename T, typename T2, typename T3> constexpr auto operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN - (hb_min (hb_max (hb_forward<T> (x), hb_forward<T2> (min)), hb_forward<T3> (max))) + (hb_min (hb_max (std::forward<T> (x), std::forward<T2> (min)), std::forward<T3> (max))) } HB_FUNCOBJ (hb_clamp); +struct +{ + template <typename T> void + operator () (T& a, T& b) const + { + using std::swap; // allow ADL + swap (a, b); + } +} +HB_FUNCOBJ (hb_swap); /* * Bithacks. @@ -795,7 +808,7 @@ hb_ceil_to_4 (unsigned int v) template <typename T> static inline bool hb_in_range (T u, T lo, T hi) { - static_assert (!hb_is_signed<T>::value, ""); + static_assert (!std::is_signed<T>::value, ""); /* The casts below are important as if T is smaller than int, * the subtract results will become a signed int! */ diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index ab0dd6ebe3..0beffb078f 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -50,14 +50,20 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> /* * Constructors. */ - 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) {} + hb_array_t () = default; + 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 <unsigned int length_> - hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {} + constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {} template <typename U, hb_enable_if (hb_is_cr_convertible(U, Type))> - hb_array_t (const hb_array_t<U> &o) : + constexpr hb_array_t (const hb_array_t<U> &o) : hb_iter_with_fallback_t<hb_array_t, Type&> (), arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {} template <typename U, @@ -281,9 +287,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> */ public: - Type *arrayZ; - unsigned int length; - unsigned int backwards_length; + Type *arrayZ = nullptr; + unsigned int length = 0; + unsigned int backwards_length = 0; }; template <typename T> inline hb_array_t<T> hb_array (T *array, unsigned int length) @@ -302,14 +308,20 @@ struct hb_sorted_array_t : static constexpr bool is_random_access_iterator = true; static constexpr bool is_sorted_iterator = true; - hb_sorted_array_t () : hb_array_t<Type> () {} - hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {} + hb_sorted_array_t () = default; + 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<Type> (array_, length_) {} template <unsigned int length_> - hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {} + constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {} template <typename U, hb_enable_if (hb_is_cr_convertible(U, Type))> - hb_sorted_array_t (const hb_array_t<U> &o) : + constexpr hb_sorted_array_t (const hb_array_t<U> &o) : hb_iter_t<hb_sorted_array_t, Type&> (), hb_array_t<Type> (o) {} template <typename U, diff --git a/thirdparty/harfbuzz/src/hb-atomic.hh b/thirdparty/harfbuzz/src/hb-atomic.hh index 93265f655f..e640d1b586 100644 --- a/thirdparty/harfbuzz/src/hb-atomic.hh +++ b/thirdparty/harfbuzz/src/hb-atomic.hh @@ -102,20 +102,12 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif defined(HB_NO_MT) +#else /* defined(HB_NO_MT) */ #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) - #define _hb_memory_barrier() do {} while (0) - #define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) - -#else - -#error "Could not find any system to define atomic_int macros." -#error "Check hb-atomic.hh for possible resolutions." - #endif diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh index d409880751..d466af8b60 100644 --- a/thirdparty/harfbuzz/src/hb-bimap.hh +++ b/thirdparty/harfbuzz/src/hb-bimap.hh @@ -33,15 +33,14 @@ /* Bi-directional map */ struct hb_bimap_t { - hb_bimap_t () { init (); } - ~hb_bimap_t () { fini (); } - + /* XXX(remove) */ void init () { forw_map.init (); back_map.init (); } + /* XXX(remove) */ void fini () { forw_map.fini (); @@ -99,14 +98,6 @@ struct hb_bimap_t /* Inremental bimap: only lhs is given, rhs is incrementally assigned */ struct hb_inc_bimap_t : hb_bimap_t { - hb_inc_bimap_t () { init (); } - - void init () - { - hb_bimap_t::init (); - next_value = 0; - } - /* Add a mapping from lhs to rhs with a unique value if lhs is unknown. * Return the rhs value as the result. */ @@ -165,7 +156,7 @@ struct hb_inc_bimap_t : hb_bimap_t } protected: - unsigned int next_value; + unsigned int next_value = 0; }; #endif /* HB_BIMAP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh index f48b72fe63..0832b0fc23 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh @@ -35,10 +35,20 @@ struct hb_bit_set_invertible_t { hb_bit_set_t s; - bool inverted; - - hb_bit_set_invertible_t () { init (); } - ~hb_bit_set_invertible_t () { fini (); } + bool inverted = false; + + hb_bit_set_invertible_t () = default; + hb_bit_set_invertible_t (hb_bit_set_invertible_t& o) = default; + hb_bit_set_invertible_t (hb_bit_set_invertible_t&& o) = default; + hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default; + hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& o) = default; + friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b) + { + if (likely (!a.s.successful || !b.s.successful)) + return; + hb_swap (a.inverted, b.inverted); + hb_swap (a.s, b.s); + } void init () { s.init (); inverted = false; } void fini () { s.fini (); } diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index c21778d88e..a471ee48b5 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -35,13 +35,22 @@ struct hb_bit_set_t { - hb_bit_set_t () { init (); } - ~hb_bit_set_t () { fini (); } + hb_bit_set_t () = default; + ~hb_bit_set_t () = default; hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other); } - void operator= (const hb_bit_set_t& other) { set (other); } - // TODO Add move construtor/assign - // TODO Add constructor for Iterator; with specialization for (sorted) vector / array? + hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); } + hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; } + hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; } + friend void swap (hb_bit_set_t &a, hb_bit_set_t &b) + { + if (likely (!a.successful || !b.successful)) + return; + hb_swap (a.population, b.population); + hb_swap (a.last_page_lookup, b.last_page_lookup); + hb_swap (a.page_map, b.page_map); + hb_swap (a.pages, b.pages); + } void init () { @@ -67,9 +76,9 @@ struct hb_bit_set_t uint32_t index; }; - bool successful; /* Allocations successful */ - mutable unsigned int population; - mutable unsigned int last_page_lookup; + bool successful = true; /* Allocations successful */ + mutable unsigned int population = 0; + mutable unsigned int last_page_lookup = 0; hb_sorted_vector_t<page_map_t> page_map; hb_vector_t<page_t> pages; diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index c6591ca230..be3161a54d 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -224,6 +224,7 @@ hb_buffer_t::reset () flags = HB_BUFFER_FLAG_DEFAULT; replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; invisible = 0; + not_found = 0; clear (); } @@ -395,52 +396,6 @@ hb_buffer_t::set_masks (hb_mask_t value, } void -hb_buffer_t::reverse_range (unsigned int start, - unsigned int end) -{ - if (end - start < 2) - return; - - hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end); - - if (have_positions) { - hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end); - } -} - -void -hb_buffer_t::reverse () -{ - if (unlikely (!len)) - return; - - reverse_range (0, len); -} - -void -hb_buffer_t::reverse_clusters () -{ - unsigned int i, start, count, last_cluster; - - if (unlikely (!len)) - return; - - reverse (); - - count = len; - start = 0; - last_cluster = info[0].cluster; - for (i = 1; i < count; i++) { - if (last_cluster != info[i].cluster) { - reverse_range (start, i); - start = i; - last_cluster = info[i].cluster; - } - } - reverse_range (start, i); -} - -void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { @@ -542,7 +497,7 @@ void hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end) { unsigned int cluster = UINT_MAX; - cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster); + cluster = _infos_find_min_cluster (info, start, end, cluster); _unsafe_to_break_set_mask (info, start, end, cluster); } void @@ -558,8 +513,9 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en assert (idx <= end); unsigned int cluster = UINT_MAX; - cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster); - cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster); + cluster = _infos_find_min_cluster (out_info, start, out_len, cluster); + cluster = _infos_find_min_cluster (info, idx, end, cluster); + _unsafe_to_break_set_mask (out_info, start, out_len, cluster); _unsafe_to_break_set_mask (info, idx, end, cluster); } @@ -608,6 +564,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, 0, /* invisible */ + 0, /* not_found */ HB_BUFFER_SCRATCH_FLAG_DEFAULT, HB_BUFFER_MAX_LEN_DEFAULT, HB_BUFFER_MAX_OPS_DEFAULT, @@ -1158,6 +1115,46 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer) return buffer->invisible; } +/** + * hb_buffer_set_not_found_glyph: + * @buffer: An #hb_buffer_t + * @not_found: the not-found #hb_codepoint_t + * + * Sets the #hb_codepoint_t that replaces characters not found in + * the font during shaping. + * + * The not-found glyph defaults to zero, sometimes knows as the + * ".notdef" glyph. This API allows for differentiating the two. + * + * Since: 3.1.0 + **/ +void +hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, + hb_codepoint_t not_found) +{ + if (unlikely (hb_object_is_immutable (buffer))) + return; + + buffer->not_found = not_found; +} + +/** + * hb_buffer_get_not_found_glyph: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_not_found_glyph(). + * + * Return value: + * The @buffer not-found #hb_codepoint_t + * + * Since: 3.1.0 + **/ +hb_codepoint_t +hb_buffer_get_not_found_glyph (hb_buffer_t *buffer) +{ + return buffer->not_found; +} + /** * hb_buffer_reset: diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h index 865ccb2273..a183cb9d4a 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.h +++ b/thirdparty/harfbuzz/src/hb-buffer.h @@ -383,6 +383,13 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_invisible_glyph (hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, + hb_codepoint_t not_found); + +HB_EXTERN hb_codepoint_t +hb_buffer_get_not_found_glyph (hb_buffer_t *buffer); + HB_EXTERN void hb_buffer_reset (hb_buffer_t *buffer); diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index 8635ebd35f..0f8140f1b3 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -93,6 +93,7 @@ struct hb_buffer_t hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ hb_codepoint_t invisible; /* 0 or something else. */ + hb_codepoint_t not_found; /* 0 or something else. */ hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ @@ -200,9 +201,55 @@ struct hb_buffer_t unsigned int cluster); HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info); - HB_INTERNAL void reverse_range (unsigned int start, unsigned int end); - HB_INTERNAL void reverse (); - HB_INTERNAL void reverse_clusters (); + void reverse_range (unsigned start, unsigned end) + { + hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end); + if (have_positions) + hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end); + } + void reverse () { reverse_range (0, len); } + + template <typename FuncType> + void reverse_groups (const FuncType& group, + bool merge_clusters = false) + { + if (unlikely (!len)) + return; + + unsigned start = 0; + unsigned i; + for (i = 1; i < len; i++) + { + if (!group (info[i - 1], info[i])) + { + if (merge_clusters) + this->merge_clusters (start, i); + reverse_range (start, i); + start = i; + } + } + if (merge_clusters) + this->merge_clusters (start, i); + reverse_range (start, i); + + reverse (); + } + + template <typename FuncType> + unsigned group_end (unsigned start, const FuncType& group) const + { + while (++start < len && group (info[start - 1], info[start])) + ; + + return start; + } + + static bool _cluster_group_func (const hb_glyph_info_t& a, + const hb_glyph_info_t& b) + { return a.cluster == b.cluster; } + + void reverse_clusters () { reverse_groups (_cluster_group_func); } + HB_INTERNAL void guess_segment_properties (); HB_INTERNAL void swap_buffers (); @@ -427,10 +474,10 @@ struct hb_buffer_t inf.cluster = cluster; } - unsigned int - _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos, - unsigned int start, unsigned int end, - unsigned int cluster) const + static unsigned + _infos_find_min_cluster (const hb_glyph_info_t *infos, + unsigned start, unsigned end, + unsigned cluster) { for (unsigned int i = start; i < end; i++) cluster = hb_min (cluster, infos[i].cluster); @@ -449,36 +496,24 @@ struct hb_buffer_t } } - void unsafe_to_break_all () { unsafe_to_break_impl (0, len); } - void safe_to_break_all () + void clear_glyph_flags (hb_mask_t mask = 0) { for (unsigned int i = 0; i < len; i++) - info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + info[i].mask = (info[i].mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED); } }; DECLARE_NULL_INSTANCE (hb_buffer_t); -/* Loop over clusters. Duplicated in foreach_syllable(). */ -#define foreach_cluster(buffer, start, end) \ +#define foreach_group(buffer, start, end, group_func) \ for (unsigned int \ _count = buffer->len, \ - start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \ + start = 0, end = _count ? buffer->group_end (0, group_func) : 0; \ start < _count; \ - start = end, end = _next_cluster (buffer, start)) - -static inline unsigned int -_next_cluster (hb_buffer_t *buffer, unsigned int start) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - - unsigned int cluster = info[start].cluster; - while (++start < count && cluster == info[start].cluster) - ; + start = end, end = buffer->group_end (start, group_func)) - return start; -} +#define foreach_cluster(buffer, start, end) \ + foreach_group (buffer, start, end, hb_buffer_t::_cluster_group_func) #define HB_BUFFER_XALLOCATE_VAR(b, func, var) \ diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index ad800f0f74..7d00d9088a 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -86,8 +86,11 @@ #define HB_NO_LEGACY #endif -#ifdef HAVE_CONFIG_OVERRIDE_H -#include "config-override.h" +#if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H) +#ifndef HB_CONFIG_OVERRIDE_H +#define HB_CONFIG_OVERRIDE_H "config-override.h" +#endif +#include HB_CONFIG_OVERRIDE_H #endif /* Closure of options. */ diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index 4b6c67c1ee..a512f3b8b7 100644 --- a/thirdparty/harfbuzz/src/hb-coretext.cc +++ b/thirdparty/harfbuzz/src/hb-coretext.cc @@ -1213,7 +1213,7 @@ resize_and_retry: } } - buffer->unsafe_to_break_all (); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); #undef FAIL diff --git a/thirdparty/harfbuzz/src/hb-debug.hh b/thirdparty/harfbuzz/src/hb-debug.hh index f80c8980ba..3ac7440e80 100644 --- a/thirdparty/harfbuzz/src/hb-debug.hh +++ b/thirdparty/harfbuzz/src/hb-debug.hh @@ -302,7 +302,7 @@ struct hb_auto_trace_t { if (unlikely (returned)) { fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n"); - return hb_forward<T> (v); + return std::forward<T> (v); } _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1, @@ -311,7 +311,7 @@ struct hb_auto_trace_t if (plevel) --*plevel; plevel = nullptr; returned = true; - return hb_forward<T> (v); + return std::forward<T> (v); } private: @@ -333,7 +333,7 @@ struct hb_auto_trace_t<0, ret_t> template <typename T> T ret (T&& v, const char *func HB_UNUSED = nullptr, - unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); } + unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); } }; /* For disabled tracing; optimize out everything. @@ -343,7 +343,7 @@ struct hb_no_trace_t { template <typename T> T ret (T&& v, const char *func HB_UNUSED = nullptr, - unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); } + unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); } }; #define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__) diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc index 8f6d73b639..dea87b8cd0 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -762,6 +762,8 @@ retry_getglyphs: if (isRightToLeft) hb_buffer_reverse (buffer); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); + delete [] clusterMap; delete [] glyphIndices; delete [] textProperties; diff --git a/thirdparty/harfbuzz/src/hb-dispatch.hh b/thirdparty/harfbuzz/src/hb-dispatch.hh index 4b2b65a8de..37ca681465 100644 --- a/thirdparty/harfbuzz/src/hb-dispatch.hh +++ b/thirdparty/harfbuzz/src/hb-dispatch.hh @@ -50,7 +50,7 @@ struct hb_dispatch_context_t bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } template <typename T, typename ...Ts> return_t dispatch (const T &obj, Ts&&... ds) - { return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); } + { return obj.dispatch (thiz (), std::forward<Ts> (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; } unsigned debug_depth = 0; diff --git a/thirdparty/harfbuzz/src/hb-fallback-shape.cc b/thirdparty/harfbuzz/src/hb-fallback-shape.cc index c5b7c2c230..f8524ecc8e 100644 --- a/thirdparty/harfbuzz/src/hb-fallback-shape.cc +++ b/thirdparty/harfbuzz/src/hb-fallback-shape.cc @@ -117,7 +117,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED, if (HB_DIRECTION_IS_BACKWARD (direction)) hb_buffer_reverse (buffer); - buffer->safe_to_break_all (); + buffer->clear_glyph_flags (); return true; } diff --git a/thirdparty/harfbuzz/src/hb-font.hh b/thirdparty/harfbuzz/src/hb-font.hh index 8fc7f44d44..1b7f445e8b 100644 --- a/thirdparty/harfbuzz/src/hb-font.hh +++ b/thirdparty/harfbuzz/src/hb-font.hh @@ -217,9 +217,10 @@ struct hb_font_t } hb_bool_t get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph) + hb_codepoint_t *glyph, + hb_codepoint_t not_found = 0) { - *glyph = 0; + *glyph = not_found; return klass->get.f.nominal_glyph (this, user_data, unicode, glyph, klass->user_data.nominal_glyph); @@ -238,9 +239,10 @@ struct hb_font_t } hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) + hb_codepoint_t *glyph, + hb_codepoint_t not_found = 0) { - *glyph = 0; + *glyph = not_found; return klass->get.f.variation_glyph (this, user_data, unicode, variation_selector, glyph, klass->user_data.variation_glyph); @@ -618,9 +620,7 @@ struct hb_font_t } hb_position_t em_mult (int16_t v, int64_t mult) - { - return (hb_position_t) ((v * mult) >> 16); - } + { return (hb_position_t) ((v * mult + 32768) >> 16); } hb_position_t em_scalef (float v, int scale) { return (hb_position_t) roundf (v * scale / face->get_upem ()); } float em_fscale (int16_t v, int scale) diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index 97a2c82e68..67691e3ff3 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -361,6 +361,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, } } +#ifndef HB_NO_VERTICAL static hb_position_t hb_ft_get_glyph_v_advance (hb_font_t *font, void *font_data, @@ -381,7 +382,9 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, * have a Y growing upward. Hence the extra negation. */ return (-v + (1<<9)) >> 10; } +#endif +#ifndef HB_NO_VERTICAL static hb_bool_t hb_ft_get_glyph_v_origin (hb_font_t *font, void *font_data, @@ -409,6 +412,7 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, return true; } +#endif #ifndef HB_NO_OT_SHAPE_FALLBACK static hb_position_t @@ -569,15 +573,20 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft { hb_font_funcs_t *funcs = hb_font_funcs_create (); - hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); - //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr); hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr); hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr); + +#ifndef HB_NO_VERTICAL + //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr); + hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr); +#endif + #ifndef HB_NO_OT_SHAPE_FALLBACK hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr); #endif diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index 209207f1e5..42420ac0b0 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -439,7 +439,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, if (feats) gr_featureval_destroy (feats); gr_seg_destroy (seg); - buffer->unsafe_to_break_all (); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); return true; } diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index b8c4472636..ad2e45e3c5 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -162,7 +162,7 @@ struct { template <typename T> hb_iter_type<T> operator () (T&& c) const - { return hb_deref (hb_forward<T> (c)).iter (); } + { return hb_deref (std::forward<T> (c)).iter (); } /* Specialization for C arrays. */ @@ -353,7 +353,7 @@ static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable). template <typename Lhs, typename Rhs, hb_requires (hb_is_iterator (Lhs))> static inline auto -operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward<Rhs> (rhs) (hb_forward<Lhs> (lhs))) +operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (std::forward<Rhs> (rhs) (std::forward<Lhs> (lhs))) /* hb_map(), hb_filter(), hb_reduce() */ @@ -581,6 +581,91 @@ struct } HB_FUNCOBJ (hb_zip); +/* hb_concat() */ + +template <typename A, typename B> +struct hb_concat_iter_t : + hb_iter_t<hb_concat_iter_t<A, B>, typename A::item_t> +{ + hb_concat_iter_t () {} + hb_concat_iter_t (A& a, B& b) : a (a), b (b) {} + hb_concat_iter_t (const A& a, const B& b) : a (a), b (b) {} + + + typedef typename A::item_t __item_t__; + static constexpr bool is_random_access_iterator = + A::is_random_access_iterator && + B::is_random_access_iterator; + static constexpr bool is_sorted_iterator = false; + + __item_t__ __item__ () const + { + if (!a) + return *b; + return *a; + } + + __item_t__ __item_at__ (unsigned i) const + { + unsigned a_len = a.len (); + if (i < a_len) + return a[i]; + return b[i - a_len]; + } + + bool __more__ () const { return bool (a) || bool (b); } + + unsigned __len__ () const { return a.len () + b.len (); } + + void __next__ () + { + if (a) + ++a; + else + ++b; + } + + void __forward__ (unsigned n) + { + if (!n) return; + if (!is_random_access_iterator) { + while (n-- && *this) { + (*this)++; + } + return; + } + + unsigned a_len = a.len (); + if (n > a_len) { + n -= a_len; + a.__forward__ (a_len); + b.__forward__ (n); + } else { + a.__forward__ (n); + } + } + + hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); } + bool operator != (const hb_concat_iter_t& o) const + { + return a != o.a + || b != o.b; + } + + private: + A a; + B b; +}; +struct +{ HB_PARTIALIZE(2); + template <typename A, typename B, + hb_requires (hb_is_iterable (A) && hb_is_iterable (B))> + hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> + operator () (A&& a, B&& b) const + { return hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); } +} +HB_FUNCOBJ (hb_concat); + /* hb_apply() */ template <typename Appl> @@ -674,8 +759,8 @@ struct hb_iota_iter_t : template <typename S2 = S> auto inc (hb_type_identity<S2> s, hb_priority<1>) - -> hb_void_t<decltype (hb_invoke (hb_forward<S2> (s), hb_declval<T&> ()))> - { v = hb_invoke (hb_forward<S2> (s), v); } + -> hb_void_t<decltype (hb_invoke (std::forward<S2> (s), hb_declval<T&> ()))> + { v = hb_invoke (std::forward<S2> (s), v); } void inc (S s, hb_priority<0>) @@ -874,7 +959,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (!hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it))) + if (!hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it))) return false; return true; } @@ -891,7 +976,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it))) + if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it))) return true; return false; } @@ -908,7 +993,7 @@ struct Proj&& f = hb_identity) const { for (auto it = hb_iter (c); it; ++it) - if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it))) + if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it))) return false; return true; } diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index dcd5267d74..793dcf22ca 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -35,16 +35,39 @@ */ template <typename K, typename V, - 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> + typename k_invalid_t = K, + typename v_invalid_t = V, + k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1, + v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1> struct hb_hashmap_t { - HB_DELETE_COPY_ASSIGN (hb_hashmap_t); + static constexpr K INVALID_KEY = kINVALID; + static constexpr V INVALID_VALUE = vINVALID; + hb_hashmap_t () { init (); } ~hb_hashmap_t () { fini (); } - static_assert (hb_is_integral (K) || hb_is_pointer (K), ""); - static_assert (hb_is_integral (V) || hb_is_pointer (V), ""); + hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { hb_copy (o, *this); } + hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); } + hb_hashmap_t& operator= (const hb_hashmap_t& o) { hb_copy (o, *this); return *this; } + hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; } + + hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t () + { + for (auto&& item : lst) + set (item.first, item.second); + } + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + hb_hashmap_t (const Iterable &o) : hb_hashmap_t () + { + hb_copy (o, *this); + } + + static_assert (std::is_trivially_copyable<K>::value, ""); + static_assert (std::is_trivially_copyable<V>::value, ""); + static_assert (std::is_trivially_destructible<K>::value, ""); + static_assert (std::is_trivially_destructible<V>::value, ""); struct item_t { @@ -70,6 +93,16 @@ struct hb_hashmap_t unsigned int prime; item_t *items; + friend void swap (hb_hashmap_t& a, hb_hashmap_t& b) + { + if (unlikely (!a.successful || !b.successful)) + return; + hb_swap (a.population, b.population); + hb_swap (a.occupancy, b.occupancy); + hb_swap (a.mask, b.mask); + hb_swap (a.prime, b.prime); + hb_swap (a.items, b.items); + } void init_shallow () { successful = true; @@ -133,17 +166,15 @@ struct hb_hashmap_t if (old_items[i].is_real ()) set_with_hash (old_items[i].key, old_items[i].hash, - old_items[i].value); + std::move (old_items[i].value)); hb_free (old_items); return true; } - bool set (K key, V value) - { - return set_with_hash (key, hb_hash (key), value); - } + bool set (K key, const V& value) { return set_with_hash (key, hb_hash (key), value); } + bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); } V get (K key) const { @@ -213,7 +244,8 @@ struct hb_hashmap_t protected: - bool set_with_hash (K key, uint32_t hash, V value) + template <typename VV> + bool set_with_hash (K key, uint32_t hash, VV&& value) { if (unlikely (!successful)) return false; if (unlikely (key == kINVALID)) return true; @@ -320,8 +352,27 @@ struct hb_hashmap_t struct hb_map_t : hb_hashmap_t<hb_codepoint_t, hb_codepoint_t, + hb_codepoint_t, + hb_codepoint_t, HB_MAP_VALUE_INVALID, - HB_MAP_VALUE_INVALID> {}; - + HB_MAP_VALUE_INVALID> +{ + using hashmap = hb_hashmap_t<hb_codepoint_t, + hb_codepoint_t, + hb_codepoint_t, + hb_codepoint_t, + HB_MAP_VALUE_INVALID, + HB_MAP_VALUE_INVALID>; + + hb_map_t () = default; + ~hb_map_t () = 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<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {} + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + hb_map_t (const Iterable &o) : hashmap (o) {} +}; #endif /* HB_MAP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index a714bc2bf0..0ea5774a9f 100644 --- a/thirdparty/harfbuzz/src/hb-meta.hh +++ b/thirdparty/harfbuzz/src/hb-meta.hh @@ -29,6 +29,9 @@ #include "hb.hh" +#include <type_traits> +#include <utility> + /* * C++ template meta-programming & fundamentals used with them. @@ -129,40 +132,7 @@ template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (h /* TODO Add feature-parity to std::decay. */ template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>; - -template<bool B, class T, class F> -struct _hb_conditional { typedef T type; }; -template<class T, class F> -struct _hb_conditional<false, T, F> { typedef F type; }; -template<bool B, class T, class F> -using hb_conditional = typename _hb_conditional<B, T, F>::type; - - -template <typename From, typename To> -struct hb_is_convertible -{ - private: - static constexpr bool from_void = hb_is_same (void, hb_decay<From>); - static constexpr bool to_void = hb_is_same (void, hb_decay<To> ); - static constexpr bool either_void = from_void || to_void; - static constexpr bool both_void = from_void && to_void; - - static hb_true_type impl2 (hb_conditional<to_void, int, To>); - - template <typename T> - static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T))); - template <typename T> - static hb_false_type impl (hb_priority<0>); - public: - static constexpr bool value = both_void || - (!either_void && - decltype (impl<hb_conditional<from_void, int, From>> (hb_prioritize))::value); -}; -#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value - -template <typename Base, typename Derived> -using hb_is_base_of = hb_is_convertible<hb_decay<Derived> *, hb_decay<Base> *>; -#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value +#define hb_is_convertible(From,To) std::is_convertible<From, To>::value template <typename From, typename To> using hb_is_cr_convertible = hb_bool_constant< @@ -172,20 +142,11 @@ using hb_is_cr_convertible = hb_bool_constant< >; #define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value -/* std::move and std::forward */ - -template <typename T> -static constexpr hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); } - -template <typename T> -static constexpr T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; } -template <typename T> -static constexpr T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; } struct { template <typename T> constexpr auto - operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v)) + operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v)) template <typename T> constexpr auto operator () (T *v) const HB_AUTO_RETURN (*v) @@ -195,7 +156,7 @@ HB_FUNCOBJ (hb_deref); struct { template <typename T> constexpr auto - operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v)) + operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v)) template <typename T> constexpr auto operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v)) @@ -226,50 +187,6 @@ struct hb_reference_wrapper<T&> /* Type traits */ -template <typename T> -using hb_is_integral = hb_bool_constant< - hb_is_same (hb_decay<T>, char) || - hb_is_same (hb_decay<T>, signed char) || - hb_is_same (hb_decay<T>, unsigned char) || - hb_is_same (hb_decay<T>, signed int) || - hb_is_same (hb_decay<T>, unsigned int) || - hb_is_same (hb_decay<T>, signed short) || - hb_is_same (hb_decay<T>, unsigned short) || - hb_is_same (hb_decay<T>, signed long) || - hb_is_same (hb_decay<T>, unsigned long) || - hb_is_same (hb_decay<T>, signed long long) || - hb_is_same (hb_decay<T>, unsigned long long) || - false ->; -#define hb_is_integral(T) hb_is_integral<T>::value -template <typename T> -using hb_is_floating_point = hb_bool_constant< - hb_is_same (hb_decay<T>, float) || - hb_is_same (hb_decay<T>, double) || - hb_is_same (hb_decay<T>, long double) || - false ->; -#define hb_is_floating_point(T) hb_is_floating_point<T>::value -template <typename T> -using hb_is_arithmetic = hb_bool_constant< - hb_is_integral (T) || - hb_is_floating_point (T) || - false ->; -#define hb_is_arithmetic(T) hb_is_arithmetic<T>::value - - -template <typename T, bool is_arithmetic> struct hb_is_signed_; -template <typename T> struct hb_is_signed_<T, false> : hb_false_type {}; -template <typename T> struct hb_is_signed_<T, true> : hb_bool_constant<(T) -1 < (T) 0> {}; -template <typename T> struct hb_is_signed : hb_is_signed_<T, hb_is_arithmetic (T)> {}; -#define hb_is_signed(T) hb_is_signed<T>::value -template <typename T, bool is_arithmetic> struct hb_is_unsigned_; -template <typename T> struct hb_is_unsigned_<T, false> : hb_false_type {}; -template <typename T> struct hb_is_unsigned_<T, true> : hb_bool_constant<(T) 0 < (T) -1> {}; -template <typename T> struct hb_is_unsigned : hb_is_unsigned_<T, hb_is_arithmetic (T)> {}; -#define hb_is_unsigned(T) hb_is_unsigned<T>::value - template <typename T> struct hb_int_min; template <> struct hb_int_min<char> : hb_integral_constant<char, CHAR_MIN> {}; template <> struct hb_int_min<signed char> : hb_integral_constant<signed char, SCHAR_MIN> {}; @@ -309,108 +226,6 @@ template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigne TypeName(const TypeName&) = delete; \ void operator=(const TypeName&) = delete -template <typename T, typename> -struct _hb_is_destructible : hb_false_type {}; -template <typename T> -struct _hb_is_destructible<T, hb_void_t<decltype (hb_declval (T).~T ())>> : hb_true_type {}; -template <typename T> -using hb_is_destructible = _hb_is_destructible<T, void>; -#define hb_is_destructible(T) hb_is_destructible<T>::value - -template <typename T, typename, typename ...Ts> -struct _hb_is_constructible : hb_false_type {}; -template <typename T, typename ...Ts> -struct _hb_is_constructible<T, hb_void_t<decltype (T (hb_declval (Ts)...))>, Ts...> : hb_true_type {}; -template <typename T, typename ...Ts> -using hb_is_constructible = _hb_is_constructible<T, void, Ts...>; -#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value - -template <typename T> -using hb_is_default_constructible = hb_is_constructible<T>; -#define hb_is_default_constructible(T) hb_is_default_constructible<T>::value - -template <typename T> -using hb_is_copy_constructible = hb_is_constructible<T, hb_add_lvalue_reference<hb_add_const<T>>>; -#define hb_is_copy_constructible(T) hb_is_copy_constructible<T>::value - -template <typename T> -using hb_is_move_constructible = hb_is_constructible<T, hb_add_rvalue_reference<hb_add_const<T>>>; -#define hb_is_move_constructible(T) hb_is_move_constructible<T>::value - -template <typename T, typename U, typename> -struct _hb_is_assignable : hb_false_type {}; -template <typename T, typename U> -struct _hb_is_assignable<T, U, hb_void_t<decltype (hb_declval (T) = hb_declval (U))>> : hb_true_type {}; -template <typename T, typename U> -using hb_is_assignable = _hb_is_assignable<T, U, void>; -#define hb_is_assignable(T,U) hb_is_assignable<T, U>::value - -template <typename T> -using hb_is_copy_assignable = hb_is_assignable<hb_add_lvalue_reference<T>, - hb_add_lvalue_reference<hb_add_const<T>>>; -#define hb_is_copy_assignable(T) hb_is_copy_assignable<T>::value - -template <typename T> -using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>, - hb_add_rvalue_reference<T>>; -#define hb_is_move_assignable(T) hb_is_move_assignable<T>::value - -/* Trivial versions. */ - -template <typename T> union hb_trivial { T value; }; - -template <typename T> -using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>; -#define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value - -/* Don't know how to do the following. */ -//template <typename T, typename ...Ts> -//using hb_is_trivially_constructible= hb_is_constructible<hb_trivial<T>, hb_trivial<Ts>...>; -//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value - -template <typename T> -using hb_is_trivially_default_constructible= hb_is_default_constructible<hb_trivial<T>>; -#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible<T>::value - -template <typename T> -using hb_is_trivially_copy_constructible= hb_is_copy_constructible<hb_trivial<T>>; -#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible<T>::value - -template <typename T> -using hb_is_trivially_move_constructible= hb_is_move_constructible<hb_trivial<T>>; -#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible<T>::value - -/* Don't know how to do the following. */ -//template <typename T, typename U> -//using hb_is_trivially_assignable= hb_is_assignable<hb_trivial<T>, hb_trivial<U>>; -//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable<T, U>::value - -template <typename T> -using hb_is_trivially_copy_assignable= hb_is_copy_assignable<hb_trivial<T>>; -#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable<T>::value - -template <typename T> -using hb_is_trivially_move_assignable= hb_is_move_assignable<hb_trivial<T>>; -#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable<T>::value - -template <typename T> -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<T>::value - -template <typename T> -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<T>::value - /* hb_unwrap_type (T) * If T has no T::type, returns T. Otherwise calls itself on T::type recursively. */ diff --git a/thirdparty/harfbuzz/src/hb-mutex.hh b/thirdparty/harfbuzz/src/hb-mutex.hh index a9227a741d..6914b22450 100644 --- a/thirdparty/harfbuzz/src/hb-mutex.hh +++ b/thirdparty/harfbuzz/src/hb-mutex.hh @@ -47,7 +47,7 @@ /* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ -#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__)) +#elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && (defined(HAVE_PTHREAD) || defined(__APPLE__)) #include <pthread.h> typedef pthread_mutex_t hb_mutex_impl_t; @@ -57,7 +57,7 @@ typedef pthread_mutex_t hb_mutex_impl_t; #define hb_mutex_impl_finish(M) pthread_mutex_destroy (M) -#elif !defined(HB_NO_MT) && defined(_WIN32) +#elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && defined(_WIN32) typedef CRITICAL_SECTION hb_mutex_impl_t; #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) @@ -70,7 +70,17 @@ typedef CRITICAL_SECTION hb_mutex_impl_t; #define hb_mutex_impl_finish(M) DeleteCriticalSection (M) -#elif defined(HB_NO_MT) +#elif !defined(HB_NO_MT) + +#include <mutex> +typedef std::mutex hb_mutex_impl_t; +#define hb_mutex_impl_init(M) HB_STMT_START { new (M) hb_mutex_impl_t; } HB_STMT_END +#define hb_mutex_impl_lock(M) (M)->lock () +#define hb_mutex_impl_unlock(M) (M)->unlock () +#define hb_mutex_impl_finish(M) HB_STMT_START { (M)->~hb_mutex_impl_t(); } HB_STMT_END + + +#else /* defined(HB_NO_MT) */ typedef int hb_mutex_impl_t; #define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END @@ -79,22 +89,21 @@ typedef int hb_mutex_impl_t; #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END -#else - -#error "Could not find any system to define mutex macros." -#error "Check hb-mutex.hh for possible resolutions." - #endif struct hb_mutex_t { - hb_mutex_impl_t m; - - void init () { hb_mutex_impl_init (&m); } - void lock () { hb_mutex_impl_lock (&m); } - void unlock () { hb_mutex_impl_unlock (&m); } - void fini () { hb_mutex_impl_finish (&m); } + /* Create space for, but do not initialize m. */ + alignas(hb_mutex_impl_t) char m[sizeof (hb_mutex_impl_t)]; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" + void init () { hb_mutex_impl_init ((hb_mutex_impl_t *) m); } + void lock () { hb_mutex_impl_lock ((hb_mutex_impl_t *) m); } + void unlock () { hb_mutex_impl_unlock ((hb_mutex_impl_t *) m); } + void fini () { hb_mutex_impl_finish ((hb_mutex_impl_t *) m); } +#pragma GCC diagnostic pop }; struct hb_lock_t diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index 49653ce97e..7e524177f6 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -64,7 +64,7 @@ struct IntType IntType& operator = (Type i) { v = i; return *this; } /* For reason we define cast out operator for signed/unsigned, instead of Type, see: * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ - operator hb_conditional<hb_is_signed (Type), signed, unsigned> () const { return v; } + operator typename std::conditional<std::is_signed<Type>::value, signed, unsigned>::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); } @@ -86,7 +86,7 @@ struct IntType return pb->cmp (*pa); } template <typename Type2, - hb_enable_if (hb_is_integral (Type2) && + hb_enable_if (std::is_integral<Type2>::value && sizeof (Type2) < sizeof (int) && sizeof (Type) < sizeof (int))> int cmp (Type2 a) const @@ -122,6 +122,15 @@ typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */ * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ +/* 15-bit unsigned number; top bit used for extension. */ +struct HBUINT15 : HBUINT16 +{ + /* TODO Flesh out; actually mask top bit. */ + HBUINT15& operator = (uint16_t i ) { HBUINT16::operator= (i); return *this; } + public: + DEFINE_SIZE_STATIC (2); +}; + /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ typedef HBINT16 FWORD; @@ -182,9 +191,9 @@ struct Tag : HBUINT32 }; /* Glyph index number, same as uint16 (length = 16 bits) */ -struct HBGlyphID : HBUINT16 +struct HBGlyphID16 : HBUINT16 { - HBGlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } + HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } }; /* Script/language-system/feature index */ @@ -332,7 +341,7 @@ struct OffsetTo : Offset<OffsetType, has_null> s->push (); - bool ret = c->dispatch (src_base+src, hb_forward<Ts> (ds)...); + bool ret = c->dispatch (src_base+src, std::forward<Ts> (ds)...); if (ret || !has_null) s->add_link (*this, s->pop_pack ()); @@ -349,7 +358,7 @@ struct OffsetTo : Offset<OffsetType, has_null> *this = 0; Type* obj = c->push<Type> (); - bool ret = obj->serialize (c, hb_forward<Ts> (ds)...); + bool ret = obj->serialize (c, std::forward<Ts> (ds)...); if (ret) c->add_link (*this, c->pop_pack ()); @@ -375,7 +384,7 @@ struct OffsetTo : Offset<OffsetType, has_null> c->push (); - bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...); + bool ret = c->copy (src_base+src, std::forward<Ts> (ds)...); c->add_link (*this, c->pop_pack (), whence, dst_bias); @@ -401,7 +410,7 @@ struct OffsetTo : Offset<OffsetType, has_null> TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && (this->is_null () || - c->dispatch (StructAtOffset<Type> (base, *this), hb_forward<Ts> (ds)...) || + c->dispatch (StructAtOffset<Type> (base, *this), std::forward<Ts> (ds)...) || neuter (c))); } @@ -509,9 +518,9 @@ struct UnsizedArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true); for (unsigned int i = 0; i < count; i++) - if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...))) return_trace (false); return_trace (true); } @@ -556,7 +565,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_ { TRACE_SANITIZE (this); return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null> - ::sanitize (c, count, this, hb_forward<Ts> (ds)...))); + ::sanitize (c, count, this, std::forward<Ts> (ds)...))); } }; @@ -698,10 +707,10 @@ struct ArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...))) return_trace (false); return_trace (true); } @@ -759,7 +768,7 @@ struct List16OfOffset16To : Array16OfOffset16To<Type> bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); - return_trace (Array16OfOffset16To<Type>::sanitize (c, this, hb_forward<Ts> (ds)...)); + return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...)); } }; @@ -826,10 +835,10 @@ struct HeadlessArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...))) return_trace (false); return_trace (true); } @@ -875,10 +884,10 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) + if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...))) return_trace (false); return_trace (true); } @@ -1061,10 +1070,10 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); + if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, hb_forward<Ts> (ds)...))) + if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...))) return_trace (false); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh index eaaf5e12ec..180c87cb89 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh @@ -373,7 +373,7 @@ struct Dict : UnsizedByteStr { TRACE_SERIALIZE (this); for (unsigned int i = 0; i < dictval.get_count (); i++) - if (unlikely (!opszr.serialize (c, dictval[i], hb_forward<Ts> (ds)...))) + if (unlikely (!opszr.serialize (c, dictval[i], std::forward<Ts> (ds)...))) return_trace (false); return_trace (true); diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh index b904bb46a8..d837adc788 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -93,120 +93,192 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { + template<typename Iterator, + typename Writer, hb_requires (hb_is_iterator (Iterator))> - HBUINT16* serialize_endcode_array (hb_serialize_context_t *c, - Iterator it) - { - HBUINT16 *endCode = c->start_embed<HBUINT16> (); - hb_codepoint_t prev_endcp = 0xFFFF; + void to_ranges (Iterator it, Writer& range_writer) + { + hb_codepoint_t start_cp = 0, prev_run_start_cp = 0, run_start_cp = 0, end_cp = 0, last_gid = 0; + int run_length = 0 , delta = 0, prev_delta = 0; + + enum { + FIRST_SUB_RANGE, + FOLLOWING_SUB_RANGE, + } mode; + + while (it) { + // Start a new range + start_cp = (*it).first; + prev_run_start_cp = (*it).first; + run_start_cp = (*it).first; + end_cp = (*it).first; + last_gid = (*it).second; + run_length = 1; + prev_delta = 0; + + delta = (*it).second - (*it).first; + mode = FIRST_SUB_RANGE; + it++; + + while (it) { + // Process range + hb_codepoint_t next_cp = (*it).first; + hb_codepoint_t next_gid = (*it).second; + if (next_cp != end_cp + 1) { + // Current range is over, stop processing. + break; + } - for (const auto& _ : +it) - { - if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first) - { - HBUINT16 end_code; - end_code = prev_endcp; - c->copy<HBUINT16> (end_code); - } - prev_endcp = _.first; - } + if (next_gid == last_gid + 1) { + // The current run continues. + end_cp = next_cp; + run_length++; + last_gid = next_gid; + it++; + continue; + } - { - // last endCode - HBUINT16 endcode; - endcode = prev_endcp; - if (unlikely (!c->copy<HBUINT16> (endcode))) return nullptr; - // There must be a final entry with end_code == 0xFFFF. - if (prev_endcp != 0xFFFF) - { - HBUINT16 finalcode; - finalcode = 0xFFFF; - if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr; + // A new run is starting, decide if we want to commit the current run. + int split_cost = (mode == FIRST_SUB_RANGE) ? 8 : 16; + int run_cost = run_length * 2; + if (run_cost >= split_cost) { + commit_current_range(start_cp, + prev_run_start_cp, + run_start_cp, + end_cp, + delta, + prev_delta, + split_cost, + range_writer); + start_cp = next_cp; + } + + // Start the new run + mode = FOLLOWING_SUB_RANGE; + prev_run_start_cp = run_start_cp; + run_start_cp = next_cp; + end_cp = next_cp; + prev_delta = delta; + delta = next_gid - run_start_cp; + run_length = 1; + last_gid = next_gid; + it++; } + + // Finalize range + commit_current_range (start_cp, + prev_run_start_cp, + run_start_cp, + end_cp, + delta, + prev_delta, + 8, + range_writer); } - return endCode; + if (likely (end_cp != 0xFFFF)) { + range_writer (0xFFFF, 0xFFFF, 1); + } } - template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - HBUINT16* serialize_startcode_array (hb_serialize_context_t *c, - Iterator it) - { - HBUINT16 *startCode = c->start_embed<HBUINT16> (); - hb_codepoint_t prev_cp = 0xFFFF; - - for (const auto& _ : +it) - { - if (prev_cp == 0xFFFF || prev_cp + 1u != _.first) - { - HBUINT16 start_code; - start_code = _.first; - c->copy<HBUINT16> (start_code); + /* + * Writes the current range as either one or two ranges depending on what is most efficient. + */ + template<typename Writer> + void commit_current_range (hb_codepoint_t start, + hb_codepoint_t prev_run_start, + hb_codepoint_t run_start, + hb_codepoint_t end, + int run_delta, + int previous_run_delta, + int split_cost, + Writer& range_writer) { + bool should_split = false; + if (start < run_start && run_start < end) { + int run_cost = (end - run_start + 1) * 2; + if (run_cost >= split_cost) { + should_split = true; } + } - prev_cp = _.first; + // TODO(grieger): handle case where delta is legitimately 0, mark range offset array instead? + if (should_split) { + if (start == prev_run_start) + range_writer (start, run_start - 1, previous_run_delta); + else + range_writer (start, run_start - 1, 0); + range_writer (run_start, end, run_delta); + return; } - // There must be a final entry with end_code == 0xFFFF. - if (it.len () == 0 || prev_cp != 0xFFFF) - { - HBUINT16 finalcode; - finalcode = 0xFFFF; - if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr; + + if (start == run_start) { + // Range is only a run + range_writer (start, end, run_delta); + return; } - return startCode; + // Write only a single non-run range. + range_writer (start, end, 0); } template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - HBINT16* serialize_idDelta_array (hb_serialize_context_t *c, - Iterator it, - HBUINT16 *endCode, - HBUINT16 *startCode, - unsigned segcount) - { - unsigned i = 0; - hb_codepoint_t last_gid = 0, start_gid = 0, last_cp = 0xFFFF; - bool use_delta = true; - - HBINT16 *idDelta = c->start_embed<HBINT16> (); - if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size) - return nullptr; - - for (const auto& _ : +it) - { - if (_.first == startCode[i]) - { - use_delta = true; - start_gid = _.second; + unsigned serialize_find_segcount (Iterator it) { + struct Counter { + unsigned segcount = 0; + + void operator() (hb_codepoint_t start, + hb_codepoint_t end, + int delta) { + segcount++; } - else if (_.second != last_gid + 1) use_delta = false; + } counter; - if (_.first == endCode[i]) - { - HBINT16 delta; - if (use_delta) delta = (int)start_gid - (int)startCode[i]; - else delta = 0; - c->copy<HBINT16> (delta); + to_ranges (+it, counter); + return counter.segcount; + } - i++; + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize_start_end_delta_arrays (hb_serialize_context_t *c, + Iterator it, + int segcount) + { + struct Writer { + hb_serialize_context_t *serializer_; + HBUINT16* end_code_; + HBUINT16* start_code_; + HBINT16* id_delta_; + int index_; + + Writer(hb_serialize_context_t *serializer) + : serializer_(serializer), + end_code_(nullptr), + start_code_(nullptr), + id_delta_(nullptr), + index_ (0) {} + void operator() (hb_codepoint_t start, + hb_codepoint_t end, + int delta) { + start_code_[index_] = start; + end_code_[index_] = end; + id_delta_[index_] = delta; + index_++; } + } writer(c); - last_gid = _.second; - last_cp = _.first; - } + writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); + c->allocate_size<HBUINT16> (2); // padding + writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); + writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount); - if (it.len () == 0 || last_cp != 0xFFFF) - { - HBINT16 delta; - delta = 1; - if (unlikely (!c->copy<HBINT16> (delta))) return nullptr; - } + if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false; - return idDelta; + to_ranges (+it, writer); + return true; } template<typename Iterator, @@ -257,22 +329,14 @@ struct CmapSubtableFormat4 if (unlikely (!c->extend_min (this))) return; this->format = 4; - //serialize endCode[] - HBUINT16 *endCode = serialize_endcode_array (c, format4_iter); - if (unlikely (!endCode)) return; - - unsigned segcount = (c->length () - min_size) / HBUINT16::static_size; - - // 2 bytes of padding. - if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding. - - // serialize startCode[] - HBUINT16 *startCode = serialize_startcode_array (c, format4_iter); - if (unlikely (!startCode)) return; + //serialize endCode[], startCode[], idDelta[] + HBUINT16* endCode = c->start_embed<HBUINT16> (); + unsigned segcount = serialize_find_segcount (format4_iter); + if (unlikely (!serialize_start_end_delta_arrays (c, format4_iter, segcount))) + return; - //serialize idDelta[] - HBINT16 *idDelta = serialize_idDelta_array (c, format4_iter, endCode, startCode, segcount); - if (unlikely (!idDelta)) return; + HBUINT16 *startCode = endCode + segcount + 1; + HBINT16 *idDelta = ((HBINT16*)startCode) + segcount; HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, format4_iter, endCode, startCode, idDelta, segcount); if (unlikely (!c->check_success (idRangeOffset))) return; @@ -604,7 +668,7 @@ struct CmapSubtableTrimmed UINT length; /* Byte length of this subtable. */ UINT language; /* Ignore. */ UINT startCharCode; /* First character code covered. */ - ArrayOf<HBGlyphID, UINT> + ArrayOf<HBGlyphID16, UINT> glyphIdArray; /* Array of glyph index values for character * codes in the range. */ public: @@ -900,7 +964,7 @@ struct UVSMapping } HBUINT24 unicodeValue; /* Base Unicode value of the UVS */ - HBGlyphID glyphID; /* Glyph ID of the UVS */ + HBGlyphID16 glyphID; /* Glyph ID of the UVS */ public: DEFINE_SIZE_STATIC (5); }; diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh index 6c31d1b53e..14459914ee 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh @@ -508,8 +508,8 @@ struct IndexSubtableRecord offset, length, format); } - HBGlyphID firstGlyphIndex; - HBGlyphID lastGlyphIndex; + HBGlyphID16 firstGlyphIndex; + HBGlyphID16 lastGlyphIndex; Offset32To<IndexSubtable> offsetToSubtable; public: DEFINE_SIZE_STATIC (8); @@ -679,8 +679,8 @@ struct BitmapSizeTable HBUINT32 colorRef; SBitLineMetrics horizontal; SBitLineMetrics vertical; - HBGlyphID startGlyphIndex; - HBGlyphID endGlyphIndex; + HBGlyphID16 startGlyphIndex; + HBGlyphID16 endGlyphIndex; HBUINT8 ppemX; HBUINT8 ppemY; HBUINT8 bitDepth; diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index 007ff3f47b..008422d089 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" +#include "hb-ot-var-common.hh" /* * COLR -- Color @@ -37,12 +38,12 @@ */ #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 -#define COLRV1_ENABLE_SUBSETTING 0 +#define COLRV1_ENABLE_SUBSETTING 1 #endif namespace OT { @@ -101,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_), @@ -121,7 +122,7 @@ struct LayerRecord } public: - HBGlyphID glyphId; /* Glyph ID of layer glyph */ + HBGlyphID16 glyphId; /* Glyph ID of layer glyph */ Index colorIdx; /* Index value to use with a * selected color palette. * An index value of 0xFFFF @@ -148,7 +149,7 @@ struct BaseGlyphRecord } public: - HBGlyphID glyphId; /* Glyph ID of reference glyph */ + HBGlyphID16 glyphId; /* Glyph ID of reference glyph */ HBUINT16 firstLayerIdx; /* Index (from beginning of * the Layer Records) to the * layer record. There will be @@ -163,15 +164,31 @@ struct BaseGlyphRecord template <typename T> struct Variable { + Variable<T>* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); + } + + void closurev1 (hb_colrv1_closure_context_t* c) const + { value.closurev1 (c); } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + if (!value.subset (c)) return_trace (false); + return_trace (c->serializer->embed (varIdxBase)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (c->check_struct (this) && value.sanitize (c)); } protected: T value; - VarIdx varIdx; + VarIdx varIdxBase; public: DEFINE_SIZE_STATIC (4 + T::static_size); }; @@ -179,51 +196,46 @@ struct Variable template <typename T> struct NoVariable { - bool sanitize (hb_sanitize_context_t *c) const + NoVariable<T>* copy (hb_serialize_context_t *c) const { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); } - T value; - public: - DEFINE_SIZE_STATIC (T::static_size); -}; - -// Color structures + void closurev1 (hb_colrv1_closure_context_t* c) const + { value.closurev1 (c); } -template <template<typename> class Var> -struct ColorIndex -{ bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex), - HB_SERIALIZE_ERROR_INT_OVERFLOW)); + return_trace (value.subset (c)); } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (c->check_struct (this) && value.sanitize (c)); } - HBUINT16 paletteIndex; - Var<F2DOT14> alpha; + T value; public: - DEFINE_SIZE_STATIC (2 + Var<F2DOT14>::static_size); + DEFINE_SIZE_STATIC (T::static_size); }; -template <template<typename> class Var> +// Color structures + struct ColorStop { + void closurev1 (hb_colrv1_closure_context_t* c) const + { c->add_palette_index (paletteIndex); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - if (unlikely (!c->serializer->embed (stopOffset))) return_trace (false); - return_trace (color.subset (c)); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -232,10 +244,11 @@ struct ColorStop return_trace (c->check_struct (this)); } - Var<F2DOT14> stopOffset; - ColorIndex<Var> color; + F2DOT14 stopOffset; + HBUINT16 paletteIndex; + F2DOT14 alpha; public: - DEFINE_SIZE_STATIC (Var<F2DOT14>::static_size + ColorIndex<Var>::static_size); + DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size); }; struct Extend : HBUINT8 @@ -252,6 +265,12 @@ struct Extend : HBUINT8 template <template<typename> class Var> struct ColorLine { + void closurev1 (hb_colrv1_closure_context_t* c) const + { + for (const auto &stop : stops.iter ()) + stop.closurev1 (c); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -276,8 +295,8 @@ struct ColorLine stops.sanitize (c)); } - Extend extend; - Array16Of<ColorStop<Var>> stops; + Extend extend; + Array16Of<Var<ColorStop>> stops; public: DEFINE_SIZE_ARRAY_SIZED (3, stops); }; @@ -331,7 +350,6 @@ struct CompositeMode : HBUINT8 DEFINE_SIZE_STATIC (1); }; -template <template<typename> class Var> struct Affine2x3 { bool sanitize (hb_sanitize_context_t *c) const @@ -340,14 +358,14 @@ struct Affine2x3 return_trace (c->check_struct (this)); } - Var<HBFixed> xx; - Var<HBFixed> yx; - Var<HBFixed> xy; - Var<HBFixed> yy; - Var<HBFixed> dx; - Var<HBFixed> dy; + HBFixed xx; + HBFixed yx; + HBFixed xy; + HBFixed yy; + HBFixed dx; + HBFixed dy; public: - DEFINE_SIZE_STATIC (6 * Var<HBFixed>::static_size); + DEFINE_SIZE_STATIC (6 * HBFixed::static_size); }; struct PaintColrLayers @@ -373,22 +391,23 @@ struct PaintColrLayers HBUINT8 format; /* format = 1 */ HBUINT8 numLayers; - HBUINT32 firstLayerIndex; /* index into COLRv1::layersV1 */ + HBUINT32 firstLayerIndex; /* index into COLRv1::layerList */ public: DEFINE_SIZE_STATIC (6); }; -template <template<typename> class Var> struct PaintSolid { void closurev1 (hb_colrv1_closure_context_t* c) const - { c->add_palette_index (color.paletteIndex); } + { c->add_palette_index (paletteIndex); } bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - if (unlikely (!c->serializer->embed (format))) return_trace (false); - return_trace (color.subset (c)); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -397,20 +416,18 @@ struct PaintSolid return_trace (c->check_struct (this)); } - HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ - ColorIndex<Var> color; + HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ + HBUINT16 paletteIndex; + F2DOT14 alpha; public: - DEFINE_SIZE_STATIC (1 + ColorIndex<Var>::static_size); + DEFINE_SIZE_STATIC (3 + F2DOT14::static_size); }; template <template<typename> class Var> struct PaintLinearGradient { void closurev1 (hb_colrv1_closure_context_t* c) const - { - for (const auto &stop : (this+colorLine).stops.iter ()) - c->add_palette_index (stop.color.paletteIndex); - } + { (this+colorLine).closurev1 (c); } bool subset (hb_subset_context_t *c) const { @@ -430,19 +447,22 @@ struct PaintLinearGradient HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ Offset24To<ColorLine<Var>> colorLine; /* Offset (from beginning of PaintLinearGradient * table) to ColorLine subtable. */ - Var<FWORD> x0; - Var<FWORD> y0; - Var<FWORD> x1; - Var<FWORD> y1; - Var<FWORD> x2; - Var<FWORD> y2; + FWORD x0; + FWORD y0; + FWORD x1; + FWORD y1; + FWORD x2; + FWORD y2; public: - DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size); + DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size); }; template <template<typename> class Var> struct PaintRadialGradient { + void closurev1 (hb_colrv1_closure_context_t* c) const + { (this+colorLine).closurev1 (c); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -452,12 +472,6 @@ struct PaintRadialGradient return_trace (out->colorLine.serialize_subset (c, colorLine, this)); } - void closurev1 (hb_colrv1_closure_context_t* c) const - { - for (const auto &stop : (this+colorLine).stops.iter ()) - c->add_palette_index (stop.color.paletteIndex); - } - bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -467,19 +481,22 @@ struct PaintRadialGradient HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ Offset24To<ColorLine<Var>> colorLine; /* Offset (from beginning of PaintRadialGradient * table) to ColorLine subtable. */ - Var<FWORD> x0; - Var<FWORD> y0; - Var<UFWORD> radius0; - Var<FWORD> x1; - Var<FWORD> y1; - Var<UFWORD> radius1; + FWORD x0; + FWORD y0; + UFWORD radius0; + FWORD x1; + FWORD y1; + UFWORD radius1; public: - DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size); + DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size); }; template <template<typename> class Var> struct PaintSweepGradient { + void closurev1 (hb_colrv1_closure_context_t* c) const + { (this+colorLine).closurev1 (c); } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -489,12 +506,6 @@ struct PaintSweepGradient return_trace (out->colorLine.serialize_subset (c, colorLine, this)); } - void closurev1 (hb_colrv1_closure_context_t* c) const - { - for (const auto &stop : (this+colorLine).stops.iter ()) - c->add_palette_index (stop.color.paletteIndex); - } - bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -504,12 +515,12 @@ struct PaintSweepGradient HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ Offset24To<ColorLine<Var>> colorLine; /* Offset (from beginning of PaintSweepGradient * table) to ColorLine subtable. */ - Var<FWORD> centerX; - Var<FWORD> centerY; - Var<HBFixed> startAngle; - Var<HBFixed> endAngle; + FWORD centerX; + FWORD centerY; + F2DOT14 startAngle; + F2DOT14 endAngle; public: - DEFINE_SIZE_STATIC (2 * Var<FWORD>::static_size + 2 * Var<HBFixed>::static_size); + DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size); }; struct Paint; @@ -580,24 +591,25 @@ struct PaintTransform TRACE_SUBSET (this); auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - + if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false); return_trace (out->src.serialize_subset (c, src, this)); } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && src.sanitize (c, this)); + return_trace (c->check_struct (this) && + src.sanitize (c, this) && + transform.sanitize (c, this)); } - HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ - Offset24To<Paint> src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */ - Affine2x3<Var> transform; + HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */ + Offset24To<Var<Affine2x3>> transform; public: - DEFINE_SIZE_STATIC (4 + Affine2x3<Var>::static_size); + DEFINE_SIZE_STATIC (7); }; -template <template<typename> class Var> struct PaintTranslate { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; @@ -619,14 +631,13 @@ struct PaintTranslate HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ Offset24To<Paint> src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */ - Var<HBFixed> dx; - Var<HBFixed> dy; + FWORD dx; + FWORD dy; public: - DEFINE_SIZE_STATIC (4 + Var<HBFixed>::static_size); + DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size); }; -template <template<typename> class Var> -struct PaintRotate +struct PaintScale { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; @@ -646,15 +657,150 @@ struct PaintRotate } HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintScale table) to Paint subtable. */ + F2DOT14 scaleX; + F2DOT14 scaleY; + public: + DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size); +}; + +struct PaintScaleAroundCenter +{ + HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->src.serialize_subset (c, src, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && src.sanitize (c, this)); + } + + HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */ + F2DOT14 scaleX; + F2DOT14 scaleY; + FWORD centerX; + FWORD centerY; + public: + DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size); +}; + +struct PaintScaleUniform +{ + HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->src.serialize_subset (c, src, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && src.sanitize (c, this)); + } + + HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */ + F2DOT14 scale; + public: + DEFINE_SIZE_STATIC (4 + F2DOT14::static_size); +}; + +struct PaintScaleUniformAroundCenter +{ + HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->src.serialize_subset (c, src, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && src.sanitize (c, this)); + } + + HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */ + F2DOT14 scale; + FWORD centerX; + FWORD centerY; + public: + DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size); +}; + +struct PaintRotate +{ + HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->src.serialize_subset (c, src, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && src.sanitize (c, this)); + } + + HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ Offset24To<Paint> src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */ - Var<HBFixed> angle; - Var<HBFixed> centerX; - Var<HBFixed> centerY; + F2DOT14 angle; public: - DEFINE_SIZE_STATIC (4 + 3 * Var<HBFixed>::static_size); + DEFINE_SIZE_STATIC (4 + F2DOT14::static_size); +}; + +struct PaintRotateAroundCenter +{ + HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->src.serialize_subset (c, src, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && src.sanitize (c, this)); + } + + HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */ + F2DOT14 angle; + FWORD centerX; + FWORD centerY; + public: + DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size); }; -template <template<typename> class Var> struct PaintSkew { HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; @@ -674,14 +820,41 @@ struct PaintSkew return_trace (c->check_struct (this) && src.sanitize (c, this)); } - HBUINT8 format; /* format = 18(noVar) or 19 (Var) */ + HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ Offset24To<Paint> src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */ - Var<HBFixed> xSkewAngle; - Var<HBFixed> ySkewAngle; - Var<HBFixed> centerX; - Var<HBFixed> centerY; + F2DOT14 xSkewAngle; + F2DOT14 ySkewAngle; + public: + DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size); +}; + +struct PaintSkewAroundCenter +{ + HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const; + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + return_trace (out->src.serialize_subset (c, src, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && src.sanitize (c, this)); + } + + HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */ + F2DOT14 xSkewAngle; + F2DOT14 ySkewAngle; + FWORD centerX; + FWORD centerY; public: - DEFINE_SIZE_STATIC (4 + 4 * Var<HBFixed>::static_size); + DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size); }; struct PaintComposite @@ -706,7 +879,7 @@ struct PaintComposite backdrop.sanitize (c, this)); } - HBUINT8 format; /* format = 20 */ + HBUINT8 format; /* format = 32 */ Offset24To<Paint> src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */ CompositeMode mode; /* If mode is unrecognized use COMPOSITE_CLEAR */ Offset24To<Paint> backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */ @@ -714,65 +887,274 @@ struct PaintComposite DEFINE_SIZE_STATIC (8); }; +struct ClipBoxFormat1 +{ + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: + HBUINT8 format; /* format = 1(noVar) or 2(Var)*/ + FWORD xMin; + FWORD yMin; + FWORD xMax; + FWORD yMax; + public: + DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size); +}; + +struct ClipBoxFormat2 : Variable<ClipBoxFormat1> {}; + +struct ClipBox +{ + ClipBox* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + switch (u.format) { + case 1: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format1))); + case 2: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format2))); + default:return_trace (nullptr); + } + } + + template <typename context_t, typename ...Ts> + 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, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + + protected: + union { + HBUINT8 format; /* Format identifier */ + ClipBoxFormat1 format1; + ClipBoxFormat2 format2; + } u; +}; + +struct ClipRecord +{ + ClipRecord* copy (hb_serialize_context_t *c, const void *base) const + { + TRACE_SERIALIZE (this); + auto *out = c->embed (this); + if (unlikely (!out)) return_trace (nullptr); + if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr); + return_trace (out); + } + + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && clipBox.sanitize (c, base)); + } + + public: + HBUINT16 startGlyphID; // first gid clip applies to + HBUINT16 endGlyphID; // last gid clip applies to, inclusive + Offset24To<ClipBox> clipBox; // Box or VarBox + public: + DEFINE_SIZE_STATIC (7); +}; + +struct ClipList +{ + unsigned serialize_clip_records (hb_serialize_context_t *c, + const hb_set_t& gids, + const hb_map_t& gid_offset_map) const + { + TRACE_SERIALIZE (this); + if (gids.is_empty () || + gid_offset_map.get_population () != gids.get_population ()) + return_trace (0); + + unsigned count = 0; + + hb_codepoint_t start_gid= gids.get_min (); + hb_codepoint_t prev_gid = start_gid; + + unsigned offset = gid_offset_map.get (start_gid); + unsigned prev_offset = offset; + for (const hb_codepoint_t _ : gids.iter ()) + { + if (_ == start_gid) continue; + + offset = gid_offset_map.get (_); + if (_ == prev_gid + 1 && offset == prev_offset) + { + prev_gid = _; + continue; + } + + ClipRecord record; + record.startGlyphID = start_gid; + record.endGlyphID = prev_gid; + record.clipBox = prev_offset; + + if (!c->copy (record, this)) return_trace (0); + count++; + + start_gid = _; + prev_gid = _; + prev_offset = offset; + } + + //last one + { + ClipRecord record; + record.startGlyphID = start_gid; + record.endGlyphID = prev_gid; + record.clipBox = prev_offset; + if (!c->copy (record, this)) return_trace (0); + count++; + } + return_trace (count); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); + + const hb_set_t& glyphset = *c->plan->_glyphset_colred; + 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 ()) + { + unsigned start_gid = record.startGlyphID; + unsigned end_gid = record.endGlyphID; + for (unsigned gid = start_gid; gid <= end_gid; gid++) + { + if (!glyphset.has (gid) || !glyph_map.has (gid)) continue; + unsigned new_gid = glyph_map.get (gid); + new_gid_offset_map.set (new_gid, record.clipBox); + new_gids.add (new_gid); + } + } + + unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map); + if (!count) return_trace (false); + return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && clips.sanitize (c, this)); + } + + HBUINT8 format; // Set to 1. + Array32Of<ClipRecord> clips; // Clip records, sorted by startGlyphID + public: + DEFINE_SIZE_ARRAY_SIZED (5, clips); +}; + struct Paint { + + template <typename ...Ts> + 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<Ts> (ds)...))); + } + template <typename context_t, typename ...Ts> 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.paintformat1, hb_forward<Ts> (ds)...)); - case 2: return_trace (c->dispatch (u.paintformat2, hb_forward<Ts> (ds)...)); - case 3: return_trace (c->dispatch (u.paintformat3, hb_forward<Ts> (ds)...)); - case 4: return_trace (c->dispatch (u.paintformat4, hb_forward<Ts> (ds)...)); - case 5: return_trace (c->dispatch (u.paintformat5, hb_forward<Ts> (ds)...)); - case 6: return_trace (c->dispatch (u.paintformat6, hb_forward<Ts> (ds)...)); - case 7: return_trace (c->dispatch (u.paintformat7, hb_forward<Ts> (ds)...)); - case 8: return_trace (c->dispatch (u.paintformat8, hb_forward<Ts> (ds)...)); - case 9: return_trace (c->dispatch (u.paintformat9, hb_forward<Ts> (ds)...)); - case 10: return_trace (c->dispatch (u.paintformat10, hb_forward<Ts> (ds)...)); - case 11: return_trace (c->dispatch (u.paintformat11, hb_forward<Ts> (ds)...)); - case 12: return_trace (c->dispatch (u.paintformat12, hb_forward<Ts> (ds)...)); - case 13: return_trace (c->dispatch (u.paintformat13, hb_forward<Ts> (ds)...)); - case 14: return_trace (c->dispatch (u.paintformat14, hb_forward<Ts> (ds)...)); - case 15: return_trace (c->dispatch (u.paintformat15, hb_forward<Ts> (ds)...)); - case 16: return_trace (c->dispatch (u.paintformat16, hb_forward<Ts> (ds)...)); - case 17: return_trace (c->dispatch (u.paintformat17, hb_forward<Ts> (ds)...)); - case 18: return_trace (c->dispatch (u.paintformat18, hb_forward<Ts> (ds)...)); - case 19: return_trace (c->dispatch (u.paintformat19, hb_forward<Ts> (ds)...)); - case 20: return_trace (c->dispatch (u.paintformat20, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.paintformat1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.paintformat3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.paintformat4, std::forward<Ts> (ds)...)); + case 5: return_trace (c->dispatch (u.paintformat5, std::forward<Ts> (ds)...)); + case 6: return_trace (c->dispatch (u.paintformat6, std::forward<Ts> (ds)...)); + case 7: return_trace (c->dispatch (u.paintformat7, std::forward<Ts> (ds)...)); + case 8: return_trace (c->dispatch (u.paintformat8, std::forward<Ts> (ds)...)); + case 9: return_trace (c->dispatch (u.paintformat9, std::forward<Ts> (ds)...)); + case 10: return_trace (c->dispatch (u.paintformat10, std::forward<Ts> (ds)...)); + case 11: return_trace (c->dispatch (u.paintformat11, std::forward<Ts> (ds)...)); + case 12: return_trace (c->dispatch (u.paintformat12, std::forward<Ts> (ds)...)); + case 13: return_trace (c->dispatch (u.paintformat13, std::forward<Ts> (ds)...)); + case 14: return_trace (c->dispatch (u.paintformat14, std::forward<Ts> (ds)...)); + case 15: return_trace (c->dispatch (u.paintformat15, std::forward<Ts> (ds)...)); + case 16: return_trace (c->dispatch (u.paintformat16, std::forward<Ts> (ds)...)); + case 17: return_trace (c->dispatch (u.paintformat17, std::forward<Ts> (ds)...)); + case 18: return_trace (c->dispatch (u.paintformat18, std::forward<Ts> (ds)...)); + case 19: return_trace (c->dispatch (u.paintformat19, std::forward<Ts> (ds)...)); + case 20: return_trace (c->dispatch (u.paintformat20, std::forward<Ts> (ds)...)); + case 21: return_trace (c->dispatch (u.paintformat21, std::forward<Ts> (ds)...)); + case 22: return_trace (c->dispatch (u.paintformat22, std::forward<Ts> (ds)...)); + case 23: return_trace (c->dispatch (u.paintformat23, std::forward<Ts> (ds)...)); + case 24: return_trace (c->dispatch (u.paintformat24, std::forward<Ts> (ds)...)); + case 25: return_trace (c->dispatch (u.paintformat25, std::forward<Ts> (ds)...)); + case 26: return_trace (c->dispatch (u.paintformat26, std::forward<Ts> (ds)...)); + case 27: return_trace (c->dispatch (u.paintformat27, std::forward<Ts> (ds)...)); + case 28: return_trace (c->dispatch (u.paintformat28, std::forward<Ts> (ds)...)); + case 29: return_trace (c->dispatch (u.paintformat29, std::forward<Ts> (ds)...)); + case 30: return_trace (c->dispatch (u.paintformat30, std::forward<Ts> (ds)...)); + case 31: return_trace (c->dispatch (u.paintformat31, std::forward<Ts> (ds)...)); + case 32: return_trace (c->dispatch (u.paintformat32, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } protected: union { - HBUINT8 format; - PaintColrLayers paintformat1; - PaintSolid<NoVariable> paintformat2; - PaintSolid<Variable> paintformat3; - PaintLinearGradient<NoVariable> paintformat4; - PaintLinearGradient<Variable> paintformat5; - PaintRadialGradient<NoVariable> paintformat6; - PaintRadialGradient<Variable> paintformat7; - PaintSweepGradient<NoVariable> paintformat8; - PaintSweepGradient<Variable> paintformat9; - PaintGlyph paintformat10; - PaintColrGlyph paintformat11; - PaintTransform<NoVariable> paintformat12; - PaintTransform<Variable> paintformat13; - PaintTranslate<NoVariable> paintformat14; - PaintTranslate<Variable> paintformat15; - PaintRotate<NoVariable> paintformat16; - PaintRotate<Variable> paintformat17; - PaintSkew<NoVariable> paintformat18; - PaintSkew<Variable> paintformat19; - PaintComposite paintformat20; + HBUINT8 format; + PaintColrLayers paintformat1; + PaintSolid paintformat2; + Variable<PaintSolid> paintformat3; + PaintLinearGradient<NoVariable> paintformat4; + Variable<PaintLinearGradient<Variable>> paintformat5; + PaintRadialGradient<NoVariable> paintformat6; + Variable<PaintRadialGradient<Variable>> paintformat7; + PaintSweepGradient<NoVariable> paintformat8; + Variable<PaintSweepGradient<Variable>> paintformat9; + PaintGlyph paintformat10; + PaintColrGlyph paintformat11; + PaintTransform<NoVariable> paintformat12; + PaintTransform<Variable> paintformat13; + PaintTranslate paintformat14; + Variable<PaintTranslate> paintformat15; + PaintScale paintformat16; + Variable<PaintScale> paintformat17; + PaintScaleAroundCenter paintformat18; + Variable<PaintScaleAroundCenter> paintformat19; + PaintScaleUniform paintformat20; + Variable<PaintScaleUniform> paintformat21; + PaintScaleUniformAroundCenter paintformat22; + Variable<PaintScaleUniformAroundCenter> paintformat23; + PaintRotate paintformat24; + Variable<PaintRotate> paintformat25; + PaintRotateAroundCenter paintformat26; + Variable<PaintRotateAroundCenter> paintformat27; + PaintSkew paintformat28; + Variable<PaintSkew> paintformat29; + PaintSkewAroundCenter paintformat30; + Variable<PaintSkewAroundCenter> paintformat31; + PaintComposite paintformat32; } u; }; -struct BaseGlyphV1Record +struct BaseGlyphPaintRecord { int cmp (hb_codepoint_t g) const { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } @@ -797,21 +1179,21 @@ struct BaseGlyphV1Record } public: - HBGlyphID glyphId; /* Glyph ID of reference glyph */ - Offset32To<Paint> paint; /* Offset (from beginning of BaseGlyphV1Record array) to Paint, + HBGlyphID16 glyphId; /* Glyph ID of reference glyph */ + Offset32To<Paint> paint; /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint, * Typically PaintColrLayers */ public: DEFINE_SIZE_STATIC (6); }; -struct BaseGlyphV1List : SortedArray32Of<BaseGlyphV1Record> +struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord> { bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - const hb_set_t* glyphset = c->plan->_glyphset; + const hb_set_t* glyphset = c->plan->_glyphset_colred; for (const auto& _ : as_array ()) { @@ -828,11 +1210,11 @@ struct BaseGlyphV1List : SortedArray32Of<BaseGlyphV1Record> bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (SortedArray32Of<BaseGlyphV1Record>::sanitize (c, this)); + return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this)); } }; -struct LayerV1List : Array32OfOffset32To<Paint> +struct LayerList : Array32OfOffset32To<Paint> { const Paint& get_paint (unsigned i) const { return this+(*this)[i]; } @@ -952,24 +1334,24 @@ struct COLR hb_set_t visited_glyphs; hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); - const BaseGlyphV1List &baseglyphV1_records = this+baseGlyphsV1List; + const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; - for (const BaseGlyphV1Record &baseglyphV1record: baseglyphV1_records.iter ()) + for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ()) { - unsigned gid = baseglyphV1record.glyphId; + unsigned gid = baseglyph_paintrecord.glyphId; if (!glyphset->has (gid)) continue; - const Paint &paint = &baseglyphV1_records+baseglyphV1record.paint; + const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint; paint.dispatch (&c); } hb_set_union (glyphset, &visited_glyphs); } - const LayerV1List& get_layerV1List () const - { return (this+layersV1); } + const LayerList& get_layerList () const + { return (this+layerList); } - const BaseGlyphV1List& get_baseglyphV1List () const - { return (this+baseGlyphsV1List); } + const BaseGlyphList& get_baseglyphList () const + { return (this+baseGlyphList); } bool sanitize (hb_sanitize_context_t *c) const { @@ -979,8 +1361,10 @@ struct COLR (this+layersZ).sanitize (c, numLayers) && (version == 0 || (COLRV1_ENABLE_SUBSETTING && version == 1 && - baseGlyphsV1List.sanitize (c, this) && - layersV1.sanitize (c, this) && + baseGlyphList.sanitize (c, this) && + layerList.sanitize (c, this) && + clipList.sanitize (c, this) && + varIdxMap.sanitize (c, this) && varStore.sanitize (c, this)))); } @@ -996,19 +1380,17 @@ struct COLR if (unlikely (base_it.len () != layer_it.len ())) return_trace (false); - if (unlikely (!c->extend_min (this))) return_trace (false); this->version = version; numLayers = 0; numBaseGlyphs = base_it.len (); - if (base_it.len () == 0) + if (numBaseGlyphs == 0) { baseGlyphsZ = 0; layersZ = 0; return_trace (true); } - baseGlyphsZ = COLR::min_size; - layersZ = COLR::min_size + numBaseGlyphs * BaseGlyphRecord::min_size; + c->push (); for (const hb_item_type<BaseIterator> _ : + base_it.iter ()) { auto* record = c->embed (_); @@ -1016,26 +1398,29 @@ struct COLR record->firstLayerIdx = numLayers; numLayers += record->numLayers; } + c->add_link (baseGlyphsZ, c->pop_pack ()); + c->push (); for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ()) _.as_array ().copy (c); + c->add_link (layersZ, c->pop_pack ()); + return_trace (true); } const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const { - if ((unsigned int) gid == 0) // Ignore notdef. - return nullptr; const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid); - if ((record && (hb_codepoint_t) record->glyphId != gid)) + if (record == &Null (BaseGlyphRecord) || + (record && (hb_codepoint_t) record->glyphId != gid)) record = nullptr; return record; } - const BaseGlyphV1Record* get_base_glyphV1_record (hb_codepoint_t gid) const + const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const { - const BaseGlyphV1Record* record = &(this+baseGlyphsV1List).bsearch ((unsigned) gid); + const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid); if ((record && (hb_codepoint_t) record->glyphId != gid)) record = nullptr; return record; @@ -1046,9 +1431,16 @@ struct COLR TRACE_SUBSET (this); const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map; + const hb_set_t& glyphset = *c->plan->_glyphset_colred; auto base_it = + hb_range (c->plan->num_output_glyphs ()) + | hb_filter ([&](hb_codepoint_t new_gid) + { + hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); + if (glyphset.has (old_gid)) return true; + return false; + }) | hb_map_retains_sorting ([&](hb_codepoint_t new_gid) { hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); @@ -1056,7 +1448,6 @@ struct COLR const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); if (unlikely (!old_record)) return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord)); - BaseGlyphRecord new_record = {}; new_record.glyphId = new_gid; new_record.numLayers = old_record->numLayers; @@ -1069,6 +1460,7 @@ struct COLR auto layer_it = + hb_range (c->plan->num_output_glyphs ()) | hb_map (reverse_glyph_map) + | hb_filter (glyphset) | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) { const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid); @@ -1101,23 +1493,26 @@ struct COLR return_trace (false); COLR *colr_prime = c->serializer->start_embed<COLR> (); - bool ret = colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it); + if (unlikely (!c->serializer->extend_min (colr_prime))) return_trace (false); + + if (version == 0) + return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)); - if (version == 0) return_trace (ret); auto snap = c->serializer->snapshot (); - if (!c->serializer->allocate_size<void> (3 * HBUINT32::static_size)) return_trace (false); - if (!colr_prime->baseGlyphsV1List.serialize_subset (c, baseGlyphsV1List, this)) + if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false); + if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this)) { if (c->serializer->in_error ()) return_trace (false); //no more COLRv1 glyphs: downgrade to version 0 c->serializer->revert (snap); - colr_prime->version = 0; - return_trace (true); + return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it)); } - if (!colr_prime->layersV1.serialize_subset (c, layersV1, this)) return_trace (false); + if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false); - colr_prime->varStore = 0; + colr_prime->layerList.serialize_subset (c, layerList, this); + colr_prime->clipList.serialize_subset (c, clipList, this); + colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this); //TODO: subset varStore once it's implemented in fonttools return_trace (true); } @@ -1131,8 +1526,10 @@ struct COLR layersZ; /* Offset to Layer Records. */ HBUINT16 numLayers; /* Number of Layer Records. */ // Version-1 additions - Offset32To<BaseGlyphV1List> baseGlyphsV1List; - Offset32To<LayerV1List> layersV1; + Offset32To<BaseGlyphList> baseGlyphList; + Offset32To<LayerList> layerList; + Offset32To<ClipList> clipList; // Offset to ClipList table (may be NULL) + Offset32To<DeltaSetIndexMap> varIdxMap; // Offset to DeltaSetIndexMap table (may be NULL) Offset32To<VariationStore> varStore; public: DEFINE_SIZE_MIN (14); diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh b/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh index 4124efe0b1..ca85ba6ad6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh @@ -40,7 +40,7 @@ namespace OT { HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const { c->add_layer_indices (firstLayerIndex, numLayers); - const LayerV1List &paint_offset_lists = c->get_colr_table ()->get_layerV1List (); + const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i]; @@ -57,37 +57,44 @@ HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const { const COLR *colr_table = c->get_colr_table (); - const BaseGlyphV1Record* baseglyphV1_record = colr_table->get_base_glyphV1_record (gid); - if (!baseglyphV1_record) return; + const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid); + if (!baseglyph_paintrecord) return; c->add_glyph (gid); - const BaseGlyphV1List &baseglyphV1_list = colr_table->get_baseglyphV1List (); - (&baseglyphV1_list+baseglyphV1_record->paint).dispatch (c); + const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList (); + (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c); } template <template<typename> class Var> HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const -{ - (this+src).dispatch (c); -} +{ (this+src).dispatch (c); } -template <template<typename> class Var> -HB_INTERNAL void PaintTranslate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const -{ - (this+src).dispatch (c); -} +HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } -template <template<typename> class Var> -HB_INTERNAL void PaintRotate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const -{ - (this+src).dispatch (c); -} +HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } -template <template<typename> class Var> -HB_INTERNAL void PaintSkew<Var>::closurev1 (hb_colrv1_closure_context_t* c) const -{ - (this+src).dispatch (c); -} +HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } + +HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const +{ (this+src).dispatch (c); } HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh index ffbbb1bc53..eff09838af 100644 --- a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh @@ -67,8 +67,11 @@ HB_OT_ACCELERATOR (OT, meta) #endif /* Vertical layout. */ +#ifndef HB_NO_VERTICAL HB_OT_TABLE (OT, vhea) HB_OT_ACCELERATOR (OT, vmtx) +HB_OT_TABLE (OT, VORG) +#endif /* TrueType outlines. */ HB_OT_ACCELERATOR (OT, glyf) @@ -77,7 +80,6 @@ HB_OT_ACCELERATOR (OT, glyf) #ifndef HB_NO_CFF HB_OT_ACCELERATOR (OT, cff1) HB_OT_ACCELERATOR (OT, cff2) -HB_OT_TABLE (OT, VORG) #endif /* OpenType variations. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index 5c044c1c4f..9f0359a773 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -118,6 +118,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } } +#ifndef HB_NO_VERTICAL static void hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned count, @@ -137,7 +138,9 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } } +#endif +#ifndef HB_NO_VERTICAL static hb_bool_t hb_ot_get_glyph_v_origin (hb_font_t *font, void *font_data, @@ -150,14 +153,12 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, *x = font->get_glyph_h_advance (glyph) / 2; -#ifndef HB_NO_OT_FONT_CFF const OT::VORG &VORG = *ot_face->VORG; if (VORG.has_data ()) { *y = font->em_scale_y (VORG.get_y_origin (glyph)); return true; } -#endif hb_glyph_extents_t extents = {0}; if (ot_face->glyf->get_extents (font, glyph, &extents)) @@ -174,6 +175,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, return true; } +#endif static hb_bool_t hb_ot_get_glyph_extents (hb_font_t *font, @@ -242,6 +244,7 @@ hb_ot_get_font_h_extents (hb_font_t *font, _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap); } +#ifndef HB_NO_VERTICAL static hb_bool_t hb_ot_get_font_v_extents (hb_font_t *font, void *font_data HB_UNUSED, @@ -252,6 +255,7 @@ hb_ot_get_font_v_extents (hb_font_t *font, _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) && _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap); } +#endif static inline void free_static_ot_funcs (); @@ -261,17 +265,23 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot { hb_font_funcs_t *funcs = hb_font_funcs_create (); - hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); - hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr); hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); - hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); + +#ifndef HB_NO_VERTICAL + hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); + hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); +#endif + hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); + #ifndef HB_NO_OT_FONT_GLYPH_NAMES hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); diff --git a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh index ff7b9b2d25..6aa34295c7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh @@ -93,22 +93,16 @@ struct glyf template<typename Iterator, hb_requires (hb_is_source_of (Iterator, unsigned int))> static bool - _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets) + _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca) { - unsigned max_offset = - + padded_offsets - | hb_reduce (hb_add, 0) - ; unsigned num_offsets = padded_offsets.len () + 1; - bool use_short_loca = max_offset < 0x1FFFF; unsigned entry_size = use_short_loca ? 2 : 4; char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); if (unlikely (!loca_prime_data)) return false; - DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d " - "max_offset %d size %d", - entry_size, num_offsets, max_offset, entry_size * num_offsets); + DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d", + entry_size, num_offsets, entry_size * num_offsets); if (use_short_loca) _write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets)); @@ -151,11 +145,12 @@ struct glyf template <typename Iterator> bool serialize (hb_serialize_context_t *c, Iterator it, + bool use_short_loca, const hb_subset_plan_t *plan) { TRACE_SERIALIZE (this); unsigned init_len = c->length (); - for (const auto &_ : it) _.serialize (c, plan); + for (const auto &_ : it) _.serialize (c, use_short_loca, plan); /* As a special case when all glyph in the font are empty, add a zero byte * to the table, so that OTS doesn’t reject it, and to make the table work @@ -183,16 +178,28 @@ struct glyf hb_vector_t<SubsetGlyph> glyphs; _populate_subset_glyphs (c->plan, &glyphs); - glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan); - auto padded_offsets = + hb_iter (glyphs) | hb_map (&SubsetGlyph::padded_size) ; + unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0); + bool use_short_loca = max_offset < 0x1FFFF; + + + glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan); + if (!use_short_loca) { + padded_offsets = + + hb_iter (glyphs) + | hb_map (&SubsetGlyph::length) + ; + } + + if (unlikely (c->serializer->in_error ())) return_trace (false); return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, - padded_offsets))); + padded_offsets, + use_short_loca))); } template <typename SubsetGlyph> @@ -388,7 +395,7 @@ struct glyf protected: HBUINT16 flags; - HBGlyphID glyphIndex; + HBGlyphID16 glyphIndex; public: DEFINE_SIZE_MIN (4); }; @@ -792,10 +799,23 @@ struct glyf hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init (); - int h_delta = (int) header->xMin - glyf_accelerator.hmtx->get_side_bearing (gid); - int v_orig = (int) header->yMax + glyf_accelerator.vmtx->get_side_bearing (gid); + int h_delta = (int) header->xMin - + glyf_accelerator.hmtx->get_side_bearing (gid); + int v_orig = (int) header->yMax + +#ifndef HB_NO_VERTICAL + glyf_accelerator.vmtx->get_side_bearing (gid) +#else + 0 +#endif + ; unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); - unsigned v_adv = glyf_accelerator.vmtx->get_advance (gid); + unsigned v_adv = +#ifndef HB_NO_VERTICAL + glyf_accelerator.vmtx->get_advance (gid) +#else + - font->face->get_upem () +#endif + ; phantoms[PHANTOM_LEFT].x = h_delta; phantoms[PHANTOM_RIGHT].x = h_adv + h_delta; phantoms[PHANTOM_TOP].y = v_orig; @@ -910,7 +930,9 @@ struct glyf gvar = nullptr; #endif hmtx = nullptr; +#ifndef HB_NO_VERTICAL vmtx = nullptr; +#endif face = face_; const OT::head &head = *face->table.head; if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0) @@ -924,7 +946,9 @@ struct glyf gvar = face->table.gvar; #endif hmtx = face->table.hmtx; +#ifndef HB_NO_VERTICAL vmtx = face->table.vmtx; +#endif num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ()); @@ -1037,7 +1061,11 @@ struct glyf success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); if (unlikely (!success)) - return is_vertical ? vmtx->get_advance (gid) : hmtx->get_advance (gid); + return +#ifndef HB_NO_VERTICAL + is_vertical ? vmtx->get_advance (gid) : +#endif + hmtx->get_advance (gid); float result = is_vertical ? phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y @@ -1053,7 +1081,11 @@ struct glyf contour_point_t phantoms[PHANTOM_COUNT]; if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) - return is_vertical ? vmtx->get_side_bearing (gid) : hmtx->get_side_bearing (gid); + return +#ifndef HB_NO_VERTICAL + is_vertical ? vmtx->get_side_bearing (gid) : +#endif + hmtx->get_side_bearing (gid); return is_vertical ? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing @@ -1118,7 +1150,7 @@ struct glyf while (it) { auto item = *(it++); - operation_count += + operation_count = add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count); } @@ -1250,7 +1282,9 @@ struct glyf const gvar_accelerator_t *gvar; #endif const hmtx_accelerator_t *hmtx; +#ifndef HB_NO_VERTICAL const vmtx_accelerator_t *vmtx; +#endif private: bool short_offset; @@ -1269,13 +1303,14 @@ struct glyf hb_bytes_t dest_end; /* region of source_glyph to copy second */ bool serialize (hb_serialize_context_t *c, + bool use_short_loca, const hb_subset_plan_t *plan) const { TRACE_SERIALIZE (this); hb_bytes_t dest_glyph = dest_start.copy (c); dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); - unsigned int pad_length = padding (); + unsigned int pad_length = use_short_loca ? padding () : 0; DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); HBUINT8 pad; diff --git a/thirdparty/harfbuzz/src/hb-ot-head-table.hh b/thirdparty/harfbuzz/src/hb-ot-head-table.hh index ac588e3af6..20991aab2b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-head-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-head-table.hh @@ -72,12 +72,14 @@ struct head UNDERLINE = 1u<<2, OUTLINE = 1u<<3, SHADOW = 1u<<4, - CONDENSED = 1u<<5 + CONDENSED = 1u<<5, + EXPANDED = 1u<<6, }; bool is_bold () const { return macStyle & BOLD; } bool is_italic () const { return macStyle & ITALIC; } bool is_condensed () const { return macStyle & CONDENSED; } + bool is_expanded () const { return macStyle & EXPANDED; } bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index 4038329938..7d2d2d3eb8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -165,7 +165,14 @@ struct hmtxvmtx { default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face); - num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics; + num_advances = T::is_horizontal ? + face->table.hhea->numberOfLongMetrics : +#ifndef HB_NO_VERTICAL + face->table.vhea->numberOfLongMetrics +#else + 0 +#endif + ; table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag); diff --git a/thirdparty/harfbuzz/src/hb-ot-kern-table.hh b/thirdparty/harfbuzz/src/hb-ot-kern-table.hh index 3563cab8bd..ffa11bc249 100644 --- a/thirdparty/harfbuzz/src/hb-ot-kern-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-kern-table.hh @@ -134,11 +134,11 @@ struct KernSubTable switch (subtable_type) { case 0: return_trace (c->dispatch (u.format0)); #ifndef HB_NO_AAT_SHAPE - case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ()); + case 1: return_trace (u.header.apple ? c->dispatch (u.format1, std::forward<Ts> (ds)...) : c->default_return_value ()); #endif case 2: return_trace (c->dispatch (u.format2)); #ifndef HB_NO_AAT_SHAPE - case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ()); + case 3: return_trace (u.header.apple ? c->dispatch (u.format3, std::forward<Ts> (ds)...) : c->default_return_value ()); #endif default: return_trace (c->default_return_value ()); } @@ -325,9 +325,9 @@ struct kern unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case 0: return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...)); + case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...)); #ifndef HB_NO_AAT_SHAPE - case 1: return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...)); #endif default: return_trace (c->default_return_value ()); } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh index 492947751e..eb4c3b46e2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh @@ -73,7 +73,7 @@ struct BaseCoordFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ FWORD coordinate; /* X or Y value, in design units */ - HBGlyphID referenceGlyph; /* Glyph ID of control glyph */ + HBGlyphID16 referenceGlyph; /* Glyph ID of control glyph */ HBUINT16 coordPoint; /* Index of contour point on the * reference glyph */ public: diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 65f499a00d..4fb1893435 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -68,8 +68,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 +89,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,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<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_), @@ -137,7 +137,7 @@ struct hb_prune_langsys_context_t 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; @@ -173,20 +173,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 +237,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 +268,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 +346,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 +545,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); @@ -1249,7 +1286,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 +1336,7 @@ struct Lookup outMarkFilteringSet = markFilteringSet; } - return_trace (true); + return_trace (out->subTable.len); } template <typename TSubTable> @@ -1320,7 +1357,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 +1491,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 +1869,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 +1896,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 +1963,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 +2081,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 +2181,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 +2330,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 +2507,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 +2631,7 @@ struct VarRegionList public: HBUINT16 axisCount; - HBUINT16 regionCount; + HBUINT15 regionCount; protected: UnsizedArrayOf<VarRegionAxis> axesZ; @@ -2947,7 +3035,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 ()); } } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh index 31a4a3e84c..aea644f3e1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh @@ -84,7 +84,7 @@ struct AttachList bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); @@ -248,9 +248,9 @@ struct CaretValue 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 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); - case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -371,7 +371,7 @@ struct LigCaretList bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index 1e305518f5..6db3e08940 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -118,7 +118,13 @@ struct ValueFormat : HBUINT16 if (!format) return ret; hb_font_t *font = c->font; - bool horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction); + bool horizontal = +#ifndef HB_NO_VERTICAL + HB_DIRECTION_IS_HORIZONTAL (c->direction) +#else + true +#endif + ; if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret)); if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret)); @@ -1050,8 +1056,8 @@ struct SinglePos 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 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1144,7 +1150,7 @@ struct PairValueRecord } protected: - HBGlyphID secondGlyph; /* GlyphID of second glyph in the + HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the * pair--first glyph is listed in the * Coverage table */ ValueRecord values; /* Positioning data for the first glyph @@ -1220,9 +1226,9 @@ struct PairSet record_size); if (record) { - /* Note the intentional use of "|" instead of short-circuit "||". */ - if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) | - valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos])) + bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); + bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, pos + 1); if (len2) pos++; @@ -1386,9 +1392,9 @@ struct PairPosFormat1 | hb_filter (glyphset, hb_first) | hb_filter ([this, c, out] (const Offset16To<PairSet>& _) { + auto snap = c->serializer->snapshot (); auto *o = out->pairSet.serialize_append (c->serializer); if (unlikely (!o)) return false; - auto snap = c->serializer->snapshot (); bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat); if (!ret) { @@ -1560,9 +1566,9 @@ struct PairPosFormat2 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; - /* Note the intentional use of "|" instead of short-circuit "||". */ - if (valueFormat1.apply_value (c, this, v, buffer->cur_pos()) | - valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx])) + bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos()); + bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); + if (applied_first || applied_second) buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); buffer->idx = skippy_iter.idx; @@ -1702,8 +1708,8 @@ struct PairPos 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 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -1959,7 +1965,7 @@ struct CursivePos 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 ()); } } @@ -2194,7 +2200,7 @@ struct MarkBasePos 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 ()); } } @@ -2434,7 +2440,7 @@ struct MarkLigPos 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 ()); } } @@ -2653,7 +2659,7 @@ struct MarkMarkPos 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 ()); } } @@ -2704,15 +2710,15 @@ struct PosLookupSubTable { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { - case Single: return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...)); - case Pair: return_trace (u.pair.dispatch (c, hb_forward<Ts> (ds)...)); - case Cursive: return_trace (u.cursive.dispatch (c, hb_forward<Ts> (ds)...)); - case MarkBase: return_trace (u.markBase.dispatch (c, hb_forward<Ts> (ds)...)); - case MarkLig: return_trace (u.markLig.dispatch (c, hb_forward<Ts> (ds)...)); - case MarkMark: return_trace (u.markMark.dispatch (c, hb_forward<Ts> (ds)...)); - case Context: return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...)); - case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...)); - case Extension: return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...)); + case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...)); + case Pair: return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...)); + case Cursive: return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...)); + case MarkBase: return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...)); + case MarkLig: return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...)); + case MarkMark: return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...)); + case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...)); + case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...)); + case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...)); default: return_trace (c->default_return_value ()); } } @@ -2800,7 +2806,7 @@ struct PosLookup : Lookup template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const - { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } + { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); } bool subset (hb_subset_context_t *c) const { return Lookup::subset<SubTable> (c); } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index 393ada1351..b7ce30135e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -225,7 +225,7 @@ struct SingleSubstFormat2 + hb_zip (this+coverage, substitute) | hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_second) - | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID &> p) -> hb_codepoint_pair_t + | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) ; @@ -245,7 +245,7 @@ struct SingleSubstFormat2 Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16Of<HBGlyphID> + Array16Of<HBGlyphID16> substitute; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: @@ -290,8 +290,8 @@ struct SingleSubst 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 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -391,7 +391,7 @@ struct Sequence } protected: - Array16Of<HBGlyphID> + Array16Of<HBGlyphID16> substitute; /* String of GlyphIDs to substitute */ public: DEFINE_SIZE_ARRAY (2, substitute); @@ -443,9 +443,9 @@ struct MultipleSubstFormat1 } bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t<const HBGlyphID> glyphs, + hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> substitute_len_list, - hb_array_t<const HBGlyphID> substitute_glyphs_list) + hb_array_t<const HBGlyphID16> substitute_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); @@ -504,9 +504,9 @@ struct MultipleSubstFormat1 struct MultipleSubst { bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t<const HBGlyphID> glyphs, + hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> substitute_len_list, - hb_array_t<const HBGlyphID> substitute_glyphs_list) + hb_array_t<const HBGlyphID16> substitute_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); @@ -524,7 +524,7 @@ struct MultipleSubst 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 ()); } } @@ -566,7 +566,7 @@ struct AlternateSet { /* Maybe we can do better than unsafe-to-break all; but since we are * changing random state, it would be hard to track that. Good 'nough. */ - c->buffer->unsafe_to_break_all (); + c->buffer->unsafe_to_break (0, c->buffer->len); alt_index = c->random_number () % count + 1; } @@ -624,7 +624,7 @@ struct AlternateSet } protected: - Array16Of<HBGlyphID> + Array16Of<HBGlyphID16> alternates; /* Array of alternate GlyphIDs--in * arbitrary order */ public: @@ -686,9 +686,9 @@ struct AlternateSubstFormat1 } bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t<const HBGlyphID> glyphs, + hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> alternate_len_list, - hb_array_t<const HBGlyphID> alternate_glyphs_list) + hb_array_t<const HBGlyphID16> alternate_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); @@ -747,9 +747,9 @@ struct AlternateSubstFormat1 struct AlternateSubst { bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t<const HBGlyphID> glyphs, + hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> alternate_len_list, - hb_array_t<const HBGlyphID> alternate_glyphs_list) + hb_array_t<const HBGlyphID16> alternate_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); @@ -767,7 +767,7 @@ struct AlternateSubst 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 ()); } } @@ -861,13 +861,15 @@ struct Ligature return_trace (true); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, unsigned coverage_idx) const { TRACE_SUBSET (this); const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false); + // Ensure Coverage table is always packed after this. + c->serializer->add_virtual_link (coverage_idx); auto it = + hb_iter (component) @@ -888,8 +890,8 @@ struct Ligature } protected: - HBGlyphID ligGlyph; /* GlyphID of ligature to substitute */ - HeadlessArrayOf<HBGlyphID> + HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */ + HeadlessArrayOf<HBGlyphID16> component; /* Array of component GlyphIDs--start * with the second component--ordered * in writing direction */ @@ -949,9 +951,9 @@ struct LigatureSet } bool serialize (hb_serialize_context_t *c, - hb_array_t<const HBGlyphID> ligatures, + hb_array_t<const HBGlyphID16> ligatures, hb_array_t<const unsigned int> component_count_list, - hb_array_t<const HBGlyphID> &component_list /* Starting from second for each ligature */) + hb_array_t<const HBGlyphID16> &component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); @@ -968,16 +970,21 @@ struct LigatureSet return_trace (true); } - bool subset (hb_subset_context_t *c) const + bool subset (hb_subset_context_t *c, unsigned coverage_idx) const { TRACE_SUBSET (this); auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + hb_iter (ligature) - | hb_filter (subset_offset_array (c, out->ligature, this)) + | hb_filter (subset_offset_array (c, out->ligature, this, coverage_idx)) | hb_drain ; + + if (bool (out->ligature)) + // Ensure Coverage table is always packed after this. + c->serializer->add_virtual_link (coverage_idx); + return_trace (bool (out->ligature)); } @@ -1059,11 +1066,11 @@ struct LigatureSubstFormat1 } bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t<const HBGlyphID> first_glyphs, + hb_sorted_array_t<const HBGlyphID16> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, - hb_array_t<const HBGlyphID> ligatures_list, + hb_array_t<const HBGlyphID16> ligatures_list, hb_array_t<const unsigned int> component_count_list, - hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) + hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (this))) return_trace (false); @@ -1092,15 +1099,38 @@ struct LigatureSubstFormat1 if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; - hb_sorted_vector_t<hb_codepoint_t> new_coverage; - + hb_zip (this+coverage, ligatureSet) + // Due to a bug in some older versions of windows 7 the Coverage table must be + // packed after the LigatureSet and Ligature tables, so serialize Coverage first + // which places it last in the packed order. + hb_set_t new_coverage; + + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this))) | hb_filter (glyphset, hb_first) - | hb_filter (subset_offset_array (c, out->ligatureSet, this), hb_second) + | hb_filter ([&] (const LigatureSet& _) { + return _.intersects (&glyphset); + }, hb_second) | hb_map (hb_first) - | hb_map (glyph_map) - | hb_sink (new_coverage) + | hb_sink (new_coverage); + + if (!c->serializer->push<Coverage> () + ->serialize (c->serializer, + + new_coverage.iter () | hb_map_retains_sorting (glyph_map))) + { + c->serializer->pop_discard (); + return_trace (false); + } + + unsigned coverage_idx = c->serializer->pop_pack (); + c->serializer->add_link (out->coverage, coverage_idx); + + + hb_zip (this+coverage, ligatureSet) + | hb_filter (new_coverage, hb_first) + | hb_map (hb_second) + // to ensure that the repacker always orders the coverage table after the LigatureSet + // and LigatureSubtable's they will be linked to the Coverage table via a virtual link + // the coverage table object idx is passed down to facilitate this. + | hb_apply (subset_offset_array (c, out->ligatureSet, this, coverage_idx)) ; - out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); + return_trace (bool (new_coverage)); } @@ -1125,11 +1155,11 @@ struct LigatureSubstFormat1 struct LigatureSubst { bool serialize (hb_serialize_context_t *c, - hb_sorted_array_t<const HBGlyphID> first_glyphs, + hb_sorted_array_t<const HBGlyphID16> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, - hb_array_t<const HBGlyphID> ligatures_list, + hb_array_t<const HBGlyphID16> ligatures_list, hb_array_t<const unsigned int> component_count_list, - hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) + hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); @@ -1152,7 +1182,7 @@ struct LigatureSubst 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 ()); } } @@ -1208,7 +1238,7 @@ struct ReverseChainSingleSubstFormat1 if (!intersects (c->glyphs)) return; const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + hb_zip (this+coverage, substitute) | hb_filter (c->parent_active_glyphs (), hb_first) @@ -1234,7 +1264,7 @@ struct ReverseChainSingleSubstFormat1 for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; - const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -1254,7 +1284,7 @@ struct ReverseChainSingleSubstFormat1 if (likely (index == NOT_COVERED)) return_trace (false); const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); if (unlikely (index >= substitute.len)) return_trace (false); @@ -1317,7 +1347,7 @@ struct ReverseChainSingleSubstFormat1 if (!serialize_coverage_offset_array (c, backtrack_iter)) return_trace (false); if (!serialize_coverage_offset_array (c, lookahead_iter)) return_trace (false); - auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID>> (); + auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID16>> (); auto substitutes = + coverage_subst_iter | hb_map (hb_second) @@ -1342,13 +1372,13 @@ struct ReverseChainSingleSubstFormat1 const hb_map_t &glyph_map = *c->plan->glyph_map; const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); auto it = + hb_zip (this+coverage, substitute) | hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_second) - | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID &> p) -> hb_codepoint_pair_t + | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) ; @@ -1363,7 +1393,7 @@ struct ReverseChainSingleSubstFormat1 const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); return_trace (substitute.sanitize (c)); } @@ -1380,7 +1410,7 @@ struct ReverseChainSingleSubstFormat1 lookaheadX; /* Array of coverage tables * in lookahead sequence, in glyph * sequence order */ - Array16Of<HBGlyphID> + Array16Of<HBGlyphID16> substituteX; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: @@ -1395,7 +1425,7 @@ struct ReverseChainSingleSubst 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 ()); } } @@ -1434,14 +1464,14 @@ struct SubstLookupSubTable { TRACE_DISPATCH (this, lookup_type); switch (lookup_type) { - case Single: return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...)); - case Multiple: return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...)); - case Alternate: return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...)); - case Ligature: return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...)); - case Context: return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...)); - case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...)); - case Extension: return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...)); - case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...)); + case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...)); + case Multiple: return_trace (u.multiple.dispatch (c, std::forward<Ts> (ds)...)); + case Alternate: return_trace (u.alternate.dispatch (c, std::forward<Ts> (ds)...)); + case Ligature: return_trace (u.ligature.dispatch (c, std::forward<Ts> (ds)...)); + case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...)); + case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...)); + case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...)); + case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, std::forward<Ts> (ds)...)); default: return_trace (c->default_return_value ()); } } @@ -1561,8 +1591,8 @@ struct SubstLookup : Lookup bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t<const HBGlyphID> glyphs, - hb_array_t<const HBGlyphID> substitutes) + hb_sorted_array_t<const HBGlyphID16> glyphs, + hb_array_t<const HBGlyphID16> substitutes) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); @@ -1577,9 +1607,9 @@ struct SubstLookup : Lookup bool serialize_multiple (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t<const HBGlyphID> glyphs, + hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> substitute_len_list, - hb_array_t<const HBGlyphID> substitute_glyphs_list) + hb_array_t<const HBGlyphID16> substitute_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false); @@ -1598,9 +1628,9 @@ struct SubstLookup : Lookup bool serialize_alternate (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t<const HBGlyphID> glyphs, + hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> alternate_len_list, - hb_array_t<const HBGlyphID> alternate_glyphs_list) + hb_array_t<const HBGlyphID16> alternate_glyphs_list) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false); @@ -1620,11 +1650,11 @@ struct SubstLookup : Lookup bool serialize_ligature (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t<const HBGlyphID> first_glyphs, + hb_sorted_array_t<const HBGlyphID16> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, - hb_array_t<const HBGlyphID> ligatures_list, + hb_array_t<const HBGlyphID16> ligatures_list, hb_array_t<const unsigned int> component_count_list, - hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) + hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false); @@ -1667,7 +1697,7 @@ struct SubstLookup : Lookup template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const - { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } + { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); } bool subset (hb_subset_context_t *c) const { return Lookup::subset<SubTable> (c); } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 626abc5577..191d3bebc5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -81,12 +81,15 @@ struct hb_closure_context_t : nesting_level_left++; } + void reset_lookup_visit_count () + { lookup_count = 0; } + bool lookup_limit_exceeded () - { return lookup_count > HB_MAX_LOOKUP_INDICES; } + { return lookup_count > HB_MAX_LOOKUP_VISIT_COUNT; } bool should_visit_lookup (unsigned int lookup_index) { - if (lookup_count++ > HB_MAX_LOOKUP_INDICES) + if (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT) return false; if (is_lookup_done (lookup_index)) @@ -163,7 +166,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<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set_, + hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), @@ -192,7 +195,7 @@ struct hb_closure_context_t : private: hb_map_t *done_lookups_glyph_count; - hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set; + hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set; unsigned int lookup_count; }; @@ -211,7 +214,11 @@ struct hb_closure_lookups_context_t : return; /* Return if new lookup was recursed to before. */ - if (is_lookup_visited (lookup_index)) + if (lookup_limit_exceeded () + || visited_lookups->in_error () + || visited_lookups->has (lookup_index)) + // Don't increment lookup count here, that will be done in the call to closure_lookups() + // made by recurse_func. return; nesting_level_left--; @@ -226,12 +233,20 @@ struct hb_closure_lookups_context_t : { inactive_lookups->add (lookup_index); } bool lookup_limit_exceeded () - { return lookup_count > HB_MAX_LOOKUP_INDICES; } + { + bool ret = lookup_count > HB_MAX_LOOKUP_VISIT_COUNT; + if (ret) + DEBUG_MSG (SUBSET, nullptr, "lookup visit count limit exceeded in lookup closure!"); + return ret; } bool is_lookup_visited (unsigned lookup_index) { - if (unlikely (lookup_count++ > HB_MAX_LOOKUP_INDICES)) + if (unlikely (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT)) + { + DEBUG_MSG (SUBSET, nullptr, "total visited lookup count %u exceeds max limit, lookup %u is dropped.", + lookup_count, lookup_index); return true; + } if (unlikely (visited_lookups->in_error ())) return true; @@ -1210,15 +1225,14 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c, struct LookupRecord { - LookupRecord* copy (hb_serialize_context_t *c, - const hb_map_t *lookup_map) const + bool serialize (hb_serialize_context_t *c, + const hb_map_t *lookup_map) const { TRACE_SERIALIZE (this); auto *out = c->embed (*this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); - out->lookupListIndex = hb_map_get (lookup_map, lookupListIndex); - return_trace (out); + return_trace (c->check_assign (out->lookupListIndex, lookup_map->get (lookupListIndex), HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -1235,6 +1249,24 @@ struct LookupRecord DEFINE_SIZE_STATIC (4); }; +static unsigned serialize_lookuprecord_array (hb_serialize_context_t *c, + const hb_array_t<const LookupRecord> lookupRecords, + const hb_map_t *lookup_map) +{ + unsigned count = 0; + for (const LookupRecord& r : lookupRecords) + { + if (!lookup_map->has (r.lookupListIndex)) + continue; + + if (!r.serialize (c, lookup_map)) + return 0; + + count++; + } + return count; +} + enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 }; static void context_closure_recurse_lookups (hb_closure_context_t *c, @@ -1286,8 +1318,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, } hb_set_add (covered_seq_indicies, seqIndex); - if (pos_glyphs) - c->push_cur_active_glyphs (pos_glyphs); + c->push_cur_active_glyphs (pos_glyphs ? pos_glyphs : c->glyphs); unsigned endIndex = inputCount; if (context_format == ContextFormat::CoverageBasedContext) @@ -1295,10 +1326,9 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex); - if (pos_glyphs) { - c->pop_cur_done_glyphs (); + c->pop_cur_done_glyphs (); + if (pos_glyphs) hb_set_destroy (pos_glyphs); - } } hb_set_destroy (covered_seq_indicies); @@ -1605,8 +1635,6 @@ struct Rule if (unlikely (!c->extend_min (out))) return_trace (false); out->inputCount = inputCount; - out->lookupCount = lookupCount; - const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); for (const auto org : input) { @@ -1617,17 +1645,9 @@ struct Rule const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); - for (unsigned i = 0; i < (unsigned) lookupCount; i++) - { - if (!lookup_map->has (lookupRecord[i].lookupListIndex)) - { - out->lookupCount--; - continue; - } - c->copy (lookupRecord[i], lookup_map); - } - return_trace (true); + unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (lookupCount), lookup_map); + return_trace (c->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool subset (hb_subset_context_t *c, @@ -1635,9 +1655,8 @@ struct Rule const hb_map_t *klass_map = nullptr) const { TRACE_SUBSET (this); - - const hb_array_t<const HBUINT16> input = inputZ.as_array ((inputCount ? inputCount - 1 : 0)); - if (!input.length) return_trace (false); + if (unlikely (!inputCount)) return_trace (false); + const hb_array_t<const HBUINT16> 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); @@ -1752,10 +1771,10 @@ struct RuleSet for (const Offset16To<Rule>& _ : rule) { if (!_) continue; + auto o_snap = c->serializer->snapshot (); auto *o = out->rule.serialize_append (c->serializer); if (unlikely (!o)) continue; - auto o_snap = c->serializer->snapshot (); if (!o->serialize_subset (c, _, this, lookup_map, klass_map)) { out->rule.pop (); @@ -1943,12 +1962,20 @@ struct ContextFormat2 &class_def }; + hb_set_t retained_coverage_glyphs; + (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs); + + hb_set_t coverage_glyph_classes; + class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); + + return + hb_iter (ruleSet) | hb_map (hb_add (this)) | hb_enumerate | hb_map ([&] (const hb_pair_t<unsigned, const RuleSet &> p) { return class_def.intersects_class (glyphs, p.first) && + coverage_glyph_classes.has (p.first) && p.second.intersects (glyphs, lookup_context); }) | hb_any ; @@ -2069,9 +2096,16 @@ struct ContextFormat2 hb_map_t klass_map; out->classDef.serialize_subset (c, classDef, this, &klass_map); + const hb_set_t* glyphset = c->plan->glyphset_gsub (); + hb_set_t retained_coverage_glyphs; + (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs); + + hb_set_t coverage_glyph_classes; + (this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); + const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; bool ret = true; - int non_zero_index = 0, index = 0; + int non_zero_index = -1, index = 0; for (const auto& _ : + hb_enumerate (ruleSet) | hb_filter (klass_map, hb_first)) { @@ -2082,13 +2116,14 @@ struct ContextFormat2 break; } - if (o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) + if (coverage_glyph_classes.has (_.first) && + o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) non_zero_index = index; index++; } - if (!ret) return_trace (ret); + if (!ret || non_zero_index == -1) return_trace (false); //prune empty trailing ruleSets --index; @@ -2226,7 +2261,6 @@ struct ContextFormat3 out->format = format; out->glyphCount = glyphCount; - out->lookupCount = lookupCount; auto coverages = coverageZ.as_array (glyphCount); @@ -2238,19 +2272,12 @@ struct ContextFormat3 if (!o->serialize_subset (c, offset, this)) return_trace (false); } - const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); + const UnsizedArrayOf<LookupRecord>& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount)); const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; - for (unsigned i = 0; i < (unsigned) lookupCount; i++) - { - if (!lookup_map->has (lookupRecord[i].lookupListIndex)) - { - out->lookupCount--; - continue; - } - c->serializer->copy (lookupRecord[i], lookup_map); - } - return_trace (true); + + unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (lookupCount), lookup_map); + return_trace (c->serializer->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -2289,9 +2316,9 @@ struct Context 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 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); - case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -2539,15 +2566,15 @@ struct ChainRule c->copy ((HBUINT16) g); } - ChainRule* copy (hb_serialize_context_t *c, - const hb_map_t *lookup_map, - const hb_map_t *backtrack_map, - const hb_map_t *input_map = nullptr, - const hb_map_t *lookahead_map = nullptr) const + bool serialize (hb_serialize_context_t *c, + const hb_map_t *lookup_map, + const hb_map_t *backtrack_map, + const hb_map_t *input_map = nullptr, + const hb_map_t *lookahead_map = nullptr) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); const hb_map_t *mapping = backtrack_map; serialize_array (c, backtrack.len, + backtrack.iter () @@ -2566,19 +2593,10 @@ struct ChainRule const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); HBUINT16* lookupCount = c->embed (&(lookupRecord.len)); - if (!lookupCount) return_trace (nullptr); + if (!lookupCount) return_trace (false); - for (unsigned i = 0; i < lookupRecord.len; i++) - { - if (!lookup_map->has (lookupRecord[i].lookupListIndex)) - { - (*lookupCount)--; - continue; - } - if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr); - } - - return_trace (out); + unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (), lookup_map); + return_trace (c->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool subset (hb_subset_context_t *c, @@ -2600,7 +2618,7 @@ struct ChainRule !hb_all (lookahead, glyphset)) return_trace (false); - copy (c->serializer, lookup_map, c->plan->glyph_map); + serialize (c->serializer, lookup_map, c->plan->glyph_map); } else { @@ -2609,7 +2627,7 @@ struct ChainRule !hb_all (lookahead, lookahead_map)) return_trace (false); - copy (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map); + serialize (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map); } return_trace (true); @@ -2724,10 +2742,10 @@ struct ChainRuleSet for (const Offset16To<ChainRule>& _ : rule) { if (!_) continue; + auto o_snap = c->serializer->snapshot (); auto *o = out->rule.serialize_append (c->serializer); if (unlikely (!o)) continue; - auto o_snap = c->serializer->snapshot (); if (!o->serialize_subset (c, _, this, lookup_map, backtrack_klass_map, @@ -2920,12 +2938,19 @@ struct ChainContextFormat2 &lookahead_class_def} }; + hb_set_t retained_coverage_glyphs; + (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs); + + hb_set_t coverage_glyph_classes; + input_class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); + return + hb_iter (ruleSet) | hb_map (hb_add (this)) | hb_enumerate | hb_map ([&] (const hb_pair_t<unsigned, const ChainRuleSet &> p) { return input_class_def.intersects_class (glyphs, p.first) && + coverage_glyph_classes.has (p.first) && p.second.intersects (glyphs, lookup_context); }) | hb_any ; @@ -3080,13 +3105,19 @@ struct ChainContextFormat2 lookahead_klass_map))) return_trace (false); + const hb_set_t* glyphset = c->plan->glyphset_gsub (); + hb_set_t retained_coverage_glyphs; + (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs); + + hb_set_t coverage_glyph_classes; + (this+inputClassDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); + int non_zero_index = -1, index = 0; bool ret = true; const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; auto last_non_zero = c->serializer->snapshot (); - for (const Offset16To<ChainRuleSet>& _ : + hb_enumerate (ruleSet) - | hb_filter (input_klass_map, hb_first) - | hb_map (hb_second)) + for (const auto& _ : + hb_enumerate (ruleSet) + | hb_filter (input_klass_map, hb_first)) { auto *o = out->ruleSet.serialize_append (c->serializer); if (unlikely (!o)) @@ -3094,7 +3125,8 @@ struct ChainContextFormat2 ret = false; break; } - if (o->serialize_subset (c, _, this, + if (coverage_glyph_classes.has (_.first) && + o->serialize_subset (c, _.second, this, lookup_map, &backtrack_klass_map, &input_klass_map, @@ -3107,7 +3139,7 @@ struct ChainContextFormat2 index++; } - if (!ret) return_trace (ret); + if (!ret || non_zero_index == -1) return_trace (false); // prune empty trailing ruleSets if (index > non_zero_index) { @@ -3318,22 +3350,12 @@ struct ChainContextFormat3 const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; - hb_set_t lookup_indices; - for (unsigned i = 0; i < (unsigned) lookupRecord.len; i++) - if (lookup_map->has (lookupRecord[i].lookupListIndex)) - lookup_indices.add (i); - - HBUINT16 lookupCount; - lookupCount = lookup_indices.get_population (); - if (!c->serializer->copy (lookupCount)) return_trace (false); - for (unsigned i : lookup_indices.iter ()) - { - if (!c->serializer->copy (lookupRecord[i], lookup_map)) - return_trace (false); - } + HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookupRecord.len); + if (!lookupCount) return_trace (false); - return_trace (true); + unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (), lookup_map); + return_trace (c->serializer->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } bool sanitize (hb_sanitize_context_t *c) const @@ -3378,9 +3400,9 @@ struct ChainContext 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 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); - case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -3409,7 +3431,7 @@ struct ExtensionFormat1 { TRACE_DISPATCH (this, format); if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); - return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...)); + return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), std::forward<Ts> (ds)...)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c) const @@ -3489,7 +3511,7 @@ struct Extension 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, hb_forward<Ts> (ds)...)); + case 1: return_trace (u.format1.dispatch (c, std::forward<Ts> (ds)...)); default:return_trace (c->default_return_value ()); } } @@ -3621,7 +3643,7 @@ struct GSUBGPOS } void prune_langsys (const hb_map_t *duplicate_feature_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_set_t *new_feature_indexes /* OUT */) const { hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes); @@ -3678,57 +3700,72 @@ struct GSUBGPOS const hb_set_t *feature_indices, hb_map_t *duplicate_feature_map /* OUT */) const { + if (feature_indices->is_empty ()) return; + hb_hashmap_t<hb_tag_t, hb_set_t *> unique_features; //find out duplicate features after subset - unsigned prev = 0xFFFFu; for (unsigned i : feature_indices->iter ()) { - if (prev == 0xFFFFu) + hb_tag_t t = get_feature_tag (i); + if (t == unique_features.INVALID_KEY) continue; + if (!unique_features.has (t)) { + hb_set_t* indices = hb_set_create (); + if (unlikely (indices == hb_set_get_empty () || + !unique_features.set (t, indices))) + { + hb_set_destroy (indices); + for (auto _ : unique_features.iter ()) + hb_set_destroy (_.second); + return; + } + if (unique_features.get (t)) + unique_features.get (t)->add (i); duplicate_feature_map->set (i, i); - prev = i; continue; } - hb_tag_t t = get_feature_tag (i); - hb_tag_t prev_t = get_feature_tag (prev); - if (t != prev_t) + bool found = false; + + hb_set_t* same_tag_features = unique_features.get (t); + for (unsigned other_f_index : same_tag_features->iter ()) { - duplicate_feature_map->set (i, i); - prev = i; - continue; - } + const Feature& f = get_feature (i); + const Feature& other_f = get_feature (other_f_index); - const Feature& f = get_feature (i); - const Feature& prev_f = get_feature (prev); + auto f_iter = + + hb_iter (f.lookupIndex) + | hb_filter (lookup_indices) + ; - auto f_iter = - + hb_iter (f.lookupIndex) - | hb_filter (lookup_indices) - ; + auto other_f_iter = + + hb_iter (other_f.lookupIndex) + | hb_filter (lookup_indices) + ; + + bool is_equal = true; + for (; f_iter && other_f_iter; f_iter++, other_f_iter++) + { + unsigned a = *f_iter; + unsigned b = *other_f_iter; + if (a != b) { is_equal = false; break; } + } - auto prev_iter = - + hb_iter (prev_f.lookupIndex) - | hb_filter (lookup_indices) - ; + if (is_equal == false || f_iter || other_f_iter) continue; - if (f_iter.len () != prev_iter.len ()) - { - duplicate_feature_map->set (i, i); - prev = i; - continue; + found = true; + duplicate_feature_map->set (i, other_f_index); + break; } - bool is_equal = true; - for (auto _ : + hb_zip (f_iter, prev_iter)) - if (_.first != _.second) { is_equal = false; break; } - - if (is_equal == true) duplicate_feature_map->set (i, prev); - else + if (found == false) { + same_tag_features->add (i); duplicate_feature_map->set (i, i); - prev = i; } } + + for (auto _ : unique_features.iter ()) + hb_set_destroy (_.second); } void prune_features (const hb_map_t *lookup_indices, /* IN */ @@ -3759,8 +3796,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-jstf-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh index 3b2293dff0..a1c125b11b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh @@ -136,7 +136,7 @@ struct JstfLangSys : List16OfOffset16To<JstfPriority> * ExtenderGlyphs -- Extender Glyph Table */ -typedef SortedArray16Of<HBGlyphID> ExtenderGlyphs; +typedef SortedArray16Of<HBGlyphID16> ExtenderGlyphs; /* diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 0454af2063..60733648c1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -613,7 +613,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, * hb_ot_layout_table_find_feature: * @face: #hb_face_t to work upon * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS - * @feature_tag: The #hb_tag_t og the requested feature tag + * @feature_tag: The #hb_tag_t of the requested feature tag * @feature_index: (out): The index of the requested feature * * Fetches the index for a given feature tag in the specified face's GSUB table @@ -688,8 +688,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: ?? + * Since: 0.6.0 + * Deprecated: 2.0.0 **/ hb_bool_t hb_ot_layout_script_find_language (hb_face_t *face, @@ -717,10 +717,14 @@ hb_ot_layout_script_find_language (hb_face_t *face, * @language_tags: The array of language tags * @language_index: (out): The index of the requested language * - * Fetches the index of a given language tag in the specified face's GSUB table - * or GPOS table, underneath the specified script index. + * Fetches the index of the first language tag fom @language_tags that is present + * in the specified face's GSUB or GPOS table, underneath the specified script + * index. * - * Return value: %true if the language tag is found, %false otherwise + * If none of the given language tags is found, %false is returned and + * @language_index is set to the default language index. + * + * Return value: %true if one of the given language tags is found, %false otherwise * * Since: 2.0.0 **/ @@ -746,7 +750,8 @@ hb_ot_layout_script_select_language (hb_face_t *face, if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) return false; - if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; + if (language_index) + *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; return false; } @@ -1013,24 +1018,15 @@ struct hb_collect_features_context_t } has_feature_filter = true; + hb_set_t features_set; for (; *features; features++) - { - hb_tag_t tag = *features; - unsigned index; - g.find_feature_index (tag, &index); - if (index == OT::Index::NOT_FOUND_INDEX) continue; + features_set.add (*features); - feature_indices_filter.add(index); - for (int i = (int) index - 1; i >= 0; i--) - { - if (g.get_feature_tag (i) != tag) break; - feature_indices_filter.add(i); - } - for (unsigned i = index + 1; i < g.get_feature_count (); i++) - { - if (g.get_feature_tag (i) != tag) break; + for (unsigned i = 0; i < g.get_feature_count (); i++) + { + hb_tag_t tag = g.get_feature_tag (i); + if (features_set.has (tag)) feature_indices_filter.add(i); - } } } @@ -1497,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<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set; + hb_hashmap_t<unsigned, hb_set_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); @@ -1526,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<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set; + hb_hashmap_t<unsigned, hb_set_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; @@ -1534,6 +1530,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, unsigned int glyphs_length; do { + c.reset_lookup_visit_count (); glyphs_length = glyphs->get_population (); if (lookups) { @@ -2011,14 +2008,14 @@ struct hb_get_glyph_alternates_dispatch_t : private: template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN - ( obj.get_glyph_alternates (hb_forward<Ts> (ds)...) ) + ( obj.get_glyph_alternates (std::forward<Ts> (ds)...) ) template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN ( default_return_value () ) public: template <typename T, typename ...Ts> auto dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN - ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) + ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) ) }; /** diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index bcc014ee98..2c825e0c81 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -187,7 +187,7 @@ _hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, * - General_Category: 5 bits. * - A bit each for: * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). - * * Whether it's one of the three Mongolian Free Variation Selectors, + * * Whether it's one of the four Mongolian Free Variation Selectors, * CGJ, or other characters that are hidden but should not be ignored * like most other Default_Ignorable()s do during matching. * * Whether it's a grapheme continuation. @@ -202,7 +202,7 @@ _hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, enum hb_unicode_props_flags_t { UPROPS_MASK_GEN_CAT = 0x001Fu, UPROPS_MASK_IGNORABLE = 0x0020u, - UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3, or TAG characters */ + UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */ UPROPS_MASK_CONTINUATION=0x0080u, /* If GEN_CAT=FORMAT, top byte masks: */ @@ -236,7 +236,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) * FVSes are GC=Mn, we have use a separate bit to remember them. * Fixes: * https://github.com/harfbuzz/harfbuzz/issues/234 */ - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_HIDDEN; + else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu))) props |= UPROPS_MASK_HIDDEN; /* TAG characters need similar treatment. Fixes: * https://github.com/harfbuzz/harfbuzz/issues/463 */ else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN; @@ -350,24 +350,20 @@ _hb_glyph_info_is_continuation (const hb_glyph_info_t *info) { return info->unicode_props() & UPROPS_MASK_CONTINUATION; } -/* Loop over grapheme. Based on foreach_cluster(). */ -#define foreach_grapheme(buffer, start, end) \ - for (unsigned int \ - _count = buffer->len, \ - start = 0, end = _count ? _hb_next_grapheme (buffer, 0) : 0; \ - start < _count; \ - start = end, end = _hb_next_grapheme (buffer, start)) -static inline unsigned int -_hb_next_grapheme (hb_buffer_t *buffer, unsigned int start) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; +static inline bool +_hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED, + const hb_glyph_info_t& b) +{ return _hb_glyph_info_is_continuation (&b); } - while (++start < count && _hb_glyph_info_is_continuation (&info[start])) - ; +#define foreach_grapheme(buffer, start, end) \ + foreach_group (buffer, start, end, _hb_grapheme_group_func) - return start; +static inline void +_hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer) +{ + buffer->reverse_groups (_hb_grapheme_group_func, + buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); } static inline bool diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh index 5916ad29f2..8d0b4317c3 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh @@ -41,6 +41,16 @@ struct MathValueRecord hb_position_t get_y_value (hb_font_t *font, const void *base) const { return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); } + MathValueRecord* copy (hb_serialize_context_t *c, const void *base) const + { + TRACE_SERIALIZE (this); + auto *out = c->embed (this); + if (unlikely (!out)) return_trace (nullptr); + out->deviceTable.serialize_copy (c, deviceTable, base, 0, hb_serialize_context_t::Head); + + return_trace (out); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -59,6 +69,29 @@ struct MathValueRecord struct MathConstants { + MathConstants* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!out)) return_trace (nullptr); + + HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2); + if (unlikely (!p)) return_trace (nullptr); + memcpy (p, percentScaleDown, HBINT16::static_size * 2); + + HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2); + if (unlikely (!m)) return_trace (nullptr); + memcpy (m, minHeight, HBUINT16::static_size * 2); + + unsigned count = ARRAY_LENGTH (mathValueRecords); + for (unsigned i = 0; i < count; i++) + if (!c->copy (mathValueRecords[i], this)) + return_trace (nullptr); + + if (!c->embed (radicalDegreeBottomRaisePercent)) return_trace (nullptr); + return_trace (out); + } + bool sanitize_math_value_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -165,6 +198,28 @@ struct MathConstants struct MathItalicsCorrectionInfo { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->_glyphset_mathed; + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + hb_zip (this+coverage, italicsCorrection) + | hb_filter (glyphset, hb_first) + | hb_filter (serialize_math_record_array (c->serializer, out->italicsCorrection, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -196,6 +251,28 @@ struct MathItalicsCorrectionInfo struct MathTopAccentAttachment { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->_glyphset_mathed; + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + hb_zip (this+topAccentCoverage, topAccentAttachment) + | hb_filter (glyphset, hb_first) + | hb_filter (serialize_math_record_array (c->serializer, out->topAccentAttachment, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + out->topAccentCoverage.serialize_serialize (c->serializer, new_coverage.iter ()); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -229,6 +306,22 @@ struct MathTopAccentAttachment struct MathKern { + MathKern* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!out)) return_trace (nullptr); + + if (unlikely (!c->embed (heightCount))) return_trace (nullptr); + + unsigned count = 2 * heightCount + 1; + for (unsigned i = 0; i < count; i++) + if (!c->copy (mathValueRecordsZ.arrayZ[i], this)) + return_trace (nullptr); + + return_trace (out); + } + bool sanitize_math_value_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -295,6 +388,19 @@ struct MathKern struct MathKernInfoRecord { + MathKernInfoRecord* copy (hb_serialize_context_t *c, const void *base) const + { + TRACE_SERIALIZE (this); + auto *out = c->embed (this); + if (unlikely (!out)) return_trace (nullptr); + + unsigned count = ARRAY_LENGTH (mathKern); + for (unsigned i = 0; i < count; i++) + out->mathKern[i].serialize_copy (c, mathKern[i], base, 0, hb_serialize_context_t::Head); + + return_trace (out); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -328,6 +434,28 @@ struct MathKernInfoRecord struct MathKernInfo { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->_glyphset_mathed; + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + hb_sorted_vector_t<hb_codepoint_t> new_coverage; + + hb_zip (this+mathKernCoverage, mathKernInfoRecords) + | hb_filter (glyphset, hb_first) + | hb_filter (serialize_math_record_array (c->serializer, out->mathKernInfoRecords, this), hb_second) + | hb_map (hb_first) + | hb_map (glyph_map) + | hb_sink (new_coverage) + ; + + out->mathKernCoverage.serialize_serialize (c->serializer, new_coverage.iter ()); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -365,6 +493,31 @@ struct MathKernInfo struct MathGlyphInfo { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + out->mathItalicsCorrectionInfo.serialize_subset (c, mathItalicsCorrectionInfo, this); + out->mathTopAccentAttachment.serialize_subset (c, mathTopAccentAttachment, this); + + const hb_set_t &glyphset = *c->plan->_glyphset_mathed; + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto it = + + hb_iter (this+extendedShapeCoverage) + | hb_filter (glyphset) + | hb_map_retains_sorting (glyph_map) + ; + + if (it) out->extendedShapeCoverage.serialize_serialize (c->serializer, it); + else out->extendedShapeCoverage = 0; + + out->mathKernInfo.serialize_subset (c, mathKernInfo, this); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -420,14 +573,27 @@ struct MathGlyphVariantRecord { friend struct MathGlyphConstruction; + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + const hb_map_t& glyph_map = *c->plan->glyph_map; + return_trace (c->serializer->check_assign (out->variantGlyph, glyph_map.get (variantGlyph), HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this)); } + void closure_glyphs (hb_set_t *variant_glyphs) const + { variant_glyphs->add (variantGlyph); } + protected: - HBGlyphID variantGlyph; /* Glyph ID for the variant. */ + HBGlyphID16 variantGlyph; /* Glyph ID for the variant. */ HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the * variant, in the direction of requested * glyph extension. */ @@ -450,6 +616,16 @@ struct PartFlags : HBUINT16 struct MathGlyphPartRecord { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + const hb_map_t& glyph_map = *c->plan->glyph_map; + return_trace (c->serializer->check_assign (out->glyph, glyph_map.get (glyph), HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -474,8 +650,11 @@ struct MathGlyphPartRecord (partFlags & PartFlags::Defined); } + void closure_glyphs (hb_set_t *variant_glyphs) const + { variant_glyphs->add (glyph); } + protected: - HBGlyphID glyph; /* Glyph ID for the part. */ + HBGlyphID16 glyph; /* Glyph ID for the part. */ HBUINT16 startConnectorLength; /* Advance width/ height of the straight bar * connector material, in design units, is at @@ -497,6 +676,20 @@ struct MathGlyphPartRecord struct MathGlyphAssembly { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out)) return_trace (false); + + if (!c->serializer->copy (italicsCorrection, this)) return_trace (false); + if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false); + + for (const auto& record : partRecords.iter ()) + if (!record.subset (c)) return_trace (false); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -526,6 +719,12 @@ struct MathGlyphAssembly return partRecords.len; } + void closure_glyphs (hb_set_t *variant_glyphs) const + { + for (const auto& _ : partRecords.iter ()) + _.closure_glyphs (variant_glyphs); + } + protected: MathValueRecord italicsCorrection; @@ -543,6 +742,22 @@ struct MathGlyphAssembly struct MathGlyphConstruction { + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + out->glyphAssembly.serialize_subset (c, glyphAssembly, this); + + if (!c->serializer->check_assign (out->mathGlyphVariantRecord.len, mathGlyphVariantRecord.len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + for (const auto& record : mathGlyphVariantRecord.iter ()) + if (!record.subset (c)) return_trace (false); + + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -569,6 +784,14 @@ struct MathGlyphConstruction return mathGlyphVariantRecord.len; } + void closure_glyphs (hb_set_t *variant_glyphs) const + { + (this+glyphAssembly).closure_glyphs (variant_glyphs); + + for (const auto& _ : mathGlyphVariantRecord.iter ()) + _.closure_glyphs (variant_glyphs); + } + protected: /* Offset to MathGlyphAssembly table for this shape - from the beginning of MathGlyphConstruction table. May be NULL. */ @@ -583,6 +806,94 @@ struct MathGlyphConstruction struct MathVariants { + void closure_glyphs (const hb_set_t *glyph_set, + hb_set_t *variant_glyphs) const + { + const hb_array_t<const Offset16To<MathGlyphConstruction>> glyph_construction_offsets = glyphConstruction.as_array (vertGlyphCount + horizGlyphCount); + + if (vertGlyphCoverage) + { + const auto vert_offsets = glyph_construction_offsets.sub_array (0, vertGlyphCount); + + hb_zip (this+vertGlyphCoverage, vert_offsets) + | hb_filter (glyph_set, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); }) + ; + } + + if (horizGlyphCoverage) + { + const auto hori_offsets = glyph_construction_offsets.sub_array (vertGlyphCount, horizGlyphCount); + + hb_zip (this+horizGlyphCoverage, hori_offsets) + | hb_filter (glyph_set, hb_first) + | hb_map (hb_second) + | hb_map (hb_add (this)) + | hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); }) + ; + } + } + + void collect_coverage_and_indices (hb_sorted_vector_t<hb_codepoint_t>& new_coverage, + const Offset16To<Coverage>& coverage, + unsigned i, + unsigned end_index, + hb_set_t& indices, + const hb_set_t& glyphset, + const hb_map_t& glyph_map) const + { + if (!coverage) return; + + for (const auto _ : (this+coverage).iter ()) + { + if (i >= end_index) return; + if (glyphset.has (_)) + { + unsigned new_gid = glyph_map.get (_); + new_coverage.push (new_gid); + indices.add (i); + } + i++; + } + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->_glyphset_mathed; + const hb_map_t &glyph_map = *c->plan->glyph_map; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + if (!c->serializer->check_assign (out->minConnectorOverlap, minConnectorOverlap, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + hb_sorted_vector_t<hb_codepoint_t> new_vert_coverage; + hb_sorted_vector_t<hb_codepoint_t> new_hori_coverage; + hb_set_t indices; + collect_coverage_and_indices (new_vert_coverage, vertGlyphCoverage, 0, vertGlyphCount, indices, glyphset, glyph_map); + collect_coverage_and_indices (new_hori_coverage, horizGlyphCoverage, vertGlyphCount, vertGlyphCount + horizGlyphCount, indices, glyphset, glyph_map); + + if (!c->serializer->check_assign (out->vertGlyphCount, new_vert_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + if (!c->serializer->check_assign (out->horizGlyphCount, new_hori_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + for (unsigned i : indices.iter ()) + { + auto *o = c->serializer->embed (glyphConstruction[i]); + if (!o) return_trace (false); + o->serialize_subset (c, glyphConstruction[i], this); + } + + if (new_vert_coverage) + out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ()); + + if (new_hori_coverage) + out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ()); + return_trace (true); + } + bool sanitize_offsets (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -690,6 +1001,28 @@ struct MATH bool has_data () const { return version.to_int (); } + void closure_glyphs (hb_set_t *glyph_set) const + { + if (mathVariants) + { + hb_set_t variant_glyphs; + (this+mathVariants).closure_glyphs (glyph_set, &variant_glyphs); + hb_set_union (glyph_set, &variant_glyphs); + } + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + out->mathConstants.serialize_copy (c->serializer, mathConstants, this, 0, hb_serialize_context_t::Head); + out->mathGlyphInfo.serialize_subset (c, mathGlyphInfo, this); + out->mathVariants.serialize_subset (c, mathVariants, this); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc index 72aeff82d6..dbd4a1ffbe 100644 --- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc +++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc @@ -77,6 +77,7 @@ _hb_ot_metrics_get_position_common (hb_font_t *font, (face->table.TABLE->has_data () && \ (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \ face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true)) + case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER: return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) || GET_METRIC_Y (hhea, ascender); @@ -86,9 +87,13 @@ _hb_ot_metrics_get_position_common (hb_font_t *font, case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP: return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) || GET_METRIC_Y (hhea, lineGap); + +#ifndef HB_NO_VERTICAL case HB_OT_METRICS_TAG_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender); case HB_OT_METRICS_TAG_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender); case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap); +#endif + #undef GET_METRIC_Y #undef GET_METRIC_X #undef GET_VAR @@ -158,9 +163,11 @@ hb_ot_metrics_get_position (hb_font_t *font, case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise); case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun); case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset); +#ifndef HB_NO_VERTICAL case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise); case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun); case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset); +#endif case HB_OT_METRICS_TAG_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight); case HB_OT_METRICS_TAG_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight); case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize); diff --git a/thirdparty/harfbuzz/src/hb-ot-name.h b/thirdparty/harfbuzz/src/hb-ot-name.h index 9359014c8a..1ea4b55e5c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name.h +++ b/thirdparty/harfbuzz/src/hb-ot-name.h @@ -36,12 +36,42 @@ HB_BEGIN_DECLS /** * hb_ot_name_id_t: + * @HB_OT_NAME_ID_COPYRIGHT: Copyright notice + * @HB_OT_NAME_ID_FONT_FAMILY: Font Family name + * @HB_OT_NAME_ID_FONT_SUBFAMILY: Font Subfamily name + * @HB_OT_NAME_ID_UNIQUE_ID: Unique font identifier + * @HB_OT_NAME_ID_FULL_NAME: Full font name that reflects + * all family and relevant subfamily descriptors + * @HB_OT_NAME_ID_VERSION_STRING: Version string + * @HB_OT_NAME_ID_POSTSCRIPT_NAME: PostScript name for the font + * @HB_OT_NAME_ID_TRADEMARK: Trademark + * @HB_OT_NAME_ID_MANUFACTURER: Manufacturer Name + * @HB_OT_NAME_ID_DESIGNER: Designer + * @HB_OT_NAME_ID_DESCRIPTION: Description + * @HB_OT_NAME_ID_VENDOR_URL: URL of font vendor + * @HB_OT_NAME_ID_DESIGNER_URL: URL of typeface designer + * @HB_OT_NAME_ID_LICENSE: License Description + * @HB_OT_NAME_ID_LICENSE_URL: URL where additional licensing + * information can be found + * @HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY: Typographic Family name + * @HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY: Typographic Subfamily name + * @HB_OT_NAME_ID_MAC_FULL_NAME: Compatible Full Name for MacOS + * @HB_OT_NAME_ID_SAMPLE_TEXT: Sample text + * @HB_OT_NAME_ID_CID_FINDFONT_NAME: PostScript CID findfont name + * @HB_OT_NAME_ID_WWS_FAMILY: WWS Family Name + * @HB_OT_NAME_ID_WWS_SUBFAMILY: WWS Subfamily Name + * @HB_OT_NAME_ID_LIGHT_BACKGROUND: Light Background Palette + * @HB_OT_NAME_ID_DARK_BACKGROUND: Dark Background Palette + * @HB_OT_NAME_ID_VARIATIONS_PS_PREFIX: Variations PostScript Name Prefix * @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID. * * An integral type representing an OpenType 'name' table name identifier. * There are predefined name IDs, as well as name IDs return from other * API. These can be used to fetch name strings from a font face. * + * For more information on these fields, see the + * [OpenType spec](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids). + * * Since: 2.0.0 **/ enum diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh index 94450eb53a..504de2de74 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<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> 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-ot-shape-complex-arabic-fallback.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh index 2b3b134ae3..78f46c1cac 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh @@ -49,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS hb_font_t *font, unsigned int feature_index) { - OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; - OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; + OT::HBGlyphID16 glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; + OT::HBGlyphID16 substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; unsigned int num_glyphs = 0; /* Populate arrays */ @@ -78,7 +78,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS /* Bubble-sort or something equally good! * May not be good-enough for presidential candidate interviews, but good-enough for us... */ hb_stable_sort (&glyphs[0], num_glyphs, - (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp, + (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::cmp, &substitutes[0]); @@ -99,15 +99,15 @@ static OT::SubstLookup * arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font) { - OT::HBGlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)]; + OT::HBGlyphID16 first_glyphs[ARRAY_LENGTH_CONST (ligature_table)]; unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)]; unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)]; unsigned int num_first_glyphs = 0; /* We know that all our ligatures are 2-component */ - OT::HBGlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)]; + OT::HBGlyphID16 ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)]; unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)]; - OT::HBGlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */]; + OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */]; unsigned int num_ligatures = 0; /* Populate arrays */ @@ -125,7 +125,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN num_first_glyphs++; } hb_stable_sort (&first_glyphs[0], num_first_glyphs, - (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp, + (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::cmp, &first_glyphs_indirection[0]); /* Now that the first-glyphs are sorted, walk again, populate ligatures. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc index 1f8c1410fc..222c5d6b71 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc @@ -349,7 +349,7 @@ mongolian_variation_selectors (hb_buffer_t *buffer) unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du))) + if (unlikely (hb_in_ranges<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu))) info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action(); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc index 0983a32848..4a8781c8f8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc @@ -202,9 +202,6 @@ collect_features_indic (hb_ot_shape_planner_t *plan) for (; i < INDIC_NUM_FEATURES; i++) map->add_feature (indic_features[i]); - map->enable_feature (HB_TAG('c','a','l','t')); - map->enable_feature (HB_TAG('c','l','i','g')); - map->add_gsub_pause (_hb_clear_syllables); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh index e24d68a8b5..35bfbb64d5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh @@ -49,13 +49,15 @@ enum khmer_category_t //OT_VPst = 29, }; +using khmer_position_t = indic_position_t; + static inline void set_khmer_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); khmer_category_t cat = (khmer_category_t) (type & 0xFFu); - indic_position_t pos = (indic_position_t) (type >> 8); + khmer_position_t pos = (khmer_position_t) (type >> 8); /* diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh index c09497896d..f4ef33004d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh @@ -51,6 +51,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_H 4u #define myanmar_syllable_machine_ex_IV 2u #define myanmar_syllable_machine_ex_MH 21u +#define myanmar_syllable_machine_ex_ML 33u #define myanmar_syllable_machine_ex_MR 22u #define myanmar_syllable_machine_ex_MW 23u #define myanmar_syllable_machine_ex_MY 24u @@ -67,35 +68,36 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 71 "hb-ot-shape-complex-myanmar-machine.hh" +#line 72 "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, 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, 29u, 3u, 30u, - 3u, 29u, 1u, 32u, 1u, 32u, 8u, 8u, 0 + 1u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, + 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u, + 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, 3u, 33u, + 3u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, + 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u, + 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, + 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 1u, 33u, 1u, 32u, 8u, 8u, + 0 }; 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, 27, - 25, 4, 25, 23, 21, 21, 27, 27, - 27, 27, 16, 28, 27, 27, 27, 27, - 27, 28, 27, 27, 27, 27, 27, 28, - 27, 32, 32, 1 + 33, 31, 25, 4, 25, 23, 21, 21, + 31, 27, 27, 27, 31, 16, 31, 31, + 27, 27, 27, 28, 27, 31, 31, 31, + 31, 31, 25, 4, 25, 23, 21, 21, + 31, 27, 27, 27, 31, 16, 31, 31, + 31, 27, 27, 27, 28, 27, 31, 31, + 31, 31, 31, 31, 31, 33, 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, - 625, 651, 656, 682, 706, 728, 750, 778, - 806, 834, 862, 879, 908, 936, 964, 992, - 1020, 1048, 1077, 1105, 1133, 1161, 1189, 1217, - 1246, 1274, 1307, 1340 + 0, 34, 66, 92, 97, 123, 147, 169, + 191, 223, 251, 279, 307, 339, 356, 388, + 420, 448, 476, 504, 533, 561, 593, 625, + 657, 689, 721, 747, 752, 778, 802, 824, + 846, 878, 906, 934, 962, 994, 1011, 1043, + 1075, 1107, 1135, 1163, 1191, 1220, 1248, 1280, + 1312, 1344, 1376, 1408, 1440, 1472, 1506, 1539 }; static const char _myanmar_syllable_machine_indicies[] = { @@ -103,192 +105,217 @@ static const char _myanmar_syllable_machine_indicies[] = { 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, 21, 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, 44, 21, 21, 28, - 29, 30, 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, 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, 46, 46, 45, 5, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 47, 45, - 45, 45, 45, 45, 45, 14, 45, 45, - 45, 18, 45, 46, 46, 45, 5, 45, - 46, 46, 45, 5, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 14, 45, 45, 45, - 18, 45, 48, 45, 46, 46, 45, 5, - 45, 14, 45, 45, 45, 45, 45, 45, - 45, 49, 45, 45, 45, 45, 45, 45, - 14, 45, 46, 46, 45, 5, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 49, - 45, 45, 45, 45, 45, 45, 14, 45, - 46, 46, 45, 5, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 14, 45, 2, 45, - 46, 46, 45, 5, 45, 6, 45, 45, - 45, 45, 45, 45, 45, 50, 45, 45, - 50, 45, 45, 45, 14, 51, 45, 45, - 18, 45, 2, 45, 46, 46, 45, 5, - 45, 6, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 14, 45, 45, 45, 18, 45, 2, 45, - 46, 46, 45, 5, 45, 6, 45, 45, - 45, 45, 45, 45, 45, 50, 45, 45, - 45, 45, 45, 45, 14, 51, 45, 45, - 18, 45, 2, 45, 46, 46, 45, 5, - 45, 6, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 14, 51, 45, 45, 18, 45, 52, 52, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 52, 45, 2, - 3, 46, 46, 45, 5, 45, 6, 45, - 45, 45, 45, 45, 45, 45, 8, 45, - 45, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 45, 2, 45, 46, 46, - 45, 5, 45, 6, 45, 45, 45, 45, - 45, 45, 45, 8, 45, 45, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 45, - 2, 45, 46, 46, 45, 5, 45, 6, - 45, 45, 45, 45, 45, 45, 45, 53, - 45, 45, 45, 45, 45, 45, 14, 15, - 16, 17, 18, 45, 2, 45, 46, 46, - 45, 5, 45, 6, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 14, 15, 16, 17, 18, 45, - 2, 45, 46, 46, 45, 5, 45, 6, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 14, 15, - 16, 45, 18, 45, 2, 45, 46, 46, - 45, 5, 45, 6, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 14, 45, 16, 45, 18, 45, - 2, 45, 46, 46, 45, 5, 45, 6, - 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 14, 15, - 16, 17, 18, 53, 45, 2, 45, 46, - 46, 45, 5, 45, 6, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 10, - 45, 12, 45, 14, 15, 16, 17, 18, - 45, 2, 45, 46, 46, 45, 5, 45, - 6, 45, 45, 45, 45, 45, 45, 45, - 53, 45, 45, 10, 45, 45, 45, 14, - 15, 16, 17, 18, 45, 2, 45, 46, - 46, 45, 5, 45, 6, 45, 45, 45, - 45, 45, 45, 45, 54, 45, 45, 10, - 11, 12, 45, 14, 15, 16, 17, 18, - 45, 2, 45, 46, 46, 45, 5, 45, - 6, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 10, 11, 12, 45, 14, - 15, 16, 17, 18, 45, 2, 3, 46, - 46, 45, 5, 45, 6, 45, 45, 45, - 45, 45, 45, 45, 8, 45, 45, 10, - 11, 12, 13, 14, 15, 16, 17, 18, - 45, 22, 23, 24, 24, 21, 25, 21, - 26, 21, 21, 21, 21, 21, 21, 21, - 55, 21, 21, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 21, 22, 56, - 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, 46, 46, - 45, 5, 45, 6, 1, 45, 45, 45, - 45, 1, 45, 8, 45, 45, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, - 45, 1, 45, 1, 1, 57, 57, 57, - 57, 57, 57, 57, 57, 1, 57, 57, - 57, 57, 1, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 1, 57, 58, 57, 0 + 21, 0, 23, 24, 25, 25, 22, 26, + 22, 27, 22, 22, 22, 22, 22, 22, + 22, 28, 22, 22, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 22, 22, + 39, 22, 25, 25, 22, 26, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 40, + 22, 22, 22, 22, 22, 22, 33, 22, + 22, 22, 37, 22, 25, 25, 22, 26, + 22, 25, 25, 22, 26, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 33, 22, 22, + 22, 37, 22, 41, 22, 25, 25, 22, + 26, 22, 33, 22, 22, 22, 22, 22, + 22, 22, 42, 22, 22, 22, 22, 22, + 22, 33, 22, 25, 25, 22, 26, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 42, 22, 22, 22, 22, 22, 22, 33, + 22, 25, 25, 22, 26, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 33, 22, 23, + 22, 25, 25, 22, 26, 22, 27, 22, + 22, 22, 22, 22, 22, 22, 43, 22, + 22, 44, 22, 22, 22, 33, 45, 22, + 22, 37, 22, 22, 22, 43, 22, 23, + 22, 25, 25, 22, 26, 22, 27, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 33, 22, 22, + 22, 37, 22, 23, 22, 25, 25, 22, + 26, 22, 27, 22, 22, 22, 22, 22, + 22, 22, 43, 22, 22, 22, 22, 22, + 22, 33, 45, 22, 22, 37, 22, 23, + 22, 25, 25, 22, 26, 22, 27, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 33, 45, 22, + 22, 37, 22, 23, 22, 25, 25, 22, + 26, 22, 27, 22, 22, 22, 22, 22, + 22, 22, 43, 22, 22, 22, 22, 22, + 22, 33, 45, 22, 22, 37, 22, 22, + 22, 43, 22, 1, 1, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 1, 22, 23, 22, 25, 25, + 22, 26, 22, 27, 22, 22, 22, 22, + 22, 22, 22, 28, 22, 22, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 22, + 22, 22, 39, 22, 23, 22, 25, 25, + 22, 26, 22, 27, 22, 22, 22, 22, + 22, 22, 22, 46, 22, 22, 22, 22, + 22, 22, 33, 34, 35, 36, 37, 22, + 22, 22, 39, 22, 23, 22, 25, 25, + 22, 26, 22, 27, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 34, 35, 36, 37, 22, + 23, 22, 25, 25, 22, 26, 22, 27, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 33, 34, + 35, 22, 37, 22, 23, 22, 25, 25, + 22, 26, 22, 27, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 33, 22, 35, 22, 37, 22, + 23, 22, 25, 25, 22, 26, 22, 27, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 33, 34, + 35, 36, 37, 46, 22, 23, 22, 25, + 25, 22, 26, 22, 27, 22, 22, 22, + 22, 22, 22, 22, 46, 22, 22, 22, + 22, 22, 22, 33, 34, 35, 36, 37, + 22, 23, 22, 25, 25, 22, 26, 22, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 29, 22, 31, 22, 33, + 34, 35, 36, 37, 22, 22, 22, 39, + 22, 23, 22, 25, 25, 22, 26, 22, + 27, 22, 22, 22, 22, 22, 22, 22, + 46, 22, 22, 29, 22, 22, 22, 33, + 34, 35, 36, 37, 22, 22, 22, 39, + 22, 23, 22, 25, 25, 22, 26, 22, + 27, 22, 22, 22, 22, 22, 22, 22, + 47, 22, 22, 29, 30, 31, 22, 33, + 34, 35, 36, 37, 22, 22, 22, 39, + 22, 23, 22, 25, 25, 22, 26, 22, + 27, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 29, 30, 31, 22, 33, + 34, 35, 36, 37, 22, 22, 22, 39, + 22, 23, 24, 25, 25, 22, 26, 22, + 27, 22, 22, 22, 22, 22, 22, 22, + 28, 22, 22, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 22, 22, 22, 39, + 22, 49, 49, 48, 5, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 50, 48, + 48, 48, 48, 48, 48, 14, 48, 48, + 48, 18, 48, 49, 49, 48, 5, 48, + 49, 49, 48, 5, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 14, 48, 48, 48, + 18, 48, 51, 48, 49, 49, 48, 5, + 48, 14, 48, 48, 48, 48, 48, 48, + 48, 52, 48, 48, 48, 48, 48, 48, + 14, 48, 49, 49, 48, 5, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 52, + 48, 48, 48, 48, 48, 48, 14, 48, + 49, 49, 48, 5, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 14, 48, 2, 48, + 49, 49, 48, 5, 48, 6, 48, 48, + 48, 48, 48, 48, 48, 53, 48, 48, + 54, 48, 48, 48, 14, 55, 48, 48, + 18, 48, 48, 48, 53, 48, 2, 48, + 49, 49, 48, 5, 48, 6, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 14, 48, 48, 48, + 18, 48, 2, 48, 49, 49, 48, 5, + 48, 6, 48, 48, 48, 48, 48, 48, + 48, 53, 48, 48, 48, 48, 48, 48, + 14, 55, 48, 48, 18, 48, 2, 48, + 49, 49, 48, 5, 48, 6, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 14, 55, 48, 48, + 18, 48, 2, 48, 49, 49, 48, 5, + 48, 6, 48, 48, 48, 48, 48, 48, + 48, 53, 48, 48, 48, 48, 48, 48, + 14, 55, 48, 48, 18, 48, 48, 48, + 53, 48, 56, 56, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 56, 48, 2, 3, 49, 49, 48, + 5, 48, 6, 48, 48, 48, 48, 48, + 48, 48, 8, 48, 48, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 48, + 48, 21, 48, 2, 48, 49, 49, 48, + 5, 48, 6, 48, 48, 48, 48, 48, + 48, 48, 8, 48, 48, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 48, 48, + 48, 21, 48, 2, 48, 49, 49, 48, + 5, 48, 6, 48, 48, 48, 48, 48, + 48, 48, 57, 48, 48, 48, 48, 48, + 48, 14, 15, 16, 17, 18, 48, 48, + 48, 21, 48, 2, 48, 49, 49, 48, + 5, 48, 6, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 14, 15, 16, 17, 18, 48, 2, + 48, 49, 49, 48, 5, 48, 6, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 14, 15, 16, + 48, 18, 48, 2, 48, 49, 49, 48, + 5, 48, 6, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 14, 48, 16, 48, 18, 48, 2, + 48, 49, 49, 48, 5, 48, 6, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 14, 15, 16, + 17, 18, 57, 48, 2, 48, 49, 49, + 48, 5, 48, 6, 48, 48, 48, 48, + 48, 48, 48, 57, 48, 48, 48, 48, + 48, 48, 14, 15, 16, 17, 18, 48, + 2, 48, 49, 49, 48, 5, 48, 6, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 10, 48, 12, 48, 14, 15, + 16, 17, 18, 48, 48, 48, 21, 48, + 2, 48, 49, 49, 48, 5, 48, 6, + 48, 48, 48, 48, 48, 48, 48, 57, + 48, 48, 10, 48, 48, 48, 14, 15, + 16, 17, 18, 48, 48, 48, 21, 48, + 2, 48, 49, 49, 48, 5, 48, 6, + 48, 48, 48, 48, 48, 48, 48, 58, + 48, 48, 10, 11, 12, 48, 14, 15, + 16, 17, 18, 48, 48, 48, 21, 48, + 2, 48, 49, 49, 48, 5, 48, 6, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 10, 11, 12, 48, 14, 15, + 16, 17, 18, 48, 48, 48, 21, 48, + 2, 3, 49, 49, 48, 5, 48, 6, + 48, 48, 48, 48, 48, 48, 48, 8, + 48, 48, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 48, 48, 48, 21, 48, + 23, 24, 25, 25, 22, 26, 22, 27, + 22, 22, 22, 22, 22, 22, 22, 59, + 22, 22, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 22, 22, 39, 22, + 23, 60, 25, 25, 22, 26, 22, 27, + 22, 22, 22, 22, 22, 22, 22, 28, + 22, 22, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 22, 22, 22, 39, 22, + 1, 1, 2, 3, 49, 49, 48, 5, + 48, 6, 1, 48, 48, 48, 48, 1, + 48, 8, 48, 48, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 48, 1, + 21, 48, 1, 1, 61, 61, 61, 61, + 61, 61, 61, 61, 1, 61, 61, 61, + 61, 1, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, + 61, 1, 61, 62, 61, 0 }; static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 24, 34, 0, 25, 31, 47, - 36, 50, 37, 42, 43, 44, 27, 39, - 40, 41, 30, 46, 51, 0, 2, 12, - 0, 3, 9, 13, 14, 19, 20, 21, - 5, 16, 17, 18, 8, 23, 4, 6, - 7, 10, 11, 15, 22, 0, 0, 26, - 28, 29, 32, 33, 35, 38, 45, 48, - 49, 0, 0 + 0, 1, 26, 37, 0, 27, 33, 51, + 39, 54, 40, 46, 47, 48, 29, 42, + 43, 44, 32, 50, 55, 45, 0, 2, + 13, 0, 3, 9, 14, 15, 21, 22, + 23, 5, 17, 18, 19, 8, 25, 20, + 4, 6, 7, 10, 12, 11, 16, 24, + 0, 0, 28, 30, 31, 34, 36, 35, + 38, 41, 49, 52, 53, 0, 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, 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, - 0, 9, 10 + 7, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 10 }; static const char _myanmar_syllable_machine_to_state_actions[] = { @@ -298,7 +325,7 @@ 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 }; static const char _myanmar_syllable_machine_from_state_actions[] = { @@ -308,17 +335,17 @@ 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 }; 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, 22, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 22, - 22, 46, 58, 58 + 0, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 23, 23, 49, 62, 62 }; static const int myanmar_syllable_machine_start = 0; @@ -332,7 +359,7 @@ static const int myanmar_syllable_machine_en_main = 0; -#line 101 "hb-ot-shape-complex-myanmar-machine.rl" +#line 102 "hb-ot-shape-complex-myanmar-machine.rl" #define found_syllable(syllable_type) \ @@ -351,7 +378,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 355 "hb-ot-shape-complex-myanmar-machine.hh" +#line 382 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -359,7 +386,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) act = 0; } -#line 121 "hb-ot-shape-complex-myanmar-machine.rl" +#line 122 "hb-ot-shape-complex-myanmar-machine.rl" p = 0; @@ -367,7 +394,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 371 "hb-ot-shape-complex-myanmar-machine.hh" +#line 398 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -381,7 +408,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 385 "hb-ot-shape-complex-myanmar-machine.hh" +#line 412 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -400,38 +427,38 @@ _eof_trans: switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { case 6: -#line 93 "hb-ot-shape-complex-myanmar-machine.rl" +#line 94 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} break; case 4: -#line 94 "hb-ot-shape-complex-myanmar-machine.rl" +#line 95 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; case 10: -#line 95 "hb-ot-shape-complex-myanmar-machine.rl" +#line 96 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_punctuation_cluster); }} break; case 8: -#line 96 "hb-ot-shape-complex-myanmar-machine.rl" +#line 97 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_broken_cluster); }} break; case 3: -#line 97 "hb-ot-shape-complex-myanmar-machine.rl" +#line 98 "hb-ot-shape-complex-myanmar-machine.rl" {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; case 5: -#line 93 "hb-ot-shape-complex-myanmar-machine.rl" +#line 94 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} break; case 7: -#line 96 "hb-ot-shape-complex-myanmar-machine.rl" +#line 97 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_broken_cluster); }} break; case 9: -#line 97 "hb-ot-shape-complex-myanmar-machine.rl" +#line 98 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 435 "hb-ot-shape-complex-myanmar-machine.hh" +#line 462 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -440,7 +467,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 444 "hb-ot-shape-complex-myanmar-machine.hh" +#line 471 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe ) @@ -456,7 +483,7 @@ _again: } -#line 129 "hb-ot-shape-complex-myanmar-machine.rl" +#line 130 "hb-ot-shape-complex-myanmar-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc index 6e92a9b0ae..e6ae75e8f2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc @@ -185,7 +185,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer, info[i].myanmar_position() = POS_BASE_C; i++; } - indic_position_t pos = POS_AFTER_MAIN; + myanmar_position_t pos = POS_AFTER_MAIN; /* The following loop may be ugly, but it implements all of * Myanmar reordering! */ for (; i < end; i++) diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh index a6d68aae57..7fbca3878f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh @@ -56,8 +56,10 @@ enum myanmar_category_t { OT_VS = 30, /* Variation selectors */ OT_P = 31, /* Punctuation */ OT_D = 32, /* Digits except zero */ + OT_ML = 33, /* Various consonant medial types */ }; +using myanmar_position_t = indic_position_t; static inline void set_myanmar_properties (hb_glyph_info_t &info) @@ -65,7 +67,7 @@ set_myanmar_properties (hb_glyph_info_t &info) hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); unsigned int cat = type & 0xFFu; - indic_position_t pos = (indic_position_t) (type >> 8); + myanmar_position_t pos = (myanmar_position_t) (type >> 8); /* Myanmar * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze @@ -114,10 +116,14 @@ set_myanmar_properties (hb_glyph_info_t &info) cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ break; - case 0x103Eu: case 0x1060u: + case 0x103Eu: cat = OT_MH; break; + case 0x1060u: + cat = OT_ML; + break; + case 0x103Cu: cat = OT_MR; break; diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh index bb046a72ec..c3920b2cc6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh @@ -41,7 +41,6 @@ #define USE(Cat) use_syllable_machine_ex_##Cat enum use_syllable_type_t { - use_independent_cluster, use_virama_terminated_cluster, use_sakot_terminated_cluster, use_standard_cluster, @@ -54,8 +53,9 @@ enum use_syllable_type_t { }; -#line 58 "hb-ot-shape-complex-use-machine.hh" +#line 57 "hb-ot-shape-complex-use-machine.hh" #define use_syllable_machine_ex_B 1u +#define use_syllable_machine_ex_CGJ 6u #define use_syllable_machine_ex_CMAbv 31u #define use_syllable_machine_ex_CMBlw 32u #define use_syllable_machine_ex_CS 43u @@ -78,7 +78,6 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_N 4u #define use_syllable_machine_ex_O 0u #define use_syllable_machine_ex_R 18u -#define use_syllable_machine_ex_S 19u #define use_syllable_machine_ex_SB 51u #define use_syllable_machine_ex_SE 52u #define use_syllable_machine_ex_SMAbv 41u @@ -96,280 +95,278 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 100 "hb-ot-shape-complex-use-machine.hh" +#line 99 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 1u, 1u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, + 0u, 51u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, - 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, - 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, - 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, - 22u, 48u, 11u, 48u, 1u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, - 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0 + 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, + 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, + 24u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, + 22u, 48u, 11u, 48u, 1u, 48u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, 41u, 42u, + 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 1, 1, 52, 38, 38, 1, 27, 26, + 52, 2, 1, 38, 38, 1, 27, 26, 24, 23, 22, 2, 1, 25, 25, 25, 1, 25, 26, 26, 26, 27, 27, 27, - 38, 48, 1, 1, 38, 2, 1, 38, - 27, 26, 24, 23, 22, 2, 1, 25, - 25, 25, 25, 26, 26, 26, 27, 27, - 27, 38, 48, 1, 1, 1, 48, 38, - 2, 1, 5, 3, 4, 3 + 38, 48, 1, 1, 38, 38, 1, 27, + 26, 24, 23, 22, 2, 1, 25, 25, + 25, 1, 25, 26, 26, 26, 27, 27, + 27, 38, 48, 1, 1, 48, 38, 2, + 1, 5, 3, 4, 3 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 2, 4, 57, 96, 135, 137, 165, - 192, 217, 241, 264, 267, 269, 295, 321, - 347, 349, 375, 402, 429, 456, 484, 512, - 540, 579, 628, 630, 632, 671, 674, 676, - 715, 743, 770, 795, 819, 842, 845, 847, - 873, 899, 925, 951, 978, 1005, 1032, 1060, - 1088, 1116, 1155, 1204, 1206, 1208, 1210, 1259, - 1298, 1301, 1303, 1309, 1313, 1318 + 0, 53, 56, 58, 97, 136, 138, 166, + 193, 218, 242, 265, 268, 270, 296, 322, + 348, 350, 376, 403, 430, 457, 485, 513, + 541, 580, 629, 631, 633, 672, 711, 713, + 741, 768, 793, 817, 840, 843, 845, 871, + 897, 923, 925, 951, 978, 1005, 1032, 1060, + 1088, 1116, 1155, 1204, 1206, 1208, 1257, 1296, + 1299, 1301, 1307, 1311, 1316 }; static const char _use_syllable_machine_indicies[] = { - 1, 0, 2, 0, 3, 4, 5, 5, - 6, 7, 5, 5, 5, 5, 5, 1, - 8, 9, 5, 5, 5, 5, 10, 11, - 5, 5, 12, 13, 14, 15, 16, 17, - 18, 12, 19, 20, 21, 22, 23, 24, - 5, 25, 26, 27, 5, 28, 29, 30, - 31, 32, 33, 34, 8, 35, 5, 36, - 5, 38, 39, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 40, 41, 42, 43, - 44, 45, 46, 40, 47, 4, 48, 49, - 50, 51, 37, 52, 53, 54, 37, 37, - 37, 37, 55, 56, 57, 58, 39, 37, - 38, 39, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 40, 41, 42, 43, 44, - 45, 46, 40, 47, 48, 48, 49, 50, - 51, 37, 52, 53, 54, 37, 37, 37, - 37, 55, 56, 57, 58, 39, 37, 38, - 59, 40, 41, 42, 43, 44, 37, 37, - 37, 37, 37, 37, 49, 50, 51, 37, - 52, 53, 54, 37, 37, 37, 37, 41, - 56, 57, 58, 60, 37, 41, 42, 43, - 44, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 52, 53, 54, 37, 37, - 37, 37, 37, 56, 57, 58, 60, 37, - 42, 43, 44, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 56, 57, 58, - 37, 43, 44, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 56, 57, 58, - 37, 44, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 56, 57, 58, 37, - 56, 57, 37, 57, 37, 42, 43, 44, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 52, 53, 54, 37, 37, 37, - 37, 37, 56, 57, 58, 60, 37, 42, - 43, 44, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 53, 54, 37, - 37, 37, 37, 37, 56, 57, 58, 60, - 37, 42, 43, 44, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 54, 37, 37, 37, 37, 37, 56, 57, - 58, 60, 37, 62, 61, 42, 43, 44, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 56, 57, 58, 60, 37, 41, - 42, 43, 44, 37, 37, 37, 37, 37, - 37, 49, 50, 51, 37, 52, 53, 54, - 37, 37, 37, 37, 41, 56, 57, 58, - 60, 37, 41, 42, 43, 44, 37, 37, - 37, 37, 37, 37, 37, 50, 51, 37, - 52, 53, 54, 37, 37, 37, 37, 41, - 56, 57, 58, 60, 37, 41, 42, 43, - 44, 37, 37, 37, 37, 37, 37, 37, - 37, 51, 37, 52, 53, 54, 37, 37, - 37, 37, 41, 56, 57, 58, 60, 37, - 40, 41, 42, 43, 44, 37, 46, 40, - 37, 37, 37, 49, 50, 51, 37, 52, - 53, 54, 37, 37, 37, 37, 41, 56, - 57, 58, 60, 37, 40, 41, 42, 43, - 44, 37, 37, 40, 37, 37, 37, 49, - 50, 51, 37, 52, 53, 54, 37, 37, - 37, 37, 41, 56, 57, 58, 60, 37, - 40, 41, 42, 43, 44, 45, 46, 40, - 37, 37, 37, 49, 50, 51, 37, 52, - 53, 54, 37, 37, 37, 37, 41, 56, - 57, 58, 60, 37, 38, 39, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 40, - 41, 42, 43, 44, 45, 46, 40, 47, - 37, 48, 49, 50, 51, 37, 52, 53, - 54, 37, 37, 37, 37, 55, 56, 57, - 58, 39, 37, 38, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 41, 42, 43, 44, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 52, - 53, 54, 59, 59, 59, 59, 59, 56, - 57, 58, 60, 59, 64, 63, 6, 65, - 38, 39, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 40, 41, 42, 43, 44, - 45, 46, 40, 47, 4, 48, 49, 50, - 51, 37, 52, 53, 54, 37, 11, 66, - 37, 55, 56, 57, 58, 39, 37, 11, - 66, 67, 66, 67, 1, 69, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 12, - 13, 14, 15, 16, 17, 18, 12, 19, - 21, 21, 22, 23, 24, 68, 25, 26, - 27, 68, 68, 68, 68, 31, 32, 33, - 34, 69, 68, 12, 13, 14, 15, 16, - 68, 68, 68, 68, 68, 68, 22, 23, - 24, 68, 25, 26, 27, 68, 68, 68, - 68, 13, 32, 33, 34, 70, 68, 13, - 14, 15, 16, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 25, 26, 27, - 68, 68, 68, 68, 68, 32, 33, 34, - 70, 68, 14, 15, 16, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 32, - 33, 34, 68, 15, 16, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 32, - 33, 34, 68, 16, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 32, 33, - 34, 68, 32, 33, 68, 33, 68, 14, - 15, 16, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 25, 26, 27, 68, - 68, 68, 68, 68, 32, 33, 34, 70, - 68, 14, 15, 16, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 26, - 27, 68, 68, 68, 68, 68, 32, 33, - 34, 70, 68, 14, 15, 16, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 27, 68, 68, 68, 68, 68, - 32, 33, 34, 70, 68, 14, 15, 16, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 32, 33, 34, 70, 68, 13, - 14, 15, 16, 68, 68, 68, 68, 68, - 68, 22, 23, 24, 68, 25, 26, 27, - 68, 68, 68, 68, 13, 32, 33, 34, - 70, 68, 13, 14, 15, 16, 68, 68, - 68, 68, 68, 68, 68, 23, 24, 68, - 25, 26, 27, 68, 68, 68, 68, 13, - 32, 33, 34, 70, 68, 13, 14, 15, - 16, 68, 68, 68, 68, 68, 68, 68, - 68, 24, 68, 25, 26, 27, 68, 68, - 68, 68, 13, 32, 33, 34, 70, 68, - 12, 13, 14, 15, 16, 68, 18, 12, - 68, 68, 68, 22, 23, 24, 68, 25, - 26, 27, 68, 68, 68, 68, 13, 32, - 33, 34, 70, 68, 12, 13, 14, 15, - 16, 68, 68, 12, 68, 68, 68, 22, - 23, 24, 68, 25, 26, 27, 68, 68, - 68, 68, 13, 32, 33, 34, 70, 68, - 12, 13, 14, 15, 16, 17, 18, 12, - 68, 68, 68, 22, 23, 24, 68, 25, - 26, 27, 68, 68, 68, 68, 13, 32, - 33, 34, 70, 68, 1, 69, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 12, - 13, 14, 15, 16, 17, 18, 12, 19, - 68, 21, 22, 23, 24, 68, 25, 26, - 27, 68, 68, 68, 68, 31, 32, 33, - 34, 69, 68, 1, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 13, 14, 15, 16, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 25, - 26, 27, 68, 68, 68, 68, 68, 32, - 33, 34, 70, 68, 1, 71, 72, 68, - 9, 68, 4, 68, 68, 68, 4, 68, - 68, 68, 68, 68, 1, 69, 9, 68, - 68, 68, 68, 68, 68, 68, 68, 12, - 13, 14, 15, 16, 17, 18, 12, 19, - 20, 21, 22, 23, 24, 68, 25, 26, - 27, 68, 28, 29, 68, 31, 32, 33, - 34, 69, 68, 1, 69, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 12, 13, - 14, 15, 16, 17, 18, 12, 19, 20, - 21, 22, 23, 24, 68, 25, 26, 27, - 68, 68, 68, 68, 31, 32, 33, 34, - 69, 68, 28, 29, 68, 29, 68, 4, - 71, 71, 71, 4, 71, 74, 73, 35, - 73, 35, 74, 73, 74, 73, 35, 73, - 36, 73, 0 + 0, 1, 2, 2, 3, 4, 2, 2, + 2, 2, 2, 5, 6, 7, 2, 2, + 2, 2, 8, 2, 2, 2, 9, 10, + 11, 12, 13, 14, 15, 9, 16, 17, + 18, 19, 20, 21, 2, 22, 23, 24, + 2, 25, 26, 27, 28, 29, 30, 31, + 6, 32, 2, 33, 2, 0, 35, 34, + 35, 34, 37, 38, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 39, 40, 41, + 42, 43, 44, 45, 39, 46, 1, 47, + 48, 49, 50, 36, 51, 52, 53, 36, + 36, 36, 36, 54, 55, 56, 57, 38, + 36, 37, 38, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 39, 40, 41, 42, + 43, 44, 45, 39, 46, 47, 47, 48, + 49, 50, 36, 51, 52, 53, 36, 36, + 36, 36, 54, 55, 56, 57, 38, 36, + 37, 58, 39, 40, 41, 42, 43, 36, + 36, 36, 36, 36, 36, 48, 49, 50, + 36, 51, 52, 53, 36, 36, 36, 36, + 40, 55, 56, 57, 59, 36, 40, 41, + 42, 43, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 51, 52, 53, 36, + 36, 36, 36, 36, 55, 56, 57, 59, + 36, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 55, 56, + 57, 36, 42, 43, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 55, 56, + 57, 36, 43, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 55, 56, 57, + 36, 55, 56, 36, 56, 36, 41, 42, + 43, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 51, 52, 53, 36, 36, + 36, 36, 36, 55, 56, 57, 59, 36, + 41, 42, 43, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 52, 53, + 36, 36, 36, 36, 36, 55, 56, 57, + 59, 36, 41, 42, 43, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 53, 36, 36, 36, 36, 36, 55, + 56, 57, 59, 36, 61, 60, 41, 42, + 43, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 55, 56, 57, 59, 36, + 40, 41, 42, 43, 36, 36, 36, 36, + 36, 36, 48, 49, 50, 36, 51, 52, + 53, 36, 36, 36, 36, 40, 55, 56, + 57, 59, 36, 40, 41, 42, 43, 36, + 36, 36, 36, 36, 36, 36, 49, 50, + 36, 51, 52, 53, 36, 36, 36, 36, + 40, 55, 56, 57, 59, 36, 40, 41, + 42, 43, 36, 36, 36, 36, 36, 36, + 36, 36, 50, 36, 51, 52, 53, 36, + 36, 36, 36, 40, 55, 56, 57, 59, + 36, 39, 40, 41, 42, 43, 36, 45, + 39, 36, 36, 36, 48, 49, 50, 36, + 51, 52, 53, 36, 36, 36, 36, 40, + 55, 56, 57, 59, 36, 39, 40, 41, + 42, 43, 36, 36, 39, 36, 36, 36, + 48, 49, 50, 36, 51, 52, 53, 36, + 36, 36, 36, 40, 55, 56, 57, 59, + 36, 39, 40, 41, 42, 43, 44, 45, + 39, 36, 36, 36, 48, 49, 50, 36, + 51, 52, 53, 36, 36, 36, 36, 40, + 55, 56, 57, 59, 36, 37, 38, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 39, 40, 41, 42, 43, 44, 45, 39, + 46, 36, 47, 48, 49, 50, 36, 51, + 52, 53, 36, 36, 36, 36, 54, 55, + 56, 57, 38, 36, 37, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 40, 41, 42, 43, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, + 51, 52, 53, 58, 58, 58, 58, 58, + 55, 56, 57, 59, 58, 63, 62, 3, + 64, 37, 38, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 39, 40, 41, 42, + 43, 44, 45, 39, 46, 1, 47, 48, + 49, 50, 36, 51, 52, 53, 36, 0, + 35, 36, 54, 55, 56, 57, 38, 36, + 5, 6, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 9, 10, 11, 12, 13, + 14, 15, 9, 16, 18, 18, 19, 20, + 21, 65, 22, 23, 24, 65, 65, 65, + 65, 28, 29, 30, 31, 6, 65, 5, + 65, 9, 10, 11, 12, 13, 65, 65, + 65, 65, 65, 65, 19, 20, 21, 65, + 22, 23, 24, 65, 65, 65, 65, 10, + 29, 30, 31, 66, 65, 10, 11, 12, + 13, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 22, 23, 24, 65, 65, + 65, 65, 65, 29, 30, 31, 66, 65, + 11, 12, 13, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 29, 30, 31, + 65, 12, 13, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 29, 30, 31, + 65, 13, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 29, 30, 31, 65, + 29, 30, 65, 30, 65, 11, 12, 13, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 22, 23, 24, 65, 65, 65, + 65, 65, 29, 30, 31, 66, 65, 11, + 12, 13, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 23, 24, 65, + 65, 65, 65, 65, 29, 30, 31, 66, + 65, 11, 12, 13, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 24, 65, 65, 65, 65, 65, 29, 30, + 31, 66, 65, 67, 65, 11, 12, 13, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 29, 30, 31, 66, 65, 10, + 11, 12, 13, 65, 65, 65, 65, 65, + 65, 19, 20, 21, 65, 22, 23, 24, + 65, 65, 65, 65, 10, 29, 30, 31, + 66, 65, 10, 11, 12, 13, 65, 65, + 65, 65, 65, 65, 65, 20, 21, 65, + 22, 23, 24, 65, 65, 65, 65, 10, + 29, 30, 31, 66, 65, 10, 11, 12, + 13, 65, 65, 65, 65, 65, 65, 65, + 65, 21, 65, 22, 23, 24, 65, 65, + 65, 65, 10, 29, 30, 31, 66, 65, + 9, 10, 11, 12, 13, 65, 15, 9, + 65, 65, 65, 19, 20, 21, 65, 22, + 23, 24, 65, 65, 65, 65, 10, 29, + 30, 31, 66, 65, 9, 10, 11, 12, + 13, 65, 65, 9, 65, 65, 65, 19, + 20, 21, 65, 22, 23, 24, 65, 65, + 65, 65, 10, 29, 30, 31, 66, 65, + 9, 10, 11, 12, 13, 14, 15, 9, + 65, 65, 65, 19, 20, 21, 65, 22, + 23, 24, 65, 65, 65, 65, 10, 29, + 30, 31, 66, 65, 5, 6, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 9, + 10, 11, 12, 13, 14, 15, 9, 16, + 65, 18, 19, 20, 21, 65, 22, 23, + 24, 65, 65, 65, 65, 28, 29, 30, + 31, 6, 65, 5, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, + 65, 10, 11, 12, 13, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 22, + 23, 24, 65, 65, 65, 65, 65, 29, + 30, 31, 66, 65, 68, 65, 7, 65, + 1, 65, 65, 65, 1, 65, 65, 65, + 65, 65, 5, 6, 7, 65, 65, 65, + 65, 65, 65, 65, 65, 9, 10, 11, + 12, 13, 14, 15, 9, 16, 17, 18, + 19, 20, 21, 65, 22, 23, 24, 65, + 25, 26, 65, 28, 29, 30, 31, 6, + 65, 5, 6, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 9, 10, 11, 12, + 13, 14, 15, 9, 16, 17, 18, 19, + 20, 21, 65, 22, 23, 24, 65, 65, + 65, 65, 28, 29, 30, 31, 6, 65, + 25, 26, 65, 26, 65, 1, 69, 69, + 69, 1, 69, 71, 70, 32, 70, 32, + 71, 70, 71, 70, 32, 70, 33, 70, + 0 }; static const char _use_syllable_machine_trans_targs[] = { - 2, 31, 42, 2, 3, 2, 26, 28, - 51, 52, 54, 29, 32, 33, 34, 35, - 36, 46, 47, 48, 55, 49, 43, 44, - 45, 39, 40, 41, 56, 57, 58, 50, - 37, 38, 2, 59, 61, 2, 4, 5, - 6, 7, 8, 9, 10, 21, 22, 23, - 24, 18, 19, 20, 13, 14, 15, 25, - 11, 12, 2, 2, 16, 2, 17, 2, - 27, 2, 30, 2, 2, 0, 1, 2, - 53, 2, 60 + 1, 3, 0, 26, 28, 29, 30, 51, + 53, 31, 32, 33, 34, 35, 46, 47, + 48, 54, 49, 43, 44, 45, 38, 39, + 40, 55, 56, 57, 50, 36, 37, 0, + 58, 60, 0, 2, 0, 4, 5, 6, + 7, 8, 9, 10, 21, 22, 23, 24, + 18, 19, 20, 13, 14, 15, 25, 11, + 12, 0, 0, 16, 0, 17, 0, 27, + 0, 0, 41, 42, 52, 0, 0, 59 }; static const char _use_syllable_machine_trans_actions[] = { - 1, 2, 2, 5, 0, 6, 0, 0, - 0, 0, 2, 0, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 0, 0, 0, 2, - 0, 0, 7, 0, 0, 8, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 10, 0, 11, 0, 12, - 0, 13, 0, 14, 15, 0, 0, 16, - 0, 17, 0 + 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 5, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 8, 0, 9, 0, 10, 0, + 11, 12, 0, 0, 0, 13, 14, 0 }; static const char _use_syllable_machine_to_state_actions[] = { - 0, 0, 3, 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, 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, 4, 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, 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, 1, 0, 38, 38, 60, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 62, 38, 38, 38, 38, 38, 38, 38, - 38, 60, 64, 66, 38, 68, 68, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 72, 69, 69, 69, 69, - 69, 69, 72, 74, 74, 74 + 0, 35, 35, 37, 37, 59, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 61, 37, 37, 37, 37, 37, 37, 37, + 37, 59, 63, 65, 37, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 70, 71, 71, 71 }; -static const int use_syllable_machine_start = 2; -static const int use_syllable_machine_first_final = 2; +static const int use_syllable_machine_start = 0; +static const int use_syllable_machine_first_final = 0; static const int use_syllable_machine_error = -1; -static const int use_syllable_machine_en_main = 2; +static const int use_syllable_machine_en_main = 0; -#line 59 "hb-ot-shape-complex-use-machine.rl" +#line 58 "hb-ot-shape-complex-use-machine.rl" -#line 176 "hb-ot-shape-complex-use-machine.rl" +#line 179 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ @@ -422,8 +419,8 @@ HB_FUNCOBJ (machine_index); static bool -not_standard_default_ignorable (const hb_glyph_info_t &i) -{ return !(i.use_category() == USE(O) && _hb_glyph_info_is_default_ignorable (&i)); } +not_ccs_default_ignorable (const hb_glyph_info_t &i) +{ return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); } static inline void find_syllables_use (hb_buffer_t *buffer) @@ -432,13 +429,13 @@ find_syllables_use (hb_buffer_t *buffer) auto p = + hb_iter (info, buffer->len) | hb_enumerate - | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); }, + | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); }, hb_second) | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) { if (p.second.use_category() == USE(ZWNJ)) for (unsigned i = p.first + 1; i < buffer->len; ++i) - if (not_standard_default_ignorable (info[i])) + if (not_ccs_default_ignorable (info[i])) return !_hb_glyph_info_is_unicode_mark (&info[i]); return true; }) @@ -452,7 +449,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 456 "hb-ot-shape-complex-use-machine.hh" +#line 453 "hb-ot-shape-complex-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -460,12 +457,12 @@ find_syllables_use (hb_buffer_t *buffer) act = 0; } -#line 260 "hb-ot-shape-complex-use-machine.rl" +#line 263 "hb-ot-shape-complex-use-machine.rl" unsigned int syllable_serial = 1; -#line 469 "hb-ot-shape-complex-use-machine.hh" +#line 466 "hb-ot-shape-complex-use-machine.hh" { int _slen; int _trans; @@ -475,11 +472,11 @@ find_syllables_use (hb_buffer_t *buffer) goto _test_eof; _resume: switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 4: + case 2: #line 1 "NONE" {ts = p;} break; -#line 483 "hb-ot-shape-complex-use-machine.hh" +#line 480 "hb-ot-shape-complex-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -497,76 +494,64 @@ _eof_trans: goto _again; switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 2: -#line 1 "NONE" - {te = p+1;} - break; - case 5: -#line 163 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (use_independent_cluster); }} - break; - case 9: -#line 166 "hb-ot-shape-complex-use-machine.rl" + case 7: +#line 169 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (use_standard_cluster); }} break; - case 7: -#line 171 "hb-ot-shape-complex-use-machine.rl" + case 4: +#line 174 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (use_broken_cluster); }} break; - case 6: -#line 172 "hb-ot-shape-complex-use-machine.rl" + case 3: +#line 175 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (use_non_cluster); }} break; - case 10: -#line 164 "hb-ot-shape-complex-use-machine.rl" + case 8: +#line 167 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} break; - case 11: -#line 165 "hb-ot-shape-complex-use-machine.rl" + case 9: +#line 168 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} break; - case 8: -#line 166 "hb-ot-shape-complex-use-machine.rl" + case 6: +#line 169 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_standard_cluster); }} break; - case 13: -#line 167 "hb-ot-shape-complex-use-machine.rl" + case 11: +#line 170 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} break; - case 12: -#line 168 "hb-ot-shape-complex-use-machine.rl" + case 10: +#line 171 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_numeral_cluster); }} break; - case 14: -#line 169 "hb-ot-shape-complex-use-machine.rl" + case 5: +#line 172 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_symbol_cluster); }} break; - case 17: -#line 170 "hb-ot-shape-complex-use-machine.rl" + case 14: +#line 173 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} break; - case 15: -#line 171 "hb-ot-shape-complex-use-machine.rl" + case 12: +#line 174 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_broken_cluster); }} break; - case 16: -#line 172 "hb-ot-shape-complex-use-machine.rl" + case 13: +#line 175 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (use_non_cluster); }} break; - case 1: -#line 171 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (use_broken_cluster); }} - break; -#line 561 "hb-ot-shape-complex-use-machine.hh" +#line 546 "hb-ot-shape-complex-use-machine.hh" } _again: switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 3: + case 1: #line 1 "NONE" {ts = 0;} break; -#line 570 "hb-ot-shape-complex-use-machine.hh" +#line 555 "hb-ot-shape-complex-use-machine.hh" } if ( ++p != pe ) @@ -582,7 +567,7 @@ _again: } -#line 265 "hb-ot-shape-complex-use-machine.rl" +#line 268 "hb-ot-shape-complex-use-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh index 7903a0ef89..7a3a995c8c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh @@ -2,7 +2,7 @@ /* * The following table is generated by running: * - * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt + * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt * * on files with these headers: * @@ -12,22 +12,28 @@ * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] * # ArabicShaping-14.0.0.txt * # Date: 2021-05-21, 01:54:00 GMT [KW, RP] + * # DerivedCoreProperties-14.0.0.txt + * # Date: 2021-08-12, 23:12:53 GMT * # Blocks-14.0.0.txt * # Date: 2021-01-22, 23:29:00 GMT [KW] + * # Scripts-14.0.0.txt + * # Date: 2021-07-10, 00:35:31 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 - * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 - * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24 - * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 + * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 + * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24 + * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 + * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25 * # Override values For Indic_Positional_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 - * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 + * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 * # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21 - * # Updated for L2/19-083 by Andrew Glass 2019-05-06 - * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30 - * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 + * # Updated for L2/19-083 by Andrew Glass 2019-05-06 + * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30 + * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 + * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28 * UnicodeData.txt does not have a header. */ @@ -41,6 +47,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-macros" #define B USE(B) /* BASE */ +#define CGJ USE(CGJ) /* CGJ */ #define CS USE(CS) /* CONS_WITH_STACKER */ #define G USE(G) /* HIEROGLYPH */ #define GB USE(GB) /* BASE_OTHER */ @@ -51,7 +58,6 @@ #define N USE(N) /* BASE_NUM */ #define O USE(O) /* OTHER */ #define R USE(R) /* REPHA */ -#define S USE(S) /* SYM */ #define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */ #define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */ #define SUB USE(SUB) /* CONS_SUB */ @@ -101,14 +107,20 @@ static const uint8_t use_table[] = { /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 00D0 */ O, O, O, O, O, O, O, GB, -#define use_offset_0x0640u 80 +#define use_offset_0x0348u 80 + + + /* Combining Diacritical Marks */ + O, O, O, O, O, O, O, CGJ, + +#define use_offset_0x0640u 88 /* Arabic */ /* 0640 */ B, O, O, O, O, O, O, O, -#define use_offset_0x07c8u 88 +#define use_offset_0x07c8u 96 /* NKo */ @@ -117,7 +129,7 @@ static const uint8_t use_table[] = { /* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, O, O, VMAbv, O, O, -#define use_offset_0x0840u 144 +#define use_offset_0x0840u 152 /* Mandaic */ @@ -125,7 +137,7 @@ static const uint8_t use_table[] = { /* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, O, O, O, O, -#define use_offset_0x0900u 176 +#define use_offset_0x0900u 184 /* Devanagari */ @@ -238,7 +250,7 @@ static const uint8_t use_table[] = { /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0DF0 */ O, O, VPst, VPst, O, O, O, O, -#define use_offset_0x0f00u 1448 +#define use_offset_0x0f00u 1456 /* Tibetan */ @@ -257,7 +269,7 @@ static const uint8_t use_table[] = { /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O, /* 0FC0 */ O, O, O, O, O, O, FBlw, O, -#define use_offset_0x1000u 1648 +#define use_offset_0x1000u 1656 /* Myanmar */ @@ -273,7 +285,7 @@ static const uint8_t use_table[] = { /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, -#define use_offset_0x1700u 1808 +#define use_offset_0x1700u 1816 /* Tagalog */ @@ -301,7 +313,7 @@ static const uint8_t use_table[] = { /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, + /* 17B0 */ B, B, B, B, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv, /* 17D0 */ FMAbv, VAbv, H, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, O, O, /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, @@ -309,7 +321,7 @@ static const uint8_t use_table[] = { /* Mongolian */ - /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, O, O, O, O, O, + /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, CGJ, CGJ, CGJ, O, CGJ, /* 1810 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, @@ -321,7 +333,7 @@ static const uint8_t use_table[] = { /* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, O, O, O, O, O, -#define use_offset_0x1900u 2240 +#define use_offset_0x1900u 2248 /* Limbu */ @@ -365,7 +377,7 @@ static const uint8_t use_table[] = { /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x1b00u 2656 +#define use_offset_0x1b00u 2664 /* Balinese */ @@ -376,7 +388,7 @@ static const uint8_t use_table[] = { /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, B, O, O, O, /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB, - /* 1B60 */ O, S, GB, S, S, S, S, S, GB, S, S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, + /* 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 */ @@ -401,7 +413,7 @@ static const uint8_t use_table[] = { /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O, /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, -#define use_offset_0x1cd0u 2992 +#define use_offset_0x1cd0u 3000 /* Vedic Extensions */ @@ -410,20 +422,20 @@ static const uint8_t use_table[] = { /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O, -#define use_offset_0x1df8u 3040 +#define use_offset_0x1df8u 3048 /* Combining Diacritical Marks Supplement */ O, O, O, FMAbv, O, O, O, O, -#define use_offset_0x2008u 3048 +#define use_offset_0x2008u 3056 /* General Punctuation */ - O, O, O, O, ZWNJ, O, O, O, + O, O, O, O, ZWNJ, CGJ, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O, -#define use_offset_0x2070u 3064 +#define use_offset_0x2070u 3072 /* Superscripts and Subscripts */ @@ -431,20 +443,20 @@ static const uint8_t use_table[] = { /* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O, /* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O, -#define use_offset_0x20f0u 3088 +#define use_offset_0x20f0u 3096 /* Combining Diacritical Marks for Symbols */ /* 20F0 */ VMAbv, O, O, O, O, O, O, O, -#define use_offset_0x25c8u 3096 +#define use_offset_0x25c8u 3104 /* Geometric Shapes */ O, O, O, O, B, O, O, O, -#define use_offset_0x2d30u 3104 +#define use_offset_0x2d30u 3112 /* Tifinagh */ @@ -455,7 +467,7 @@ static const uint8_t use_table[] = { /* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B, /* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H, -#define use_offset_0xa800u 3184 +#define use_offset_0xa800u 3192 /* Syloti Nagri */ @@ -542,7 +554,7 @@ static const uint8_t use_table[] = { /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAF0 */ O, O, O, O, O, VMPst, H, O, -#define use_offset_0xabc0u 3944 +#define use_offset_0xabc0u 3952 /* Meetei Mayek */ @@ -552,7 +564,25 @@ static const uint8_t use_table[] = { /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x10a00u 4008 +#define use_offset_0xfe00u 4016 + + + /* Variation Selectors */ + + /* FE00 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + +#define use_offset_0x10570u 4032 + + + /* Vithkuqi */ + + /* 10570 */ B, B, B, B, B, B, B, B, B, B, B, O, B, B, B, B, + /* 10580 */ B, B, B, B, B, B, B, B, B, B, B, O, B, B, B, B, + /* 10590 */ B, B, B, O, B, B, O, B, B, B, B, B, B, B, B, B, + /* 105A0 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 105B0 */ B, B, O, B, B, B, B, B, B, B, O, B, B, O, O, O, + +#define use_offset_0x10a00u 4112 /* Kharoshthi */ @@ -563,16 +593,16 @@ static const uint8_t use_table[] = { /* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, /* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, -#define use_offset_0x10ac0u 4088 +#define use_offset_0x10ac0u 4192 /* Manichaean */ /* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O, + /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O, O, O, O, B, B, B, B, B, -#define use_offset_0x10b80u 4128 +#define use_offset_0x10b80u 4240 /* Psalter Pahlavi */ @@ -581,7 +611,7 @@ static const uint8_t use_table[] = { /* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O, -#define use_offset_0x10d00u 4176 +#define use_offset_0x10d00u 4288 /* Hanifi Rohingya */ @@ -591,7 +621,7 @@ static const uint8_t use_table[] = { /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O, /* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x10e80u 4240 +#define use_offset_0x10e80u 4352 /* Yezidi */ @@ -601,17 +631,22 @@ static const uint8_t use_table[] = { /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O, /* 10EB0 */ B, B, O, O, O, O, O, O, -#define use_offset_0x10f30u 4296 +#define use_offset_0x10f30u 4408 /* Sogdian */ /* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, - /* 10F50 */ VMBlw, B, B, B, B, O, O, O, + /* 10F50 */ VMBlw, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, + /* 10F60 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, -#define use_offset_0x10fb0u 4336 + /* Old Uyghur */ + /* 10F70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10F80 */ B, B, CMBlw, CMBlw, CMBlw, CMBlw, O, O, O, O, O, O, O, O, O, O, + /* 10F90 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 10FA0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Chorasmian */ @@ -627,7 +662,7 @@ static const uint8_t use_table[] = { /* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, - /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, HVM, O, O, O, O, O, O, O, O, O, + /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O, /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, /* 11070 */ VAbv, B, B, VAbv, VAbv, B, O, O, O, O, O, O, O, O, O, HN, @@ -640,7 +675,7 @@ static const uint8_t use_table[] = { /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, /* 110C0 */ O, O, VBlw, O, O, O, O, O, -#define use_offset_0x11100u 4616 +#define use_offset_0x11100u 4816 /* Chakma */ @@ -678,7 +713,7 @@ static const uint8_t use_table[] = { /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O, -#define use_offset_0x11280u 4936 +#define use_offset_0x11280u 5136 /* Multani */ @@ -706,7 +741,7 @@ static const uint8_t use_table[] = { /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, -#define use_offset_0x11400u 5184 +#define use_offset_0x11400u 5384 /* Newa */ @@ -729,7 +764,7 @@ static const uint8_t use_table[] = { /* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11580u 5408 +#define use_offset_0x11580u 5608 /* Siddham */ @@ -773,7 +808,7 @@ static const uint8_t use_table[] = { /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, /* 11740 */ B, B, B, B, B, B, B, O, -#define use_offset_0x11800u 5864 +#define use_offset_0x11800u 6064 /* Dogra */ @@ -783,7 +818,7 @@ static const uint8_t use_table[] = { /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O, -#define use_offset_0x11900u 5928 +#define use_offset_0x11900u 6128 /* Dives Akuru */ @@ -795,7 +830,7 @@ static const uint8_t use_table[] = { /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x119a0u 6024 +#define use_offset_0x119a0u 6224 /* Nandinagari */ @@ -823,7 +858,7 @@ static const uint8_t use_table[] = { /* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O, -#define use_offset_0x11c00u 6280 +#define use_offset_0x11c00u 6480 /* Bhaiksuki */ @@ -844,7 +879,7 @@ static const uint8_t use_table[] = { /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O, -#define use_offset_0x11d00u 6464 +#define use_offset_0x11d00u 6664 /* Masaram Gondi */ @@ -864,7 +899,7 @@ static const uint8_t use_table[] = { /* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O, /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11ee0u 6640 +#define use_offset_0x11ee0u 6840 /* Makasar */ @@ -872,85 +907,92 @@ static const uint8_t use_table[] = { /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, -#define use_offset_0x13000u 6664 +#define use_offset_0x13000u 6864 /* Egyptian Hieroglyphs */ - /* 13000 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13010 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13020 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13030 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13040 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13050 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13060 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13070 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13080 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13090 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 130A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 130B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 130C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 130D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 130E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 130F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13100 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13110 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13120 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13130 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13140 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13150 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13160 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13170 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13180 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13190 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 131A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 131B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 131C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 131D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 131E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 131F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13200 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13210 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13220 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13230 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13240 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13250 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13260 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13270 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13280 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13290 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 132A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 132B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 132C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 132D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 132E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 132F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13300 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13310 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13320 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13330 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13340 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13350 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13360 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13370 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13380 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13390 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 133A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 133B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 133C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 133D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 133E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 133F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13400 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13410 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, - /* 13420 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, O, + /* 13000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13030 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13040 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13050 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13060 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13070 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13080 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 130A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 130B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 130C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 130D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 130E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 130F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13130 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13140 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13170 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13180 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 131A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 131B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 131C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 131D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 131E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 131F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13210 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13220 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13230 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13240 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13250 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13260 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13270 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13280 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 132A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 132B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 132C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 132D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 132E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 132F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13300 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13310 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13320 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13330 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13340 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13350 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13360 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13370 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13380 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13390 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 133A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 133B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 133C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 133D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 133E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 133F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 13420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, /* Egyptian Hieroglyph Format Controls */ - /* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O, + /* 13430 */ H, H, H, H, H, H, H, B, B, O, O, O, O, O, O, O, + +#define use_offset_0x16ac0u 7952 -#define use_offset_0x16b00u 7752 + /* Tangsa */ + + /* 16AC0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 16AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 16AE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 16AF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Pahawh Hmong */ @@ -959,7 +1001,7 @@ static const uint8_t use_table[] = { /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, -#define use_offset_0x16f00u 7808 +#define use_offset_0x16f00u 8072 /* Miao */ @@ -975,14 +1017,14 @@ static const uint8_t use_table[] = { /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw, /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O, -#define use_offset_0x16fe0u 7960 +#define use_offset_0x16fe0u 8224 /* Ideographic Symbols and Punctuation */ /* 16FE0 */ O, O, O, O, B, O, O, O, -#define use_offset_0x18b00u 7968 +#define use_offset_0x18b00u 8232 /* Khitan Small Script */ @@ -1018,7 +1060,7 @@ static const uint8_t use_table[] = { /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 18CD0 */ B, B, B, B, B, B, O, O, -#define use_offset_0x1bc00u 8440 +#define use_offset_0x1bc00u 8704 /* Duployan */ @@ -1034,7 +1076,7 @@ static const uint8_t use_table[] = { /* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O, -#define use_offset_0x1e100u 8600 +#define use_offset_0x1e100u 8864 /* Nyiakeng Puachue Hmong */ @@ -1045,8 +1087,14 @@ static const uint8_t use_table[] = { /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O, /* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B, -#define use_offset_0x1e2c0u 8680 +#define use_offset_0x1e290u 8944 + + + /* Toto */ + /* 1E290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1E2A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, O, + /* 1E2B0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Wancho */ @@ -1055,7 +1103,7 @@ static const uint8_t use_table[] = { /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x1e900u 8744 +#define use_offset_0x1e900u 9056 /* Adlam */ @@ -1067,7 +1115,28 @@ static const uint8_t use_table[] = { /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O, /* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -}; /* Table items: 8840; occupancy: 79% */ +#define use_offset_0xe0100u 9152 + + + /* Variation Selectors Supplement */ + + /* E0100 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0110 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0120 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0130 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0140 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0150 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0160 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0170 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0180 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E0190 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E01A0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E01B0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E01C0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E01D0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + /* E01E0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, + +}; /* Table items: 9392; occupancy: 79% */ static inline uint8_t hb_use_get_category (hb_codepoint_t u) @@ -1077,6 +1146,7 @@ hb_use_get_category (hb_codepoint_t u) case 0x0u: if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u]; if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u]; if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u]; if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u]; @@ -1106,18 +1176,22 @@ hb_use_get_category (hb_codepoint_t u) if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; break; + case 0xFu: + if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u]; + break; + case 0x10u: + if (hb_in_range<hb_codepoint_t> (u, 0x10570u, 0x105BFu)) return use_table[u - 0x10570u + use_offset_0x10570u]; if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AE7u)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u]; if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u]; if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u]; if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F57u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; break; case 0x11u: - if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u]; if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; @@ -1135,7 +1209,7 @@ hb_use_get_category (hb_codepoint_t u) break; case 0x16u: - if (hb_in_range<hb_codepoint_t> (u, 0x16B00u, 0x16B37u)) return use_table[u - 0x16B00u + use_offset_0x16b00u]; + if (hb_in_range<hb_codepoint_t> (u, 0x16AC0u, 0x16B37u)) return use_table[u - 0x16AC0u + use_offset_0x16ac0u]; if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u]; if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u]; break; @@ -1150,10 +1224,14 @@ hb_use_get_category (hb_codepoint_t u) case 0x1Eu: if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1E2C0u, 0x1E2FFu)) return use_table[u - 0x1E2C0u + use_offset_0x1e2c0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x1E290u, 0x1E2FFu)) return use_table[u - 0x1E290u + use_offset_0x1e290u]; if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u]; break; + case 0xE0u: + if (hb_in_range<hb_codepoint_t> (u, 0xE0100u, 0xE01EFu)) return use_table[u - 0xE0100u + use_offset_0xe0100u]; + break; + default: break; } @@ -1161,6 +1239,7 @@ hb_use_get_category (hb_codepoint_t u) } #undef B +#undef CGJ #undef CS #undef G #undef GB @@ -1171,7 +1250,6 @@ hb_use_get_category (hb_codepoint_t u) #undef N #undef O #undef R -#undef S #undef SB #undef SE #undef SUB diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc index 1e4804c4a2..70b637933d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc @@ -257,7 +257,6 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F); switch (syllable_type) { - case use_independent_cluster: case use_symbol_cluster: case use_hieroglyph_cluster: case use_non_cluster: diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc index 778b5b8bd8..839cc9122c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc @@ -171,7 +171,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor hb_codepoint_t u = buffer->cur().codepoint; hb_codepoint_t glyph = 0; - if (shortest && c->font->get_nominal_glyph (u, &glyph)) + if (shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found)) { next_char (buffer, glyph); return; @@ -183,7 +183,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor return; } - if (!shortest && c->font->get_nominal_glyph (u, &glyph)) + if (!shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found)) { next_char (buffer, glyph); return; @@ -312,6 +312,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer, font, buffer->unicode, + buffer->not_found, plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode, plan->shaper->compose ? plan->shaper->compose : compose_unicode }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh index 04f1a80091..12c78a2352 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.hh @@ -56,6 +56,7 @@ struct hb_ot_shape_normalize_context_t hb_buffer_t *buffer; hb_font_t *font; hb_unicode_funcs_t *unicode; + const hb_codepoint_t not_found; bool (*decompose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, hb_codepoint_t *a, diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 0e215c24f7..4dde3520d8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -150,23 +150,25 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, */ #ifndef HB_NO_AAT_SHAPE - bool has_gsub = hb_ot_layout_has_substitution (face); + bool has_kerx = hb_aat_layout_has_positioning (face); + bool has_gsub = !apply_morx && hb_ot_layout_has_substitution (face); #endif bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); if (false) ; #ifndef HB_NO_AAT_SHAPE - else if (hb_aat_layout_has_positioning (face) && !(has_gsub && has_gpos)) + /* Prefer GPOS over kerx if GSUB is present; + * https://github.com/harfbuzz/harfbuzz/issues/3008 */ + else if (has_kerx && !(has_gsub && has_gpos)) plan.apply_kerx = true; #endif - else if (!apply_morx && has_gpos) + else if (has_gpos) plan.apply_gpos = true; if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) { - /* Apparently Apple applies kerx if GPOS kern was not applied. */ #ifndef HB_NO_AAT_SHAPE - if (hb_aat_layout_has_positioning (face)) + if (has_kerx) plan.apply_kerx = true; else #endif @@ -626,20 +628,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { - - if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) - foreach_grapheme (buffer, start, end) - { - buffer->merge_clusters (start, end); - buffer->reverse_range (start, end); - } - else - foreach_grapheme (buffer, start, end) - /* form_clusters() merged clusters already, we don't merge. */ - buffer->reverse_range (start, end); - - buffer->reverse (); - + _hb_ot_layout_reverse_graphemes (buffer); buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction); } } @@ -649,6 +638,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) * Substitute */ +#ifndef HB_NO_VERTICAL static hb_codepoint_t hb_vert_char_for (hb_codepoint_t u) { @@ -699,6 +689,7 @@ hb_vert_char_for (hb_codepoint_t u) return u; } +#endif static inline void hb_ot_rotate_chars (const hb_ot_shape_context_t *c) @@ -721,6 +712,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) } } +#ifndef HB_NO_VERTICAL if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert) { for (unsigned int i = 0; i < count; i++) { @@ -729,6 +721,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c) info[i].codepoint = codepoint; } } +#endif } static inline void diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index fc9bffc23f..2c6316df4f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh @@ -6,7 +6,7 @@ * * on files with these headers: * - * <meta name="updated_at" content="2021-09-02 09:40 PM" /> + * <meta name="updated_at" content="2021-12-09 12:01 AM" /> * File-Date: 2021-08-06 */ @@ -933,6 +933,7 @@ static const LangTag ot_languages[] = { {"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 */ + {"mnw", HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */ {"mnx", HB_TAG_NONE }, /* Manikion != Manx */ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */ {"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */ @@ -1422,6 +1423,7 @@ static const LangTag ot_languages[] = { {"tia", HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */ /*{"tiv", HB_TAG('T','I','V',' ')},*/ /* Tiv */ +/*{"tjl", HB_TAG('T','J','L',' ')},*/ /* Tai Laing */ {"tjo", HB_TAG('B','B','R',' ')}, /* Temacine Tamazight -> Berber */ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ {"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ @@ -2521,6 +2523,14 @@ hb_ot_tags_from_complex_language (const char *lang_str, *count = 1; return true; } + if (0 == strncmp (&lang_str[1], "nw-", 3) + && subtag_matches (lang_str, limit, "-th")) + { + /* Mon; Thailand */ + tags[0] = HB_TAG('M','O','N','T'); /* Thailand Mon */ + *count = 1; + return true; + } break; case 'n': if (lang_matches (&lang_str[1], "an-hant-hk")) @@ -2884,6 +2894,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */ case HB_TAG('M','O','L',' '): /* Moldavian */ return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */ + case HB_TAG('M','O','N','T'): /* Thailand Mon */ + return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */ case HB_TAG('M','Y','N',' '): /* Mayan */ return hb_language_from_string ("myn", -1); /* Mayan [family] */ case HB_TAG('N','A','H',' '): /* Nahuatl */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh new file mode 100644 index 0000000000..0eafb949d5 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -0,0 +1,264 @@ +/* + * Copyright © 2021 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. + * + */ + +#ifndef HB_OT_VAR_COMMON_HH +#define HB_OT_VAR_COMMON_HH + +#include "hb-ot-layout-common.hh" + + +namespace OT { + +struct DeltaSetIndexMapFormat0 +{ + friend struct DeltaSetIndexMap; + + private: + DeltaSetIndexMapFormat0* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!out)) return_trace (nullptr); + + unsigned total_size = min_size + mapCount * get_width (); + HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); + if (unlikely (!p)) return_trace (nullptr); + + memcpy (p, this, HBUINT8::static_size * total_size); + return_trace (out); + } + + template <typename T> + bool serialize (hb_serialize_context_t *c, const T &plan) + { + unsigned int width = plan.get_width (); + unsigned int inner_bit_count = plan.get_inner_bit_count (); + const hb_array_t<const uint32_t> output_map = plan.get_output_map (); + + TRACE_SERIALIZE (this); + if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) + return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + + entryFormat = ((width-1)<<4)|(inner_bit_count-1); + mapCount = output_map.length; + HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length); + if (unlikely (!p)) return_trace (false); + for (unsigned int i = 0; i < output_map.length; i++) + { + unsigned int v = output_map[i]; + unsigned int outer = v >> 16; + unsigned int inner = v & 0xFFFF; + unsigned int u = (outer << inner_bit_count) | inner; + for (unsigned int w = width; w > 0;) + { + p[--w] = u; + u >>= 8; + } + p += width; + } + return_trace (true); + } + + uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ + { + /* If count is zero, pass value unchanged. This takes + * care of direct mapping for advance map. */ + if (!mapCount) + return v; + + if (v >= mapCount) + v = mapCount - 1; + + unsigned int u = 0; + { /* Fetch it. */ + unsigned int w = get_width (); + const HBUINT8 *p = mapDataZ.arrayZ + w * v; + for (; w; w--) + u = (u << 8) + *p++; + } + + { /* Repack it. */ + unsigned int n = get_inner_bit_count (); + unsigned int outer = u >> n; + unsigned int inner = u & ((1 << n) - 1); + u = (outer<<16) | inner; + } + + return u; + } + + unsigned get_map_count () const { return mapCount; } + unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } + unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } + + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_range (mapDataZ.arrayZ, + mapCount, + get_width ())); + } + + protected: + HBUINT8 format; /* Format identifier--format = 0 */ + HBUINT8 entryFormat; /* A packed field that describes the compressed + * representation of delta-set indices. */ + HBUINT16 mapCount; /* The number of mapping entries. */ + UnsizedArrayOf<HBUINT8> + mapDataZ; /* The delta-set index mapping data. */ + + public: + DEFINE_SIZE_ARRAY (4, mapDataZ); +}; + +struct DeltaSetIndexMapFormat1 +{ + friend struct DeltaSetIndexMap; + + private: + DeltaSetIndexMapFormat1* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!out)) return_trace (nullptr); + + unsigned total_size = min_size + mapCount * get_width (); + HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); + if (unlikely (!p)) return_trace (nullptr); + + memcpy (p, this, HBUINT8::static_size * total_size); + return_trace (out); + } + + unsigned get_map_count () const { return mapCount; } + unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } + unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_range (mapDataZ.arrayZ, + mapCount, + get_width ())); + } + + protected: + HBUINT8 format; /* Format identifier--format = 1 */ + HBUINT8 entryFormat; /* A packed field that describes the compressed + * representation of delta-set indices. */ + HBUINT32 mapCount; /* The number of mapping entries. */ + UnsizedArrayOf<HBUINT8> + mapDataZ; /* The delta-set index mapping data. */ + + public: + DEFINE_SIZE_ARRAY (6, mapDataZ); +}; + +struct DeltaSetIndexMap +{ + template <typename T> + bool serialize (hb_serialize_context_t *c, const T &plan) + { + TRACE_SERIALIZE (this); + switch (u.format) { + case 0: return_trace (u.format0.serialize (c, plan)); + default:return_trace (false); + } + } + + uint32_t map (unsigned v) const + { + switch (u.format) { + case 0: return (u.format0.map (v)); + default:return v; + } + } + + unsigned get_map_count () const + { + switch (u.format) { + case 0: return u.format0.get_map_count (); + case 1: return u.format1.get_map_count (); + default:return 0; + } + } + + unsigned get_width () const + { + switch (u.format) { + case 0: return u.format0.get_width (); + case 1: return u.format1.get_width (); + default:return 0; + } + } + + unsigned get_inner_bit_count () const + { + switch (u.format) { + case 0: return u.format0.get_inner_bit_count (); + case 1: return u.format1.get_inner_bit_count (); + default:return 0; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 0: return_trace (u.format0.sanitize (c)); + case 1: return_trace (u.format1.sanitize (c)); + default:return_trace (true); + } + } + + DeltaSetIndexMap* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + switch (u.format) { + case 0: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format0.copy (c))); + case 1: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format1.copy (c))); + default:return_trace (nullptr); + } + } + + protected: + union { + HBUINT8 format; /* Format identifier */ + DeltaSetIndexMapFormat0 format0; + DeltaSetIndexMapFormat1 format1; + } u; + public: + DEFINE_SIZE_UNION (1, format); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_VAR_COMMON_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index 72217e7f29..074b6a3785 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -28,97 +28,11 @@ #define HB_OT_VAR_HVAR_TABLE_HH #include "hb-ot-layout-common.hh" - +#include "hb-ot-var-common.hh" namespace OT { -struct DeltaSetIndexMap -{ - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_range (mapDataZ.arrayZ, - mapCount, - get_width ())); - } - - template <typename T> - bool serialize (hb_serialize_context_t *c, const T &plan) - { - unsigned int width = plan.get_width (); - unsigned int inner_bit_count = plan.get_inner_bit_count (); - const hb_array_t<const uint32_t> output_map = plan.get_output_map (); - - TRACE_SERIALIZE (this); - if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) - return_trace (false); - if (unlikely (!c->extend_min (this))) return_trace (false); - - format = ((width-1)<<4)|(inner_bit_count-1); - mapCount = output_map.length; - HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length); - if (unlikely (!p)) return_trace (false); - for (unsigned int i = 0; i < output_map.length; i++) - { - unsigned int v = output_map[i]; - unsigned int outer = v >> 16; - unsigned int inner = v & 0xFFFF; - unsigned int u = (outer << inner_bit_count) | inner; - for (unsigned int w = width; w > 0;) - { - p[--w] = u; - u >>= 8; - } - p += width; - } - return_trace (true); - } - - uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ - { - /* If count is zero, pass value unchanged. This takes - * care of direct mapping for advance map. */ - if (!mapCount) - return v; - - if (v >= mapCount) - v = mapCount - 1; - - unsigned int u = 0; - { /* Fetch it. */ - unsigned int w = get_width (); - const HBUINT8 *p = mapDataZ.arrayZ + w * v; - for (; w; w--) - u = (u << 8) + *p++; - } - - { /* Repack it. */ - unsigned int n = get_inner_bit_count (); - unsigned int outer = u >> n; - unsigned int inner = u & ((1 << n) - 1); - u = (outer<<16) | inner; - } - - return u; - } - - unsigned int get_map_count () const { return mapCount; } - unsigned int get_width () const { return ((format >> 4) & 3) + 1; } - unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; } - - protected: - HBUINT16 format; /* A packed field that describes the compressed - * representation of delta-set indices. */ - HBUINT16 mapCount; /* The number of mapping entries. */ - UnsizedArrayOf<HBUINT8> - mapDataZ; /* The delta-set index mapping data. */ - - public: - DEFINE_SIZE_ARRAY (4, mapDataZ); -}; - struct index_map_subset_plan_t { enum index_map_index_t { diff --git a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh index efa7737d6f..811e13919e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh @@ -48,7 +48,7 @@ struct VertOriginMetric } public: - HBGlyphID glyph; + HBGlyphID16 glyph; FWORD vertOriginY; public: diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index b02128b5c4..5c46b4cccc 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -33,6 +33,10 @@ #include "hb-serialize.hh" #include "hb-vector.hh" +/* + * For a detailed writeup on the overflow resolution algorithm see: + * docs/repacker.md + */ struct graph_t { @@ -40,33 +44,74 @@ struct graph_t { vertex_t () : distance (0), - incoming_edges (0), + space (0), + parents (), start (0), end (0), priority(0) {} - void fini () { obj.fini (); } + void fini () { + obj.fini (); + parents.fini (); + } hb_serialize_context_t::object_t obj; int64_t distance; - unsigned incoming_edges; + int64_t space; + hb_vector_t<unsigned> parents; unsigned start; unsigned end; unsigned priority; bool is_shared () const { - return incoming_edges > 1; + return parents.length > 1; + } + + unsigned incoming_edges () const + { + return parents.length; + } + + void remove_parent (unsigned parent_index) + { + for (unsigned i = 0; i < parents.length; i++) + { + if (parents[i] != parent_index) continue; + parents.remove (i); + break; + } + } + + void remap_parents (const hb_vector_t<unsigned>& id_map) + { + for (unsigned i = 0; i < parents.length; i++) + parents[i] = id_map[parents[i]]; + } + + void remap_parent (unsigned old_index, unsigned new_index) + { + for (unsigned i = 0; i < parents.length; i++) + { + if (parents[i] == old_index) + parents[i] = new_index; + } } bool is_leaf () const { - return !obj.links.length; + return !obj.real_links.length && !obj.virtual_links.length; } - void raise_priority () + bool raise_priority () { + if (has_max_priority ()) return false; priority++; + return true; + } + + bool has_max_priority () const { + return priority >= 3; } int64_t modified_distance (unsigned order) const @@ -76,49 +121,29 @@ struct graph_t // it's parent where possible. int64_t modified_distance = - hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFF); - return (modified_distance << 24) | (0x00FFFFFF & order); + hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF); + if (has_max_priority ()) { + modified_distance = 0; + } + return (modified_distance << 18) | (0x003FFFF & order); } int64_t distance_modifier () const { if (!priority) return 0; int64_t table_size = obj.tail - obj.head; - return -(table_size - table_size / (1 << hb_min(priority, 16u))); + + if (priority == 1) + return -table_size / 2; + + return -table_size; } }; struct overflow_record_t { unsigned parent; - const hb_serialize_context_t::object_t::link_t* link; - }; - - struct clone_buffer_t - { - clone_buffer_t () : head (nullptr), tail (nullptr) {} - - bool copy (const hb_serialize_context_t::object_t& object) - { - fini (); - unsigned size = object.tail - object.head; - head = (char*) hb_malloc (size); - if (!head) return false; - - memcpy (head, object.head, size); - tail = head + size; - return true; - } - - char* head; - char* tail; - - void fini () - { - if (!head) return; - hb_free (head); - head = nullptr; - } + unsigned child; }; /* @@ -129,11 +154,12 @@ struct graph_t * serializer */ graph_t (const hb_vector_t<hb_serialize_context_t::object_t *>& objects) - : edge_count_invalid (true), + : parents_invalid (true), distance_invalid (true), positions_invalid (true), successful (true) { + num_roots_for_space_.push (1); bool removed_nil = false; for (unsigned i = 0; i < objects.length; i++) { @@ -151,21 +177,23 @@ struct graph_t if (check_success (!vertices_.in_error ())) v->obj = *objects[i]; if (!removed_nil) continue; - for (unsigned i = 0; i < v->obj.links.length; i++) - // Fix indices to account for removed nil object. - v->obj.links[i].objidx--; + // Fix indices to account for removed nil object. + for (auto& l : v->obj.all_links_writer ()) { + l.objidx--; + } } } ~graph_t () { vertices_.fini_deep (); - clone_buffers_.fini_deep (); } bool in_error () const { - return !successful || vertices_.in_error () || clone_buffers_.in_error (); + return !successful || + vertices_.in_error () || + num_roots_for_space_.in_error (); } const vertex_t& root () const @@ -189,26 +217,46 @@ struct graph_t /* * serialize graph into the provided serialization buffer. */ - void serialize (hb_serialize_context_t* c) const + hb_blob_t* serialize () const { - c->start_serialize<void> (); + hb_vector_t<char> buffer; + size_t size = serialized_length (); + if (!buffer.alloc (size)) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer."); + return nullptr; + } + hb_serialize_context_t c((void *) buffer, size); + + c.start_serialize<void> (); for (unsigned i = 0; i < vertices_.length; i++) { - c->push (); + c.push (); size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; - char* start = c->allocate_size <char> (size); - if (!start) return; + char* start = c.allocate_size <char> (size); + if (!start) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space."); + return nullptr; + } memcpy (start, vertices_[i].obj.head, size); - for (const auto& link : vertices_[i].obj.links) - serialize_link (link, start, c); + // Only real links needs to be serialized. + for (const auto& link : vertices_[i].obj.real_links) + serialize_link (link, start, &c); // All duplications are already encoded in the graph, so don't // enable sharing during packing. - c->pop_pack (false); + c.pop_pack (false); } - c->end_serialize (); + c.end_serialize (); + + if (c.in_error ()) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d", + c.errors); + return nullptr; + } + + return c.copy_blob (); } /* @@ -226,12 +274,13 @@ struct graph_t hb_vector_t<unsigned> queue; hb_vector_t<vertex_t> sorted_graph; + if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t<unsigned> id_map; if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; hb_vector_t<unsigned> removed_edges; if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; - update_incoming_edge_count (); + update_parents (); queue.push (root_idx ()); int new_id = vertices_.length - 1; @@ -242,12 +291,12 @@ struct graph_t queue.remove (0); vertex_t& next = vertices_[next_id]; - sorted_graph.push (next); + sorted_graph[new_id] = next; id_map[next_id] = new_id--; - for (const auto& link : next.obj.links) { + for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; - if (!(vertices_[link.objidx].incoming_edges - removed_edges[link.objidx])) + if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) queue.push (link.objidx); } } @@ -255,14 +304,11 @@ struct graph_t check_success (!queue.in_error ()); check_success (!sorted_graph.in_error ()); if (!check_success (new_id == -1)) - DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); - - remap_obj_indices (id_map, &sorted_graph); + print_orphaned_nodes (); - sorted_graph.as_array ().reverse (); + remap_all_obj_indices (id_map, &sorted_graph); - vertices_.fini_deep (); - vertices_ = sorted_graph; + hb_swap (vertices_, sorted_graph); sorted_graph.fini_deep (); } @@ -283,12 +329,13 @@ struct graph_t hb_priority_queue_t queue; hb_vector_t<vertex_t> sorted_graph; + if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t<unsigned> id_map; if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; hb_vector_t<unsigned> removed_edges; if (unlikely (!check_success (removed_edges.resize (vertices_.length)))) return; - update_incoming_edge_count (); + update_parents (); queue.insert (root ().modified_distance (0), root_idx ()); int new_id = root_idx (); @@ -298,12 +345,12 @@ struct graph_t unsigned next_id = queue.pop_minimum().second; vertex_t& next = vertices_[next_id]; - sorted_graph.push (next); + sorted_graph[new_id] = next; id_map[next_id] = new_id--; - for (const auto& link : next.obj.links) { + for (const auto& link : next.obj.all_links ()) { removed_edges[link.objidx]++; - if (!(vertices_[link.objidx].incoming_edges - removed_edges[link.objidx])) + if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx])) // Add the order that the links were encountered to the priority. // This ensures that ties between priorities objects are broken in a consistent // way. More specifically this is set up so that if a set of objects have the same @@ -317,72 +364,276 @@ struct graph_t check_success (!queue.in_error ()); check_success (!sorted_graph.in_error ()); if (!check_success (new_id == -1)) - DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); - - remap_obj_indices (id_map, &sorted_graph); + print_orphaned_nodes (); - sorted_graph.as_array ().reverse (); + remap_all_obj_indices (id_map, &sorted_graph); - vertices_.fini_deep (); - vertices_ = sorted_graph; + hb_swap (vertices_, sorted_graph); sorted_graph.fini_deep (); } /* - * Creates a copy of child and re-assigns the link from - * parent to the clone. The copy is a shallow copy, objects - * linked from child are not duplicated. + * Assign unique space numbers to each connected subgraph of 32 bit offset(s). */ - void duplicate (unsigned parent_idx, unsigned child_idx) + bool assign_32bit_spaces () { - DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d", - parent_idx, child_idx); + unsigned root_index = root_idx (); + hb_set_t visited; + hb_set_t roots; + for (unsigned i = 0; i <= root_index; i++) + { + // Only real links can form 32 bit spaces + for (auto& l : vertices_[i].obj.real_links) + { + if (l.width == 4 && !l.is_signed) + { + roots.add (l.objidx); + find_subgraph (l.objidx, visited); + } + } + } - positions_invalid = true; + // Mark everything not in the subgraphs of 32 bit roots as visited. + // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs. + visited.invert (); - auto* clone = vertices_.push (); - auto& child = vertices_[child_idx]; - clone_buffer_t* buffer = clone_buffers_.push (); - if (vertices_.in_error () - || clone_buffers_.in_error () - || !check_success (buffer->copy (child.obj))) { - return; + if (!roots) return false; + + while (roots) + { + unsigned next = HB_SET_VALUE_INVALID; + if (!roots.next (&next)) break; + + hb_set_t connected_roots; + find_connected_nodes (next, roots, visited, connected_roots); + isolate_subgraph (connected_roots); + + unsigned next_space = this->next_space (); + num_roots_for_space_.push (0); + for (unsigned root : connected_roots) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Subgraph %u gets space %u", root, next_space); + vertices_[root].space = next_space; + num_roots_for_space_[next_space] = num_roots_for_space_[next_space] + 1; + distance_invalid = true; + positions_invalid = true; + } + + // TODO(grieger): special case for GSUB/GPOS use extension promotions to move 16 bit space + // into the 32 bit space as needed, instead of using isolation. } - clone->obj.head = buffer->head; - clone->obj.tail = buffer->tail; - clone->distance = child.distance; + return true; + } - for (const auto& l : child.obj.links) - clone->obj.links.push (l); + /* + * Isolates the subgraph of nodes reachable from root. Any links to nodes in the subgraph + * that originate from outside of the subgraph will be removed by duplicating the linked to + * object. + * + * Indices stored in roots will be updated if any of the roots are duplicated to new indices. + */ + bool isolate_subgraph (hb_set_t& roots) + { + update_parents (); + hb_hashmap_t<unsigned, unsigned> subgraph; + + // incoming edges to root_idx should be all 32 bit in length so we don't need to de-dup these + // set the subgraph incoming edge count to match all of root_idx's incoming edges + hb_set_t parents; + for (unsigned root_idx : roots) + { + subgraph.set (root_idx, wide_parents (root_idx, parents)); + find_subgraph (root_idx, subgraph); + } - check_success (!clone->obj.links.in_error ()); + unsigned original_root_idx = root_idx (); + hb_hashmap_t<unsigned, unsigned> index_map; + bool made_changes = false; + for (auto entry : subgraph.iter ()) + { + const auto& node = vertices_[entry.first]; + unsigned subgraph_incoming_edges = entry.second; - auto& parent = vertices_[parent_idx]; - unsigned clone_idx = vertices_.length - 2; - for (unsigned i = 0; i < parent.obj.links.length; i++) + if (subgraph_incoming_edges < node.incoming_edges ()) + { + // Only de-dup objects with incoming links from outside the subgraph. + made_changes = true; + duplicate_subgraph (entry.first, index_map); + } + } + + if (!made_changes) + return false; + + if (original_root_idx != root_idx () + && parents.has (original_root_idx)) + { + // If the root idx has changed since parents was determined, update root idx in parents + parents.add (root_idx ()); + parents.del (original_root_idx); + } + + auto new_subgraph = + + subgraph.keys () + | hb_map([&] (unsigned node_idx) { + if (index_map.has (node_idx)) return index_map[node_idx]; + return node_idx; + }) + ; + + remap_obj_indices (index_map, new_subgraph); + remap_obj_indices (index_map, parents.iter (), true); + + // Update roots set with new indices as needed. + unsigned next = HB_SET_VALUE_INVALID; + while (roots.next (&next)) { - auto& l = parent.obj.links[i]; - if (l.objidx == child_idx) + if (index_map.has (next)) { - l.objidx = clone_idx; - clone->incoming_edges++; - child.incoming_edges--; + roots.del (next); + roots.add (index_map[next]); } } + return true; + } + + void find_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& subgraph) + { + for (const auto& link : vertices_[node_idx].obj.all_links ()) + { + if (subgraph.has (link.objidx)) + { + subgraph.set (link.objidx, subgraph[link.objidx] + 1); + continue; + } + subgraph.set (link.objidx, 1); + find_subgraph (link.objidx, subgraph); + } + } + + void find_subgraph (unsigned node_idx, hb_set_t& subgraph) + { + if (subgraph.has (node_idx)) return; + subgraph.add (node_idx); + for (const auto& link : vertices_[node_idx].obj.all_links ()) + find_subgraph (link.objidx, subgraph); + } + + /* + * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign + * links. index_map is updated with mappings from old id to new id. If a duplication has already + * been performed for a given index, then it will be skipped. + */ + void duplicate_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& index_map) + { + if (index_map.has (node_idx)) + return; + + index_map.set (node_idx, duplicate (node_idx)); + for (const auto& l : object (node_idx).all_links ()) { + duplicate_subgraph (l.objidx, index_map); + } + } + + /* + * Creates a copy of node_idx and returns it's new index. + */ + unsigned duplicate (unsigned node_idx) + { + positions_invalid = true; + distance_invalid = true; + + auto* clone = vertices_.push (); + auto& child = vertices_[node_idx]; + if (vertices_.in_error ()) { + return -1; + } + + clone->obj.head = child.obj.head; + clone->obj.tail = child.obj.tail; + clone->distance = child.distance; + clone->space = child.space; + clone->parents.reset (); + + unsigned clone_idx = vertices_.length - 2; + for (const auto& l : child.obj.real_links) + { + clone->obj.real_links.push (l); + vertices_[l.objidx].parents.push (clone_idx); + } + for (const auto& l : child.obj.virtual_links) + { + clone->obj.virtual_links.push (l); + vertices_[l.objidx].parents.push (clone_idx); + } + + check_success (!clone->obj.real_links.in_error ()); + check_success (!clone->obj.virtual_links.in_error ()); + // The last object is the root of the graph, so swap back the root to the end. // The root's obj idx does change, however since it's root nothing else refers to it. // all other obj idx's will be unaffected. vertex_t root = vertices_[vertices_.length - 2]; - vertices_[vertices_.length - 2] = *clone; + vertices_[clone_idx] = *clone; vertices_[vertices_.length - 1] = root; + + // Since the root moved, update the parents arrays of all children on the root. + for (const auto& l : root.obj.all_links ()) + vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ()); + + return clone_idx; + } + + /* + * Creates a copy of child and re-assigns the link from + * parent to the clone. The copy is a shallow copy, objects + * linked from child are not duplicated. + */ + bool duplicate (unsigned parent_idx, unsigned child_idx) + { + update_parents (); + + unsigned links_to_child = 0; + for (const auto& l : vertices_[parent_idx].obj.all_links ()) + { + if (l.objidx == child_idx) links_to_child++; + } + + if (vertices_[child_idx].incoming_edges () <= links_to_child) + { + // Can't duplicate this node, doing so would orphan the original one as all remaining links + // to child are from parent. + DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %d => %d", + parent_idx, child_idx); + return false; + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d", + parent_idx, child_idx); + + unsigned clone_idx = duplicate (child_idx); + if (clone_idx == (unsigned) -1) return false; + // duplicate shifts the root node idx, so if parent_idx was root update it. + if (parent_idx == clone_idx) parent_idx++; + + auto& parent = vertices_[parent_idx]; + for (auto& l : parent.obj.all_links_writer ()) + { + if (l.objidx != child_idx) + continue; + + reassign_link (l, parent_idx, clone_idx); + } + + return true; } /* * Raises the sorting priority of all children. */ - void raise_childrens_priority (unsigned parent_idx) + bool raise_childrens_priority (unsigned parent_idx) { DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d", parent_idx); @@ -390,8 +641,10 @@ struct graph_t // to invalidate positions. It does not change graph structure so no need // to update distances or edge counts. auto& parent = vertices_[parent_idx].obj; - for (unsigned i = 0; i < parent.links.length; i++) - vertices_[parent.links[i].objidx].raise_priority (); + bool made_change = false; + for (auto& l : parent.all_links_writer ()) + made_change |= vertices_[l.objidx].raise_priority (); + return made_change; } /* @@ -404,7 +657,8 @@ struct graph_t for (int parent_idx = vertices_.length - 1; parent_idx >= 0; parent_idx--) { - for (const auto& link : vertices_[parent_idx].obj.links) + // Don't need to check virtual links for overflow + for (const auto& link : vertices_[parent_idx].obj.real_links) { int64_t offset = compute_offset (parent_idx, link); if (is_valid_offset (offset, link)) @@ -414,7 +668,7 @@ struct graph_t overflow_record_t r; r.parent = parent_idx; - r.link = &link; + r.child = link.objidx; overflows->push (r); } } @@ -423,48 +677,156 @@ struct graph_t return overflows->length; } + void print_orphaned_nodes () + { + if (!DEBUG_ENABLED(SUBSET_REPACK)) return; + + DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + parents_invalid = true; + update_parents(); + + for (unsigned i = 0; i < root_idx (); i++) + { + const auto& v = vertices_[i]; + if (!v.parents) + DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i); + } + } + void print_overflows (const hb_vector_t<overflow_record_t>& overflows) { if (!DEBUG_ENABLED(SUBSET_REPACK)) return; - update_incoming_edge_count (); + update_parents (); + int limit = 10; for (const auto& o : overflows) { - const auto& child = vertices_[o.link->objidx]; - DEBUG_MSG (SUBSET_REPACK, nullptr, " overflow from %d => %d (%d incoming , %d outgoing)", + if (!limit--) break; + const auto& parent = vertices_[o.parent]; + const auto& child = vertices_[o.child]; + DEBUG_MSG (SUBSET_REPACK, nullptr, + " overflow from " + "%4d (%4d in, %4d out, space %2d) => " + "%4d (%4d in, %4d out, space %2d)", o.parent, - o.link->objidx, - child.incoming_edges, - child.obj.links.length); + parent.incoming_edges (), + parent.obj.real_links.length + parent.obj.virtual_links.length, + space_for (o.parent), + o.child, + child.incoming_edges (), + child.obj.real_links.length + child.obj.virtual_links.length, + space_for (o.child)); + } + if (overflows.length > 10) { + DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10); + } + } + + unsigned num_roots_for_space (unsigned space) const + { + return num_roots_for_space_[space]; + } + + unsigned next_space () const + { + return num_roots_for_space_.length; + } + + void move_to_new_space (const hb_set_t& indices) + { + num_roots_for_space_.push (0); + unsigned new_space = num_roots_for_space_.length - 1; + + for (unsigned index : indices) { + auto& node = vertices_[index]; + num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1; + num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1; + node.space = new_space; + distance_invalid = true; + positions_invalid = true; } } + unsigned space_for (unsigned index, unsigned* root = nullptr) const + { + const auto& node = vertices_[index]; + if (node.space) + { + if (root != nullptr) + *root = index; + return node.space; + } + + if (!node.parents) + { + if (root) + *root = index; + return 0; + } + + return space_for (node.parents[0], root); + } + void err_other_error () { this->successful = false; } private: + size_t serialized_length () const { + size_t total_size = 0; + for (unsigned i = 0; i < vertices_.length; i++) { + size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; + total_size += size; + } + return total_size; + } + + /* + * Returns the numbers of incoming edges that are 32bits wide. + */ + unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const + { + unsigned count = 0; + hb_set_t visited; + for (unsigned p : vertices_[node_idx].parents) + { + if (visited.has (p)) continue; + visited.add (p); + + // Only real links can be wide + for (const auto& l : vertices_[p].obj.real_links) + { + if (l.objidx == node_idx && l.width == 4 && !l.is_signed) + { + count++; + parents.add (p); + } + } + } + return count; + } + bool check_success (bool success) { return this->successful && (success || (err_other_error (), false)); } /* * Creates a map from objid to # of incoming edges. */ - void update_incoming_edge_count () + void update_parents () { - if (!edge_count_invalid) return; + if (!parents_invalid) return; for (unsigned i = 0; i < vertices_.length; i++) - vertices_[i].incoming_edges = 0; + vertices_[i].parents.reset (); - for (const vertex_t& v : vertices_) + for (unsigned p = 0; p < vertices_.length; p++) { - for (auto& l : v.obj.links) + for (auto& l : vertices_[p].obj.all_links ()) { - vertices_[l.objidx].incoming_edges++; + vertices_[l.objidx].parents.push (p); } } - edge_count_invalid = false; + parents_invalid = false; } /* @@ -515,23 +877,25 @@ struct graph_t hb_priority_queue_t queue; queue.insert (0, vertices_.length - 1); - hb_set_t visited; + hb_vector_t<bool> visited; + visited.resize (vertices_.length); while (!queue.in_error () && !queue.is_empty ()) { unsigned next_idx = queue.pop_minimum ().second; - if (visited.has (next_idx)) continue; + if (visited[next_idx]) continue; const auto& next = vertices_[next_idx]; int64_t next_distance = vertices_[next_idx].distance; - visited.add (next_idx); + visited[next_idx] = true; - for (const auto& link : next.obj.links) + for (const auto& link : next.obj.all_links ()) { - if (visited.has (link.objidx)) continue; + if (visited[link.objidx]) continue; const auto& child = vertices_[link.objidx].obj; - int64_t child_weight = child.tail - child.head + - ((int64_t) 1 << (link.width * 8)); + unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide + int64_t child_weight = (child.tail - child.head) + + ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1); int64_t child_distance = next_distance + child_weight; if (child_distance < vertices_[link.objidx].distance) @@ -545,7 +909,7 @@ struct graph_t check_success (!queue.in_error ()); if (!check_success (queue.is_empty ())) { - DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + print_orphaned_nodes (); return; } @@ -576,6 +940,10 @@ struct graph_t bool is_valid_offset (int64_t offset, const hb_serialize_context_t::object_t::link_t& link) const { + if (unlikely (!link.width)) + // Virtual links can't overflow. + return link.is_signed || offset >= 0; + if (link.is_signed) { if (link.width == 4) @@ -595,16 +963,51 @@ struct graph_t } /* + * Updates a link in the graph to point to a different object. Corrects the + * parents vector on the previous and new child nodes. + */ + void reassign_link (hb_serialize_context_t::object_t::link_t& link, + unsigned parent_idx, + unsigned new_idx) + { + unsigned old_idx = link.objidx; + link.objidx = new_idx; + vertices_[old_idx].remove_parent (parent_idx); + vertices_[new_idx].parents.push (parent_idx); + } + + /* + * Updates all objidx's in all links using the provided mapping. Corrects incoming edge counts. + */ + template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> + void remap_obj_indices (const hb_hashmap_t<unsigned, unsigned>& id_map, + Iterator subgraph, + bool only_wide = false) + { + if (!id_map) return; + for (unsigned i : subgraph) + { + for (auto& link : vertices_[i].obj.all_links_writer ()) + { + if (!id_map.has (link.objidx)) continue; + if (only_wide && !(link.width == 4 && !link.is_signed)) continue; + + reassign_link (link, i, id_map[link.objidx]); + } + } + } + + /* * Updates all objidx's in all links using the provided mapping. */ - void remap_obj_indices (const hb_vector_t<unsigned>& id_map, - hb_vector_t<vertex_t>* sorted_graph) const + void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map, + hb_vector_t<vertex_t>* sorted_graph) const { for (unsigned i = 0; i < sorted_graph->length; i++) { - for (unsigned j = 0; j < (*sorted_graph)[i].obj.links.length; j++) + (*sorted_graph)[i].remap_parents (id_map); + for (auto& link : (*sorted_graph)[i].obj.all_links_writer ()) { - auto& link = (*sorted_graph)[i].obj.links[j]; link.objidx = id_map[link.objidx]; } } @@ -631,6 +1034,9 @@ struct graph_t { switch (link.width) { + case 0: + // Virtual links aren't serialized. + return; case 4: if (link.is_signed) { @@ -656,17 +1062,143 @@ struct graph_t } } + /* + * Finds all nodes in targets that are reachable from start_idx, nodes in visited will be skipped. + * For this search the graph is treated as being undirected. + * + * Connected targets will be added to connected and removed from targets. All visited nodes + * will be added to visited. + */ + void find_connected_nodes (unsigned start_idx, + hb_set_t& targets, + hb_set_t& visited, + hb_set_t& connected) + { + if (visited.has (start_idx)) return; + visited.add (start_idx); + + if (targets.has (start_idx)) + { + targets.del (start_idx); + connected.add (start_idx); + } + + const auto& v = vertices_[start_idx]; + + // Graph is treated as undirected so search children and parents of start_idx + for (const auto& l : v.obj.all_links ()) + find_connected_nodes (l.objidx, targets, visited, connected); + + for (unsigned p : v.parents) + find_connected_nodes (p, targets, visited, connected); + } + public: // TODO(garretrieger): make private, will need to move most of offset overflow code into graph. hb_vector_t<vertex_t> vertices_; private: - hb_vector_t<clone_buffer_t> clone_buffers_; - bool edge_count_invalid; + bool parents_invalid; bool distance_invalid; bool positions_invalid; bool successful; + hb_vector_t<unsigned> num_roots_for_space_; }; +static bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows, + graph_t& sorted_graph) +{ + unsigned space = 0; + hb_set_t roots_to_isolate; + + for (int i = overflows.length - 1; i >= 0; i--) + { + const graph_t::overflow_record_t& r = overflows[i]; + + unsigned root; + unsigned overflow_space = sorted_graph.space_for (r.parent, &root); + if (!overflow_space) continue; + if (sorted_graph.num_roots_for_space (overflow_space) <= 1) continue; + + if (!space) { + space = overflow_space; + } + + if (space == overflow_space) + roots_to_isolate.add(root); + } + + if (!roots_to_isolate) return false; + + unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u); + if (roots_to_isolate.get_population () > maximum_to_move) { + // Only move at most half of the roots in a space at a time. + unsigned extra = roots_to_isolate.get_population () - maximum_to_move; + while (extra--) { + unsigned root = HB_SET_VALUE_INVALID; + roots_to_isolate.previous (&root); + roots_to_isolate.del (root); + } + } + + DEBUG_MSG (SUBSET_REPACK, nullptr, + "Overflow in space %d (%d roots). Moving %d roots to space %d.", + space, + sorted_graph.num_roots_for_space (space), + roots_to_isolate.get_population (), + sorted_graph.next_space ()); + + sorted_graph.isolate_subgraph (roots_to_isolate); + sorted_graph.move_to_new_space (roots_to_isolate); + + return true; +} + +static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows, + hb_set_t& priority_bumped_parents, + graph_t& sorted_graph) +{ + bool resolution_attempted = false; + + // Try resolving the furthest overflows first. + for (int i = overflows.length - 1; i >= 0; i--) + { + const graph_t::overflow_record_t& r = overflows[i]; + const auto& child = sorted_graph.vertices_[r.child]; + if (child.is_shared ()) + { + // The child object is shared, we may be able to eliminate the overflow + // by duplicating it. + if (!sorted_graph.duplicate (r.parent, r.child)) continue; + return true; + } + + if (child.is_leaf () && !priority_bumped_parents.has (r.parent)) + { + // This object is too far from it's parent, attempt to move it closer. + // + // TODO(garretrieger): initially limiting this to leaf's since they can be + // moved closer with fewer consequences. However, this can + // likely can be used for non-leafs as well. + // TODO(garretrieger): also try lowering priority of the parent. Make it + // get placed further up in the ordering, closer to it's children. + // this is probably preferable if the total size of the parent object + // is < then the total size of the children (and the parent can be moved). + // Since in that case moving the parent will cause a smaller increase in + // the length of other offsets. + if (sorted_graph.raise_childrens_priority (r.parent)) { + priority_bumped_parents.add (r.parent); + resolution_attempted = true; + } + continue; + } + + // TODO(garretrieger): add additional offset resolution strategies + // - Promotion to extension lookups. + // - Table splitting. + } + + return resolution_attempted; +} /* * Attempts to modify the topological sorting of the provided object graph to @@ -677,93 +1209,70 @@ struct graph_t * If necessary the structure of the graph may be modified in ways that do not * affect the functionality of the graph. For example shared objects may be * duplicated. + * + * For a detailed writeup describing how the algorithm operates see: + * docs/repacker.md */ -inline void +inline hb_blob_t* hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed, - hb_serialize_context_t* c) { + hb_tag_t table_tag, + unsigned max_rounds = 20) { // Kahn sort is ~twice as fast as shortest distance sort and works for many fonts // so try it first to save time. graph_t sorted_graph (packed); sorted_graph.sort_kahn (); if (!sorted_graph.will_overflow ()) { - sorted_graph.serialize (c); - return; + return sorted_graph.serialize (); } sorted_graph.sort_shortest_distance (); + if ((table_tag == HB_OT_TAG_GPOS + || table_tag == HB_OT_TAG_GSUB) + && sorted_graph.will_overflow ()) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs."); + if (sorted_graph.assign_32bit_spaces ()) + sorted_graph.sort_shortest_distance (); + } + unsigned round = 0; hb_vector_t<graph_t::overflow_record_t> overflows; // TODO(garretrieger): select a good limit for max rounds. while (!sorted_graph.in_error () && sorted_graph.will_overflow (&overflows) - && round++ < 10) { - DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Over flow resolution round %d ===", round); + && round++ < max_rounds) { + DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %d ===", round); sorted_graph.print_overflows (overflows); - bool resolution_attempted = false; hb_set_t priority_bumped_parents; - // Try resolving the furthest overflows first. - for (int i = overflows.length - 1; i >= 0; i--) + + if (!_try_isolating_subgraphs (overflows, sorted_graph)) { - const graph_t::overflow_record_t& r = overflows[i]; - const auto& child = sorted_graph.vertices_[r.link->objidx]; - if (child.is_shared ()) + if (!_process_overflows (overflows, priority_bumped_parents, sorted_graph)) { - // The child object is shared, we may be able to eliminate the overflow - // by duplicating it. - sorted_graph.duplicate (r.parent, r.link->objidx); - resolution_attempted = true; - - // Stop processing overflows for this round so that object order can be - // updated to account for the newly added object. + DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :("); break; } - - if (child.is_leaf () && !priority_bumped_parents.has (r.parent)) - { - // This object is too far from it's parent, attempt to move it closer. - // - // TODO(garretrieger): initially limiting this to leaf's since they can be - // moved closer with fewer consequences. However, this can - // likely can be used for non-leafs as well. - // TODO(garretrieger): add a maximum priority, don't try to raise past this. - // TODO(garretrieger): also try lowering priority of the parent. Make it - // get placed further up in the ordering, closer to it's children. - // this is probably preferable if the total size of the parent object - // is < then the total size of the children (and the parent can be moved). - // Since in that case moving the parent will cause a smaller increase in - // the length of other offsets. - sorted_graph.raise_childrens_priority (r.parent); - priority_bumped_parents.add (r.parent); - resolution_attempted = true; - continue; - } - - // TODO(garretrieger): add additional offset resolution strategies - // - Promotion to extension lookups. - // - Table splitting. - } - - if (resolution_attempted) - { - sorted_graph.sort_shortest_distance (); - continue; } - DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :("); - c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); - return; + sorted_graph.sort_shortest_distance (); } if (sorted_graph.in_error ()) { - c->err (HB_SERIALIZE_ERROR_OTHER); - return; + DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state."); + return nullptr; } - sorted_graph.serialize (c); -} + if (sorted_graph.will_overflow ()) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed."); + return nullptr; + } + + return sorted_graph.serialize (); +} #endif /* HB_REPACKER_HH */ diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 56c46015a6..65c2772201 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), @@ -145,14 +146,14 @@ struct hb_sanitize_context_t : private: template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN - ( obj.sanitize (this, hb_forward<Ts> (ds)...) ) + ( obj.sanitize (this, std::forward<Ts> (ds)...) ) template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN - ( obj.dispatch (this, hb_forward<Ts> (ds)...) ) + ( obj.dispatch (this, std::forward<Ts> (ds)...) ) public: template <typename T, typename ...Ts> auto dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN - ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) + ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) ) void init (hb_blob_t *b) @@ -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 <typename Type> 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 7212d9872a..823c0be8b5 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -65,19 +65,26 @@ struct hb_serialize_context_t struct object_t { - void fini () { links.fini (); } + void fini () { + real_links.fini (); + virtual_links.fini (); + } bool operator == (const object_t &o) const { + // Virtual links aren't considered for equality since they don't affect the functionality + // of the object. return (tail - head == o.tail - o.head) - && (links.length == o.links.length) + && (real_links.length == o.real_links.length) && 0 == hb_memcmp (head, o.head, tail - head) - && links.as_bytes () == o.links.as_bytes (); + && real_links.as_bytes () == o.real_links.as_bytes (); } uint32_t hash () const { + // Virtual links aren't considered for equality since they don't affect the functionality + // of the object. return hb_bytes_t (head, tail - head).hash () ^ - links.as_bytes ().hash (); + real_links.as_bytes ().hash (); } struct link_t @@ -92,8 +99,14 @@ struct hb_serialize_context_t char *head; char *tail; - hb_vector_t<link_t> links; + hb_vector_t<link_t> real_links; + hb_vector_t<link_t> virtual_links; object_t *next; + + auto all_links () const HB_AUTO_RETURN + (( hb_concat (this->real_links, this->virtual_links) )); + auto all_links_writer () HB_AUTO_RETURN + (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) )); }; struct snapshot_t @@ -101,12 +114,14 @@ struct hb_serialize_context_t char *head; char *tail; object_t *current; // Just for sanity check - unsigned num_links; + unsigned num_real_links; + unsigned num_virtual_links; hb_serialize_error_t errors; }; snapshot_t snapshot () - { return snapshot_t { head, tail, current, current->links.length, errors }; } + { return snapshot_t { + head, tail, current, current->real_links.length, current->virtual_links.length, errors }; } hb_serialize_context_t (void *start_, unsigned int size) : start ((char *) start_), @@ -189,8 +204,8 @@ struct hb_serialize_context_t { return check_success (!hb_deref (obj).in_error ()); } template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os) - { return propagate_error (hb_forward<T1> (o1)) && - propagate_error (hb_forward<Ts> (os)...); } + { return propagate_error (std::forward<T1> (o1)) && + propagate_error (std::forward<Ts> (os)...); } /* To be called around main operation. */ template <typename Type> @@ -282,7 +297,8 @@ struct hb_serialize_context_t if (!len) { - assert (!obj->links.length); + assert (!obj->real_links.length); + assert (!obj->virtual_links.length); return 0; } @@ -292,6 +308,7 @@ struct hb_serialize_context_t objidx = packed_map.get (obj); if (objidx) { + merge_virtual_links (obj, objidx); obj->fini (); return objidx; } @@ -327,7 +344,8 @@ struct hb_serialize_context_t // Overflows that happened after the snapshot will be erased by the revert. if (unlikely (in_error () && !only_overflow ())) return; assert (snap.current == current); - current->links.shrink (snap.num_links); + current->real_links.shrink (snap.num_real_links); + current->virtual_links.shrink (snap.num_virtual_links); errors = snap.errors; revert (snap.head, snap.tail); } @@ -358,6 +376,35 @@ struct hb_serialize_context_t assert (packed.tail ()->head == tail); } + // Adds a virtual link from the current object to objidx. A virtual link is not associated with + // an actual offset field. They are solely used to enforce ordering constraints between objects. + // Adding a virtual link from object a to object b will ensure that object b is always packed after + // object a in the final serialized order. + // + // This is useful in certain situtations where there needs to be a specific ordering in the + // final serialization. Such as when platform bugs require certain orderings, or to provide + // guidance to the repacker for better offset overflow resolution. + void add_virtual_link (objidx_t objidx) + { + if (unlikely (in_error ())) return; + + if (!objidx) + return; + + assert (current); + + auto& link = *current->virtual_links.push (); + if (current->virtual_links.in_error ()) + err (HB_SERIALIZE_ERROR_OTHER); + + link.width = 0; + link.objidx = objidx; + link.is_signed = 0; + link.whence = 0; + link.position = 0; + link.bias = 0; + } + template <typename T> void add_link (T &ofs, objidx_t objidx, whence_t whence = Head, @@ -371,16 +418,27 @@ struct hb_serialize_context_t assert (current); assert (current->head <= (const char *) &ofs); - auto& link = *current->links.push (); - if (current->links.in_error ()) + auto& link = *current->real_links.push (); + if (current->real_links.in_error ()) err (HB_SERIALIZE_ERROR_OTHER); link.width = sizeof (T); - link.is_signed = hb_is_signed (hb_unwrap_type (T)); + link.objidx = objidx; + if (unlikely (!sizeof (T))) + { + // This link is not associated with an actual offset and exists merely to enforce + // an ordering constraint. + link.is_signed = 0; + link.whence = 0; + link.position = 0; + link.bias = 0; + return; + } + + link.is_signed = std::is_signed<hb_unwrap_type (T)>::value; link.whence = (unsigned) whence; link.position = (const char *) &ofs - current->head; link.bias = bias; - link.objidx = objidx; } unsigned to_bias (const void *base) const @@ -400,7 +458,7 @@ struct hb_serialize_context_t assert (packed.length > 1); for (const object_t* parent : ++hb_iter (packed)) - for (const object_t::link_t &link : parent->links) + for (const object_t::link_t &link : parent->real_links) { const object_t* child = packed[link.objidx]; if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; } @@ -494,7 +552,7 @@ struct hb_serialize_context_t template <typename Type, typename ...Ts> auto _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN - (Type *, src.copy (this, hb_forward<Ts> (ds)...)) + (Type *, src.copy (this, std::forward<Ts> (ds)...)) template <typename Type> auto _copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src)) @@ -509,16 +567,16 @@ struct hb_serialize_context_t * instead of memcpy(). */ template <typename Type, typename ...Ts> Type *copy (const Type &src, Ts&&... ds) - { return _copy (src, hb_prioritize, hb_forward<Ts> (ds)...); } + { return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); } template <typename Type, typename ...Ts> Type *copy (const Type *src, Ts&&... ds) - { return copy (*src, hb_forward<Ts> (ds)...); } + { return copy (*src, std::forward<Ts> (ds)...); } template<typename Iterator, hb_requires (hb_is_iterator (Iterator)), typename ...Ts> void copy_all (Iterator it, Ts&&... ds) - { for (decltype (*it) _ : it) copy (_, hb_forward<Ts> (ds)...); } + { for (decltype (*it) _ : it) copy (_, std::forward<Ts> (ds)...); } template <typename Type> hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } @@ -546,10 +604,10 @@ struct hb_serialize_context_t template <typename Type, typename ...Ts> Type *extend (Type *obj, Ts&&... ds) - { return extend_size (obj, obj->get_size (hb_forward<Ts> (ds)...)); } + { return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); } template <typename Type, typename ...Ts> Type *extend (Type &obj, Ts&&... ds) - { return extend (hb_addressof (obj), hb_forward<Ts> (ds)...); } + { return extend (hb_addressof (obj), std::forward<Ts> (ds)...); } /* Output routines. */ hb_bytes_t copy_bytes () const @@ -600,6 +658,13 @@ struct hb_serialize_context_t private: + void merge_virtual_links (const object_t* from, objidx_t to_idx) { + object_t* to = packed[to_idx]; + for (const auto& l : from->virtual_links) { + to->virtual_links.push (l); + } + } + /* Object memory pool. */ hb_pool_t<object_t> object_pool; @@ -610,7 +675,9 @@ struct hb_serialize_context_t hb_vector_t<object_t *> packed; /* Map view of packed objects. */ - hb_hashmap_t<const object_t *, objidx_t, nullptr, 0> packed_map; + hb_hashmap_t<const object_t *, objidx_t, + const object_t *, objidx_t, + nullptr, 0> packed_map; }; #endif /* HB_SERIALIZE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-set-digest.hh b/thirdparty/harfbuzz/src/hb-set-digest.hh index 1ef1ba5fb2..7d4979b73b 100644 --- a/thirdparty/harfbuzz/src/hb-set-digest.hh +++ b/thirdparty/harfbuzz/src/hb-set-digest.hh @@ -168,15 +168,17 @@ struct hb_set_digest_combiner_t * There is not much science to this: it's a result of intuition * and testing. */ -typedef hb_set_digest_combiner_t -< - hb_set_digest_lowest_bits_t<unsigned long, 4>, +using hb_set_digest_t = hb_set_digest_combiner_t < - hb_set_digest_lowest_bits_t<unsigned long, 0>, - hb_set_digest_lowest_bits_t<unsigned long, 9> + hb_set_digest_lowest_bits_t<unsigned long, 4>, + hb_set_digest_combiner_t + < + hb_set_digest_lowest_bits_t<unsigned long, 0>, + hb_set_digest_lowest_bits_t<unsigned long, 9> + > > -> hb_set_digest_t; +; #endif /* HB_SET_DIGEST_HH */ diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index 437e234361..af02e9e12b 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -42,9 +42,22 @@ struct hb_sparseset_t ~hb_sparseset_t () { fini (); } hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); } - void operator= (const hb_sparseset_t& other) { set (other); } - // TODO Add move construtor/assign - // TODO Add constructor for Iterator + hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); } + hb_sparseset_t& operator= (const hb_sparseset_t& other) { set (other); return *this; } + hb_sparseset_t& operator= (hb_sparseset_t&& other) { hb_swap (*this, other); return *this; } + friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); } + + hb_sparseset_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t () + { + for (auto&& item : lst) + add (item); + } + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + hb_sparseset_t (const Iterable &o) : hb_sparseset_t () + { + hb_copy (o, *this); + } void init_shallow () { s.init (); } void init () @@ -140,7 +153,18 @@ struct hb_sparseset_t operator iter_t () const { return iter (); } }; -struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> {}; +struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> +{ + hb_set_t () = default; + ~hb_set_t () = 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<hb_codepoint_t> lst) : hb_sparseset_t<hb_bit_set_invertible_t> (lst) {} + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + hb_set_t (const Iterable &o) : hb_sparseset_t<hb_bit_set_invertible_t> (o) {} +}; static_assert (hb_set_t::INVALID == HB_SET_VALUE_INVALID, ""); diff --git a/thirdparty/harfbuzz/src/hb-style.cc b/thirdparty/harfbuzz/src/hb-style.cc index dfb1017c88..f1b44cea53 100644 --- a/thirdparty/harfbuzz/src/hb-style.cc +++ b/thirdparty/harfbuzz/src/hb-style.cc @@ -113,7 +113,9 @@ hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag) case HB_STYLE_TAG_WIDTH: return face->table.OS2->has_data () ? face->table.OS2->get_width () - : (face->table.head->is_condensed () ? 75 : 100); + : (face->table.head->is_condensed () ? 75 : + face->table.head->is_expanded () ? 125 : + 100); case HB_STYLE_TAG_WEIGHT: return face->table.OS2->has_data () ? face->table.OS2->usWeightClass diff --git a/thirdparty/harfbuzz/src/hb-subset-input.hh b/thirdparty/harfbuzz/src/hb-subset-input.hh index a3e28b0562..07c0e22676 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.hh +++ b/thirdparty/harfbuzz/src/hb-subset-input.hh @@ -42,17 +42,19 @@ struct hb_subset_input_t { hb_object_header_t header; + struct sets_t { + hb_set_t *glyphs; + hb_set_t *unicodes; + hb_set_t *no_subset_tables; + hb_set_t *drop_tables; + hb_set_t *name_ids; + hb_set_t *name_languages; + hb_set_t *layout_features; + }; + union { - struct { - hb_set_t *glyphs; - hb_set_t *unicodes; - hb_set_t *no_subset_tables; - hb_set_t *drop_tables; - hb_set_t *name_ids; - hb_set_t *name_languages; - hb_set_t *layout_features; - } sets; - hb_set_t* set_ptrs[sizeof (sets) / sizeof (hb_set_t*)]; + sets_t sets; + hb_set_t* set_ptrs[sizeof (sets_t) / sizeof (hb_set_t*)]; }; unsigned flags; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 677df35fad..883ab82093 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -38,9 +38,10 @@ #include "hb-ot-color-colrv1-closure.hh" #include "hb-ot-var-fvar-table.hh" #include "hb-ot-stat-table.hh" +#include "hb-ot-math-table.hh" -typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map; +typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, @@ -99,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) @@ -112,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, @@ -221,6 +234,49 @@ _cmap_closure (hb_face_t *face, cmap.fini (); } +static void _colr_closure (hb_face_t *face, + hb_map_t *layers_map, + hb_map_t *palettes_map, + hb_set_t *glyphs_colred) +{ + OT::COLR::accelerator_t colr; + colr.init (face); + if (!colr.is_valid ()) return; + + unsigned iteration_count = 0; + hb_set_t palette_indices, layer_indices; + unsigned glyphs_num; + { + glyphs_num = glyphs_colred->get_population (); + // Collect all glyphs referenced by COLRv0 + hb_set_t glyphset_colrv0; + for (hb_codepoint_t gid : glyphs_colred->iter ()) + colr.closure_glyphs (gid, &glyphset_colrv0); + + glyphs_colred->union_ (glyphset_colrv0); + + //closure for COLRv1 + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); + } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && + glyphs_num != glyphs_colred->get_population ()); + + colr.closure_V0palette_indices (glyphs_colred, &palette_indices); + _remap_indexes (&layer_indices, layers_map); + _remap_palette_indexes (&palette_indices, palettes_map); + colr.fini (); +} + +static inline void +_math_closure (hb_face_t *face, + hb_set_t *glyphset) +{ + hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face); + if (math->has_data ()) + math->closure_glyphs (glyphset); + math.destroy (); +} + + static inline void _remove_invalid_gids (hb_set_t *glyphs, unsigned int num_glyphs) @@ -301,12 +357,10 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #ifndef HB_NO_SUBSET_CFF OT::cff1::accelerator_t cff; #endif - OT::COLR::accelerator_t colr; glyf.init (plan->source); #ifndef HB_NO_SUBSET_CFF cff.init (plan->source); #endif - colr.init (plan->source); plan->_glyphset_gsub->add (0); // Not-def @@ -334,30 +388,18 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #endif _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); - // Collect all glyphs referenced by COLRv0 - hb_set_t* cur_glyphset = plan->_glyphset_gsub; - hb_set_t glyphset_colrv0; - if (colr.is_valid ()) - { - glyphset_colrv0.union_ (*cur_glyphset); - for (hb_codepoint_t gid : cur_glyphset->iter ()) - colr.closure_glyphs (gid, &glyphset_colrv0); - cur_glyphset = &glyphset_colrv0; - } - - hb_set_t palette_indices; - colr.closure_V0palette_indices (cur_glyphset, &palette_indices); + hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub); + _math_closure (plan->source, plan->_glyphset_mathed); + _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ()); - hb_set_t layer_indices; - colr.closure_forV1 (cur_glyphset, &layer_indices, &palette_indices); - _remap_indexes (&layer_indices, plan->colrv1_layers); - _remap_palette_indexes (&palette_indices, plan->colr_palettes); - colr.fini (); - _remove_invalid_gids (cur_glyphset, plan->source->get_num_glyphs ()); + hb_set_t cur_glyphset = *plan->_glyphset_mathed; + _colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset); + _remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ()); + hb_set_set (plan->_glyphset_colred, &cur_glyphset); // Populate a full set of glyphs to retain by adding all referenced // composite glyphs. - for (hb_codepoint_t gid : cur_glyphset->iter ()) + for (hb_codepoint_t gid : cur_glyphset.iter ()) { glyf.add_gid_and_children (gid, plan->_glyphset); #ifndef HB_NO_SUBSET_CFF @@ -468,6 +510,8 @@ hb_subset_plan_create (hb_face_t *face, plan->_glyphset = hb_set_create (); plan->_glyphset_gsub = hb_set_create (); + plan->_glyphset_mathed = hb_set_create (); + plan->_glyphset_colred = hb_set_create (); plan->codepoint_to_glyph = hb_map_create (); plan->glyph_map = hb_map_create (); plan->reverse_glyph_map = hb_map_create (); @@ -535,6 +579,8 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_map_destroy (plan->reverse_glyph_map); hb_set_destroy (plan->_glyphset); hb_set_destroy (plan->_glyphset_gsub); + hb_set_destroy (plan->_glyphset_mathed); + hb_set_destroy (plan->_glyphset_colred); hb_map_destroy (plan->gsub_lookups); hb_map_destroy (plan->gpos_lookups); hb_map_destroy (plan->gsub_features); diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index 92a4e27ccc..b9244e5cb2 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -77,14 +77,16 @@ struct hb_subset_plan_t unsigned int _num_output_glyphs; hb_set_t *_glyphset; hb_set_t *_glyphset_gsub; + hb_set_t *_glyphset_mathed; + hb_set_t *_glyphset_colred; //active lookups we'd like to retain hb_map_t *gsub_lookups; hb_map_t *gpos_lookups; //active langsys we'd like to retain - hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gsub_langsys; - hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gpos_langsys; + hb_hashmap_t<unsigned, hb_set_t *> *gsub_langsys; + hb_hashmap_t<unsigned, hb_set_t *> *gpos_langsys; //active features after removing redundant langsys and prune_features hb_map_t *gsub_features; diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 34f92e0d81..bb46e5b97f 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -52,6 +52,7 @@ #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-var-gvar-table.hh" #include "hb-ot-var-hvar-table.hh" +#include "hb-ot-math-table.hh" #include "hb-repacker.hh" /** @@ -103,20 +104,16 @@ _repack (hb_tag_t tag, const hb_serialize_context_t& c) if (!c.offset_overflow ()) return c.copy_blob (); - hb_vector_t<char> buf; - int buf_size = c.end - c.start; - if (unlikely (!buf.alloc (buf_size))) - return nullptr; - - hb_serialize_context_t repacked ((void *) buf, buf_size); - hb_resolve_overflows (c.object_graph (), &repacked); + hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag); - if (unlikely (repacked.in_error ())) - // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset - // portion. + if (unlikely (!result)) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.", + HB_UNTAG (tag)); return nullptr; + } - return repacked.copy_blob (); + return result; } template<typename TableType> @@ -305,6 +302,7 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan); case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan); case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ + case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan); #ifndef HB_NO_SUBSET_CFF case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan); diff --git a/thirdparty/harfbuzz/src/hb-subset.hh b/thirdparty/harfbuzz/src/hb-subset.hh index c9b01c67f3..98c5f06fbf 100644 --- a/thirdparty/harfbuzz/src/hb-subset.hh +++ b/thirdparty/harfbuzz/src/hb-subset.hh @@ -45,14 +45,14 @@ struct hb_subset_context_t : private: template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN - ( obj.subset (this, hb_forward<Ts> (ds)...) ) + ( obj.subset (this, std::forward<Ts> (ds)...) ) template <typename T, typename ...Ts> auto _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN - ( obj.dispatch (this, hb_forward<Ts> (ds)...) ) + ( obj.dispatch (this, std::forward<Ts> (ds)...) ) public: template <typename T, typename ...Ts> auto dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN - ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) + ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) ) hb_blob_t *source_blob; hb_subset_plan_t *plan; diff --git a/thirdparty/harfbuzz/src/hb-unicode.hh b/thirdparty/harfbuzz/src/hb-unicode.hh index 0a79944107..4c28bb0cdf 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.hh +++ b/thirdparty/harfbuzz/src/hb-unicode.hh @@ -121,7 +121,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE static hb_bool_t is_variation_selector (hb_codepoint_t unicode) { - /* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the + /* U+180B..180D, U+180F MONGOLIAN FREE VARIATION SELECTORs are handled in the * Arabic shaper. No need to match them here. */ return unlikely (hb_in_ranges<hb_codepoint_t> (unicode, 0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */ @@ -136,7 +136,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * As such, we make exceptions for those four. * Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503 * - * Unicode 7.0: + * Unicode 14.0: * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/' * 00AD # Cf SOFT HYPHEN * 034F # Mn COMBINING GRAPHEME JOINER @@ -145,6 +145,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA * 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE * 180E # Cf MONGOLIAN VOWEL SEPARATOR + * 180F # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR * 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK * 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE * 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc index 3dc4c0937d..0e5a114f7d 100644 --- a/thirdparty/harfbuzz/src/hb-uniscribe.cc +++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc @@ -878,7 +878,7 @@ retry: if (backward) hb_buffer_reverse (buffer); - buffer->unsafe_to_break_all (); + buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK); /* Wow, done! */ return true; diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 110d457caf..b0a1e5e966 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -38,10 +38,23 @@ struct hb_vector_t typedef Type item_t; static constexpr unsigned item_size = hb_static_size (Type); - hb_vector_t () { init (); } - hb_vector_t (const hb_vector_t &o) + hb_vector_t () = default; + hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t () + { + alloc (lst.size ()); + for (auto&& item : lst) + push (item); + } + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + hb_vector_t (const Iterable &o) : hb_vector_t () + { + if (hb_iter (o).is_random_access_iterator) + alloc (hb_len (hb_iter (o))); + hb_copy (o, *this); + } + hb_vector_t (const hb_vector_t &o) : hb_vector_t () { - init (); alloc (o.length); hb_copy (o, *this); } @@ -55,11 +68,11 @@ struct hb_vector_t ~hb_vector_t () { fini (); } private: - int allocated; /* == -1 means allocation failed. */ + int allocated = 0; /* == -1 means allocation failed. */ public: - unsigned int length; + unsigned int length = 0; public: - Type *arrayZ; + Type *arrayZ = nullptr; void init () { @@ -87,6 +100,13 @@ struct hb_vector_t resize (0); } + friend void swap (hb_vector_t& a, hb_vector_t& b) + { + hb_swap (a.allocated, b.allocated); + hb_swap (a.length, b.length); + hb_swap (a.arrayZ, b.arrayZ); + } + hb_vector_t& operator = (const hb_vector_t &o) { reset (); @@ -96,11 +116,7 @@ struct hb_vector_t } hb_vector_t& operator = (hb_vector_t &&o) { - fini (); - allocated = o.allocated; - length = o.length; - arrayZ = o.arrayZ; - o.init (); + hb_swap (*this, o); return *this; } @@ -134,7 +150,7 @@ struct hb_vector_t /* Sink interface. */ template <typename T> - hb_vector_t& operator << (T&& v) { push (hb_forward<T> (v)); return *this; } + hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; } hb_array_t< Type> as_array () { return hb_array (arrayZ, length); } hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); } @@ -182,7 +198,7 @@ struct hb_vector_t // the created copy to leak memory since we won't have stored a // reference to it. return p; - *p = hb_forward<T> (v); + *p = std::forward<T> (v); return p; } @@ -239,7 +255,7 @@ struct hb_vector_t Type pop () { if (!length) return Null (Type); - return hb_move (arrayZ[--length]); /* Does this move actually work? */ + return std::move (arrayZ[--length]); /* Does this move actually work? */ } void remove (unsigned int i) @@ -295,6 +311,19 @@ struct hb_vector_t template <typename Type> struct hb_sorted_vector_t : hb_vector_t<Type> { + hb_sorted_vector_t () = default; + ~hb_sorted_vector_t () = default; + hb_sorted_vector_t (hb_sorted_vector_t& o) = default; + hb_sorted_vector_t (hb_sorted_vector_t &&o) = default; + hb_sorted_vector_t (std::initializer_list<Type> lst) : hb_vector_t<Type> (lst) {} + template <typename Iterable, + hb_requires (hb_is_iterable (Iterable))> + hb_sorted_vector_t (const Iterable &o) : hb_vector_t<Type> (o) {} + hb_sorted_vector_t& operator = (const hb_sorted_vector_t &o) = default; + hb_sorted_vector_t& operator = (hb_sorted_vector_t &&o) = default; + friend void swap (hb_sorted_vector_t& a, hb_sorted_vector_t& b) + { hb_swap ((hb_vector_t<Type>&) (a), (hb_vector_t<Type>&) (b)); } + hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); } hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); } diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 70325f88eb..52b124b745 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -47,7 +47,7 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 0 +#define HB_VERSION_MINOR 2 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "3.0.0" +#define HB_VERSION_STRING "3.2.0" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh index 829b5a1ab7..1f14267525 100644 --- a/thirdparty/harfbuzz/src/hb.hh +++ b/thirdparty/harfbuzz/src/hb.hh @@ -62,6 +62,7 @@ /* Error. Should never happen. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR +#pragma GCC diagnostic error "-Wbitwise-instead-of-logical" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" |