diff options
Diffstat (limited to 'thirdparty/harfbuzz/src')
194 files changed, 15877 insertions, 10171 deletions
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-ankr-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-ankr-table.hh index f2785a6f58..63fac84524 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-ankr-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-ankr-table.hh @@ -54,7 +54,7 @@ struct Anchor DEFINE_SIZE_STATIC (4); }; -typedef LArrayOf<Anchor> GlyphAnchors; +typedef Array32Of<Anchor> GlyphAnchors; struct ankr { @@ -64,7 +64,7 @@ struct ankr unsigned int i, unsigned int num_glyphs) const { - const NNOffsetTo<GlyphAnchors> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs); + const NNOffset16To<GlyphAnchors> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs); if (!offset) return Null (Anchor); const GlyphAnchors &anchors = &(this+anchorData) + *offset; @@ -83,9 +83,9 @@ struct ankr protected: HBUINT16 version; /* Version number (set to zero) */ HBUINT16 flags; /* Flags (currently unused; set to zero) */ - LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors>>> + Offset32To<Lookup<NNOffset16To<GlyphAnchors>>> lookupTable; /* Offset to the table's lookup table */ - LNNOffsetTo<HBUINT8> + NNOffset32To<HBUINT8> anchorData; /* Offset to the glyph data table */ public: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index 75d523f5fc..e70ce97174 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -30,6 +30,9 @@ #include "hb-aat-layout.hh" #include "hb-open-type.hh" +namespace OT { +struct GDEF; +}; namespace AAT { @@ -164,7 +167,7 @@ struct LookupSegmentArray HBGlyphID last; /* Last GlyphID in this segment */ HBGlyphID first; /* First GlyphID in this segment */ - NNOffsetTo<UnsizedArrayOf<T>> + NNOffset16To<UnsizedArrayOf<T>> valuesZ; /* A 16-bit offset from the start of * the table to the data. */ public: @@ -510,7 +513,7 @@ struct StateTable const Entry<Extra> &get_entry (int state, unsigned int klass) const { if (unlikely (klass >= nClasses)) - klass = StateTable<Types, Entry<Extra>>::CLASS_OUT_OF_BOUNDS; + klass = StateTable::CLASS_OUT_OF_BOUNDS; const HBUSHORT *states = (this+stateArrayTable).arrayZ; const Entry<Extra> *entries = (this+entryTable).arrayZ; @@ -576,7 +579,7 @@ struct StateTable if (unlikely (stop > states)) return_trace (false); for (const HBUSHORT *p = states; stop < p; p--) - num_entries = hb_max (num_entries, *(p - 1) + 1); + num_entries = hb_max (num_entries, *(p - 1) + 1u); state_neg = min_state; } } @@ -597,7 +600,7 @@ struct StateTable if (unlikely (stop < states)) return_trace (false); for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++) - num_entries = hb_max (num_entries, *p + 1); + num_entries = hb_max (num_entries, *p + 1u); state_pos = max_state + 1; } } @@ -659,7 +662,7 @@ struct ClassTable } protected: HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ - ArrayOf<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus + Array16Of<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus * firstGlyph). */ public: DEFINE_SIZE_ARRAY (4, classArray); @@ -678,7 +681,8 @@ struct ObsoleteTypes const void *base, const T *array) { - return (offset - ((const char *) array - (const char *) base)) / T::static_size; + /* https://github.com/harfbuzz/harfbuzz/issues/2816 */ + return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size; } template <typename T> static unsigned int byteOffsetToIndex (unsigned int offset, @@ -729,7 +733,10 @@ struct ExtendedTypes template <typename Types, typename EntryData> struct StateTableDriver { - StateTableDriver (const StateTable<Types, EntryData> &machine_, + using StateTableT = StateTable<Types, EntryData>; + using EntryT = Entry<EntryData>; + + StateTableDriver (const StateTableT &machine_, hb_buffer_t *buffer_, hb_face_t *face_) : machine (machine_), @@ -742,59 +749,101 @@ struct StateTableDriver if (!c->in_place) buffer->clear_output (); - int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT; + int state = StateTableT::STATE_START_OF_TEXT; for (buffer->idx = 0; buffer->successful;) { unsigned int klass = buffer->idx < buffer->len ? machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : - (unsigned) StateTable<Types, EntryData>::CLASS_END_OF_TEXT; + (unsigned) StateTableT::CLASS_END_OF_TEXT; DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); - const Entry<EntryData> &entry = machine.get_entry (state, klass); + const EntryT &entry = machine.get_entry (state, klass); + const int next_state = machine.new_state (entry.newState); - /* Unsafe-to-break before this if not in state 0, as things might - * go differently if we start from state 0 here. + /* Conditions under which it's guaranteed safe-to-break before current glyph: * - * Ugh. The indexing here is ugly... */ - if (state && buffer->backtrack_len () && buffer->idx < buffer->len) - { - /* If there's no action and we're just epsilon-transitioning to state 0, - * safe to break. */ - if (c->is_actionable (this, entry) || - !(entry.newState == StateTable<Types, EntryData>::STATE_START_OF_TEXT && - entry.flags == context_t::DontAdvance)) - buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); - } - - /* Unsafe-to-break if end-of-text would kick in here. */ - if (buffer->idx + 2 <= buffer->len) - { - const Entry<EntryData> &end_entry = machine.get_entry (state, StateTable<Types, EntryData>::CLASS_END_OF_TEXT); - if (c->is_actionable (this, end_entry)) - buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); - } + * 1. There was no action in this transition; and + * + * 2. If we break before current glyph, the results will be the same. That + * is guaranteed if: + * + * 2a. We were already in start-of-text state; or + * + * 2b. We are epsilon-transitioning to start-of-text state; or + * + * 2c. Starting from start-of-text state seeing current glyph: + * + * 2c'. There won't be any actions; and + * + * 2c". We would end up in the same state that we were going to end up + * in now, including whether epsilon-transitioning. + * + * and + * + * 3. If we break before current glyph, there won't be any end-of-text action + * after previous glyph. + * + * This triples the transitions we need to look up, but is worth returning + * granular unsafe-to-break results. See eg.: + * + * https://github.com/harfbuzz/harfbuzz/issues/2860 + */ + const EntryT *wouldbe_entry; + bool safe_to_break = + /* 1. */ + !c->is_actionable (this, entry) + && + /* 2. */ + ( + /* 2a. */ + state == StateTableT::STATE_START_OF_TEXT + || + /* 2b. */ + ( + (entry.flags & context_t::DontAdvance) && + next_state == StateTableT::STATE_START_OF_TEXT + ) + || + /* 2c. */ + ( + wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass) + , + /* 2c'. */ + !c->is_actionable (this, *wouldbe_entry) + && + /* 2c". */ + ( + next_state == machine.new_state (wouldbe_entry->newState) + && + (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance) + ) + ) + ) + && + /* 3. */ + !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT)) + ; + + if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) + buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); c->transition (this, entry); - state = machine.new_state (entry.newState); + state = next_state; DEBUG_MSG (APPLY, nullptr, "s%d", state); - if (buffer->idx == buffer->len) + if (buffer->idx == buffer->len || unlikely (!buffer->successful)) break; if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) - buffer->next_glyph (); + (void) buffer->next_glyph (); } if (!c->in_place) - { - for (; buffer->successful && buffer->idx < buffer->len;) - buffer->next_glyph (); buffer->swap_buffers (); - } } public: - const StateTable<Types, EntryData> &machine; + const StateTableT &machine; hb_buffer_t *buffer; unsigned int num_glyphs; }; @@ -817,6 +866,7 @@ struct hb_aat_apply_context_t : hb_buffer_t *buffer; hb_sanitize_context_t sanitizer; const ankr *ankr_table; + const OT::GDEF *gdef_table; /* Unused. For debug tracing only. */ unsigned int lookup_index; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh index 359e859cfc..573f0cf9f6 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh @@ -144,7 +144,7 @@ struct FeatureName protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ - LNNOffsetTo<UnsizedArrayOf<SettingName>> + NNOffset32To<UnsizedArrayOf<SettingName>> settingTableZ; /* Offset in bytes from the beginning of this table to * this feature's setting name array. The actual type of * record this offset refers to will depend on the diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh index 49506e9f5a..556d4ad75b 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh @@ -79,7 +79,7 @@ struct DecompositionAction * to decompose before more frequent ones. The ligatures * on the line of text will decompose in increasing * value of this field. */ - ArrayOf<HBUINT16> + Array16Of<HBUINT16> decomposedglyphs; /* Number of 16-bit glyph indexes that follow; * the ligature will be decomposed into these glyphs. @@ -310,7 +310,7 @@ struct WidthDeltaPair DEFINE_SIZE_STATIC (24); }; -typedef OT::LArrayOf<WidthDeltaPair> WidthDeltaCluster; +typedef OT::Array32Of<WidthDeltaPair> WidthDeltaCluster; struct JustificationCategory { @@ -358,20 +358,20 @@ struct JustificationHeader } protected: - OffsetTo<JustificationCategory> + Offset16To<JustificationCategory> justClassTable; /* Offset to the justification category state table. */ - OffsetTo<WidthDeltaCluster> + Offset16To<WidthDeltaCluster> wdcTable; /* Offset from start of justification table to start * of the subtable containing the width delta factors * for the glyphs in your font. * * The width delta clusters table. */ - OffsetTo<PostcompensationActionChain> + Offset16To<PostcompensationActionChain> pcTable; /* Offset from start of justification table to start * of postcompensation subtable (set to zero if none). * * The postcompensation subtable, if present in the font. */ - Lookup<OffsetTo<WidthDeltaCluster>> + Lookup<Offset16To<WidthDeltaCluster>> lookupTable; /* Lookup table associating glyphs with width delta * clusters. See the description of Width Delta Clusters * table for details on how to interpret the lookup values. */ @@ -398,13 +398,13 @@ struct just FixedVersion<>version; /* Version of the justification table * (0x00010000u for version 1.0). */ HBUINT16 format; /* Format of the justification table (set to 0). */ - OffsetTo<JustificationHeader> + Offset16To<JustificationHeader> horizData; /* Byte offset from the start of the justification table * to the header for tables that contain justification * information for horizontal text. * If you are not including this information, * store 0. */ - OffsetTo<JustificationHeader> + Offset16To<JustificationHeader> vertData; /* ditto, vertical */ public: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh index 1cd412164e..d0eacf0e61 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh @@ -710,18 +710,18 @@ struct KerxSubTableFormat6 { struct Long { - LNNOffsetTo<Lookup<HBUINT32>> rowIndexTable; - LNNOffsetTo<Lookup<HBUINT32>> columnIndexTable; - LNNOffsetTo<UnsizedArrayOf<FWORD32>> array; + NNOffset32To<Lookup<HBUINT32>> rowIndexTable; + NNOffset32To<Lookup<HBUINT32>> columnIndexTable; + NNOffset32To<UnsizedArrayOf<FWORD32>> array; } l; struct Short { - LNNOffsetTo<Lookup<HBUINT16>> rowIndexTable; - LNNOffsetTo<Lookup<HBUINT16>> columnIndexTable; - LNNOffsetTo<UnsizedArrayOf<FWORD>> array; + NNOffset32To<Lookup<HBUINT16>> rowIndexTable; + NNOffset32To<Lookup<HBUINT16>> columnIndexTable; + NNOffset32To<UnsizedArrayOf<FWORD>> array; } s; } u; - LNNOffsetTo<UnsizedArrayOf<FWORD>> vector; + NNOffset32To<UnsizedArrayOf<FWORD>> vector; public: DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24); }; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index 04027a61be..a807bdcfc5 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" #include "hb-ot-layout-common.hh" +#include "hb-ot-layout-gdef-table.hh" #include "hb-aat-map.hh" /* @@ -215,7 +216,9 @@ struct ContextualSubtable hb_aat_apply_context_t *c_) : ret (false), c (c_), + gdef (*c->gdef_table), mark_set (false), + has_glyph_classes (gdef.has_glyph_classes ()), mark (0), table (table_), subs (table+table->substitutionTables) {} @@ -263,6 +266,9 @@ struct ContextualSubtable { buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len)); buffer->info[mark].codepoint = *replacement; + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->info[mark], + gdef.get_glyph_props (*replacement)); ret = true; } @@ -287,6 +293,9 @@ struct ContextualSubtable if (replacement) { buffer->info[idx].codepoint = *replacement; + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&buffer->info[idx], + gdef.get_glyph_props (*replacement)); ret = true; } @@ -301,10 +310,12 @@ struct ContextualSubtable bool ret; private: hb_aat_apply_context_t *c; + const OT::GDEF &gdef; bool mark_set; + bool has_glyph_classes; unsigned int mark; const ContextualSubtable *table; - const UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false> &subs; + const UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false> &subs; }; bool apply (hb_aat_apply_context_t *c) const @@ -337,9 +348,9 @@ struct ContextualSubtable const EntryData &data = entries[i].data; if (data.markIndex != 0xFFFF) - num_lookups = hb_max (num_lookups, 1 + data.markIndex); + num_lookups = hb_max (num_lookups, 1u + data.markIndex); if (data.currentIndex != 0xFFFF) - num_lookups = hb_max (num_lookups, 1 + data.currentIndex); + num_lookups = hb_max (num_lookups, 1u + data.currentIndex); } return_trace (substitutionTables.sanitize (c, this, num_lookups)); @@ -348,7 +359,7 @@ struct ContextualSubtable protected: StateTable<Types, EntryData> machine; - NNOffsetTo<UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false>, HBUINT> + NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false>, HBUINT> substitutionTables; public: DEFINE_SIZE_STATIC (20); @@ -499,7 +510,7 @@ struct LigatureSubtable } DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1); - buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]); + if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return; if (unlikely (!actionData->sanitize (&c->sanitizer))) break; action = *actionData; @@ -525,25 +536,25 @@ struct LigatureSubtable hb_codepoint_t lig = ligatureData; DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); - buffer->replace_glyph (lig); + if (unlikely (!buffer->replace_glyph (lig))) return; unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u; /* Now go and delete all subsequent components. */ while (match_length - 1u > cursor) { DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); - buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]); - buffer->replace_glyph (DELETED_GLYPH); + if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return; + if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return; } - buffer->move_to (lig_end); + if (unlikely (!buffer->move_to (lig_end))) return; buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len); } actionData++; } while (!(action & LigActionLast)); - buffer->move_to (end); + if (unlikely (!buffer->move_to (end))) return; } } @@ -599,6 +610,9 @@ struct NoncontextualSubtable { TRACE_APPLY (this); + const OT::GDEF &gdef (*c->gdef_table); + bool has_glyph_classes = gdef.has_glyph_classes (); + bool ret = false; unsigned int num_glyphs = c->face->get_num_glyphs (); @@ -610,6 +624,9 @@ struct NoncontextualSubtable if (replacement) { info[i].codepoint = *replacement; + if (has_glyph_classes) + _hb_glyph_info_set_glyph_props (&info[i], + gdef.get_glyph_props (*replacement)); ret = true; } } @@ -733,17 +750,16 @@ struct InsertionSubtable bool before = flags & MarkedInsertBefore; unsigned int end = buffer->out_len; - buffer->move_to (mark); + if (unlikely (!buffer->move_to (mark))) return; if (buffer->idx < buffer->len && !before) - buffer->copy_glyph (); + if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - for (unsigned int i = 0; i < count; i++) - buffer->output_glyph (glyphs[i]); + if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); - buffer->move_to (end + count); + if (unlikely (!buffer->move_to (end + count))) return; buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len)); } @@ -764,10 +780,9 @@ struct InsertionSubtable unsigned int end = buffer->out_len; if (buffer->idx < buffer->len && !before) - buffer->copy_glyph (); + if (unlikely (!buffer->copy_glyph ())) return; /* TODO We ignore KashidaLike setting. */ - for (unsigned int i = 0; i < count; i++) - buffer->output_glyph (glyphs[i]); + if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return; if (buffer->idx < buffer->len && !before) buffer->skip_glyph (); @@ -786,7 +801,7 @@ struct InsertionSubtable * * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417 */ - buffer->move_to ((flags & DontAdvance) ? end : end + count); + if (unlikely (!buffer->move_to ((flags & DontAdvance) ? end : end + count))) return; } } diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh index 8c04a6482f..b1a1512821 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh @@ -58,7 +58,7 @@ struct opbdFormat0 bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, hb_glyph_extents_t *extents, const void *base) const { - const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); + const Offset16To<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); if (!bounds_offset) return false; const OpticalBounds &bounds = base+*bounds_offset; @@ -79,7 +79,7 @@ struct opbdFormat0 } protected: - Lookup<OffsetTo<OpticalBounds>> + Lookup<Offset16To<OpticalBounds>> lookupTable; /* Lookup table associating glyphs with the four * int16 values for the left-side, top-side, * right-side, and bottom-side optical bounds. */ @@ -92,7 +92,7 @@ struct opbdFormat1 bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id, hb_glyph_extents_t *extents, const void *base) const { - const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); + const Offset16To<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ()); if (!bounds_offset) return false; const OpticalBounds &bounds = base+*bounds_offset; @@ -116,7 +116,7 @@ struct opbdFormat1 } protected: - Lookup<OffsetTo<OpticalBounds>> + Lookup<Offset16To<OpticalBounds>> lookupTable; /* Lookup table associating glyphs with the four * int16 values for the left-side, top-side, * right-side, and bottom-side optical bounds. */ diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh index baa1c72020..68bcb2396f 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-trak-table.hh @@ -66,7 +66,7 @@ struct TrackTableEntry NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ - NNOffsetTo<UnsizedArrayOf<FWORD>> + NNOffset16To<UnsizedArrayOf<FWORD>> valuesZ; /* Offset from start of tracking table to * per-size tracking values for this track. */ @@ -141,7 +141,7 @@ struct TrackData protected: HBUINT16 nTracks; /* Number of separate tracks included in this table. */ HBUINT16 nSizes; /* Number of point sizes included in this table. */ - LNNOffsetTo<UnsizedArrayOf<HBFixed>> + NNOffset32To<UnsizedArrayOf<HBFixed>> sizeTable; /* Offset from start of the tracking table to * Array[nSizes] of size values.. */ UnsizedArrayOf<TrackTableEntry> @@ -212,10 +212,10 @@ struct trak FixedVersion<>version; /* Version of the tracking table * (0x00010000u for version 1.0). */ HBUINT16 format; /* Format of the tracking table (set to 0). */ - OffsetTo<TrackData> + Offset16To<TrackData> horizData; /* Offset from start of tracking table to TrackData * for horizontal text (or 0 if none). */ - OffsetTo<TrackData> + Offset16To<TrackData> vertData; /* Offset from start of tracking table to TrackData * for vertical text (or 0 if none). */ HBUINT16 reserved; /* Reserved. Set to 0. */ diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.cc b/thirdparty/harfbuzz/src/hb-aat-layout.cc index 74ebaa64ec..e2d4de2ccd 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout.cc +++ b/thirdparty/harfbuzz/src/hb-aat-layout.cc @@ -55,6 +55,7 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p buffer (buffer_), sanitizer (), ankr_table (&Null (AAT::ankr)), + gdef_table (face->table.GDEF->table), lookup_index (0) { sanitizer.init (blob); @@ -79,7 +80,7 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_) * @short_description: Apple Advanced Typography Layout * @include: hb-aat.h * - * Functions for querying AAT Layout features in the font face. + * Functions for querying AAT Layout features in the font face. * * HarfBuzz supports all of the AAT tables used to implement shaping. Other * AAT tables and their associated features are not supported. @@ -172,13 +173,13 @@ static const hb_aat_feature_mapping_t feature_mappings[] = {HB_TAG ('z','e','r','o'), HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_SLASHED_ZERO_OFF}, }; -/** +/** * hb_aat_layout_find_feature_mapping: * @tag: The requested #hb_tag_t feature tag * * Fetches the AAT feature-and-selector combination that corresponds * to a given OpenType feature tag. - * + * * Return value: the AAT features and selectors corresponding to the * OpenType feature tag queried * @@ -227,7 +228,7 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, * * <note>Note: does not examine the `GSUB` table.</note> * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.3.0 */ @@ -248,7 +249,9 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, if (morx.has_data ()) { AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob); + if (!buffer->message (font, "start table morx")) return; morx.apply (&c); + (void) buffer->message (font, "end table morx"); return; } @@ -257,7 +260,9 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, if (mort.has_data ()) { AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob); + if (!buffer->message (font, "start table mort")) return; mort.apply (&c); + (void) buffer->message (font, "end table mort"); return; } } @@ -294,7 +299,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) * * <note>Note: does not examine the `GPOS` table.</note> * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.3.0 */ @@ -313,8 +318,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> (); AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob); + if (!buffer->message (font, "start table kerx")) return; c.set_ankr_table (font->face->table.ankr.get ()); kerx.apply (&c); + (void) buffer->message (font, "end table kerx"); } @@ -325,7 +332,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, * Tests whether the specified face includes any tracking information * in the `trak` table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.3.0 */ @@ -350,7 +357,7 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, * hb_aat_layout_get_feature_types: * @face: #hb_face_t to work upon * @start_offset: offset of the first feature type to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature types to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature types to return; * Output = the actual number of feature types returned (may be zero) * @features: (out caller-allocates) (array length=feature_count): Array of feature types found * @@ -374,9 +381,9 @@ hb_aat_layout_get_feature_types (hb_face_t *face, * @face: #hb_face_t to work upon * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type * - * Fetches the name ID of the specified feature type in the face's `name` table. + * Fetches the name identifier of the specified feature type in the face's `name` table. * - * Return value: Name ID of the requested feature type + * Return value: Name identifier of the requested feature type * * Since: 2.2.0 */ @@ -388,15 +395,15 @@ hb_aat_layout_feature_type_get_name_id (hb_face_t *face, } /** - * hb_aat_layout_feature_type_get_selectors: + * hb_aat_layout_feature_type_get_selector_infos: * @face: #hb_face_t to work upon * @feature_type: The #hb_aat_layout_feature_type_t of the requested feature type * @start_offset: offset of the first feature type to retrieve - * @selector_count: (inout) (allow-none): Input = the maximum number of selectors to return; + * @selector_count: (inout) (optional): Input = the maximum number of selectors to return; * Output = the actual number of selectors returned (may be zero) - * @selectors: (out caller-allocates) (array length=selector_count): A buffer pointer. - * The selectors available for the feature type queries. - * @default_index: (out) (allow-none): The index of the feature's default selector, if any + * @selectors: (out caller-allocates) (array length=selector_count) (optional): + * A buffer pointer. The selectors available for the feature type queries. + * @default_index: (out) (optional): The index of the feature's default selector, if any * * Fetches a list of the selectors available for the specified feature in the given face. * diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.h b/thirdparty/harfbuzz/src/hb-aat-layout.h index dc1bf96573..9af2740088 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout.h +++ b/thirdparty/harfbuzz/src/hb-aat-layout.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_AAT_H_IN +#if !defined(HB_AAT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-aat.h> instead." #endif @@ -38,47 +38,47 @@ HB_BEGIN_DECLS /** * hb_aat_layout_feature_type_t: * @HB_AAT_LAYOUT_FEATURE_TYPE_INVALID: Initial, unset feature type - * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: - * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: - * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: - * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: - * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING: - * @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION: - * @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS: - * @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS: - * @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS: - * @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES: - * @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING: - * @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION: - * @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT: - * @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA: - * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES: - * @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE: - * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE: + * @HB_AAT_LAYOUT_FEATURE_TYPE_ALL_TYPOGRAPHIC: [All Typographic Features](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type0) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES: [Ligatures](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type1) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION: [Cursive Connection](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type2) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE: [Letter Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type3) + * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_SUBSTITUTION: [Vertical Substitution](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type4) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: [Linguistic Rearrangement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type5) + * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING: [Number Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type6) + * @HB_AAT_LAYOUT_FEATURE_TYPE_SMART_SWASH_TYPE: [Smart Swash](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type8) + * @HB_AAT_LAYOUT_FEATURE_TYPE_DIACRITICS_TYPE: [Diacritics](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type9) + * @HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION: [Vertical Position](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type10) + * @HB_AAT_LAYOUT_FEATURE_TYPE_FRACTIONS: [Fractions](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type11) + * @HB_AAT_LAYOUT_FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE: [Overlapping Characters](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type13) + * @HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS: [Typographic Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type14) + * @HB_AAT_LAYOUT_FEATURE_TYPE_MATHEMATICAL_EXTRAS: [Mathematical Extras](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type15) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ORNAMENT_SETS_TYPE: [Ornament Sets](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type16) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES: [Character Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type17) + * @HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE: [Design Complexity](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type18) + * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLE_OPTIONS: [Style Options](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type19) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_SHAPE: [Character Shape](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type20) + * @HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_CASE: [Number Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type21) + * @HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING: [Text Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type22) + * @HB_AAT_LAYOUT_FEATURE_TYPE_TRANSLITERATION: [Transliteration](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type23) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ANNOTATION_TYPE: [Annotation](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type24) + * @HB_AAT_LAYOUT_FEATURE_TYPE_KANA_SPACING_TYPE: [Kana Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type25) + * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE: [Ideographic Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type26) + * @HB_AAT_LAYOUT_FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE: [Unicode Decomposition](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type27) + * @HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA: [Ruby Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type28) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE: [CJK Symbol Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type29) + * @HB_AAT_LAYOUT_FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE: [Ideographic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type30) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE: [CJK Vertical Roman Placement](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type31) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ITALIC_CJK_ROMAN: [Italic CJK Roman](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type32) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CASE_SENSITIVE_LAYOUT: [Case Sensitive Layout](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type33) + * @HB_AAT_LAYOUT_FEATURE_TYPE_ALTERNATE_KANA: [Alternate Kana](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type34) + * @HB_AAT_LAYOUT_FEATURE_TYPE_STYLISTIC_ALTERNATIVES: [Stylistic Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type35) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES: [Contextual Alternatives](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type36) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE: [Lower Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type37) + * @HB_AAT_LAYOUT_FEATURE_TYPE_UPPER_CASE: [Upper Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type38) + * @HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE: [Language Tag](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type39) + * @HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE: [CJK Roman Spacing](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type103) * - * The possible feature types defined for AAT shaping. + * The possible feature types defined for AAT shaping, from Apple [Font Feature Registry](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html). * * Since: 2.2.0 */ @@ -732,6 +732,14 @@ HB_EXTERN hb_ot_name_id_t hb_aat_layout_feature_type_get_name_id (hb_face_t *face, hb_aat_layout_feature_type_t feature_type); +/** + * hb_aat_layout_feature_selector_info_t: + * @name_id: The selector's name identifier + * @enable: The value to turn the selector on + * @disable: The value to turn the selector off + * + * Structure representing a setting for an #hb_aat_layout_feature_type_t. + */ typedef struct hb_aat_layout_feature_selector_info_t { hb_ot_name_id_t name_id; hb_aat_layout_feature_selector_t enable; diff --git a/thirdparty/harfbuzz/src/hb-aat-ltag-table.hh b/thirdparty/harfbuzz/src/hb-aat-ltag-table.hh index 711f9aa6c1..6d771e1513 100644 --- a/thirdparty/harfbuzz/src/hb-aat-ltag-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-ltag-table.hh @@ -50,7 +50,7 @@ struct FTStringRange } protected: - NNOffsetTo<UnsizedArrayOf<HBUINT8>> + NNOffset16To<UnsizedArrayOf<HBUINT8>> tag; /* Offset from the start of the table to * the beginning of the string */ HBUINT16 length; /* String length (in bytes) */ @@ -80,7 +80,7 @@ struct ltag protected: HBUINT32 version; /* Table version; currently 1 */ HBUINT32 flags; /* Table flags; currently none defined */ - LArrayOf<FTStringRange> + Array32Of<FTStringRange> tagRanges; /* Range for each tag's string */ public: DEFINE_SIZE_ARRAY (12, tagRanges); diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index 98de61f3e8..bbe097fe01 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -35,6 +35,132 @@ #include "hb-number.hh" +/* + * Flags + */ + +/* Enable bitwise ops on enums marked as flags_t */ +/* To my surprise, looks like the function resolver is happy to silently cast + * one enum to another... So this doesn't provide the type-checking that I + * originally had in mind... :(. + * + * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 + */ +#ifdef _MSC_VER +# pragma warning(disable:4200) +# pragma warning(disable:4800) +#endif +#define HB_MARK_AS_FLAG_T(T) \ + extern "C++" { \ + static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ + static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ + static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ + static inline constexpr T operator ~ (T r) { return T (~(unsigned int) r); } \ + static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ + static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ + static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ + } \ + static_assert (true, "") + +/* Useful for set-operations on small enums. + * For example, for testing "x ∈ {x1, x2, x3}" use: + * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) + */ +#define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) +#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) +#define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x)) +#define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) +#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) + + +/* + * Big-endian integers. + */ + +/* Endian swap, used in Windows related backends */ +static inline constexpr uint16_t hb_uint16_swap (uint16_t v) +{ return (v >> 8) | (v << 8); } +static inline constexpr uint32_t hb_uint32_swap (uint32_t v) +{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } + +template <typename Type, int Bytes = sizeof (Type)> +struct BEInt; +template <typename Type> +struct BEInt<Type, 1> +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t (V)} {} + constexpr operator Type () const { return v; } + private: uint8_t v; +}; +template <typename Type> +struct BEInt<Type, 2> +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} + + struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; + constexpr operator Type () const + { +#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ + defined(__BYTE_ORDER) && \ + (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) + /* Spoon-feed the compiler a big-endian integer with alignment 1. + * https://github.com/harfbuzz/harfbuzz/pull/1398 */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + return __builtin_bswap16 (((packed_uint16_t *) this)->v); +#else /* __BYTE_ORDER == __BIG_ENDIAN */ + return ((packed_uint16_t *) this)->v; +#endif +#else + return (v[0] << 8) + + (v[1] ); +#endif + } + private: uint8_t v[2]; +}; +template <typename Type> +struct BEInt<Type, 3> +{ + static_assert (!hb_is_signed (Type), ""); + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} + + constexpr operator Type () const { return (v[0] << 16) + + (v[1] << 8) + + (v[2] ); } + private: uint8_t v[3]; +}; +template <typename Type> +struct BEInt<Type, 4> +{ + public: + BEInt () = default; + constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF), + uint8_t ((V >> 16) & 0xFF), + uint8_t ((V >> 8) & 0xFF), + uint8_t ((V ) & 0xFF)} {} + constexpr operator Type () const { return (v[0] << 24) + + (v[1] << 16) + + (v[2] << 8) + + (v[3] ); } + private: uint8_t v[4]; +}; + +/* Floats. */ + +/* We want our rounding towards +infinity. */ +static inline float +_hb_roundf (float x) { return floorf (x + .5f); } +#define roundf(x) _hb_roundf(x) + + /* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits, * values will be truncated / overlap, and might not decode exactly. */ #define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z)) @@ -48,6 +174,7 @@ #define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300) #define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu) + struct { /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ @@ -215,7 +342,9 @@ 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 (hb_forward<Pred> (p)).has (hb_forward<Val> (v)) + ) template <typename Pred, typename Val> auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN @@ -269,7 +398,9 @@ 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 (hb_forward<Proj> (f)).get (hb_forward<Val> (v)) + ) template <typename Proj, typename Val> auto impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN @@ -296,6 +427,40 @@ struct } HB_FUNCOBJ (hb_get); +struct +{ + private: + + 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 + ) + + 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 + ) + + 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) + ) + + public: + + template <typename T1, typename T2> auto + operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN + ( + impl (hb_forward<T1> (v1), + hb_forward<T2> (v2), + hb_prioritize) + ) +} +HB_FUNCOBJ (hb_equal); + template <typename T1, typename T2> struct hb_pair_t @@ -375,7 +540,7 @@ HB_FUNCOBJ (hb_clamp); /* Return the number of 1 bits in v. */ template <typename T> -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_popcount (T v) { #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) @@ -416,7 +581,7 @@ hb_popcount (T v) /* Returns the number of bits needed to store number */ template <typename T> -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_bit_storage (T v) { if (unlikely (!v)) return 0; @@ -490,7 +655,7 @@ hb_bit_storage (T v) /* Returns the number of zero bits in the least significant side of v */ template <typename T> -static inline HB_CONST_FUNC unsigned int +static inline unsigned int hb_ctz (T v) { if (unlikely (!v)) return 8 * sizeof (T); @@ -595,6 +760,14 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0]))) +static inline void * +hb_memcpy (void *__restrict dst, const void *__restrict src, size_t len) +{ + /* It's illegal to pass 0 as size to memcpy. */ + if (unlikely (!len)) return dst; + return memcpy (dst, src, len); +} + static inline int hb_memcmp (const void *a, const void *b, unsigned int len) { @@ -986,38 +1159,48 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o /* Operators. */ -struct hb_bitwise_and +struct { HB_PARTIALIZE(2); - static constexpr bool passthru_left = false; - static constexpr bool passthru_right = false; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b) } HB_FUNCOBJ (hb_bitwise_and); -struct hb_bitwise_or +struct { HB_PARTIALIZE(2); - static constexpr bool passthru_left = true; - static constexpr bool passthru_right = true; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b) } HB_FUNCOBJ (hb_bitwise_or); -struct hb_bitwise_xor +struct { HB_PARTIALIZE(2); - static constexpr bool passthru_left = true; - static constexpr bool passthru_right = true; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b) } HB_FUNCOBJ (hb_bitwise_xor); -struct hb_bitwise_sub +struct +{ HB_PARTIALIZE(2); + template <typename T> constexpr auto + operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a & b) +} +HB_FUNCOBJ (hb_bitwise_lt); +struct { HB_PARTIALIZE(2); - static constexpr bool passthru_left = true; - static constexpr bool passthru_right = false; template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b) } -HB_FUNCOBJ (hb_bitwise_sub); +HB_FUNCOBJ (hb_bitwise_gt); // aka sub +struct +{ HB_PARTIALIZE(2); + template <typename T> constexpr auto + operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a | b) +} +HB_FUNCOBJ (hb_bitwise_le); +struct +{ HB_PARTIALIZE(2); + template <typename T> constexpr auto + operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | ~b) +} +HB_FUNCOBJ (hb_bitwise_ge); struct { template <typename T> constexpr auto @@ -1040,6 +1223,12 @@ HB_FUNCOBJ (hb_sub); struct { HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto + operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (b - a) +} +HB_FUNCOBJ (hb_rsub); +struct +{ HB_PARTIALIZE(2); + template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b) } HB_FUNCOBJ (hb_mul); diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index 568cd02c79..ab0dd6ebe3 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -36,6 +36,14 @@ template <typename Type> struct hb_sorted_array_t; +enum hb_not_found_t +{ + HB_NOT_FOUND_DONT_STORE, + HB_NOT_FOUND_STORE, + HB_NOT_FOUND_STORE_CLOSEST, +}; + + template <typename Type> struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> { @@ -139,16 +147,34 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> return lfind (x, &i) ? &this->arrayZ[i] : not_found; } template <typename T> - bool lfind (const T &x, unsigned *pos = nullptr) const + bool lfind (const T &x, unsigned *pos = nullptr, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const { for (unsigned i = 0; i < length; ++i) - if (!this->arrayZ[i].cmp (x)) + if (hb_equal (x, this->arrayZ[i])) { if (pos) *pos = i; return true; } + if (pos) + { + switch (not_found) + { + case HB_NOT_FOUND_DONT_STORE: + break; + + case HB_NOT_FOUND_STORE: + *pos = to_store; + break; + + case HB_NOT_FOUND_STORE_CLOSEST: + *pos = length; + break; + } + } return false; } @@ -219,7 +245,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> unsigned P = sizeof (Type), hb_enable_if (P == 1)> const T *as () const - { return length < hb_null_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); } + { return length < hb_min_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); } template <typename T, unsigned P = sizeof (Type), @@ -231,9 +257,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> && (unsigned int) (arrayZ + length - (const char *) p) >= size; } - /* Only call if you allocated the underlying array using malloc() or similar. */ - void free () - { ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; } + /* Only call if you allocated the underlying array using hb_malloc() or similar. */ + void fini () + { hb_free ((void *) arrayZ); arrayZ = nullptr; length = 0; } template <typename hb_serialize_context_t> hb_array_t copy (hb_serialize_context_t *c) const @@ -266,13 +292,6 @@ template <typename T, unsigned int length_> inline hb_array_t<T> hb_array (T (&array_)[length_]) { return hb_array_t<T> (array_); } -enum hb_bfind_not_found_t -{ - HB_BFIND_NOT_FOUND_DONT_STORE, - HB_BFIND_NOT_FOUND_STORE, - HB_BFIND_NOT_FOUND_STORE_CLOSEST, -}; - template <typename Type> struct hb_sorted_array_t : hb_iter_t<hb_sorted_array_t<Type>, Type&>, @@ -323,7 +342,7 @@ struct hb_sorted_array_t : } template <typename T> bool bfind (const T &x, unsigned int *i = nullptr, - hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, unsigned int to_store = (unsigned int) -1) const { unsigned pos; @@ -339,14 +358,14 @@ struct hb_sorted_array_t : { switch (not_found) { - case HB_BFIND_NOT_FOUND_DONT_STORE: + case HB_NOT_FOUND_DONT_STORE: break; - case HB_BFIND_NOT_FOUND_STORE: + case HB_NOT_FOUND_STORE: *i = to_store; break; - case HB_BFIND_NOT_FOUND_STORE_CLOSEST: + case HB_NOT_FOUND_STORE_CLOSEST: *i = pos; break; } diff --git a/thirdparty/harfbuzz/src/hb-atomic.hh b/thirdparty/harfbuzz/src/hb-atomic.hh index b3fb296b4e..93265f655f 100644 --- a/thirdparty/harfbuzz/src/hb-atomic.hh +++ b/thirdparty/harfbuzz/src/hb-atomic.hh @@ -52,7 +52,7 @@ #elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE) -/* C++11-style GCC primitives. */ +/* C++11-style GCC primitives. We prefer these as they don't require linking to libstdc++ / libc++. */ #define _hb_memory_barrier() __sync_synchronize () @@ -73,7 +73,8 @@ _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) && __cplusplus >= 201103L + +#elif !defined(HB_NO_MT) /* C++11 atomics. */ @@ -101,117 +102,6 @@ _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) && defined(_WIN32) - -#include <windows.h> - -static inline void _hb_memory_barrier () -{ -#if !defined(MemoryBarrier) && !defined(__MINGW32_VERSION) - /* MinGW has a convoluted history of supporting MemoryBarrier. */ - LONG dummy = 0; - InterlockedExchange (&dummy, 1); -#else - MemoryBarrier (); -#endif -} -#define _hb_memory_barrier() _hb_memory_barrier () - -#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V)) -static_assert ((sizeof (LONG) == sizeof (int)), ""); - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O)) - - -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -#define _hb_memory_barrier() __sync_synchronize () - -#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) - - -#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) - -#include <atomic.h> -#include <mbarrier.h> - -#define _hb_memory_r_barrier() __machine_r_barrier () -#define _hb_memory_w_barrier() __machine_w_barrier () -#define _hb_memory_barrier() __machine_rw_barrier () - -static inline int _hb_fetch_and_add (int *AI, int V) -{ - _hb_memory_w_barrier (); - int result = atomic_add_int_nv ((uint_t *) AI, V) - V; - _hb_memory_r_barrier (); - return result; -} -static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N) -{ - _hb_memory_w_barrier (); - bool result = atomic_cas_ptr (P, O, N) == O; - _hb_memory_r_barrier (); - return result; -} - -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((P), (O), (N)) - - -#elif !defined(HB_NO_MT) && defined(__APPLE__) - -#include <libkern/OSAtomic.h> -#ifdef __MAC_OS_X_MIN_REQUIRED -#include <AvailabilityMacros.h> -#elif defined(__IPHONE_OS_MIN_REQUIRED) -#include <Availability.h> -#endif - -#define _hb_memory_barrier() OSMemoryBarrier () - -#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V)) - -#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P)) -#else -#if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) -#else -#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) -#endif -#endif - - -#elif !defined(HB_NO_MT) && defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)) - -#include <builtins.h> - -#define _hb_memory_barrier() __lwsync () - -static inline int _hb_fetch_and_add (int *AI, int V) -{ - _hb_memory_barrier (); - int result = __fetch_and_add (AI, V); - _hb_memory_barrier (); - return result; -} -static inline bool _hb_compare_and_swaplp (long *P, long O, long N) -{ - _hb_memory_barrier (); - bool result = __compare_and_swaplp (P, &O, N); - _hb_memory_barrier (); - return result; -} - -#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V)) - -#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N)) -static_assert ((sizeof (long) == sizeof (void *)), ""); - - #elif defined(HB_NO_MT) #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) @@ -259,9 +149,11 @@ inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory #endif -#define HB_ATOMIC_INT_INIT(V) {V} struct hb_atomic_int_t { + hb_atomic_int_t () = default; + constexpr hb_atomic_int_t (int v) : v (v) {} + void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } void set (int v_) { hb_atomic_int_impl_set (&v, v_); } int get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); } @@ -269,16 +161,17 @@ struct hb_atomic_int_t int inc () { return hb_atomic_int_impl_add (&v, 1); } int dec () { return hb_atomic_int_impl_add (&v, -1); } - int v; + int v = 0; }; - -#define HB_ATOMIC_PTR_INIT(V) {V} template <typename P> struct hb_atomic_ptr_t { typedef hb_remove_pointer<P> T; + hb_atomic_ptr_t () = default; + constexpr hb_atomic_ptr_t (T* v) : v (v) {} + void init (T* v_ = nullptr) { set_relaxed (v_); } void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } T *get_relaxed () const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } @@ -288,7 +181,7 @@ struct hb_atomic_ptr_t T * operator -> () const { return get (); } template <typename C> operator C * () const { return get (); } - T *v; + T *v = nullptr; }; diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh index e9f3a6a52d..d409880751 100644 --- a/thirdparty/harfbuzz/src/hb-bimap.hh +++ b/thirdparty/harfbuzz/src/hb-bimap.hh @@ -58,10 +58,15 @@ struct hb_bimap_t void set (hb_codepoint_t lhs, hb_codepoint_t rhs) { + if (in_error ()) return; if (unlikely (lhs == HB_MAP_VALUE_INVALID)) return; if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; } + forw_map.set (lhs, rhs); + if (in_error ()) return; + back_map.set (rhs, lhs); + if (in_error ()) forw_map.del (lhs); } hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); } diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh new file mode 100644 index 0000000000..263be3d044 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -0,0 +1,203 @@ +/* + * Copyright © 2012,2017 Google, Inc. + * Copyright © 2021 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BIT_PAGE_HH +#define HB_BIT_PAGE_HH + +#include "hb.hh" + +struct hb_bit_page_t +{ + void init0 () { v.clear (); } + void init1 () { v.clear (0xFF); } + + constexpr unsigned len () const + { return ARRAY_LENGTH_CONST (v); } + + bool is_empty () const + { + for (unsigned int i = 0; i < len (); i++) + if (v[i]) + return false; + return true; + } + + void add (hb_codepoint_t g) { elt (g) |= mask (g); } + void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } + void set (hb_codepoint_t g, bool v) { if (v) add (g); else del (g); } + bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } + + void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la |= (mask (b) << 1) - mask(a); + else + { + *la |= ~(mask (a) - 1); + la++; + + memset (la, 0xff, (char *) lb - (char *) la); + + *lb |= ((mask (b) << 1) - 1); + } + } + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la &= ~((mask (b) << 1) - mask(a)); + else + { + *la &= mask (a) - 1; + la++; + + memset (la, 0, (char *) lb - (char *) la); + + *lb &= ~((mask (b) << 1) - 1); + } + } + void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v) + { if (v) add_range (a, b); else del_range (a, b); } + + bool is_equal (const hb_bit_page_t &other) const + { + return 0 == hb_memcmp (&v, &other.v, sizeof (v)); + } + bool is_subset (const hb_bit_page_t &larger_page) const + { + for (unsigned i = 0; i < len (); i++) + if (~larger_page.v[i] & v[i]) + return false; + return true; + } + + unsigned int get_population () const + { + unsigned int pop = 0; + for (unsigned int i = 0; i < len (); i++) + pop += hb_popcount (v[i]); + return pop; + } + + bool next (hb_codepoint_t *codepoint) const + { + unsigned int m = (*codepoint + 1) & MASK; + if (!m) + { + *codepoint = INVALID; + return false; + } + unsigned int i = m / ELT_BITS; + unsigned int j = m & ELT_MASK; + + const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); + for (const elt_t *p = &vv; i < len (); p = &v[++i]) + if (*p) + { + *codepoint = i * ELT_BITS + elt_get_min (*p); + return true; + } + + *codepoint = INVALID; + return false; + } + bool previous (hb_codepoint_t *codepoint) const + { + unsigned int m = (*codepoint - 1) & MASK; + if (m == MASK) + { + *codepoint = INVALID; + return false; + } + unsigned int i = m / ELT_BITS; + unsigned int j = m & ELT_MASK; + + /* Fancy mask to avoid shifting by elt_t bitsize, which is undefined. */ + const elt_t mask = j < 8 * sizeof (elt_t) - 1 ? + ((elt_t (1) << (j + 1)) - 1) : + (elt_t) -1; + const elt_t vv = v[i] & mask; + const elt_t *p = &vv; + while (true) + { + if (*p) + { + *codepoint = i * ELT_BITS + elt_get_max (*p); + return true; + } + if ((int) i <= 0) break; + p = &v[--i]; + } + + *codepoint = INVALID; + return false; + } + hb_codepoint_t get_min () const + { + for (unsigned int i = 0; i < len (); i++) + if (v[i]) + return i * ELT_BITS + elt_get_min (v[i]); + return INVALID; + } + hb_codepoint_t get_max () const + { + for (int i = len () - 1; i >= 0; i--) + if (v[i]) + return i * ELT_BITS + elt_get_max (v[i]); + return 0; + } + + static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; + + typedef unsigned long long elt_t; + static constexpr unsigned PAGE_BITS = 512; + static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, ""); + + static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); } + static unsigned int elt_get_max (const elt_t &elt) { return hb_bit_storage (elt) - 1; } + + typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t; + + static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8; + static constexpr unsigned ELT_MASK = ELT_BITS - 1; + static constexpr unsigned BITS = sizeof (vector_t) * 8; + static constexpr unsigned MASK = BITS - 1; + static_assert ((unsigned) PAGE_BITS == (unsigned) BITS, ""); + + elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; } + const elt_t& elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; } + static constexpr elt_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); } + + vector_t v; +}; +static_assert (hb_bit_page_t::PAGE_BITS == sizeof (hb_bit_page_t) * 8, ""); + + +#endif /* HB_BIT_PAGE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh new file mode 100644 index 0000000000..f48b72fe63 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-bit-set-invertible.hh @@ -0,0 +1,354 @@ +/* + * Copyright © 2012,2017 Google, Inc. + * Copyright © 2021 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BIT_SET_INVERTIBLE_HH +#define HB_BIT_SET_INVERTIBLE_HH + +#include "hb.hh" +#include "hb-bit-set.hh" + + +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 (); } + + void init () { s.init (); inverted = false; } + void fini () { s.fini (); } + void err () { s.err (); } + bool in_error () const { return s.in_error (); } + explicit operator bool () const { return !is_empty (); } + + void reset () + { + s.reset (); + inverted = false; + } + void clear () + { + s.clear (); + if (likely (s.successful)) + inverted = false; + } + void invert () + { + if (likely (s.successful)) + inverted = !inverted; + } + + bool is_empty () const + { + hb_codepoint_t v = INVALID; + next (&v); + return v == INVALID; + } + hb_codepoint_t get_min () const + { + hb_codepoint_t v = INVALID; + next (&v); + return v; + } + hb_codepoint_t get_max () const + { + hb_codepoint_t v = INVALID; + previous (&v); + return v; + } + unsigned int get_population () const + { return inverted ? INVALID - s.get_population () : s.get_population (); } + + + void add (hb_codepoint_t g) { unlikely (inverted) ? s.del (g) : s.add (g); } + bool add_range (hb_codepoint_t a, hb_codepoint_t b) + { return unlikely (inverted) ? (s.del_range (a, b), true) : s.add_range (a, b); } + + template <typename T> + void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { inverted ? s.del_array (array, count, stride) : s.add_array (array, count, stride); } + template <typename T> + void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename T> + bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { return inverted ? s.del_sorted_array (array, count, stride) : s.add_sorted_array (array, count, stride); } + template <typename T> + bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } + + void del (hb_codepoint_t g) { unlikely (inverted) ? s.add (g) : s.del (g); } + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { unlikely (inverted) ? (void) s.add_range (a, b) : s.del_range (a, b); } + + bool get (hb_codepoint_t g) const { return s.get (g) ^ inverted; } + + /* Has interface. */ + static constexpr bool SENTINEL = false; + typedef bool value_t; + value_t operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + /* Predicate. */ + bool operator () (hb_codepoint_t k) const { return has (k); } + + /* Sink interface. */ + hb_bit_set_invertible_t& operator << (hb_codepoint_t v) + { add (v); return *this; } + hb_bit_set_invertible_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + { add_range (range.first, range.second); return *this; } + + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const + { + hb_codepoint_t c = first - 1; + return next (&c) && c <= last; + } + + void set (const hb_bit_set_invertible_t &other) + { + s.set (other.s); + if (likely (s.successful)) + inverted = other.inverted; + } + + bool is_equal (const hb_bit_set_invertible_t &other) const + { + if (likely (inverted == other.inverted)) + return s.is_equal (other.s); + else + { + /* TODO Add iter_ranges() and use here. */ + auto it1 = iter (); + auto it2 = other.iter (); + return hb_all (+ hb_zip (it1, it2) + | hb_map ([](hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) { return _.first == _.second; })); + } + } + + bool is_subset (const hb_bit_set_invertible_t &larger_set) const + { + if (unlikely (inverted != larger_set.inverted)) + return hb_all (hb_iter (s) | hb_map (larger_set.s)); + else + return unlikely (inverted) ? larger_set.s.is_subset (s) : s.is_subset (larger_set.s); + } + + protected: + template <typename Op> + void process (const Op& op, const hb_bit_set_invertible_t &other) + { s.process (op, other.s); } + public: + void union_ (const hb_bit_set_invertible_t &other) + { + if (likely (inverted == other.inverted)) + { + if (unlikely (inverted)) + process (hb_bitwise_and, other); + else + process (hb_bitwise_or, other); /* Main branch. */ + } + else + { + if (unlikely (inverted)) + process (hb_bitwise_gt, other); + else + process (hb_bitwise_lt, other); + } + if (likely (s.successful)) + inverted = inverted || other.inverted; + } + void intersect (const hb_bit_set_invertible_t &other) + { + if (likely (inverted == other.inverted)) + { + if (unlikely (inverted)) + process (hb_bitwise_or, other); + else + process (hb_bitwise_and, other); /* Main branch. */ + } + else + { + if (unlikely (inverted)) + process (hb_bitwise_lt, other); + else + process (hb_bitwise_gt, other); + } + if (likely (s.successful)) + inverted = inverted && other.inverted; + } + void subtract (const hb_bit_set_invertible_t &other) + { + if (likely (inverted == other.inverted)) + { + if (unlikely (inverted)) + process (hb_bitwise_lt, other); + else + process (hb_bitwise_gt, other); /* Main branch. */ + } + else + { + if (unlikely (inverted)) + process (hb_bitwise_or, other); + else + process (hb_bitwise_and, other); + } + if (likely (s.successful)) + inverted = inverted && !other.inverted; + } + void symmetric_difference (const hb_bit_set_invertible_t &other) + { + process (hb_bitwise_xor, other); + if (likely (s.successful)) + inverted = inverted ^ other.inverted; + } + + bool next (hb_codepoint_t *codepoint) const + { + if (likely (!inverted)) + return s.next (codepoint); + + auto old = *codepoint; + if (unlikely (old + 1 == INVALID)) + { + *codepoint = INVALID; + return false; + } + + auto v = old; + s.next (&v); + if (old + 1 < v) + { + *codepoint = old + 1; + return true; + } + + v = old; + s.next_range (&old, &v); + + *codepoint = v + 1; + return *codepoint != INVALID; + } + bool previous (hb_codepoint_t *codepoint) const + { + if (likely (!inverted)) + return s.previous (codepoint); + + auto old = *codepoint; + if (unlikely (old - 1 == INVALID)) + { + *codepoint = INVALID; + return false; + } + + auto v = old; + s.previous (&v); + + if (old - 1 > v || v == INVALID) + { + *codepoint = old - 1; + return true; + } + + v = old; + s.previous_range (&v, &old); + + *codepoint = v - 1; + return *codepoint != INVALID; + } + bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + if (likely (!inverted)) + return s.next_range (first, last); + + if (!next (last)) + { + *last = *first = INVALID; + return false; + } + + *first = *last; + s.next (last); + --*last; + return true; + } + bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + if (likely (!inverted)) + return s.previous_range (first, last); + + if (!previous (first)) + { + *last = *first = INVALID; + return false; + } + + *last = *first; + s.previous (first); + ++*first; + return true; + } + + static constexpr hb_codepoint_t INVALID = hb_bit_set_t::INVALID; + + /* + * Iterator implementation. + */ + struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> + { + static constexpr bool is_sorted_iterator = true; + iter_t (const hb_bit_set_invertible_t &s_ = Null (hb_bit_set_invertible_t), + bool init = true) : s (&s_), v (INVALID), l(0) + { + if (init) + { + l = s->get_population () + 1; + __next__ (); + } + } + + typedef hb_codepoint_t __item_t__; + hb_codepoint_t __item__ () const { return v; } + bool __more__ () const { return v != INVALID; } + void __next__ () { s->next (&v); if (l) l--; } + void __prev__ () { s->previous (&v); } + unsigned __len__ () const { return l; } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const + { return s != o.s || v != o.v; } + + protected: + const hb_bit_set_invertible_t *s; + hb_codepoint_t v; + unsigned l; + }; + iter_t iter () const { return iter_t (*this); } + operator iter_t () const { return iter (); } +}; + + +#endif /* HB_BIT_SET_INVERTIBLE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh new file mode 100644 index 0000000000..c21778d88e --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -0,0 +1,808 @@ +/* + * Copyright © 2012,2017 Google, Inc. + * Copyright © 2021 Behdad Esfahbod + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BIT_SET_HH +#define HB_BIT_SET_HH + +#include "hb.hh" +#include "hb-bit-page.hh" +#include "hb-machinery.hh" + + +struct hb_bit_set_t +{ + hb_bit_set_t () { init (); } + ~hb_bit_set_t () { fini (); } + + 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? + + void init () + { + successful = true; + population = 0; + last_page_lookup = 0; + page_map.init (); + pages.init (); + } + void fini () + { + page_map.fini (); + pages.fini (); + } + + using page_t = hb_bit_page_t; + struct page_map_t + { + int cmp (const page_map_t &o) const { return cmp (o.major); } + int cmp (uint32_t o_major) const { return (int) o_major - (int) major; } + + uint32_t major; + uint32_t index; + }; + + bool successful; /* Allocations successful */ + mutable unsigned int population; + mutable unsigned int last_page_lookup; + hb_sorted_vector_t<page_map_t> page_map; + hb_vector_t<page_t> pages; + + void err () { if (successful) successful = false; } /* TODO Remove */ + bool in_error () const { return !successful; } + + bool resize (unsigned int count) + { + if (unlikely (!successful)) return false; + if (unlikely (!pages.resize (count) || !page_map.resize (count))) + { + pages.resize (page_map.length); + successful = false; + return false; + } + return true; + } + + void reset () + { + successful = true; + clear (); + } + + void clear () + { + resize (0); + if (likely (successful)) + population = 0; + } + bool is_empty () const + { + unsigned int count = pages.length; + for (unsigned int i = 0; i < count; i++) + if (!pages[i].is_empty ()) + return false; + return true; + } + explicit operator bool () const { return !is_empty (); } + + private: + void dirty () { population = UINT_MAX; } + public: + + void add (hb_codepoint_t g) + { + if (unlikely (!successful)) return; + if (unlikely (g == INVALID)) return; + dirty (); + page_t *page = page_for (g, true); if (unlikely (!page)) return; + page->add (g); + } + bool add_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ + if (unlikely (a > b || a == INVALID || b == INVALID)) return false; + dirty (); + unsigned int ma = get_major (a); + unsigned int mb = get_major (b); + if (ma == mb) + { + page_t *page = page_for (a, true); if (unlikely (!page)) return false; + page->add_range (a, b); + } + else + { + page_t *page = page_for (a, true); if (unlikely (!page)) return false; + page->add_range (a, major_start (ma + 1) - 1); + + for (unsigned int m = ma + 1; m < mb; m++) + { + page = page_for (major_start (m), true); if (unlikely (!page)) return false; + page->init1 (); + } + + page = page_for (b, true); if (unlikely (!page)) return false; + page->add_range (major_start (mb), b); + } + return true; + } + + template <typename T> + void set_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + if (unlikely (!successful)) return; + if (!count) return; + dirty (); + hb_codepoint_t g = *array; + while (count) + { + unsigned int m = get_major (g); + page_t *page = page_for (g, v); if (unlikely (v && !page)) return; + unsigned int start = major_start (m); + unsigned int end = major_start (m + 1); + do + { + if (v || page) /* The v check is to optimize out the page check if v is true. */ + page->set (g, v); + + array = &StructAtOffsetUnaligned<T> (array, stride); + count--; + } + while (count && (g = *array, start <= g && g < end)); + } + } + + template <typename T> + void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { set_array (true, array, count, stride); } + template <typename T> + void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); } + + template <typename T> + void del_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { set_array (false, array, count, stride); } + template <typename T> + void del_array (const hb_array_t<const T>& arr) { del_array (&arr, arr.len ()); } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename T> + bool set_sorted_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ + if (!count) return true; + dirty (); + hb_codepoint_t g = *array; + hb_codepoint_t last_g = g; + while (count) + { + unsigned int m = get_major (g); + page_t *page = page_for (g, v); if (unlikely (v && !page)) return false; + unsigned int end = major_start (m + 1); + do + { + /* If we try harder we can change the following comparison to <=; + * Not sure if it's worth it. */ + if (g < last_g) return false; + last_g = g; + + if (v || page) /* The v check is to optimize out the page check if v is true. */ + page->add (g); + + array = (const T *) ((const char *) array + stride); + count--; + } + while (count && (g = *array, g < end)); + } + return true; + } + + template <typename T> + bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { return set_sorted_array (true, array, count, stride); } + template <typename T> + bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } + + template <typename T> + bool del_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { return set_sorted_array (false, array, count, stride); } + template <typename T> + bool del_sorted_array (const hb_sorted_array_t<const T>& arr) { return del_sorted_array (&arr, arr.len ()); } + + void del (hb_codepoint_t g) + { + if (unlikely (!successful)) return; + page_t *page = page_for (g); + if (!page) + return; + dirty (); + page->del (g); + } + + private: + void del_pages (int ds, int de) + { + if (ds <= de) + { + // Pre-allocate the workspace that compact() will need so we can bail on allocation failure + // before attempting to rewrite the page map. + hb_vector_t<unsigned> compact_workspace; + if (unlikely (!allocate_compact_workspace (compact_workspace))) return; + + unsigned int write_index = 0; + for (unsigned int i = 0; i < page_map.length; i++) + { + int m = (int) page_map[i].major; + if (m < ds || de < m) + page_map[write_index++] = page_map[i]; + } + compact (compact_workspace, write_index); + resize (write_index); + } + } + + + public: + void del_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (!successful)) return; + if (unlikely (a > b || a == INVALID)) return; + dirty (); + unsigned int ma = get_major (a); + unsigned int mb = get_major (b); + /* Delete pages from ds through de if ds <= de. */ + int ds = (a == major_start (ma))? (int) ma: (int) (ma + 1); + int de = (b + 1 == major_start (mb + 1))? (int) mb: ((int) mb - 1); + if (ds > de || (int) ma < ds) + { + page_t *page = page_for (a); + if (page) + { + if (ma == mb) + page->del_range (a, b); + else + page->del_range (a, major_start (ma + 1) - 1); + } + } + if (de < (int) mb && ma != mb) + { + page_t *page = page_for (b); + if (page) + page->del_range (major_start (mb), b); + } + del_pages (ds, de); + } + + bool get (hb_codepoint_t g) const + { + const page_t *page = page_for (g); + if (!page) + return false; + return page->get (g); + } + + /* Has interface. */ + static constexpr bool SENTINEL = false; + typedef bool value_t; + value_t operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + /* Predicate. */ + bool operator () (hb_codepoint_t k) const { return has (k); } + + /* Sink interface. */ + hb_bit_set_t& operator << (hb_codepoint_t v) + { add (v); return *this; } + hb_bit_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + { add_range (range.first, range.second); return *this; } + + bool intersects (hb_codepoint_t first, hb_codepoint_t last) const + { + hb_codepoint_t c = first - 1; + return next (&c) && c <= last; + } + void set (const hb_bit_set_t &other) + { + if (unlikely (!successful)) return; + unsigned int count = other.pages.length; + if (unlikely (!resize (count))) + return; + population = other.population; + + /* TODO switch to vector operator =. */ + hb_memcpy ((void *) pages, (const void *) other.pages, count * pages.item_size); + hb_memcpy ((void *) page_map, (const void *) other.page_map, count * page_map.item_size); + } + + bool is_equal (const hb_bit_set_t &other) const + { + if (has_population () && other.has_population () && + get_population () != other.get_population ()) + return false; + + unsigned int na = pages.length; + unsigned int nb = other.pages.length; + + unsigned int a = 0, b = 0; + for (; a < na && b < nb; ) + { + if (page_at (a).is_empty ()) { a++; continue; } + if (other.page_at (b).is_empty ()) { b++; continue; } + if (page_map[a].major != other.page_map[b].major || + !page_at (a).is_equal (other.page_at (b))) + return false; + a++; + b++; + } + for (; a < na; a++) + if (!page_at (a).is_empty ()) { return false; } + for (; b < nb; b++) + if (!other.page_at (b).is_empty ()) { return false; } + + return true; + } + + bool is_subset (const hb_bit_set_t &larger_set) const + { + if (has_population () && larger_set.has_population () && + get_population () != larger_set.get_population ()) + return false; + + uint32_t spi = 0; + for (uint32_t lpi = 0; spi < page_map.length && lpi < larger_set.page_map.length; lpi++) + { + uint32_t spm = page_map[spi].major; + uint32_t lpm = larger_set.page_map[lpi].major; + auto sp = page_at (spi); + auto lp = larger_set.page_at (lpi); + + if (spm < lpm && !sp.is_empty ()) + return false; + + if (lpm < spm) + continue; + + if (!sp.is_subset (lp)) + return false; + + spi++; + } + + while (spi < page_map.length) + if (!page_at (spi++).is_empty ()) + return false; + + return true; + } + + private: + bool allocate_compact_workspace (hb_vector_t<unsigned>& workspace) + { + if (unlikely (!workspace.resize (pages.length))) + { + successful = false; + return false; + } + + return true; + } + + /* + * workspace should be a pre-sized vector allocated to hold at exactly pages.length + * elements. + */ + void compact (hb_vector_t<unsigned>& workspace, + unsigned int length) + { + assert(workspace.length == pages.length); + hb_vector_t<unsigned>& old_index_to_page_map_index = workspace; + + hb_fill (old_index_to_page_map_index.writer(), 0xFFFFFFFF); + for (unsigned i = 0; i < length; i++) + old_index_to_page_map_index[page_map[i].index] = i; + + compact_pages (old_index_to_page_map_index); + } + void compact_pages (const hb_vector_t<unsigned>& old_index_to_page_map_index) + { + unsigned int write_index = 0; + for (unsigned int i = 0; i < pages.length; i++) + { + if (old_index_to_page_map_index[i] == 0xFFFFFFFF) continue; + + if (write_index < i) + pages[write_index] = pages[i]; + + page_map[old_index_to_page_map_index[i]].index = write_index; + write_index++; + } + } + public: + + template <typename Op> + void process (const Op& op, const hb_bit_set_t &other) + { + const bool passthru_left = op (1, 0); + const bool passthru_right = op (0, 1); + + if (unlikely (!successful)) return; + + dirty (); + + unsigned int na = pages.length; + unsigned int nb = other.pages.length; + unsigned int next_page = na; + + unsigned int count = 0, newCount = 0; + unsigned int a = 0, b = 0; + unsigned int write_index = 0; + + // Pre-allocate the workspace that compact() will need so we can bail on allocation failure + // before attempting to rewrite the page map. + hb_vector_t<unsigned> compact_workspace; + if (!passthru_left && unlikely (!allocate_compact_workspace (compact_workspace))) return; + + for (; a < na && b < nb; ) + { + if (page_map[a].major == other.page_map[b].major) + { + if (!passthru_left) + { + // Move page_map entries that we're keeping from the left side set + // to the front of the page_map vector. This isn't necessary if + // passthru_left is set since no left side pages will be removed + // in that case. + if (write_index < a) + page_map[write_index] = page_map[a]; + write_index++; + } + + count++; + a++; + b++; + } + else if (page_map[a].major < other.page_map[b].major) + { + if (passthru_left) + count++; + a++; + } + else + { + if (passthru_right) + count++; + b++; + } + } + if (passthru_left) + count += na - a; + if (passthru_right) + count += nb - b; + + if (!passthru_left) + { + na = write_index; + next_page = write_index; + compact (compact_workspace, write_index); + } + + if (unlikely (!resize (count))) + return; + + newCount = count; + + /* Process in-place backward. */ + a = na; + b = nb; + for (; a && b; ) + { + if (page_map[a - 1].major == other.page_map[b - 1].major) + { + a--; + b--; + count--; + page_map[count] = page_map[a]; + page_at (count).v = op (page_at (a).v, other.page_at (b).v); + } + else if (page_map[a - 1].major > other.page_map[b - 1].major) + { + a--; + if (passthru_left) + { + count--; + page_map[count] = page_map[a]; + } + } + else + { + b--; + if (passthru_right) + { + count--; + page_map[count].major = other.page_map[b].major; + page_map[count].index = next_page++; + page_at (count).v = other.page_at (b).v; + } + } + } + if (passthru_left) + while (a) + { + a--; + count--; + page_map[count] = page_map [a]; + } + if (passthru_right) + while (b) + { + b--; + count--; + page_map[count].major = other.page_map[b].major; + page_map[count].index = next_page++; + page_at (count).v = other.page_at (b).v; + } + assert (!count); + resize (newCount); + } + + void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); } + void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); } + void subtract (const hb_bit_set_t &other) { process (hb_bitwise_gt, other); } + void symmetric_difference (const hb_bit_set_t &other) { process (hb_bitwise_xor, other); } + + bool next (hb_codepoint_t *codepoint) const + { + // TODO: this should be merged with prev() as both implementations + // are very similar. + if (unlikely (*codepoint == INVALID)) { + *codepoint = get_min (); + return *codepoint != INVALID; + } + + const auto* page_map_array = page_map.arrayZ; + unsigned int major = get_major (*codepoint); + unsigned int i = last_page_lookup; + + if (unlikely (i >= page_map.length || page_map_array[i].major != major)) + { + page_map.bfind (major, &i, HB_NOT_FOUND_STORE_CLOSEST); + if (i >= page_map.length) { + *codepoint = INVALID; + return false; + } + } + + const auto* pages_array = pages.arrayZ; + const page_map_t ¤t = page_map_array[i]; + if (likely (current.major == major)) + { + if (pages_array[current.index].next (codepoint)) + { + *codepoint += current.major * page_t::PAGE_BITS; + last_page_lookup = i; + return true; + } + i++; + } + + for (; i < page_map.length; i++) + { + const page_map_t ¤t = page_map.arrayZ[i]; + hb_codepoint_t m = pages_array[current.index].get_min (); + if (m != INVALID) + { + *codepoint = current.major * page_t::PAGE_BITS + m; + last_page_lookup = i; + return true; + } + } + last_page_lookup = 0; + *codepoint = INVALID; + return false; + } + bool previous (hb_codepoint_t *codepoint) const + { + if (unlikely (*codepoint == INVALID)) { + *codepoint = get_max (); + return *codepoint != INVALID; + } + + page_map_t map = {get_major (*codepoint), 0}; + unsigned int i; + page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST); + if (i < page_map.length && page_map[i].major == map.major) + { + if (pages[page_map[i].index].previous (codepoint)) + { + *codepoint += page_map[i].major * page_t::PAGE_BITS; + return true; + } + } + i--; + for (; (int) i >= 0; i--) + { + hb_codepoint_t m = pages[page_map[i].index].get_max (); + if (m != INVALID) + { + *codepoint = page_map[i].major * page_t::PAGE_BITS + m; + return true; + } + } + *codepoint = INVALID; + return false; + } + bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + hb_codepoint_t i; + + i = *last; + if (!next (&i)) + { + *last = *first = INVALID; + return false; + } + + /* TODO Speed up. */ + *last = *first = i; + while (next (&i) && i == *last + 1) + (*last)++; + + return true; + } + bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + hb_codepoint_t i; + + i = *first; + if (!previous (&i)) + { + *last = *first = INVALID; + return false; + } + + /* TODO Speed up. */ + *last = *first = i; + while (previous (&i) && i == *first - 1) + (*first)--; + + return true; + } + + bool has_population () const { return population != UINT_MAX; } + unsigned int get_population () const + { + if (has_population ()) + return population; + + unsigned int pop = 0; + unsigned int count = pages.length; + for (unsigned int i = 0; i < count; i++) + pop += pages[i].get_population (); + + population = pop; + return pop; + } + hb_codepoint_t get_min () const + { + unsigned count = pages.length; + for (unsigned i = 0; i < count; i++) + { + const auto& map = page_map[i]; + const auto& page = pages[map.index]; + + if (!page.is_empty ()) + return map.major * page_t::PAGE_BITS + page.get_min (); + } + return INVALID; + } + hb_codepoint_t get_max () const + { + unsigned count = pages.length; + for (signed i = count - 1; i >= 0; i--) + { + const auto& map = page_map[(unsigned) i]; + const auto& page = pages[map.index]; + + if (!page.is_empty ()) + return map.major * page_t::PAGE_BITS + page.get_max (); + } + return INVALID; + } + + static constexpr hb_codepoint_t INVALID = page_t::INVALID; + + /* + * Iterator implementation. + */ + struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> + { + static constexpr bool is_sorted_iterator = true; + iter_t (const hb_bit_set_t &s_ = Null (hb_bit_set_t), + bool init = true) : s (&s_), v (INVALID), l(0) + { + if (init) + { + l = s->get_population () + 1; + __next__ (); + } + } + + typedef hb_codepoint_t __item_t__; + hb_codepoint_t __item__ () const { return v; } + bool __more__ () const { return v != INVALID; } + void __next__ () { s->next (&v); if (l) l--; } + void __prev__ () { s->previous (&v); } + unsigned __len__ () const { return l; } + iter_t end () const { return iter_t (*s, false); } + bool operator != (const iter_t& o) const + { return s != o.s || v != o.v; } + + protected: + const hb_bit_set_t *s; + hb_codepoint_t v; + unsigned l; + }; + iter_t iter () const { return iter_t (*this); } + operator iter_t () const { return iter (); } + + protected: + + page_t *page_for (hb_codepoint_t g, bool insert = false) + { + page_map_t map = {get_major (g), pages.length}; + unsigned int i; + if (!page_map.bfind (map, &i, HB_NOT_FOUND_STORE_CLOSEST)) + { + if (!insert) + return nullptr; + + if (unlikely (!resize (pages.length + 1))) + return nullptr; + + pages[map.index].init0 (); + memmove (page_map + i + 1, + page_map + i, + (page_map.length - 1 - i) * page_map.item_size); + page_map[i] = map; + } + return &pages[page_map[i].index]; + } + const page_t *page_for (hb_codepoint_t g) const + { + page_map_t key = {get_major (g)}; + const page_map_t *found = page_map.bsearch (key); + if (found) + return &pages[found->index]; + return nullptr; + } + page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } + const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } + unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; } + hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; } +}; + + +#endif /* HB_BIT_SET_HH */ diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc index e340bc346d..f120002d17 100644 --- a/thirdparty/harfbuzz/src/hb-blob.cc +++ b/thirdparty/harfbuzz/src/hb-blob.cc @@ -35,9 +35,6 @@ #include <sys/mman.h> #endif /* HAVE_SYS_MMAN_H */ -#include <stdio.h> -#include <stdlib.h> - /** * SECTION: hb-blob @@ -58,7 +55,7 @@ * @length: Length of @data in bytes. * @mode: Memory mode for @data. * @user_data: Data parameter to pass to @destroy. - * @destroy: (optional): Callback to call when @data is not needed anymore. + * @destroy: (nullable): Callback to call when @data is not needed anymore. * * Creates a new "blob" object wrapping @data. The @mode parameter is used * to negotiate ownership and lifecycle of @data. @@ -75,14 +72,52 @@ hb_blob_create (const char *data, void *user_data, hb_destroy_func_t destroy) { + if (!length) + { + if (destroy) + destroy (user_data); + return hb_blob_get_empty (); + } + + hb_blob_t *blob = hb_blob_create_or_fail (data, length, mode, + user_data, destroy); + return likely (blob) ? blob : hb_blob_get_empty (); +} + +/** + * hb_blob_create_or_fail: (skip) + * @data: Pointer to blob data. + * @length: Length of @data in bytes. + * @mode: Memory mode for @data. + * @user_data: Data parameter to pass to @destroy. + * @destroy: (nullable): Callback to call when @data is not needed anymore. + * + * Creates a new "blob" object wrapping @data. The @mode parameter is used + * to negotiate ownership and lifecycle of @data. + * + * Note that this function returns a freshly-allocated empty blob even if @length + * is zero. This is in contrast to hb_blob_create(), which returns the singleton + * empty blob (as returned by hb_blob_get_empty()) if @length is zero. + * + * Return value: New blob, or %NULL if failed. Destroy with hb_blob_destroy(). + * + * Since: 2.8.2 + **/ +hb_blob_t * +hb_blob_create_or_fail (const char *data, + unsigned int length, + hb_memory_mode_t mode, + void *user_data, + hb_destroy_func_t destroy) +{ hb_blob_t *blob; - if (!length || - length >= 1u << 31 || - !(blob = hb_object_create<hb_blob_t> ())) { + if (length >= 1u << 31 || + !(blob = hb_object_create<hb_blob_t> ())) + { if (destroy) destroy (user_data); - return hb_blob_get_empty (); + return nullptr; } blob->data = data; @@ -94,9 +129,10 @@ hb_blob_create (const char *data, if (blob->mode == HB_MEMORY_MODE_DUPLICATE) { blob->mode = HB_MEMORY_MODE_READONLY; - if (!blob->try_make_writable ()) { + if (!blob->try_make_writable ()) + { hb_blob_destroy (blob); - return hb_blob_get_empty (); + return nullptr; } } @@ -116,7 +152,7 @@ _hb_blob_destroy (void *data) * @length: Length of sub-blob. * * Returns a blob that represents a range of bytes in @parent. The new - * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it + * blob is always created with #HB_MEMORY_MODE_READONLY, meaning that it * will never modify data in the parent blob. The parent data is not * expected to be modified, and will result in undefined behavior if it * is. @@ -229,7 +265,7 @@ hb_blob_destroy (hb_blob_t *blob) blob->fini_shallow (); - free (blob); + hb_free (blob); } /** @@ -237,7 +273,7 @@ hb_blob_destroy (hb_blob_t *blob) * @blob: An #hb_blob_t * @key: The user-data key to set * @data: A pointer to the user data to set - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified blob. @@ -299,7 +335,7 @@ hb_blob_make_immutable (hb_blob_t *blob) * * Tests whether a blob is immutable. * - * Return value: %true if @blob is immutable, false otherwise + * Return value: %true if @blob is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -365,16 +401,14 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) { - if (!blob->try_make_writable ()) { - if (length) - *length = 0; - + if (hb_object_is_immutable (blob) || + !blob->try_make_writable ()) + { + if (length) *length = 0; return nullptr; } - if (length) - *length = blob->length; - + if (length) *length = blob->length; return const_cast<char *> (blob->data); } @@ -440,8 +474,8 @@ hb_blob_t::try_make_writable_inplace () bool hb_blob_t::try_make_writable () { - if (hb_object_is_immutable (this)) - return false; + if (unlikely (!length)) + mode = HB_MEMORY_MODE_WRITABLE; if (this->mode == HB_MEMORY_MODE_WRITABLE) return true; @@ -457,7 +491,7 @@ hb_blob_t::try_make_writable () char *new_data; - new_data = (char *) malloc (this->length); + new_data = (char *) hb_malloc (this->length); if (unlikely (!new_data)) return false; @@ -468,7 +502,7 @@ hb_blob_t::try_make_writable () this->mode = HB_MEMORY_MODE_WRITABLE; this->data = new_data; this->user_data = new_data; - this->destroy = free; + this->destroy = hb_free; return true; } @@ -522,7 +556,7 @@ _hb_mapped_file_destroy (void *file_) assert (0); // If we don't have mmap we shouldn't reach here #endif - free (file); + hb_free (file); } #endif @@ -533,7 +567,7 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) size_t name_len = strlen (file_name); size_t len = name_len + sizeof (_PATH_RSRCFORKSPEC); - char *rsrc_name = (char *) malloc (len); + char *rsrc_name = (char *) hb_malloc (len); if (unlikely (!rsrc_name)) return -1; strncpy (rsrc_name, file_name, name_len); @@ -541,7 +575,7 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) sizeof (_PATH_RSRCFORKSPEC) - 1); int fd = open (rsrc_name, O_RDONLY | O_BINARY, 0); - free (rsrc_name); + hb_free (rsrc_name); if (fd != -1) { @@ -566,17 +600,37 @@ _open_resource_fork (const char *file_name, hb_mapped_file_t *file) * Creates a new blob containing the data from the * specified binary font file. * - * Returns: An #hb_blob_t pointer with the content of the file + * Returns: An #hb_blob_t pointer with the content of the file, + * or hb_blob_get_empty() if failed. * * Since: 1.7.7 **/ hb_blob_t * hb_blob_create_from_file (const char *file_name) { + hb_blob_t *blob = hb_blob_create_from_file_or_fail (file_name); + return likely (blob) ? blob : hb_blob_get_empty (); +} + +/** + * hb_blob_create_from_file_or_fail: + * @file_name: A font filename + * + * Creates a new blob containing the data from the + * specified binary font file. + * + * Returns: An #hb_blob_t pointer with the content of the file, + * or %NULL if failed. + * + * Since: 2.8.2 + **/ +hb_blob_t * +hb_blob_create_from_file_or_fail (const char *file_name) +{ /* Adopted from glib's gmappedfile.c with Matthias Clasen and Allison Lortie permission but changed a lot to suit our need. */ #if defined(HAVE_MMAP) && !defined(HB_NO_MMAP) - hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); + hb_mapped_file_t *file = (hb_mapped_file_t *) hb_calloc (1, sizeof (hb_mapped_file_t)); if (unlikely (!file)) return hb_blob_get_empty (); int fd = open (file_name, O_RDONLY | O_BINARY, 0); @@ -606,22 +660,22 @@ hb_blob_create_from_file (const char *file_name) close (fd); - return hb_blob_create (file->contents, file->length, - HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file, - (hb_destroy_func_t) _hb_mapped_file_destroy); + return hb_blob_create_or_fail (file->contents, file->length, + HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file, + (hb_destroy_func_t) _hb_mapped_file_destroy); fail: close (fd); fail_without_close: - free (file); + hb_free (file); #elif defined(_WIN32) && !defined(HB_NO_MMAP) - hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); + hb_mapped_file_t *file = (hb_mapped_file_t *) hb_calloc (1, sizeof (hb_mapped_file_t)); if (unlikely (!file)) return hb_blob_get_empty (); HANDLE fd; unsigned int size = strlen (file_name) + 1; - wchar_t * wchar_file_name = (wchar_t *) malloc (sizeof (wchar_t) * size); + wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size); if (unlikely (!wchar_file_name)) goto fail_without_close; mbstowcs (wchar_file_name, file_name, size); #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) @@ -641,7 +695,7 @@ fail_without_close: OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, nullptr); #endif - free (wchar_file_name); + hb_free (wchar_file_name); if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close; @@ -666,22 +720,22 @@ fail_without_close: if (unlikely (!file->contents)) goto fail; CloseHandle (fd); - return hb_blob_create (file->contents, file->length, - HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file, - (hb_destroy_func_t) _hb_mapped_file_destroy); + return hb_blob_create_or_fail (file->contents, file->length, + HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, (void *) file, + (hb_destroy_func_t) _hb_mapped_file_destroy); fail: CloseHandle (fd); fail_without_close: - free (file); + hb_free (file); #endif /* The following tries to read a file without knowing its size beforehand It's used as a fallback for systems without mmap or to read from pipes */ unsigned long len = 0, allocated = BUFSIZ * 16; - char *data = (char *) malloc (allocated); - if (unlikely (!data)) return hb_blob_get_empty (); + char *data = (char *) hb_malloc (allocated); + if (unlikely (!data)) return nullptr; FILE *fp = fopen (file_name, "rb"); if (unlikely (!fp)) goto fread_fail_without_close; @@ -694,7 +748,7 @@ fail_without_close: /* Don't allocate and go more than ~536MB, our mmap reader still can cover files like that but lets limit our fallback reader */ if (unlikely (allocated > (2 << 28))) goto fread_fail; - char *new_data = (char *) realloc (data, allocated); + char *new_data = (char *) hb_realloc (data, allocated); if (unlikely (!new_data)) goto fread_fail; data = new_data; } @@ -711,13 +765,13 @@ fail_without_close: } fclose (fp); - return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data, - (hb_destroy_func_t) free); + return hb_blob_create_or_fail (data, len, HB_MEMORY_MODE_WRITABLE, data, + (hb_destroy_func_t) hb_free); fread_fail: fclose (fp); fread_fail_without_close: - free (data); - return hb_blob_get_empty (); + hb_free (data); + return nullptr; } #endif /* !HB_NO_OPEN */ diff --git a/thirdparty/harfbuzz/src/hb-blob.h b/thirdparty/harfbuzz/src/hb-blob.h index 00e41f3ce3..203f9e19dd 100644 --- a/thirdparty/harfbuzz/src/hb-blob.h +++ b/thirdparty/harfbuzz/src/hb-blob.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -38,10 +38,12 @@ HB_BEGIN_DECLS /** * hb_memory_mode_t: - * @HB_MEMORY_MODE_DUPLICATE - * @HB_MEMORY_MODE_READONLY - * @HB_MEMORY_MODE_WRITABLE - * @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE + * @HB_MEMORY_MODE_DUPLICATE: HarfBuzz immediately makes a copy of the data. + * @HB_MEMORY_MODE_READONLY: HarfBuzz client will never modify the data, + * and HarfBuzz will never modify the data. + * @HB_MEMORY_MODE_WRITABLE: HarfBuzz client made a copy of the data solely + * for HarfBuzz, so HarfBuzz may modify the data. + * @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE: See above * * Data type holding the memory modes available to * client programs. @@ -89,8 +91,18 @@ hb_blob_create (const char *data, hb_destroy_func_t destroy); HB_EXTERN hb_blob_t * +hb_blob_create_or_fail (const char *data, + unsigned int length, + hb_memory_mode_t mode, + void *user_data, + hb_destroy_func_t destroy); + +HB_EXTERN hb_blob_t * hb_blob_create_from_file (const char *file_name); +HB_EXTERN hb_blob_t * +hb_blob_create_from_file_or_fail (const char *file_name); + /* Always creates with MEMORY_MODE_READONLY. * Even if the parent blob is writable, we don't * want the user of the sub-blob to be able to diff --git a/thirdparty/harfbuzz/src/hb-blob.hh b/thirdparty/harfbuzz/src/hb-blob.hh index b03dfc1380..a3683a681e 100644 --- a/thirdparty/harfbuzz/src/hb-blob.hh +++ b/thirdparty/harfbuzz/src/hb-blob.hh @@ -88,7 +88,7 @@ struct hb_blob_ptr_t const T * get () const { return b->as<T> (); } hb_blob_t * get_blob () const { return b.get_raw (); } unsigned int get_length () const { return b.get ()->length; } - void destroy () { hb_blob_destroy (b.get ()); b = nullptr; } + void destroy () { hb_blob_destroy (b.get_raw ()); b = nullptr; } private: hb_nonnull_ptr_t<hb_blob_t> b; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh index 01db295498..e80cfea6e7 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh @@ -1,29 +1,30 @@ + #line 1 "hb-buffer-deserialize-json.rl" /* -* Copyright © 2013 Google, Inc. -* -* This is part of HarfBuzz, a text shaping library. -* -* Permission is hereby granted, without written agreement and without -* license or royalty fees, to use, copy, modify, and distribute this -* software and its documentation for any purpose, provided that the -* above copyright notice and the following two paragraphs appear in -* all copies of this software. -* -* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -* DAMAGE. -* -* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -* -* Google Author(s): Behdad Esfahbod -*/ + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ #ifndef HB_BUFFER_DESERIALIZE_JSON_HH #define HB_BUFFER_DESERIALIZE_JSON_HH @@ -31,158 +32,446 @@ #include "hb.hh" -#line 35 "hb-buffer-deserialize-json.hh" +#line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 1u, 0u, 0u, 18u, 0u, 2u, 10u, 15u, - 16u, 17u, 2u, 2u, 0u, 7u, 0u, 6u, - 5u, 6u, 0u, 19u, 0u, 19u, 0u, 19u, - 2u, 2u, 0u, 7u, 0u, 6u, 5u, 6u, - 0u, 19u, 0u, 19u, 14u, 14u, 2u, 2u, - 0u, 7u, 0u, 6u, 0u, 19u, 0u, 19u, - 16u, 17u, 2u, 2u, 0u, 7u, 0u, 6u, - 5u, 6u, 0u, 19u, 0u, 19u, 2u, 2u, - 0u, 7u, 0u, 6u, 5u, 6u, 0u, 19u, - 0u, 19u, 2u, 2u, 0u, 7u, 0u, 6u, - 2u, 8u, 0u, 19u, 2u, 8u, 0u, 19u, - 0u, 19u, 2u, 2u, 0u, 7u, 0u, 6u, - 0u, 19u, 0u, 9u, 0u, 18u, 1u, 0u, - 0u + 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, + 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, + 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 34u, 92u, 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 }; -static const signed char _deserialize_json_char_class[] = { - 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 1, 1, 5, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 7, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 8, 9, 1, 1, 1, - 10, 1, 11, 12, 1, 1, 13, 1, - 1, 1, 1, 14, 1, 1, 1, 1, - 1, 1, 1, 1, 15, 1, 1, 16, - 17, 1, 18, 1, 19, 0 +static const char _deserialize_json_key_spans[] = { + 0, 115, 26, 21, 2, 1, 50, 49, + 10, 117, 117, 117, 1, 50, 49, 10, + 117, 117, 1, 1, 50, 49, 117, 117, + 2, 1, 50, 49, 10, 117, 117, 1, + 50, 49, 10, 117, 117, 1, 50, 49, + 59, 117, 59, 117, 117, 1, 50, 49, + 117, 85, 115, 0 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 19, 22, 28, 30, 31, 39, - 46, 48, 68, 88, 108, 109, 117, 124, - 126, 146, 166, 167, 168, 176, 183, 203, - 223, 225, 226, 234, 241, 243, 263, 283, - 284, 292, 299, 301, 321, 341, 342, 350, - 357, 364, 384, 391, 411, 431, 432, 440, - 447, 467, 477, 496, 0 + 0, 0, 116, 143, 165, 168, 170, 221, + 271, 282, 400, 518, 636, 638, 689, 739, + 750, 868, 986, 988, 990, 1041, 1091, 1209, + 1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680, + 1682, 1733, 1783, 1794, 1912, 2030, 2032, 2083, + 2133, 2193, 2311, 2371, 2489, 2607, 2609, 2660, + 2710, 2828, 2914, 3030 }; -static const signed char _deserialize_json_indicies[] = { - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 3, 0, 4, 5, 6, - 7, 8, 0, 9, 10, 11, 12, 12, - 0, 0, 0, 0, 0, 0, 13, 13, - 0, 0, 0, 14, 15, 16, 18, 19, - 20, 0, 0, 21, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 22, 23, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 24, - 20, 0, 0, 21, 0, 19, 19, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 22, 25, 25, 0, 0, - 0, 0, 0, 0, 26, 26, 0, 0, - 0, 27, 28, 29, 31, 32, 33, 0, - 0, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 35, 33, 0, 0, 34, 0, 32, - 32, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 35, 36, 37, - 37, 0, 0, 0, 0, 0, 0, 38, - 38, 0, 0, 0, 0, 39, 40, 42, - 0, 0, 43, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 44, 42, 0, 0, 43, 0, - 45, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 46, - 47, 48, 48, 0, 0, 0, 0, 0, - 0, 49, 49, 0, 0, 0, 50, 51, - 52, 54, 55, 56, 0, 0, 57, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 58, 56, - 0, 0, 57, 0, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 58, 59, 59, 0, 0, 0, - 0, 0, 0, 60, 60, 0, 0, 0, - 61, 62, 63, 65, 66, 67, 0, 0, - 68, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 69, 67, 0, 0, 68, 0, 66, 66, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 69, 70, 70, 0, - 0, 0, 0, 0, 0, 71, 71, 0, - 72, 0, 0, 73, 74, 76, 75, 75, - 75, 75, 75, 77, 79, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, - 75, 0, 0, 0, 0, 0, 75, 83, - 0, 0, 84, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85, 83, 0, 0, 84, 0, - 87, 87, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 85, 88, - 88, 0, 0, 0, 0, 0, 0, 89, - 89, 0, 0, 0, 0, 90, 91, 83, - 0, 0, 84, 0, 93, 93, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85, 94, 0, 0, 95, 0, - 0, 0, 0, 0, 96, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, +static const char _deserialize_json_indicies[] = { + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 4, 1, + 5, 1, 6, 7, 1, 1, 8, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 9, 1, 10, 11, + 1, 12, 1, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 12, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 13, 1, 13, 13, + 13, 13, 13, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 13, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 14, 1, 1, 15, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 1, + 17, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 1, 19, 19, 19, 19, 19, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 19, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 20, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 21, + 1, 22, 22, 22, 22, 22, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 22, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 23, 1, 19, + 19, 19, 19, 19, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 19, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 20, 1, 1, 1, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 21, 1, 24, 1, 24, + 24, 24, 24, 24, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 24, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 25, 1, 25, 25, 25, 25, 25, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 26, 1, + 1, 27, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 1, 29, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 1, 31, + 31, 31, 31, 31, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 31, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 32, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 33, 1, 31, 31, 31, + 31, 31, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 31, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 32, 1, 1, 1, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 33, 1, 34, 1, 35, 1, 35, + 35, 35, 35, 35, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 35, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 36, 1, 36, 36, 36, 36, 36, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 36, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 37, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 1, 39, 39, 39, 39, + 39, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 39, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 41, 1, 39, 39, 39, 39, 39, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 39, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 40, 1, 1, + 1, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 41, 1, + 43, 44, 1, 45, 1, 45, 45, 45, + 45, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 45, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 46, 1, + 46, 46, 46, 46, 46, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 46, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 47, 1, 1, 48, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 1, 50, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 1, 52, 52, 52, + 52, 52, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 52, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 53, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 54, 1, 52, 52, 52, 52, 52, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 52, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 53, 1, + 1, 1, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 54, + 1, 55, 1, 55, 55, 55, 55, 55, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 55, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 56, 1, 56, 56, + 56, 56, 56, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 57, 1, 1, 58, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 1, + 60, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 1, 62, 62, 62, 62, 62, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 62, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 63, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 64, + 1, 62, 62, 62, 62, 62, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 62, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 63, 1, 1, 1, + 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 64, 1, 65, + 1, 65, 65, 65, 65, 65, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 65, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 66, 1, 66, 66, 66, 66, + 66, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 67, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 68, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 1, 71, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 72, 70, 73, 73, 73, 73, 73, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 73, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 74, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 75, 1, + 70, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 70, 1, 76, 76, 76, 76, + 76, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 76, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 77, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 78, 1, 76, 76, 76, 76, 76, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 76, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 77, 1, 1, + 1, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 78, 1, + 80, 1, 80, 80, 80, 80, 80, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 80, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 81, 1, 81, 81, 81, + 81, 81, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 81, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 82, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 1, 76, + 76, 76, 76, 76, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 76, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 77, 1, 1, 1, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 78, 1, 85, 85, 85, + 85, 85, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 85, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 86, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 87, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 0 }; -static const signed char _deserialize_json_index_defaults[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 75, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 -}; - -static const signed char _deserialize_json_cond_targs[] = { - 0, 1, 2, 2, 3, 4, 18, 24, - 37, 45, 5, 12, 6, 7, 8, 9, - 11, 8, 9, 11, 10, 2, 49, 10, - 49, 13, 14, 15, 16, 17, 15, 16, - 17, 10, 2, 49, 19, 20, 21, 22, - 23, 22, 10, 2, 49, 23, 25, 31, - 26, 27, 28, 29, 30, 28, 29, 30, - 10, 2, 49, 32, 33, 34, 35, 36, - 34, 35, 36, 10, 2, 49, 38, 39, - 40, 43, 44, 40, 41, 42, 41, 10, - 2, 49, 43, 10, 2, 49, 44, 44, - 46, 47, 43, 48, 48, 48, 49, 50, - 51, 0 +static const char _deserialize_json_trans_targs[] = { + 1, 0, 2, 2, 3, 4, 18, 24, + 37, 45, 5, 12, 6, 7, 8, 9, + 11, 9, 11, 10, 2, 49, 10, 49, + 13, 14, 15, 16, 17, 16, 17, 10, + 2, 49, 19, 20, 21, 22, 23, 10, + 2, 49, 23, 25, 31, 26, 27, 28, + 29, 30, 29, 30, 10, 2, 49, 32, + 33, 34, 35, 36, 35, 36, 10, 2, + 49, 38, 39, 40, 43, 44, 40, 41, + 42, 10, 2, 49, 10, 2, 49, 44, + 46, 47, 43, 48, 48, 49, 50, 51 }; -static const signed char _deserialize_json_cond_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 0, 3, 3, 4, 0, - 5, 0, 0, 2, 2, 2, 0, 0, - 0, 6, 6, 7, 0, 0, 0, 2, - 2, 0, 8, 8, 9, 0, 0, 0, - 0, 0, 2, 2, 2, 0, 0, 0, - 10, 10, 11, 0, 0, 2, 2, 2, - 0, 0, 0, 12, 12, 13, 0, 0, - 2, 14, 14, 0, 15, 0, 0, 16, - 16, 17, 0, 18, 18, 19, 0, 15, - 0, 0, 20, 20, 0, 21, 0, 0, - 0, 0 +static const char _deserialize_json_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 3, 3, 4, 0, 5, + 0, 0, 2, 2, 2, 0, 0, 6, + 6, 7, 0, 0, 0, 2, 2, 8, + 8, 9, 0, 0, 0, 0, 0, 2, + 2, 2, 0, 0, 10, 10, 11, 0, + 0, 2, 2, 2, 0, 0, 12, 12, + 13, 0, 0, 2, 14, 14, 0, 15, + 0, 16, 16, 17, 18, 18, 19, 15, + 0, 0, 20, 20, 21, 0, 0, 0 }; static const int deserialize_json_start = 1; @@ -197,411 +486,247 @@ static const int deserialize_json_en_main = 1; static hb_bool_t _hb_buffer_deserialize_json (hb_buffer_t *buffer, -const char *buf, -unsigned int buf_len, -const char **end_ptr, -hb_font_t *font) + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - { - *end_ptr = ++p; - } - - const char *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 223 "hb-buffer-deserialize-json.hh" + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? ',' : '[')) + { + *end_ptr = ++p; + } + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 512 "hb-buffer-deserialize-json.hh" { - cs = (int)deserialize_json_start; + cs = deserialize_json_start; } - -#line 228 "hb-buffer-deserialize-json.hh" + +#line 517 "hb-buffer-deserialize-json.hh" { - unsigned int _trans = 0; - const unsigned char * _keys; - const signed char * _inds; - int _ic; - _resume: {} - if ( p == pe ) - goto _out; - _keys = ( _deserialize_json_trans_keys + ((cs<<1))); - _inds = ( _deserialize_json_indicies + (_deserialize_json_index_offsets[cs])); - - if ( ( (*( p))) <= 125 && ( (*( p))) >= 9 ) { - _ic = (int)_deserialize_json_char_class[(int)( (*( p))) - 9]; - if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) - _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); - else - _trans = (unsigned int)_deserialize_json_index_defaults[cs]; - } - else { - _trans = (unsigned int)_deserialize_json_index_defaults[cs]; - } - - cs = (int)_deserialize_json_cond_targs[_trans]; - - if ( _deserialize_json_cond_actions[_trans] != 0 ) { - - switch ( _deserialize_json_cond_actions[_trans] ) { - case 1: { - { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_json_trans_keys + (cs<<1); + _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs]; + + _slen = _deserialize_json_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_json_trans_targs[_trans]; + + if ( _deserialize_json_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_json_trans_actions[_trans] ) { + case 1: #line 38 "hb-buffer-deserialize-json.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 264 "hb-buffer-deserialize-json.hh" - - - break; - } - case 5: { - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + break; + case 5: #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 280 "hb-buffer-deserialize-json.hh" - - - break; - } - case 2: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 2: #line 51 "hb-buffer-deserialize-json.rl" - - tok = p; - } - -#line 292 "hb-buffer-deserialize-json.hh" - - - break; - } - case 15: { - { + { + tok = p; +} + break; + case 15: #line 55 "hb-buffer-deserialize-json.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 302 "hb-buffer-deserialize-json.hh" - - - break; - } - case 21: { - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 21: #line 56 "hb-buffer-deserialize-json.rl" - if (unlikely (!buffer->ensure_unicode ())) return false; } - -#line 312 "hb-buffer-deserialize-json.hh" - - - break; - } - case 16: { - { + { if (unlikely (!buffer->ensure_unicode ())) return false; } + break; + case 16: #line 58 "hb-buffer-deserialize-json.rl" - - /* TODO Unescape \" and \\ if found. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 328 "hb-buffer-deserialize-json.hh" - - - break; - } - case 18: { - { + { + /* TODO Unescape \" and \\ if found. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 18: #line 66 "hb-buffer-deserialize-json.rl" - if (!parse_uint (tok, p, &info.codepoint)) return false; } - -#line 338 "hb-buffer-deserialize-json.hh" - - - break; - } - case 8: { - { + { if (!parse_uint (tok, p, &info.codepoint)) return false; } + break; + case 8: #line 67 "hb-buffer-deserialize-json.rl" - if (!parse_uint (tok, p, &info.cluster )) return false; } - -#line 348 "hb-buffer-deserialize-json.hh" - - - break; - } - case 10: { - { + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 10: #line 68 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.x_offset )) return false; } - -#line 358 "hb-buffer-deserialize-json.hh" - - - break; - } - case 12: { - { + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 12: #line 69 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.y_offset )) return false; } - -#line 368 "hb-buffer-deserialize-json.hh" - - - break; - } - case 3: { - { + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 3: #line 70 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.x_advance)) return false; } - -#line 378 "hb-buffer-deserialize-json.hh" - - - break; - } - case 6: { - { + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 6: #line 71 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.y_advance)) return false; } - -#line 388 "hb-buffer-deserialize-json.hh" - - - break; - } - case 14: { - { + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 14: #line 51 "hb-buffer-deserialize-json.rl" - - tok = p; - } - -#line 400 "hb-buffer-deserialize-json.hh" - - { + { + tok = p; +} #line 55 "hb-buffer-deserialize-json.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 406 "hb-buffer-deserialize-json.hh" - - - break; - } - case 20: { - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 20: #line 51 "hb-buffer-deserialize-json.rl" - - tok = p; - } - -#line 418 "hb-buffer-deserialize-json.hh" - - { + { + tok = p; +} #line 56 "hb-buffer-deserialize-json.rl" - if (unlikely (!buffer->ensure_unicode ())) return false; } - -#line 424 "hb-buffer-deserialize-json.hh" - - - break; - } - case 17: { - { + { if (unlikely (!buffer->ensure_unicode ())) return false; } + break; + case 17: #line 58 "hb-buffer-deserialize-json.rl" - - /* TODO Unescape \" and \\ if found. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 440 "hb-buffer-deserialize-json.hh" - - { + { + /* TODO Unescape \" and \\ if found. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 452 "hb-buffer-deserialize-json.hh" - - - break; - } - case 19: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 19: #line 66 "hb-buffer-deserialize-json.rl" - if (!parse_uint (tok, p, &info.codepoint)) return false; } - -#line 462 "hb-buffer-deserialize-json.hh" - - { + { if (!parse_uint (tok, p, &info.codepoint)) return false; } #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 474 "hb-buffer-deserialize-json.hh" - - - break; - } - case 9: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: #line 67 "hb-buffer-deserialize-json.rl" - if (!parse_uint (tok, p, &info.cluster )) return false; } - -#line 484 "hb-buffer-deserialize-json.hh" - - { + { if (!parse_uint (tok, p, &info.cluster )) return false; } #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 496 "hb-buffer-deserialize-json.hh" - - - break; - } - case 11: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: #line 68 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.x_offset )) return false; } - -#line 506 "hb-buffer-deserialize-json.hh" - - { + { if (!parse_int (tok, p, &pos.x_offset )) return false; } #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 518 "hb-buffer-deserialize-json.hh" - - - break; - } - case 13: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 13: #line 69 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.y_offset )) return false; } - -#line 528 "hb-buffer-deserialize-json.hh" - - { + { if (!parse_int (tok, p, &pos.y_offset )) return false; } #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 540 "hb-buffer-deserialize-json.hh" - - - break; - } - case 4: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 4: #line 70 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.x_advance)) return false; } - -#line 550 "hb-buffer-deserialize-json.hh" - - { + { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 562 "hb-buffer-deserialize-json.hh" - - - break; - } - case 7: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 7: #line 71 "hb-buffer-deserialize-json.rl" - if (!parse_int (tok, p, &pos.y_advance)) return false; } - -#line 572 "hb-buffer-deserialize-json.hh" - - { + { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-json.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 584 "hb-buffer-deserialize-json.hh" - - - break; - } - } - - } - - if ( cs != 0 ) { - p += 1; - goto _resume; - } - _out: {} + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 713 "hb-buffer-deserialize-json.hh" } - + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + #line 136 "hb-buffer-deserialize-json.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; } #endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh index fb36f56015..b599e9667c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh @@ -1,29 +1,30 @@ + #line 1 "hb-buffer-deserialize-text.rl" /* -* Copyright © 2013 Google, Inc. -* -* This is part of HarfBuzz, a text shaping library. -* -* Permission is hereby granted, without written agreement and without -* license or royalty fees, to use, copy, modify, and distribute this -* software and its documentation for any purpose, provided that the -* above copyright notice and the following two paragraphs appear in -* all copies of this software. -* -* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -* DAMAGE. -* -* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -* -* Google Author(s): Behdad Esfahbod -*/ + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ #ifndef HB_BUFFER_DESERIALIZE_TEXT_HH #define HB_BUFFER_DESERIALIZE_TEXT_HH @@ -31,143 +32,366 @@ #include "hb.hh" -#line 35 "hb-buffer-deserialize-text.hh" +#line 36 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { - 1u, 0u, 0u, 13u, 12u, 12u, 2u, 2u, - 5u, 11u, 0u, 12u, 5u, 6u, 4u, 6u, - 5u, 6u, 5u, 6u, 4u, 6u, 5u, 6u, - 3u, 3u, 4u, 6u, 5u, 6u, 3u, 6u, - 2u, 16u, 4u, 6u, 5u, 6u, 0u, 16u, - 0u, 16u, 1u, 0u, 0u, 12u, 0u, 16u, - 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u, - 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u, - 0u, 16u, 0u, 16u, 0u, 16u, 0u, 16u, - 0u, 16u, 0u + 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u, + 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, + 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 9u, 124u, + 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 0 }; -static const signed char _deserialize_text_char_class[] = { - 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 3, 4, 1, 1, 5, - 6, 6, 6, 6, 6, 6, 6, 6, - 6, 1, 1, 7, 8, 9, 1, 10, - 11, 11, 11, 11, 11, 11, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 12, 1, 1, 1, - 1, 1, 13, 14, 15, 1, 1, 1, - 11, 11, 11, 11, 11, 11, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 16, 0 +static const char _deserialize_text_key_spans[] = { + 0, 83, 1, 1, 55, 77, 10, 13, + 10, 10, 13, 10, 1, 13, 10, 14, + 82, 13, 10, 116, 116, 0, 77, 116, + 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116 }; static const short _deserialize_text_index_offsets[] = { - 0, 0, 14, 15, 16, 23, 36, 38, - 41, 43, 45, 48, 50, 51, 54, 56, - 60, 75, 78, 80, 97, 114, 114, 127, - 144, 161, 178, 195, 212, 229, 246, 263, - 280, 297, 314, 331, 348, 0 -}; - -static const signed char _deserialize_text_indicies[] = { - 1, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 3, 4, 6, - 7, 7, 0, 0, 0, 0, 7, 8, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 10, 11, 13, 14, - 15, 17, 18, 20, 21, 23, 24, 25, - 27, 28, 29, 31, 32, 33, 35, 36, - 29, 0, 28, 28, 38, 38, 0, 0, - 0, 0, 38, 0, 38, 0, 0, 0, - 38, 38, 38, 40, 41, 42, 44, 45, - 47, 0, 0, 0, 0, 48, 48, 0, - 49, 50, 0, 48, 0, 0, 0, 0, - 51, 52, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 0, 0, 0, 0, 0, - 0, 54, 8, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 56, - 0, 0, 0, 0, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 0, 0, 58, - 56, 0, 0, 0, 0, 60, 60, 0, - 0, 57, 0, 0, 0, 0, 0, 0, - 58, 63, 62, 64, 0, 62, 62, 62, - 62, 65, 62, 66, 62, 62, 62, 67, - 68, 69, 71, 38, 72, 0, 38, 38, - 38, 38, 73, 38, 74, 38, 38, 38, - 37, 75, 76, 78, 0, 0, 79, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 81, 82, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 53, 83, 84, 62, 64, - 0, 62, 62, 62, 62, 65, 62, 66, - 62, 62, 62, 67, 68, 69, 86, 0, - 87, 0, 0, 0, 0, 0, 0, 0, - 88, 0, 0, 0, 0, 57, 89, 91, - 0, 92, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 93, 94, - 91, 0, 92, 0, 0, 36, 36, 0, - 0, 0, 0, 0, 0, 0, 0, 93, - 94, 86, 0, 87, 0, 0, 97, 97, - 0, 0, 0, 88, 0, 0, 0, 0, - 57, 89, 99, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 100, 101, 99, 0, 0, 0, 0, - 45, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 100, 101, 78, 0, 0, 79, - 0, 18, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 81, 0 + 0, 0, 84, 86, 88, 144, 222, 233, + 247, 258, 269, 283, 294, 296, 310, 321, + 336, 419, 433, 444, 561, 678, 679, 757, + 874, 991, 1108, 1225, 1342, 1459, 1576, 1693, + 1810, 1927, 2044, 2161, 2278 }; -static const signed char _deserialize_text_index_defaults[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 62, 38, 0, 0, 62, 0, 0, - 0, 0, 0, 0, 0, 0 +static const char _deserialize_text_indicies[] = { + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 4, 1, 5, + 1, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 1, 1, 1, 1, 1, + 1, 1, 6, 6, 6, 6, 6, 6, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 6, 6, 6, 6, 6, 6, + 1, 7, 7, 7, 7, 7, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 7, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 4, 1, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 1, 10, 1, 1, 11, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 1, + 13, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 1, 15, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 1, 17, 1, + 1, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 1, 20, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 1, 22, + 1, 23, 1, 1, 24, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 1, 26, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 1, 22, 1, 1, 1, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 1, 28, 28, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 28, 1, 1, 28, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 28, 28, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 28, 1, 29, 1, 1, 30, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 1, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 1, 34, 34, 34, + 34, 34, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 34, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 1, 1, + 1, 36, 37, 1, 1, 35, 35, 35, + 35, 35, 35, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 35, 35, 35, + 35, 35, 35, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 38, 1, 39, 39, 39, 39, 39, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 39, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 41, 1, 1, + 7, 7, 7, 7, 7, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 7, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 4, 1, 42, 42, + 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 42, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 43, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 44, 1, 42, 42, 42, 42, 42, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 1, 1, 1, 1, + 43, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 44, 1, + 47, 47, 47, 47, 47, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 47, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 48, 1, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 49, 46, 46, 50, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 51, 52, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 53, 46, 54, 54, 54, + 54, 54, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 54, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 55, + 1, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 56, 28, 28, 57, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 58, 59, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 60, 28, 61, 61, 61, 61, 61, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 62, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 63, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 64, 1, 65, + 65, 65, 65, 65, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 65, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 40, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 66, 1, 67, 67, 67, 67, + 67, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 67, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 48, 1, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 49, 46, 46, 50, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 51, + 52, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 53, + 46, 68, 68, 68, 68, 68, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 68, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 69, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 70, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 43, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 71, 1, 72, 72, + 72, 72, 72, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 72, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 73, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 74, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 75, 1, 72, 72, 72, 72, 72, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 72, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 73, 1, 1, + 1, 1, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 74, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 75, 1, + 68, 68, 68, 68, 68, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 68, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 69, 1, 1, 1, 1, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 1, 1, 1, 1, 1, 1, 70, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 71, 1, 77, 77, 77, + 77, 77, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 78, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 79, 1, 77, 77, 77, 77, 77, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 77, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 78, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 79, 1, 61, + 61, 61, 61, 61, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 61, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 62, 1, 1, 1, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 63, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 64, 1, 0 }; -static const signed char _deserialize_text_cond_targs[] = { - 0, 1, 2, 25, 3, 3, 4, 19, - 5, 6, 23, 24, 7, 8, 27, 36, - 8, 27, 36, 9, 30, 33, 10, 11, - 12, 15, 11, 12, 15, 13, 13, 14, - 31, 32, 14, 31, 32, 16, 26, 17, - 18, 34, 35, 18, 34, 35, 19, 20, - 19, 6, 21, 22, 20, 21, 22, 23, - 20, 21, 22, 24, 24, 25, 26, 26, - 7, 9, 10, 16, 21, 29, 26, 26, - 7, 9, 10, 21, 29, 27, 28, 17, - 21, 29, 28, 29, 29, 30, 28, 7, - 10, 29, 31, 28, 7, 21, 29, 32, - 33, 33, 34, 28, 21, 29, 35, 36, - 0 +static const char _deserialize_text_trans_targs[] = { + 1, 0, 2, 25, 3, 4, 19, 5, + 23, 24, 8, 27, 36, 27, 36, 30, + 33, 11, 12, 15, 12, 15, 13, 14, + 31, 32, 31, 32, 26, 18, 34, 35, + 34, 35, 20, 19, 6, 21, 22, 20, + 21, 22, 20, 21, 22, 24, 26, 26, + 7, 9, 10, 16, 21, 29, 26, 7, + 9, 10, 16, 21, 29, 28, 17, 21, + 29, 28, 29, 29, 28, 7, 10, 29, + 28, 7, 21, 29, 33, 28, 21, 29 }; -static const signed char _deserialize_text_cond_actions[] = { - 0, 0, 0, 0, 1, 0, 0, 2, - 0, 0, 2, 2, 0, 3, 4, 4, - 0, 5, 5, 0, 4, 4, 0, 3, - 3, 3, 0, 0, 0, 6, 0, 3, - 4, 4, 0, 5, 5, 0, 5, 0, - 3, 4, 4, 0, 5, 5, 7, 7, - 8, 9, 7, 7, 0, 0, 0, 10, - 10, 10, 10, 10, 8, 11, 12, 13, - 14, 14, 14, 15, 11, 11, 16, 17, - 18, 18, 18, 16, 16, 19, 19, 20, - 19, 19, 0, 0, 13, 10, 10, 21, - 21, 10, 22, 22, 23, 22, 22, 22, - 10, 5, 24, 24, 24, 24, 24, 19, - 0 +static const char _deserialize_text_trans_actions[] = { + 0, 0, 0, 0, 1, 0, 2, 0, + 2, 2, 3, 4, 4, 5, 5, 4, + 4, 3, 3, 3, 0, 0, 6, 3, + 4, 4, 5, 5, 5, 3, 4, 4, + 5, 5, 7, 8, 9, 7, 7, 0, + 0, 0, 10, 10, 10, 8, 12, 13, + 14, 14, 14, 15, 11, 11, 17, 18, + 18, 18, 0, 16, 16, 19, 20, 19, + 19, 0, 0, 13, 10, 21, 21, 10, + 22, 23, 22, 22, 5, 24, 24, 24 }; -static const signed char _deserialize_text_eof_trans[] = { - 1, 2, 3, 6, 7, 9, 10, 13, - 17, 20, 23, 27, 28, 31, 35, 29, - 38, 40, 44, 47, 53, 54, 55, 56, - 60, 62, 71, 78, 83, 70, 86, 91, - 96, 97, 99, 103, 104, 0 +static const char _deserialize_text_eof_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 10, + 10, 11, 16, 19, 0, 11, 10, 22, + 22, 10, 24, 24, 19 }; static const int deserialize_text_start = 1; @@ -182,583 +406,448 @@ static const int deserialize_text_en_main = 1; static hb_bool_t _hb_buffer_deserialize_text (hb_buffer_t *buffer, -const char *buf, -unsigned int buf_len, -const char **end_ptr, -hb_font_t *font) + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) { - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - - const char *eof = pe, *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 204 "hb-buffer-deserialize-text.hh" - { - cs = (int)deserialize_text_start; + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + + const char *eof = pe, *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 428 "hb-buffer-deserialize-text.hh" + { + cs = deserialize_text_start; } - -#line 209 "hb-buffer-deserialize-text.hh" - { - unsigned int _trans = 0; - const unsigned char * _keys; - const signed char * _inds; - int _ic; - _resume: {} - if ( p == pe && p != eof ) - goto _out; - if ( p == eof ) { - if ( _deserialize_text_eof_trans[cs] > 0 ) { - _trans = (unsigned int)_deserialize_text_eof_trans[cs] - 1; - } - } - else { - _keys = ( _deserialize_text_trans_keys + ((cs<<1))); - _inds = ( _deserialize_text_indicies + (_deserialize_text_index_offsets[cs])); - - if ( ( (*( p))) <= 124 && ( (*( p))) >= 9 ) { - _ic = (int)_deserialize_text_char_class[(int)( (*( p))) - 9]; - if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) - _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); - else - _trans = (unsigned int)_deserialize_text_index_defaults[cs]; - } - else { - _trans = (unsigned int)_deserialize_text_index_defaults[cs]; - } - - } - cs = (int)_deserialize_text_cond_targs[_trans]; - - if ( _deserialize_text_cond_actions[_trans] != 0 ) { - - switch ( _deserialize_text_cond_actions[_trans] ) { - case 1: { - { + +#line 433 "hb-buffer-deserialize-text.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_text_trans_keys + (cs<<1); + _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs]; + + _slen = _deserialize_text_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_text_trans_targs[_trans]; + + if ( _deserialize_text_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_text_trans_actions[_trans] ) { + case 1: #line 38 "hb-buffer-deserialize-text.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 252 "hb-buffer-deserialize-text.hh" - - - break; - } - case 3: { - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + break; + case 3: #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 264 "hb-buffer-deserialize-text.hh" - - - break; - } - case 5: { - { + { + tok = p; +} + break; + case 5: #line 55 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 274 "hb-buffer-deserialize-text.hh" - - - break; - } - case 8: { - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 8: #line 56 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_unicode ())) return false; } - -#line 284 "hb-buffer-deserialize-text.hh" - - - break; - } - case 18: { - { + { if (unlikely (!buffer->ensure_unicode ())) return false; } + break; + case 18: #line 58 "hb-buffer-deserialize-text.rl" - - /* TODO Unescape delimeters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 300 "hb-buffer-deserialize-text.hh" - - - break; - } - case 9: { - { + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 9: #line 66 "hb-buffer-deserialize-text.rl" - if (!parse_hex (tok, p, &info.codepoint )) return false; } - -#line 310 "hb-buffer-deserialize-text.hh" - - - break; - } - case 21: { - { + {if (!parse_hex (tok, p, &info.codepoint )) return false; } + break; + case 21: #line 68 "hb-buffer-deserialize-text.rl" - if (!parse_uint (tok, p, &info.cluster )) return false; } - -#line 320 "hb-buffer-deserialize-text.hh" - - - break; - } - case 6: { - { + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 6: #line 69 "hb-buffer-deserialize-text.rl" - if (!parse_int (tok, p, &pos.x_offset )) return false; } - -#line 330 "hb-buffer-deserialize-text.hh" - - - break; - } - case 23: { - { + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 23: #line 70 "hb-buffer-deserialize-text.rl" - if (!parse_int (tok, p, &pos.y_offset )) return false; } - -#line 340 "hb-buffer-deserialize-text.hh" - - - break; - } - case 20: { - { + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 20: #line 71 "hb-buffer-deserialize-text.rl" - if (!parse_int (tok, p, &pos.x_advance)) return false; } - -#line 350 "hb-buffer-deserialize-text.hh" - - - break; - } - case 15: { - { + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 15: #line 38 "hb-buffer-deserialize-text.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 363 "hb-buffer-deserialize-text.hh" - - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 371 "hb-buffer-deserialize-text.hh" - - - break; - } - case 4: { - { + { + tok = p; +} + break; + case 4: #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 383 "hb-buffer-deserialize-text.hh" - - { + { + tok = p; +} #line 55 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 389 "hb-buffer-deserialize-text.hh" - - - break; - } - case 2: { - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 2: #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 401 "hb-buffer-deserialize-text.hh" - - { + { + tok = p; +} #line 56 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_unicode ())) return false; } - -#line 407 "hb-buffer-deserialize-text.hh" - - - break; - } - case 16: { - { + { if (unlikely (!buffer->ensure_unicode ())) return false; } + break; + case 16: #line 58 "hb-buffer-deserialize-text.rl" - - /* TODO Unescape delimeters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 423 "hb-buffer-deserialize-text.hh" - - { + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 435 "hb-buffer-deserialize-text.hh" - - - break; - } - case 7: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 7: #line 66 "hb-buffer-deserialize-text.rl" - if (!parse_hex (tok, p, &info.codepoint )) return false; } - -#line 445 "hb-buffer-deserialize-text.hh" - - { + {if (!parse_hex (tok, p, &info.codepoint )) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 457 "hb-buffer-deserialize-text.hh" - - - break; - } - case 10: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 10: #line 68 "hb-buffer-deserialize-text.rl" - if (!parse_uint (tok, p, &info.cluster )) return false; } - -#line 467 "hb-buffer-deserialize-text.hh" - - { + { if (!parse_uint (tok, p, &info.cluster )) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 479 "hb-buffer-deserialize-text.hh" - - - break; - } - case 22: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 22: #line 70 "hb-buffer-deserialize-text.rl" - if (!parse_int (tok, p, &pos.y_offset )) return false; } - -#line 489 "hb-buffer-deserialize-text.hh" - - { + { if (!parse_int (tok, p, &pos.y_offset )) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 501 "hb-buffer-deserialize-text.hh" - - - break; - } - case 19: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 19: #line 71 "hb-buffer-deserialize-text.rl" - if (!parse_int (tok, p, &pos.x_advance)) return false; } - -#line 511 "hb-buffer-deserialize-text.hh" - - { + { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 523 "hb-buffer-deserialize-text.hh" - - - break; - } - case 24: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 24: #line 72 "hb-buffer-deserialize-text.rl" - if (!parse_int (tok, p, &pos.y_advance)) return false; } - -#line 533 "hb-buffer-deserialize-text.hh" - - { + { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 545 "hb-buffer-deserialize-text.hh" - - - break; - } - case 12: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 12: #line 38 "hb-buffer-deserialize-text.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 558 "hb-buffer-deserialize-text.hh" - - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 566 "hb-buffer-deserialize-text.hh" - - { + { + tok = p; +} #line 55 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 572 "hb-buffer-deserialize-text.hh" - - - break; - } - case 14: { - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 14: #line 38 "hb-buffer-deserialize-text.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 585 "hb-buffer-deserialize-text.hh" - - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 593 "hb-buffer-deserialize-text.hh" - - { + { + tok = p; +} #line 58 "hb-buffer-deserialize-text.rl" - - /* TODO Unescape delimeters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 605 "hb-buffer-deserialize-text.hh" - - - break; - } - case 17: { - { + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 17: #line 58 "hb-buffer-deserialize-text.rl" - - /* TODO Unescape delimeters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 621 "hb-buffer-deserialize-text.hh" - - { + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} #line 55 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 627 "hb-buffer-deserialize-text.hh" - - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 639 "hb-buffer-deserialize-text.hh" - - - break; - } - case 11: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: #line 38 "hb-buffer-deserialize-text.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 652 "hb-buffer-deserialize-text.hh" - - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 660 "hb-buffer-deserialize-text.hh" - - { + { + tok = p; +} #line 58 "hb-buffer-deserialize-text.rl" - - /* TODO Unescape delimeters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 672 "hb-buffer-deserialize-text.hh" - - { + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 684 "hb-buffer-deserialize-text.hh" - - - break; - } - case 13: { - { + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 13: #line 38 "hb-buffer-deserialize-text.rl" - - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - -#line 697 "hb-buffer-deserialize-text.hh" - - { + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} #line 51 "hb-buffer-deserialize-text.rl" - - tok = p; - } - -#line 705 "hb-buffer-deserialize-text.hh" - - { + { + tok = p; +} #line 58 "hb-buffer-deserialize-text.rl" - - /* TODO Unescape delimeters. */ - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } - -#line 717 "hb-buffer-deserialize-text.hh" - - { + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} #line 55 "hb-buffer-deserialize-text.rl" - if (unlikely (!buffer->ensure_glyphs ())) return false; } - -#line 723 "hb-buffer-deserialize-text.hh" - - { + { if (unlikely (!buffer->ensure_glyphs ())) return false; } #line 43 "hb-buffer-deserialize-text.rl" - - buffer->add_info (info); - if (unlikely (!buffer->successful)) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; - } - -#line 735 "hb-buffer-deserialize-text.hh" - - - break; - } - } - - } - - if ( p == eof ) { - if ( cs >= 19 ) - goto _out; - } - else { - if ( cs != 0 ) { - p += 1; - goto _resume; - } - } - _out: {} + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 722 "hb-buffer-deserialize-text.hh" } - -#line 138 "hb-buffer-deserialize-text.rl" - - + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + switch ( _deserialize_text_eof_actions[cs] ) { + case 16: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 7: +#line 66 "hb-buffer-deserialize-text.rl" + {if (!parse_hex (tok, p, &info.codepoint )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 10: +#line 68 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 22: +#line 70 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 19: +#line 71 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 24: +#line 72 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 38 "hb-buffer-deserialize-text.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text.rl" + { + tok = p; +} +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimeters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; *end_ptr = p; - - return p == pe && *(p-1) != ']'; +} + break; +#line 839 "hb-buffer-deserialize-text.hh" + } + } + + _out: {} + } + +#line 138 "hb-buffer-deserialize-text.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; } #endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc index f65bad45bb..6539b89640 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc @@ -400,8 +400,8 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf. - * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @font: (nullable): the #hb_font_t used to shape this buffer, needed to * read glyph names and extents. If %NULL, and empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties @@ -514,8 +514,10 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf. + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. + * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties + * to serialize. * * Serializes @buffer into a textual representation of its content, * when the buffer contains Unicode codepoints (i.e., before shaping). This is @@ -635,8 +637,8 @@ _hb_buffer_serialize_invalid (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf. - * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to + * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of byes written into @buf. + * @font: (nullable): the #hb_font_t used to shape this buffer, needed to * read glyph names and extents. If %NULL, and empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties @@ -724,15 +726,17 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) /** * hb_buffer_deserialize_glyphs: * @buffer: an #hb_buffer_t buffer. - * @buf: (array length=buf_len): - * @buf_len: - * @end_ptr: (out): - * @font: - * @format: - * + * @buf: (array length=buf_len): string to deserialize + * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @end_ptr: (out) (optional): output pointer to the character after last + * consumed one. + * @font: (nullable): font for getting glyph IDs + * @format: the #hb_buffer_serialize_format_t of the input @buf * + * Deserializes glyphs @buffer from textual representation in the format + * produced by hb_buffer_serialize_glyphs(). * - * Return value: + * Return value: %true if @buf is not fully consumed, %false otherwise. * * Since: 0.9.7 **/ @@ -795,14 +799,16 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, /** * hb_buffer_deserialize_unicode: * @buffer: an #hb_buffer_t buffer. - * @buf: (array length=buf_len): - * @buf_len: - * @end_ptr: (out): - * @format: - * + * @buf: (array length=buf_len): string to deserialize + * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @end_ptr: (out) (optional): output pointer to the character after last + * consumed one. + * @format: the #hb_buffer_serialize_format_t of the input @buf * + * Deserializes Unicode @buffer from textual representation in the format + * produced by hb_buffer_serialize_unicode(). * - * Return value: + * Return value: %true if @buf is not fully consumed, %false otherwise. * * Since: 2.7.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index 10063db050..c6591ca230 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -96,14 +96,15 @@ hb_segment_properties_hash (const hb_segment_properties_t *p) * As an optimization, both info and out_info may point to the * same piece of memory, which is owned by info. This remains the * case as long as out_len doesn't exceed i at any time. - * In that case, swap_buffers() is no-op and the glyph operations operate - * mostly in-place. + * In that case, swap_buffers() is mostly no-op and the glyph operations + * operate mostly in-place. * * As soon as out_info gets longer than info, out_info is moved over - * to an alternate buffer (which we reuse the pos buffer for!), and its + * to an alternate buffer (which we reuse the pos buffer for), and its * current contents (out_len entries) are copied to the new place. + * * This should all remain transparent to the user. swap_buffers() then - * switches info and out_info. + * switches info over to out_info and does housekeeping. */ @@ -136,8 +137,8 @@ hb_buffer_t::enlarge (unsigned int size) if (unlikely (hb_unsigned_mul_overflows (new_allocated, sizeof (info[0])))) goto done; - new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0])); - new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0])); + new_pos = (hb_glyph_position_t *) hb_realloc (pos, new_allocated * sizeof (pos[0])); + new_info = (hb_glyph_info_t *) hb_realloc (info, new_allocated * sizeof (info[0])); done: if (unlikely (!new_pos || !new_info)) @@ -218,9 +219,6 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size) void hb_buffer_t::reset () { - if (unlikely (hb_object_is_immutable (this))) - return; - hb_unicode_funcs_destroy (unicode); unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ()); flags = HB_BUFFER_FLAG_DEFAULT; @@ -233,9 +231,6 @@ hb_buffer_t::reset () void hb_buffer_t::clear () { - if (unlikely (hb_object_is_immutable (this))) - return; - hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; props = default_props; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; @@ -288,27 +283,12 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) void -hb_buffer_t::remove_output () -{ - if (unlikely (hb_object_is_immutable (this))) - return; - - have_output = false; - have_positions = false; - - out_len = 0; - out_info = info; -} - -void hb_buffer_t::clear_output () { - if (unlikely (hb_object_is_immutable (this))) - return; - have_output = true; have_positions = false; + idx = 0; out_len = 0; out_info = info; } @@ -316,9 +296,6 @@ hb_buffer_t::clear_output () void hb_buffer_t::clear_positions () { - if (unlikely (hb_object_is_immutable (this))) - return; - have_output = false; have_positions = true; @@ -331,53 +308,26 @@ hb_buffer_t::clear_positions () void hb_buffer_t::swap_buffers () { - if (unlikely (!successful)) return; - assert (have_output); - have_output = false; + + assert (idx <= len); + + if (unlikely (!successful || !next_glyphs (len - idx))) + goto reset; if (out_info != info) { - hb_glyph_info_t *tmp_string; - tmp_string = info; + pos = (hb_glyph_position_t *) info; info = out_info; - out_info = tmp_string; - pos = (hb_glyph_position_t *) out_info; } - - unsigned int tmp; - tmp = len; len = out_len; - out_len = tmp; +reset: + have_output = false; + out_len = 0; idx = 0; } - -void -hb_buffer_t::replace_glyphs (unsigned int num_in, - unsigned int num_out, - const uint32_t *glyph_data) -{ - if (unlikely (!make_room_for (num_in, num_out))) return; - - assert (idx + num_in <= len); - - merge_clusters (idx, idx + num_in); - - hb_glyph_info_t orig_info = info[idx]; - hb_glyph_info_t *pinfo = &out_info[out_len]; - for (unsigned int i = 0; i < num_out; i++) - { - *pinfo = orig_info; - pinfo->codepoint = glyph_data[i]; - pinfo++; - } - - idx += num_in; - out_len += num_out; -} - bool hb_buffer_t::move_to (unsigned int i) { @@ -409,12 +359,11 @@ hb_buffer_t::move_to (unsigned int i) /* This will blow in our face if memory allocation fails later * in this same lookup... * - * We used to shift with extra 32 items, instead of the 0 below. + * We used to shift with extra 32 items. * But that would leave empty slots in the buffer in case of allocation - * failures. Setting to zero for now to avoid other problems (see - * comments in shift_forward(). This can cause O(N^2) behavior more - * severely than adding 32 empty slots can... */ - if (unlikely (idx < count && !shift_forward (count + 0))) return false; + * failures. See comments in shift_forward(). This can cause O(N^2) + * behavior more severely than adding 32 empty slots can... */ + if (unlikely (idx < count && !shift_forward (count - idx))) return false; assert (idx >= count); @@ -666,7 +615,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_BUFFER_CONTENT_TYPE_INVALID, HB_SEGMENT_PROPERTIES_DEFAULT, false, /* successful */ - true, /* have_output */ + false, /* have_output */ true /* have_positions */ /* Zero is good enough for everything else. */ @@ -753,14 +702,14 @@ hb_buffer_destroy (hb_buffer_t *buffer) hb_unicode_funcs_destroy (buffer->unicode); - free (buffer->info); - free (buffer->pos); + hb_free (buffer->info); + hb_free (buffer->pos); #ifndef HB_NO_BUFFER_MESSAGE if (buffer->message_destroy) buffer->message_destroy (buffer->message_data); #endif - free (buffer); + hb_free (buffer); } /** @@ -768,7 +717,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * @buffer: An #hb_buffer_t * @key: The user-data key * @data: A pointer to the user data - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified buffer. @@ -795,7 +744,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, * Fetches the user data associated with the specified key, * attached to the specified buffer. * - * Return value: (transfer-none): A pointer to the user data + * Return value: (transfer none): A pointer to the user data * * Since: 0.9.2 **/ @@ -1137,7 +1086,7 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer) * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding * when adding text to @buffer. * - * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT. + * Default is #HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT. * * Since: 0.9.31 **/ @@ -1222,6 +1171,9 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer) void hb_buffer_reset (hb_buffer_t *buffer) { + if (unlikely (hb_object_is_immutable (buffer))) + return; + buffer->reset (); } @@ -1237,6 +1189,9 @@ hb_buffer_reset (hb_buffer_t *buffer) void hb_buffer_clear_contents (hb_buffer_t *buffer) { + if (unlikely (hb_object_is_immutable (buffer))) + return; + buffer->clear (); } @@ -1321,7 +1276,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, if (unlikely (hb_object_is_immutable (buffer))) return length == 0; - if (!buffer->ensure (length)) + if (unlikely (!buffer->ensure (length))) return false; /* Wipe the new space */ @@ -1393,6 +1348,11 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, * Returns @buffer glyph position array. Returned pointer * is valid as long as @buffer contents are not modified. * + * If buffer did not have positions before, the positions will be + * initialized to zeros, unless this function is called from + * within a buffer message callback (see hb_buffer_set_message_func()), + * in which case %NULL is returned. + * * Return value: (transfer none) (array length=length): * The @buffer glyph position array. * The value valid as long as buffer has not been modified. @@ -1403,12 +1363,17 @@ hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer, unsigned int *length) { - if (!buffer->have_positions) - buffer->clear_positions (); - if (length) *length = buffer->len; + if (!buffer->have_positions) + { + if (unlikely (buffer->message_depth)) + return nullptr; + + buffer->clear_positions (); + } + return (hb_glyph_position_t *) buffer->pos; } @@ -1501,20 +1466,20 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) * * Sets unset buffer segment properties based on buffer Unicode * contents. If buffer is not empty, it must have content type - * %HB_BUFFER_CONTENT_TYPE_UNICODE. + * #HB_BUFFER_CONTENT_TYPE_UNICODE. * - * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it + * If buffer script is not set (ie. is #HB_SCRIPT_INVALID), it * will be set to the Unicode script of the first character in - * the buffer that has a script other than %HB_SCRIPT_COMMON, - * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN. + * the buffer that has a script other than #HB_SCRIPT_COMMON, + * #HB_SCRIPT_INHERITED, and #HB_SCRIPT_UNKNOWN. * - * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID), + * Next, if buffer direction is not set (ie. is #HB_DIRECTION_INVALID), * it will be set to the natural horizontal direction of the * buffer script as returned by hb_script_get_horizontal_direction(). - * If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID, - * then %HB_DIRECTION_LTR is used. + * If hb_script_get_horizontal_direction() returns #HB_DIRECTION_INVALID, + * then #HB_DIRECTION_LTR is used. * - * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID), + * Finally, if buffer language is not set (ie. is #HB_LANGUAGE_INVALID), * it will be set to the process's default language as returned by * hb_language_get_default(). This may change in the future by * taking buffer script into consideration when choosing a language. @@ -1551,7 +1516,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer, if (item_length == -1) item_length = text_length - item_offset; - buffer->ensure (buffer->len + item_length * sizeof (T) / 4); + if (unlikely (item_length < 0 || + item_length > INT_MAX / 8 || + !buffer->ensure (buffer->len + item_length * sizeof (T) / 4))) + return; /* If buffer is empty and pre-context provided, install it. * This check is written this way, to make sure people can @@ -1768,11 +1736,6 @@ hb_buffer_append (hb_buffer_t *buffer, if (start == end) return; - if (!buffer->len) - buffer->content_type = source->content_type; - if (!buffer->have_positions && source->have_positions) - buffer->clear_positions (); - if (buffer->len + (end - start) < buffer->len) /* Overflows. */ { buffer->successful = false; @@ -1784,9 +1747,36 @@ hb_buffer_append (hb_buffer_t *buffer, if (unlikely (!buffer->successful)) return; + if (!orig_len) + buffer->content_type = source->content_type; + if (!buffer->have_positions && source->have_positions) + buffer->clear_positions (); + memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0])); if (buffer->have_positions) memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0])); + + if (source->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) + { + /* See similar logic in add_utf. */ + + /* pre-context */ + if (!orig_len && start + source->context_len[0] > 0) + { + buffer->clear_context (0); + while (start > 0 && buffer->context_len[0] < buffer->CONTEXT_LENGTH) + buffer->context[0][buffer->context_len[0]++] = source->info[--start].codepoint; + for (auto i = 0u; i < source->context_len[0] && buffer->context_len[0] < buffer->CONTEXT_LENGTH; i++) + buffer->context[0][buffer->context_len[0]++] = source->context[0][i]; + } + + /* post-context */ + buffer->clear_context (1); + while (end < source->len && buffer->context_len[1] < buffer->CONTEXT_LENGTH) + buffer->context[1][buffer->context_len[1]++] = source->info[end++].codepoint; + for (auto i = 0u; i < source->context_len[1] && buffer->context_len[1] < buffer->CONTEXT_LENGTH; i++) + buffer->context[1][buffer->context_len[1]++] = source->context[1][i]; + } } @@ -1902,8 +1892,8 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1. * @position_fuzz: allowed absolute difference in position values. * - * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT - * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most + * If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT + * and #HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most * callers if just comparing two buffers is needed. * * Since: 1.5.0 @@ -1994,11 +1984,11 @@ hb_buffer_diff (hb_buffer_t *buffer, /** * hb_buffer_set_message_func: * @buffer: An #hb_buffer_t - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @func: (closure user_data) (destroy destroy) (scope notified): Callback function + * @user_data: (nullable): Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_buffer_message_func_t. * * Since: 1.1.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h index b13757e68f..865ccb2273 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.h +++ b/thirdparty/harfbuzz/src/hb-buffer.h @@ -27,7 +27,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -90,6 +90,8 @@ typedef struct hb_glyph_info_t { * breaking point only. * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags. * + * Flags for #hb_glyph_info_t. + * * Since: 1.5.0 */ typedef enum { /*< flags >*/ @@ -150,6 +152,11 @@ typedef struct hb_segment_properties_t { void *reserved2; } hb_segment_properties_t; +/** + * HB_SEGMENT_PROPERTIES_DEFAULT: + * + * The default #hb_segment_properties_t of of freshly created #hb_buffer_t. + */ #define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \ HB_SCRIPT_INVALID, \ HB_LANGUAGE_INVALID, \ @@ -203,6 +210,8 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. * @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping). * @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping). + * + * The type of #hb_buffer_t contents. */ typedef enum { HB_BUFFER_CONTENT_TYPE_INVALID = 0, @@ -288,6 +297,8 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer); * not be inserted in the rendering of incorrect * character sequences (such at <0905 093E>). Since: 2.4 * + * Flags for #hb_buffer_t. + * * Since: 0.9.20 */ typedef enum { /*< flags >*/ @@ -579,6 +590,35 @@ hb_buffer_deserialize_unicode (hb_buffer_t *buffer, * Compare buffers */ +/** + * hb_buffer_diff_flags_t: + * @HB_BUFFER_DIFF_FLAG_EQUAL: equal buffers. + * @HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH: buffers with different + * #hb_buffer_content_type_t. + * @HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH: buffers with differing length. + * @HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT: `.notdef` glyph is present in the + * reference buffer. + * @HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT: dotted circle glyph is present + * in the reference buffer. + * @HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH: difference in #hb_glyph_info_t.codepoint + * @HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH: difference in #hb_glyph_info_t.cluster + * @HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH: difference in #hb_glyph_flags_t. + * @HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH: difference in #hb_glyph_position_t. + * + * Flags from comparing two #hb_buffer_t's. + * + * Buffer with different #hb_buffer_content_type_t cannot be meaningfully + * compared in any further detail. + * + * For buffers with differing length, the per-glyph comparison is not + * attempted, though we do still scan reference buffer for dotted circle and + * `.notdef` glyphs. + * + * If the buffers have the same length, we compare them glyph-by-glyph and + * report which aspect(s) of the glyph info/position are different. + * + * Since: 1.5.0 + */ typedef enum { /*< flags >*/ HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000, @@ -618,6 +658,23 @@ hb_buffer_diff (hb_buffer_t *buffer, * Debugging. */ +/** + * hb_buffer_message_func_t: + * @buffer: An #hb_buffer_t to work upon + * @font: The #hb_font_t the @buffer is shaped with + * @message: %NULL-terminated message passed to the function + * @user_data: User data pointer passed by the caller + * + * A callback method for #hb_buffer_t. The method gets called with the + * #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a + * message describing what step of the shaping process will be performed. + * Returning %false from this method will skip this shaping step and move to + * the next one. + * + * Return value: %true to perform the shaping step, %false to skip it. + * + * Since: 1.1.3 + */ typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer, hb_font_t *font, const char *message, diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh index 9cad5206e2..8635ebd35f 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -107,7 +107,7 @@ struct hb_buffer_t unsigned int idx; /* Cursor into ->info and ->pos arrays */ unsigned int len; /* Length of ->info and ->pos arrays */ - unsigned int out_len; /* Length of ->out array if have_output */ + unsigned int out_len; /* Length of ->out_info array if have_output */ unsigned int allocated; /* Length of allocated arrays */ hb_glyph_info_t *info; @@ -128,6 +128,9 @@ struct hb_buffer_t hb_buffer_message_func_t message_func; void *message_data; hb_destroy_func_t message_destroy; + unsigned message_depth; /* How deeply are we inside a message callback? */ +#else + static constexpr unsigned message_depth = 0u; #endif /* Internal debugging. */ @@ -139,7 +142,7 @@ struct hb_buffer_t /* Methods */ - bool in_error () const { return !successful; } + HB_NODISCARD bool in_error () const { return !successful; } void allocate_var (unsigned int start, unsigned int count) { @@ -186,13 +189,10 @@ struct hb_buffer_t hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } - bool has_separate_output () const { return info != out_info; } - - HB_INTERNAL void reset (); HB_INTERNAL void clear (); - unsigned int backtrack_len () const { return have_output? out_len : idx; } + unsigned int backtrack_len () const { return have_output ? out_len : idx; } unsigned int lookahead_len () const { return len - idx; } unsigned int next_serial () { return serial++; } @@ -206,90 +206,92 @@ struct hb_buffer_t HB_INTERNAL void guess_segment_properties (); HB_INTERNAL void swap_buffers (); - HB_INTERNAL void remove_output (); HB_INTERNAL void clear_output (); HB_INTERNAL void clear_positions (); - HB_INTERNAL void replace_glyphs (unsigned int num_in, - unsigned int num_out, - const hb_codepoint_t *glyph_data); - - void replace_glyph (hb_codepoint_t glyph_index) + template <typename T> + HB_NODISCARD bool replace_glyphs (unsigned int num_in, + unsigned int num_out, + const T *glyph_data) { - if (unlikely (out_info != info || out_len != idx)) { - if (unlikely (!make_room_for (1, 1))) return; - out_info[out_len] = info[idx]; - } - out_info[out_len].codepoint = glyph_index; + if (unlikely (!make_room_for (num_in, num_out))) return false; - idx++; - out_len++; - } - /* Makes a copy of the glyph at idx to output and replace glyph_index */ - hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index) - { - if (unlikely (!make_room_for (0, 1))) return Crap (hb_glyph_info_t); + assert (idx + num_in <= len); - if (unlikely (idx == len && !out_len)) - return Crap (hb_glyph_info_t); + merge_clusters (idx, idx + num_in); - out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1]; - out_info[out_len].codepoint = glyph_index; + hb_glyph_info_t &orig_info = idx < len ? cur() : prev(); - out_len++; + hb_glyph_info_t *pinfo = &out_info[out_len]; + for (unsigned int i = 0; i < num_out; i++) + { + *pinfo = orig_info; + pinfo->codepoint = glyph_data[i]; + pinfo++; + } - return out_info[out_len - 1]; + idx += num_in; + out_len += num_out; + return true; } - void output_info (const hb_glyph_info_t &glyph_info) + + HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index) + { return replace_glyphs (1, 1, &glyph_index); } + + /* Makes a copy of the glyph at idx to output and replace glyph_index */ + HB_NODISCARD bool output_glyph (hb_codepoint_t glyph_index) + { return replace_glyphs (0, 1, &glyph_index); } + + HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info) { - if (unlikely (!make_room_for (0, 1))) return; + if (unlikely (!make_room_for (0, 1))) return false; out_info[out_len] = glyph_info; out_len++; + return true; } /* Copies glyph at idx to output but doesn't advance idx */ - void copy_glyph () + HB_NODISCARD bool copy_glyph () { - if (unlikely (!make_room_for (0, 1))) return; - - out_info[out_len] = info[idx]; - - out_len++; + /* Extra copy because cur()'s return can be freed within + * output_info() call if buffer reallocates. */ + return output_info (hb_glyph_info_t (cur())); } + /* Copies glyph at idx to output and advance idx. * If there's no output, just advance idx. */ - void - next_glyph () + HB_NODISCARD bool next_glyph () { if (have_output) { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (1, 1))) return; + if (unlikely (!make_room_for (1, 1))) return false; out_info[out_len] = info[idx]; } out_len++; } idx++; + return true; } /* Copies n glyphs at idx to output and advance idx. * If there's no output, just advance idx. */ - void - next_glyphs (unsigned int n) + HB_NODISCARD bool next_glyphs (unsigned int n) { if (have_output) { if (out_info != info || out_len != idx) { - if (unlikely (!make_room_for (n, n))) return; + if (unlikely (!make_room_for (n, n))) return false; memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); } out_len += n; } idx += n; + return true; } /* Advance idx without copying to output. */ void skip_glyph () { idx++; } @@ -329,14 +331,14 @@ struct hb_buffer_t /* Internal methods */ - HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ + HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ - HB_INTERNAL bool enlarge (unsigned int size); + HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size); - bool ensure (unsigned int size) + HB_NODISCARD bool ensure (unsigned int size) { return likely (!size || size < allocated) ? true : enlarge (size); } - bool ensure_inplace (unsigned int size) + HB_NODISCARD bool ensure_inplace (unsigned int size) { return likely (!size || size < allocated); } void assert_glyphs () @@ -349,7 +351,7 @@ struct hb_buffer_t assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) || (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID))); } - bool ensure_glyphs () + HB_NODISCARD bool ensure_glyphs () { if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS)) { @@ -360,7 +362,7 @@ struct hb_buffer_t } return true; } - bool ensure_unicode () + HB_NODISCARD bool ensure_unicode () { if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE)) { @@ -372,8 +374,8 @@ struct hb_buffer_t return true; } - HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); - HB_INTERNAL bool shift_forward (unsigned int count); + HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); + HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count); typedef long scratch_buffer_t; HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); @@ -397,10 +399,16 @@ struct hb_buffer_t #else if (!messaging ()) return true; + + message_depth++; + va_list ap; va_start (ap, fmt); bool ret = message_impl (font, fmt, ap); va_end (ap); + + message_depth--; + return ret; #endif } diff --git a/thirdparty/harfbuzz/src/hb-cache.hh b/thirdparty/harfbuzz/src/hb-cache.hh index bf26d96be4..e617b75de9 100644 --- a/thirdparty/harfbuzz/src/hb-cache.hh +++ b/thirdparty/harfbuzz/src/hb-cache.hh @@ -30,7 +30,7 @@ #include "hb.hh" -/* Implements a lock-free cache for int->int functions. */ +/* Implements a lockfree cache for int->int functions. */ template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits> struct hb_cache_t diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh index 91a9b7d0d1..c251e2d0ed 100644 --- a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh +++ b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh @@ -263,7 +263,7 @@ struct UnsizedByteStr : UnsizedArrayOf <HBUINT8> T *ip = c->allocate_size<T> (T::static_size); if (unlikely (!ip)) return_trace (false); - return_trace (c->check_assign (*ip, value)); + return_trace (c->check_assign (*ip, value, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } template <typename V> diff --git a/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh b/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh index 332ece31cd..d961566447 100644 --- a/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh +++ b/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh @@ -136,8 +136,8 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs> if (unlikely (!scalars.resize (region_count))) set_error (); else - varStore->varStore.get_scalars (get_ivs (), coords, num_coords, - &scalars[0], region_count); + varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords, + &scalars[0], region_count); } seen_blend = true; } diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index ddbcaa064c..26c8ad0f49 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -257,13 +257,11 @@ struct hb_language_item_t { bool operator == (const char *s) const { return lang_equal (lang, s); } - hb_language_item_t & operator = (const char *s) { - /* If a custom allocated is used calling strdup() pairs - badly with a call to the custom free() in fini() below. - Therefore don't call strdup(), implement its behavior. - */ + hb_language_item_t & operator = (const char *s) + { + /* We can't call strdup(), because we allow custom allocators. */ size_t len = strlen(s) + 1; - lang = (hb_language_t) malloc(len); + lang = (hb_language_t) hb_malloc(len); if (likely (lang)) { memcpy((unsigned char *) lang, s, len); @@ -274,16 +272,15 @@ struct hb_language_item_t { return *this; } - void fini () { free ((void *) lang); } + void fini () { hb_free ((void *) lang); } }; -/* Thread-safe lock-free language list */ +/* Thread-safe lockfree language list */ static hb_atomic_ptr_t <hb_language_item_t> langs; -#if HB_USE_ATEXIT -static void +static inline void free_langs () { retry: @@ -294,11 +291,10 @@ retry: while (first_lang) { hb_language_item_t *next = first_lang->next; first_lang->fini (); - free (first_lang); + hb_free (first_lang); first_lang = next; } } -#endif static hb_language_item_t * lang_find_or_insert (const char *key) @@ -311,28 +307,26 @@ retry: return lang; /* Not found; allocate one. */ - hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t)); + hb_language_item_t *lang = (hb_language_item_t *) hb_calloc (1, sizeof (hb_language_item_t)); if (unlikely (!lang)) return nullptr; lang->next = first_lang; *lang = key; if (unlikely (!lang->lang)) { - free (lang); + hb_free (lang); return nullptr; } if (unlikely (!langs.cmpexch (first_lang, lang))) { lang->fini (); - free (lang); + hb_free (lang); goto retry; } -#if HB_USE_ATEXIT if (!first_lang) - atexit (free_langs); /* First person registers atexit() callback. */ -#endif + hb_atexit (free_langs); /* First person registers atexit() callback. */ return lang; } @@ -601,6 +595,9 @@ hb_script_get_horizontal_direction (hb_script_t script) case HB_SCRIPT_CHORASMIAN: case HB_SCRIPT_YEZIDI: + /* Unicode-14.0 additions */ + case HB_SCRIPT_OLD_UYGHUR: + return HB_DIRECTION_RTL; @@ -675,8 +672,8 @@ hb_version_string () * Tests the library version against a minimum value, * as three integer components. * - * Return value: True if the library is equal to or greater than - * the test value, false otherwise + * Return value: %true if the library is equal to or greater than + * the test value, %false otherwise * * Since: 0.9.30 **/ @@ -1003,6 +1000,21 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation /** * hb_variation_from_string: + * @str: (array length=len) (element-type uint8_t): a string to parse + * @len: length of @str, or -1 if string is %NULL terminated + * @variation: (out): the #hb_variation_t to initialize with the parsed values + * + * Parses a string into a #hb_variation_t. + * + * The format for specifying variation settings follows. All valid CSS + * font-variation-settings values other than 'normal' and 'inherited' are also + * accepted, though, not documented below. + * + * The format is a tag, optionally followed by an equals sign, followed by a + * number. For example `wght=500`, or `slnt=-7.5`. + * + * Return value: + * %true if @str is successfully parsed, %false otherwise * * Since: 1.4.2 */ @@ -1029,6 +1041,13 @@ hb_variation_from_string (const char *str, int len, /** * hb_variation_to_string: + * @variation: an #hb_variation_t to convert + * @buf: (array length=size) (out): output string + * @size: the allocated size of @buf + * + * Converts an #hb_variation_t into a %NULL-terminated string in the format + * understood by hb_variation_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. * * Since: 1.4.2 */ @@ -1055,9 +1074,11 @@ hb_variation_to_string (hb_variation_t *variation, /** * hb_color_get_alpha: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. + * + * Fetches the alpha channel of the given @color. * - * Return value: Alpha channel value of the given color + * Return value: Alpha channel value * * Since: 2.1.0 */ @@ -1069,9 +1090,11 @@ uint8_t /** * hb_color_get_red: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. + * + * Fetches the red channel of the given @color. * - * Return value: Red channel value of the given color + * Return value: Red channel value * * Since: 2.1.0 */ @@ -1083,9 +1106,11 @@ uint8_t /** * hb_color_get_green: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. * - * Return value: Green channel value of the given color + * Fetches the green channel of the given @color. + * + * Return value: Green channel value * * Since: 2.1.0 */ @@ -1097,9 +1122,11 @@ uint8_t /** * hb_color_get_blue: - * color: a #hb_color_t we are interested in its channels. + * @color: an #hb_color_t we are interested in its channels. + * + * Fetches the blue channel of the given @color. * - * Return value: Blue channel value of the given color + * Return value: Blue channel value * * Since: 2.1.0 */ diff --git a/thirdparty/harfbuzz/src/hb-common.h b/thirdparty/harfbuzz/src/hb-common.h index efe185cdfd..0384117a4d 100644 --- a/thirdparty/harfbuzz/src/hb-common.h +++ b/thirdparty/harfbuzz/src/hb-common.h @@ -26,7 +26,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -135,7 +135,7 @@ typedef union _hb_var_int_t { /** * hb_tag_t: - * + * * Data type for tag identifiers. Tags are four * byte integers, each byte representing a character. * @@ -148,22 +148,48 @@ typedef uint32_t hb_tag_t; /** * HB_TAG: + * @c1: 1st character of the tag + * @c2: 2nd character of the tag + * @c3: 3rd character of the tag + * @c4: 4th character of the tag * - * Constructs an #hb_tag_t from four characters. + * Constructs an #hb_tag_t from four character literals. * **/ #define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF))) /** * HB_UNTAG: + * @tag: an #hb_tag_t + * + * Extracts four character literals from an #hb_tag_t. * - * Extracts the characters from an #hb_tag_t. + * Since: 0.6.0 * **/ #define HB_UNTAG(tag) (uint8_t)(((tag)>>24)&0xFF), (uint8_t)(((tag)>>16)&0xFF), (uint8_t)(((tag)>>8)&0xFF), (uint8_t)((tag)&0xFF) +/** + * HB_TAG_NONE: + * + * Unset #hb_tag_t. + */ #define HB_TAG_NONE HB_TAG(0,0,0,0) +/** + * HB_TAG_MAX: + * + * Maximum possible unsigned #hb_tag_t. + * + * Since: 0.9.26 + */ #define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff) +/** + * HB_TAG_MAX_SIGNED: + * + * Maximum possible signed #hb_tag_t. + * + * Since: 0.9.33 + */ #define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff) /* len=-1 means str is NUL-terminated. */ @@ -263,6 +289,13 @@ hb_direction_to_string (hb_direction_t direction); /* hb_language_t */ +/** + * hb_language_t: + * + * Data type for languages. Each #hb_language_t corresponds to a BCP 47 + * language tag. + * + */ typedef const struct hb_language_impl_t *hb_language_t; HB_EXTERN hb_language_t @@ -271,6 +304,13 @@ hb_language_from_string (const char *str, int len); HB_EXTERN const char * hb_language_to_string (hb_language_t language); +/** + * HB_LANGUAGE_INVALID: + * + * An unset #hb_language_t. + * + * Since: 0.6.0 + */ #define HB_LANGUAGE_INVALID ((hb_language_t) 0) HB_EXTERN hb_language_t @@ -279,160 +319,169 @@ hb_language_get_default (void); /** * hb_script_t: - * @HB_SCRIPT_COMMON: HB_TAG ('Z','y','y','y') - * @HB_SCRIPT_INHERITED: HB_TAG ('Z','i','n','h') - * @HB_SCRIPT_UNKNOWN: HB_TAG ('Z','z','z','z') - * @HB_SCRIPT_ARABIC - * @HB_SCRIPT_ARMENIAN - * @HB_SCRIPT_BENGALI - * @HB_SCRIPT_CYRILLIC - * @HB_SCRIPT_DEVANAGARI - * @HB_SCRIPT_GEORGIAN - * @HB_SCRIPT_GREEK - * @HB_SCRIPT_GUJARATI - * @HB_SCRIPT_GURMUKHI - * @HB_SCRIPT_HANGUL - * @HB_SCRIPT_HAN - * @HB_SCRIPT_HEBREW - * @HB_SCRIPT_HIRAGANA - * @HB_SCRIPT_KANNADA - * @HB_SCRIPT_KATAKANA - * @HB_SCRIPT_LAO - * @HB_SCRIPT_LATIN - * @HB_SCRIPT_MALAYALAM - * @HB_SCRIPT_ORIYA - * @HB_SCRIPT_TAMIL - * @HB_SCRIPT_TELUGU - * @HB_SCRIPT_THAI - * @HB_SCRIPT_TIBETAN - * @HB_SCRIPT_BOPOMOFO - * @HB_SCRIPT_BRAILLE - * @HB_SCRIPT_CANADIAN_SYLLABICS - * @HB_SCRIPT_CHEROKEE - * @HB_SCRIPT_ETHIOPIC - * @HB_SCRIPT_KHMER - * @HB_SCRIPT_MONGOLIAN - * @HB_SCRIPT_MYANMAR - * @HB_SCRIPT_OGHAM - * @HB_SCRIPT_RUNIC - * @HB_SCRIPT_SINHALA - * @HB_SCRIPT_SYRIAC - * @HB_SCRIPT_THAANA - * @HB_SCRIPT_YI - * @HB_SCRIPT_DESERET - * @HB_SCRIPT_GOTHIC - * @HB_SCRIPT_OLD_ITALIC - * @HB_SCRIPT_BUHID - * @HB_SCRIPT_HANUNOO - * @HB_SCRIPT_TAGALOG - * @HB_SCRIPT_TAGBANWA - * @HB_SCRIPT_CYPRIOT - * @HB_SCRIPT_LIMBU - * @HB_SCRIPT_LINEAR_B - * @HB_SCRIPT_OSMANYA - * @HB_SCRIPT_SHAVIAN - * @HB_SCRIPT_TAI_LE - * @HB_SCRIPT_UGARITIC - * @HB_SCRIPT_BUGINESE - * @HB_SCRIPT_COPTIC - * @HB_SCRIPT_GLAGOLITIC - * @HB_SCRIPT_KHAROSHTHI - * @HB_SCRIPT_NEW_TAI_LUE - * @HB_SCRIPT_OLD_PERSIAN - * @HB_SCRIPT_SYLOTI_NAGRI - * @HB_SCRIPT_TIFINAGH - * @HB_SCRIPT_BALINESE - * @HB_SCRIPT_CUNEIFORM - * @HB_SCRIPT_NKO - * @HB_SCRIPT_PHAGS_PA - * @HB_SCRIPT_PHOENICIAN - * @HB_SCRIPT_CARIAN - * @HB_SCRIPT_CHAM - * @HB_SCRIPT_KAYAH_LI - * @HB_SCRIPT_LEPCHA - * @HB_SCRIPT_LYCIAN - * @HB_SCRIPT_LYDIAN - * @HB_SCRIPT_OL_CHIKI - * @HB_SCRIPT_REJANG - * @HB_SCRIPT_SAURASHTRA - * @HB_SCRIPT_SUNDANESE - * @HB_SCRIPT_VAI - * @HB_SCRIPT_AVESTAN - * @HB_SCRIPT_BAMUM - * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS - * @HB_SCRIPT_IMPERIAL_ARAMAIC - * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI - * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN - * @HB_SCRIPT_JAVANESE - * @HB_SCRIPT_KAITHI - * @HB_SCRIPT_LISU - * @HB_SCRIPT_MEETEI_MAYEK - * @HB_SCRIPT_OLD_SOUTH_ARABIAN - * @HB_SCRIPT_OLD_TURKIC - * @HB_SCRIPT_SAMARITAN - * @HB_SCRIPT_TAI_THAM - * @HB_SCRIPT_TAI_VIET - * @HB_SCRIPT_BATAK - * @HB_SCRIPT_BRAHMI - * @HB_SCRIPT_MANDAIC - * @HB_SCRIPT_CHAKMA - * @HB_SCRIPT_MEROITIC_CURSIVE - * @HB_SCRIPT_MEROITIC_HIEROGLYPHS - * @HB_SCRIPT_MIAO - * @HB_SCRIPT_SHARADA - * @HB_SCRIPT_SORA_SOMPENG - * @HB_SCRIPT_TAKRI - * @HB_SCRIPT_BASSA_VAH - * @HB_SCRIPT_CAUCASIAN_ALBANIAN - * @HB_SCRIPT_DUPLOYAN - * @HB_SCRIPT_ELBASAN - * @HB_SCRIPT_GRANTHA - * @HB_SCRIPT_KHOJKI - * @HB_SCRIPT_KHUDAWADI - * @HB_SCRIPT_LINEAR_A - * @HB_SCRIPT_MAHAJANI - * @HB_SCRIPT_MANICHAEAN - * @HB_SCRIPT_MENDE_KIKAKUI - * @HB_SCRIPT_MODI - * @HB_SCRIPT_MRO - * @HB_SCRIPT_NABATAEAN - * @HB_SCRIPT_OLD_NORTH_ARABIAN - * @HB_SCRIPT_OLD_PERMIC - * @HB_SCRIPT_PAHAWH_HMONG - * @HB_SCRIPT_PALMYRENE - * @HB_SCRIPT_PAU_CIN_HAU - * @HB_SCRIPT_PSALTER_PAHLAVI - * @HB_SCRIPT_SIDDHAM - * @HB_SCRIPT_TIRHUTA - * @HB_SCRIPT_WARANG_CITI - * @HB_SCRIPT_AHOM - * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS - * @HB_SCRIPT_HATRAN - * @HB_SCRIPT_MULTANI - * @HB_SCRIPT_OLD_HUNGARIAN - * @HB_SCRIPT_SIGNWRITING - * @HB_SCRIPT_ADLAM - * @HB_SCRIPT_BHAIKSUKI - * @HB_SCRIPT_MARCHEN - * @HB_SCRIPT_OSAGE - * @HB_SCRIPT_TANGUT - * @HB_SCRIPT_NEWA - * @HB_SCRIPT_MASARAM_GONDI - * @HB_SCRIPT_NUSHU - * @HB_SCRIPT_SOYOMBO - * @HB_SCRIPT_ZANABAZAR_SQUARE - * @HB_SCRIPT_DOGRA - * @HB_SCRIPT_GUNJALA_GONDI - * @HB_SCRIPT_HANIFI_ROHINGYA - * @HB_SCRIPT_MAKASAR - * @HB_SCRIPT_MEDEFAIDRIN - * @HB_SCRIPT_OLD_SOGDIAN - * @HB_SCRIPT_SOGDIAN - * @HB_SCRIPT_ELYMAIC - * @HB_SCRIPT_NANDINAGARI - * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG - * @HB_SCRIPT_WANCHO - * @HB_SCRIPT_INVALID: #HB_TAG_NONE + * @HB_SCRIPT_COMMON: `Zyyy` + * @HB_SCRIPT_INHERITED: `Zinh` + * @HB_SCRIPT_UNKNOWN: `Zzzz` + * @HB_SCRIPT_ARABIC: `Arab` + * @HB_SCRIPT_ARMENIAN: `Armn` + * @HB_SCRIPT_BENGALI: `Beng` + * @HB_SCRIPT_CYRILLIC: `Cyrl` + * @HB_SCRIPT_DEVANAGARI: `Deva` + * @HB_SCRIPT_GEORGIAN: `Geor` + * @HB_SCRIPT_GREEK: `Grek` + * @HB_SCRIPT_GUJARATI: `Gujr` + * @HB_SCRIPT_GURMUKHI: `Guru` + * @HB_SCRIPT_HANGUL: `Hang` + * @HB_SCRIPT_HAN: `Hani` + * @HB_SCRIPT_HEBREW: `Hebr` + * @HB_SCRIPT_HIRAGANA: `Hira` + * @HB_SCRIPT_KANNADA: `Knda` + * @HB_SCRIPT_KATAKANA: `Kana` + * @HB_SCRIPT_LAO: `Laoo` + * @HB_SCRIPT_LATIN: `Latn` + * @HB_SCRIPT_MALAYALAM: `Mlym` + * @HB_SCRIPT_ORIYA: `Orya` + * @HB_SCRIPT_TAMIL: `Taml` + * @HB_SCRIPT_TELUGU: `Telu` + * @HB_SCRIPT_THAI: `Thai` + * @HB_SCRIPT_TIBETAN: `Tibt` + * @HB_SCRIPT_BOPOMOFO: `Bopo` + * @HB_SCRIPT_BRAILLE: `Brai` + * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` + * @HB_SCRIPT_CHEROKEE: `Cher` + * @HB_SCRIPT_ETHIOPIC: `Ethi` + * @HB_SCRIPT_KHMER: `Khmr` + * @HB_SCRIPT_MONGOLIAN: `Mong` + * @HB_SCRIPT_MYANMAR: `Mymr` + * @HB_SCRIPT_OGHAM: `Ogam` + * @HB_SCRIPT_RUNIC: `Runr` + * @HB_SCRIPT_SINHALA: `Sinh` + * @HB_SCRIPT_SYRIAC: `Syrc` + * @HB_SCRIPT_THAANA: `Thaa` + * @HB_SCRIPT_YI: `Yiii` + * @HB_SCRIPT_DESERET: `Dsrt` + * @HB_SCRIPT_GOTHIC: `Goth` + * @HB_SCRIPT_OLD_ITALIC: `Ital` + * @HB_SCRIPT_BUHID: `Buhd` + * @HB_SCRIPT_HANUNOO: `Hano` + * @HB_SCRIPT_TAGALOG: `Tglg` + * @HB_SCRIPT_TAGBANWA: `Tagb` + * @HB_SCRIPT_CYPRIOT: `Cprt` + * @HB_SCRIPT_LIMBU: `Limb` + * @HB_SCRIPT_LINEAR_B: `Linb` + * @HB_SCRIPT_OSMANYA: `Osma` + * @HB_SCRIPT_SHAVIAN: `Shaw` + * @HB_SCRIPT_TAI_LE: `Tale` + * @HB_SCRIPT_UGARITIC: `Ugar` + * @HB_SCRIPT_BUGINESE: `Bugi` + * @HB_SCRIPT_COPTIC: `Copt` + * @HB_SCRIPT_GLAGOLITIC: `Glag` + * @HB_SCRIPT_KHAROSHTHI: `Khar` + * @HB_SCRIPT_NEW_TAI_LUE: `Talu` + * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` + * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` + * @HB_SCRIPT_TIFINAGH: `Tfng` + * @HB_SCRIPT_BALINESE: `Bali` + * @HB_SCRIPT_CUNEIFORM: `Xsux` + * @HB_SCRIPT_NKO: `Nkoo` + * @HB_SCRIPT_PHAGS_PA: `Phag` + * @HB_SCRIPT_PHOENICIAN: `Phnx` + * @HB_SCRIPT_CARIAN: `Cari` + * @HB_SCRIPT_CHAM: `Cham` + * @HB_SCRIPT_KAYAH_LI: `Kali` + * @HB_SCRIPT_LEPCHA: `Lepc` + * @HB_SCRIPT_LYCIAN: `Lyci` + * @HB_SCRIPT_LYDIAN: `Lydi` + * @HB_SCRIPT_OL_CHIKI: `Olck` + * @HB_SCRIPT_REJANG: `Rjng` + * @HB_SCRIPT_SAURASHTRA: `Saur` + * @HB_SCRIPT_SUNDANESE: `Sund` + * @HB_SCRIPT_VAI: `Vaii` + * @HB_SCRIPT_AVESTAN: `Avst` + * @HB_SCRIPT_BAMUM: `Bamu` + * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` + * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` + * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` + * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` + * @HB_SCRIPT_JAVANESE: `Java` + * @HB_SCRIPT_KAITHI: `Kthi` + * @HB_SCRIPT_LISU: `Lisu` + * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` + * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` + * @HB_SCRIPT_OLD_TURKIC: `Orkh` + * @HB_SCRIPT_SAMARITAN: `Samr` + * @HB_SCRIPT_TAI_THAM: `Lana` + * @HB_SCRIPT_TAI_VIET: `Tavt` + * @HB_SCRIPT_BATAK: `Batk` + * @HB_SCRIPT_BRAHMI: `Brah` + * @HB_SCRIPT_MANDAIC: `Mand` + * @HB_SCRIPT_CHAKMA: `Cakm` + * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` + * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` + * @HB_SCRIPT_MIAO: `Plrd` + * @HB_SCRIPT_SHARADA: `Shrd` + * @HB_SCRIPT_SORA_SOMPENG: `Sora` + * @HB_SCRIPT_TAKRI: `Takr` + * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 + * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 + * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 + * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 + * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 + * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 + * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 + * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 + * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 + * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 + * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 + * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 + * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 + * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 + * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 + * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 + * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 + * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 + * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 + * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 + * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 + * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 + * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 + * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 + * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 + * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 + * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 + * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 + * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 + * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 + * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 + * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 + * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 + * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 + * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 + * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 + * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 + * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 + * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 + * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 + * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 + * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 + * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 + * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 + * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 + * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 + * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 + * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 + * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 + * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 + * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 + * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 + * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 + * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 + * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0 + * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0 + * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0 + * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 + * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 + * @HB_SCRIPT_INVALID: No script set * * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). @@ -441,208 +490,217 @@ hb_language_get_default (void); * **/ -/* https://unicode.org/iso15924/ */ /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ -/* Unicode Character Database property: Script (sc) */ typedef enum { - /*1.1*/ HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), - /*1.1*/ HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), - /*5.0*/ HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), - - /*1.1*/ HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), - /*1.1*/ HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), - /*1.1*/ HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), - /*1.1*/ HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), - /*1.1*/ HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), - /*1.1*/ HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), - /*1.1*/ HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), - /*1.1*/ HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), - /*1.1*/ HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), - /*1.1*/ HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), - /*1.1*/ HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), - /*1.1*/ HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), - /*1.1*/ HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), - /*1.1*/ HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), - /*1.1*/ HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), - /*1.1*/ HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), - /*1.1*/ HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), - /*1.1*/ HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), - /*1.1*/ HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), - /*1.1*/ HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), - /*1.1*/ HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), - /*1.1*/ HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), - - /*2.0*/ HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), - - /*3.0*/ HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), - /*3.0*/ HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), - /*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), - /*3.0*/ HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), - /*3.0*/ HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), - /*3.0*/ HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), - /*3.0*/ HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), - /*3.0*/ HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), - /*3.0*/ HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), - /*3.0*/ HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), - /*3.0*/ HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), - /*3.0*/ HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), - /*3.0*/ HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), - /*3.0*/ HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), - - /*3.1*/ HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), - /*3.1*/ HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), - /*3.1*/ HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), - - /*3.2*/ HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), - /*3.2*/ HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), - /*3.2*/ HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), - /*3.2*/ HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), - - /*4.0*/ HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), - /*4.0*/ HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), - /*4.0*/ HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), - /*4.0*/ HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), - /*4.0*/ HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), - /*4.0*/ HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), - /*4.0*/ HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), - - /*4.1*/ HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), - /*4.1*/ HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), - /*4.1*/ HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), - /*4.1*/ HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), - /*4.1*/ HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), - /*4.1*/ HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), - /*4.1*/ HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), - /*4.1*/ HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), - - /*5.0*/ HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), - /*5.0*/ HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), - /*5.0*/ HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), - /*5.0*/ HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), - /*5.0*/ HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), - - /*5.1*/ HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), - /*5.1*/ HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), - /*5.1*/ HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), - /*5.1*/ HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), - /*5.1*/ HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), - /*5.1*/ HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), - /*5.1*/ HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), - /*5.1*/ HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), - /*5.1*/ HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), - /*5.1*/ HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), - /*5.1*/ HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), - - /*5.2*/ HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), - /*5.2*/ HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), - /*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), - /*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), - /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), - /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), - /*5.2*/ HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), - /*5.2*/ HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), - /*5.2*/ HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), - /*5.2*/ HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), - /*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), - /*5.2*/ HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), - /*5.2*/ HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), - /*5.2*/ HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), - /*5.2*/ HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), - - /*6.0*/ HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), - /*6.0*/ HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), - /*6.0*/ HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), - - /*6.1*/ HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), - /*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), - /*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), - /*6.1*/ HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), - /*6.1*/ HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), - /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), - /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), + HB_SCRIPT_COMMON = HB_TAG ('Z','y','y','y'), /*1.1*/ + HB_SCRIPT_INHERITED = HB_TAG ('Z','i','n','h'), /*1.1*/ + HB_SCRIPT_UNKNOWN = HB_TAG ('Z','z','z','z'), /*5.0*/ + + HB_SCRIPT_ARABIC = HB_TAG ('A','r','a','b'), /*1.1*/ + HB_SCRIPT_ARMENIAN = HB_TAG ('A','r','m','n'), /*1.1*/ + HB_SCRIPT_BENGALI = HB_TAG ('B','e','n','g'), /*1.1*/ + HB_SCRIPT_CYRILLIC = HB_TAG ('C','y','r','l'), /*1.1*/ + HB_SCRIPT_DEVANAGARI = HB_TAG ('D','e','v','a'), /*1.1*/ + HB_SCRIPT_GEORGIAN = HB_TAG ('G','e','o','r'), /*1.1*/ + HB_SCRIPT_GREEK = HB_TAG ('G','r','e','k'), /*1.1*/ + HB_SCRIPT_GUJARATI = HB_TAG ('G','u','j','r'), /*1.1*/ + HB_SCRIPT_GURMUKHI = HB_TAG ('G','u','r','u'), /*1.1*/ + HB_SCRIPT_HANGUL = HB_TAG ('H','a','n','g'), /*1.1*/ + HB_SCRIPT_HAN = HB_TAG ('H','a','n','i'), /*1.1*/ + HB_SCRIPT_HEBREW = HB_TAG ('H','e','b','r'), /*1.1*/ + HB_SCRIPT_HIRAGANA = HB_TAG ('H','i','r','a'), /*1.1*/ + HB_SCRIPT_KANNADA = HB_TAG ('K','n','d','a'), /*1.1*/ + HB_SCRIPT_KATAKANA = HB_TAG ('K','a','n','a'), /*1.1*/ + HB_SCRIPT_LAO = HB_TAG ('L','a','o','o'), /*1.1*/ + HB_SCRIPT_LATIN = HB_TAG ('L','a','t','n'), /*1.1*/ + HB_SCRIPT_MALAYALAM = HB_TAG ('M','l','y','m'), /*1.1*/ + HB_SCRIPT_ORIYA = HB_TAG ('O','r','y','a'), /*1.1*/ + HB_SCRIPT_TAMIL = HB_TAG ('T','a','m','l'), /*1.1*/ + HB_SCRIPT_TELUGU = HB_TAG ('T','e','l','u'), /*1.1*/ + HB_SCRIPT_THAI = HB_TAG ('T','h','a','i'), /*1.1*/ + + HB_SCRIPT_TIBETAN = HB_TAG ('T','i','b','t'), /*2.0*/ + + HB_SCRIPT_BOPOMOFO = HB_TAG ('B','o','p','o'), /*3.0*/ + HB_SCRIPT_BRAILLE = HB_TAG ('B','r','a','i'), /*3.0*/ + HB_SCRIPT_CANADIAN_SYLLABICS = HB_TAG ('C','a','n','s'), /*3.0*/ + HB_SCRIPT_CHEROKEE = HB_TAG ('C','h','e','r'), /*3.0*/ + HB_SCRIPT_ETHIOPIC = HB_TAG ('E','t','h','i'), /*3.0*/ + HB_SCRIPT_KHMER = HB_TAG ('K','h','m','r'), /*3.0*/ + HB_SCRIPT_MONGOLIAN = HB_TAG ('M','o','n','g'), /*3.0*/ + HB_SCRIPT_MYANMAR = HB_TAG ('M','y','m','r'), /*3.0*/ + HB_SCRIPT_OGHAM = HB_TAG ('O','g','a','m'), /*3.0*/ + HB_SCRIPT_RUNIC = HB_TAG ('R','u','n','r'), /*3.0*/ + HB_SCRIPT_SINHALA = HB_TAG ('S','i','n','h'), /*3.0*/ + HB_SCRIPT_SYRIAC = HB_TAG ('S','y','r','c'), /*3.0*/ + HB_SCRIPT_THAANA = HB_TAG ('T','h','a','a'), /*3.0*/ + HB_SCRIPT_YI = HB_TAG ('Y','i','i','i'), /*3.0*/ + + HB_SCRIPT_DESERET = HB_TAG ('D','s','r','t'), /*3.1*/ + HB_SCRIPT_GOTHIC = HB_TAG ('G','o','t','h'), /*3.1*/ + HB_SCRIPT_OLD_ITALIC = HB_TAG ('I','t','a','l'), /*3.1*/ + + HB_SCRIPT_BUHID = HB_TAG ('B','u','h','d'), /*3.2*/ + HB_SCRIPT_HANUNOO = HB_TAG ('H','a','n','o'), /*3.2*/ + HB_SCRIPT_TAGALOG = HB_TAG ('T','g','l','g'), /*3.2*/ + HB_SCRIPT_TAGBANWA = HB_TAG ('T','a','g','b'), /*3.2*/ + + HB_SCRIPT_CYPRIOT = HB_TAG ('C','p','r','t'), /*4.0*/ + HB_SCRIPT_LIMBU = HB_TAG ('L','i','m','b'), /*4.0*/ + HB_SCRIPT_LINEAR_B = HB_TAG ('L','i','n','b'), /*4.0*/ + HB_SCRIPT_OSMANYA = HB_TAG ('O','s','m','a'), /*4.0*/ + HB_SCRIPT_SHAVIAN = HB_TAG ('S','h','a','w'), /*4.0*/ + HB_SCRIPT_TAI_LE = HB_TAG ('T','a','l','e'), /*4.0*/ + HB_SCRIPT_UGARITIC = HB_TAG ('U','g','a','r'), /*4.0*/ + + HB_SCRIPT_BUGINESE = HB_TAG ('B','u','g','i'), /*4.1*/ + HB_SCRIPT_COPTIC = HB_TAG ('C','o','p','t'), /*4.1*/ + HB_SCRIPT_GLAGOLITIC = HB_TAG ('G','l','a','g'), /*4.1*/ + HB_SCRIPT_KHAROSHTHI = HB_TAG ('K','h','a','r'), /*4.1*/ + HB_SCRIPT_NEW_TAI_LUE = HB_TAG ('T','a','l','u'), /*4.1*/ + HB_SCRIPT_OLD_PERSIAN = HB_TAG ('X','p','e','o'), /*4.1*/ + HB_SCRIPT_SYLOTI_NAGRI = HB_TAG ('S','y','l','o'), /*4.1*/ + HB_SCRIPT_TIFINAGH = HB_TAG ('T','f','n','g'), /*4.1*/ + + HB_SCRIPT_BALINESE = HB_TAG ('B','a','l','i'), /*5.0*/ + HB_SCRIPT_CUNEIFORM = HB_TAG ('X','s','u','x'), /*5.0*/ + HB_SCRIPT_NKO = HB_TAG ('N','k','o','o'), /*5.0*/ + HB_SCRIPT_PHAGS_PA = HB_TAG ('P','h','a','g'), /*5.0*/ + HB_SCRIPT_PHOENICIAN = HB_TAG ('P','h','n','x'), /*5.0*/ + + HB_SCRIPT_CARIAN = HB_TAG ('C','a','r','i'), /*5.1*/ + HB_SCRIPT_CHAM = HB_TAG ('C','h','a','m'), /*5.1*/ + HB_SCRIPT_KAYAH_LI = HB_TAG ('K','a','l','i'), /*5.1*/ + HB_SCRIPT_LEPCHA = HB_TAG ('L','e','p','c'), /*5.1*/ + HB_SCRIPT_LYCIAN = HB_TAG ('L','y','c','i'), /*5.1*/ + HB_SCRIPT_LYDIAN = HB_TAG ('L','y','d','i'), /*5.1*/ + HB_SCRIPT_OL_CHIKI = HB_TAG ('O','l','c','k'), /*5.1*/ + HB_SCRIPT_REJANG = HB_TAG ('R','j','n','g'), /*5.1*/ + HB_SCRIPT_SAURASHTRA = HB_TAG ('S','a','u','r'), /*5.1*/ + HB_SCRIPT_SUNDANESE = HB_TAG ('S','u','n','d'), /*5.1*/ + HB_SCRIPT_VAI = HB_TAG ('V','a','i','i'), /*5.1*/ + + HB_SCRIPT_AVESTAN = HB_TAG ('A','v','s','t'), /*5.2*/ + HB_SCRIPT_BAMUM = HB_TAG ('B','a','m','u'), /*5.2*/ + HB_SCRIPT_EGYPTIAN_HIEROGLYPHS = HB_TAG ('E','g','y','p'), /*5.2*/ + HB_SCRIPT_IMPERIAL_ARAMAIC = HB_TAG ('A','r','m','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PAHLAVI = HB_TAG ('P','h','l','i'), /*5.2*/ + HB_SCRIPT_INSCRIPTIONAL_PARTHIAN = HB_TAG ('P','r','t','i'), /*5.2*/ + HB_SCRIPT_JAVANESE = HB_TAG ('J','a','v','a'), /*5.2*/ + HB_SCRIPT_KAITHI = HB_TAG ('K','t','h','i'), /*5.2*/ + HB_SCRIPT_LISU = HB_TAG ('L','i','s','u'), /*5.2*/ + HB_SCRIPT_MEETEI_MAYEK = HB_TAG ('M','t','e','i'), /*5.2*/ + HB_SCRIPT_OLD_SOUTH_ARABIAN = HB_TAG ('S','a','r','b'), /*5.2*/ + HB_SCRIPT_OLD_TURKIC = HB_TAG ('O','r','k','h'), /*5.2*/ + HB_SCRIPT_SAMARITAN = HB_TAG ('S','a','m','r'), /*5.2*/ + HB_SCRIPT_TAI_THAM = HB_TAG ('L','a','n','a'), /*5.2*/ + HB_SCRIPT_TAI_VIET = HB_TAG ('T','a','v','t'), /*5.2*/ + + HB_SCRIPT_BATAK = HB_TAG ('B','a','t','k'), /*6.0*/ + HB_SCRIPT_BRAHMI = HB_TAG ('B','r','a','h'), /*6.0*/ + HB_SCRIPT_MANDAIC = HB_TAG ('M','a','n','d'), /*6.0*/ + + HB_SCRIPT_CHAKMA = HB_TAG ('C','a','k','m'), /*6.1*/ + HB_SCRIPT_MEROITIC_CURSIVE = HB_TAG ('M','e','r','c'), /*6.1*/ + HB_SCRIPT_MEROITIC_HIEROGLYPHS = HB_TAG ('M','e','r','o'), /*6.1*/ + HB_SCRIPT_MIAO = HB_TAG ('P','l','r','d'), /*6.1*/ + HB_SCRIPT_SHARADA = HB_TAG ('S','h','r','d'), /*6.1*/ + HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ + HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ /* * Since: 0.9.30 */ - /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), - /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), - /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), - /*7.0*/ HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), - /*7.0*/ HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), - /*7.0*/ HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), - /*7.0*/ HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), - /*7.0*/ HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), - /*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), - /*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), - /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), - /*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), - /*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), - /*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), - /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), - /*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), - /*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), - /*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), - /*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), - /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), - /*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), - /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), - /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), - - /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), - /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), - /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), - /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), - /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), - /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ + HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ + HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ + HB_SCRIPT_ELBASAN = HB_TAG ('E','l','b','a'), /*7.0*/ + HB_SCRIPT_GRANTHA = HB_TAG ('G','r','a','n'), /*7.0*/ + HB_SCRIPT_KHOJKI = HB_TAG ('K','h','o','j'), /*7.0*/ + HB_SCRIPT_KHUDAWADI = HB_TAG ('S','i','n','d'), /*7.0*/ + HB_SCRIPT_LINEAR_A = HB_TAG ('L','i','n','a'), /*7.0*/ + HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ + HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ + HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ + HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'), /*7.0*/ + HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ + HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ + HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ + HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ + HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ + HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ + HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'), /*7.0*/ + HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ + HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'), /*7.0*/ + HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ + HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ + + HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), /*8.0*/ + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), /*8.0*/ + HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), /*8.0*/ + HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), /*8.0*/ + HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), /*8.0*/ + HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), /*8.0*/ /* * Since 1.3.0 */ - /*9.0*/ HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), - /*9.0*/ HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), - /*9.0*/ HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), - /*9.0*/ HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), - /*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), - /*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), + HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), /*9.0*/ + HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), /*9.0*/ + HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), /*9.0*/ + HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), /*9.0*/ + HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), /*9.0*/ + HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /*9.0*/ /* * Since 1.6.0 */ - /*10.0*/HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), - /*10.0*/HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), - /*10.0*/HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), - /*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), + HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'), /*10.0*/ + HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'), /*10.0*/ + HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'), /*10.0*/ + HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'), /*10.0*/ /* * Since 1.8.0 */ - /*11.0*/HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), - /*11.0*/HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), - /*11.0*/HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), - /*11.0*/HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), - /*11.0*/HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), - /*11.0*/HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), - /*11.0*/HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), + HB_SCRIPT_DOGRA = HB_TAG ('D','o','g','r'), /*11.0*/ + HB_SCRIPT_GUNJALA_GONDI = HB_TAG ('G','o','n','g'), /*11.0*/ + HB_SCRIPT_HANIFI_ROHINGYA = HB_TAG ('R','o','h','g'), /*11.0*/ + HB_SCRIPT_MAKASAR = HB_TAG ('M','a','k','a'), /*11.0*/ + HB_SCRIPT_MEDEFAIDRIN = HB_TAG ('M','e','d','f'), /*11.0*/ + HB_SCRIPT_OLD_SOGDIAN = HB_TAG ('S','o','g','o'), /*11.0*/ + HB_SCRIPT_SOGDIAN = HB_TAG ('S','o','g','d'), /*11.0*/ /* * Since 2.4.0 */ - /*12.0*/HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), - /*12.0*/HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), - /*12.0*/HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), - /*12.0*/HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), + HB_SCRIPT_ELYMAIC = HB_TAG ('E','l','y','m'), /*12.0*/ + HB_SCRIPT_NANDINAGARI = HB_TAG ('N','a','n','d'), /*12.0*/ + HB_SCRIPT_NYIAKENG_PUACHUE_HMONG = HB_TAG ('H','m','n','p'), /*12.0*/ + HB_SCRIPT_WANCHO = HB_TAG ('W','c','h','o'), /*12.0*/ /* * Since 2.6.7 */ - /*13.0*/HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), - /*13.0*/HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), - /*13.0*/HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), - /*13.0*/HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), + HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ + HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ + HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ + HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ + + /* + * Since 3.0.0 + */ + HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/ + HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/ + HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/ + HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/ + HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/ /* No script set. */ - HB_SCRIPT_INVALID = HB_TAG_NONE, + HB_SCRIPT_INVALID = HB_TAG_NONE, + + /*< private >*/ /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t * without risking undefined behavior. We have two, for historical reasons. @@ -687,19 +745,33 @@ typedef struct hb_user_data_key_t { char unused; } hb_user_data_key_t; +/** + * hb_destroy_func_t: + * @user_data: the data to be destroyed + * + * A virtual method for destroy user-data callbacks. + * + */ typedef void (*hb_destroy_func_t) (void *user_data); /* Font features and variations. */ /** - * HB_FEATURE_GLOBAL_START + * HB_FEATURE_GLOBAL_START: + * + * Special setting for #hb_feature_t.start to apply the feature from the start + * of the buffer. * * Since: 2.0.0 */ #define HB_FEATURE_GLOBAL_START 0 + /** - * HB_FEATURE_GLOBAL_END + * HB_FEATURE_GLOBAL_END: + * + * Special setting for #hb_feature_t.end to apply the feature from to the end + * of the buffer. * * Since: 2.0.0 */ @@ -717,7 +789,7 @@ typedef void (*hb_destroy_func_t) (void *user_data); * The #hb_feature_t is the structure that holds information about requested * feature application. The feature will be applied with the given value to all * glyphs which are in clusters between @start (inclusive) and @end (exclusive). - * Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END + * Setting start to #HB_FEATURE_GLOBAL_START and end to #HB_FEATURE_GLOBAL_END * specifies that the feature always applies to the entire buffer. */ typedef struct hb_feature_t { @@ -741,8 +813,8 @@ hb_feature_to_string (hb_feature_t *feature, * @value: The value of the variation axis * * Data type for holding variation data. Registered OpenType - * variation-axis tags are listed at - * https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg + * variation-axis tags are listed in + * [OpenType Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg). * * Since: 1.4.2 */ @@ -769,6 +841,17 @@ hb_variation_to_string (hb_variation_t *variation, */ typedef uint32_t hb_color_t; +/** + * HB_COLOR: + * @b: blue channel value + * @g: green channel value + * @r: red channel value + * @a: alpha channel value + * + * Constructs an #hb_color_t from four integers. + * + * Since: 2.1.0 + */ #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a))) HB_EXTERN uint8_t diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index fc8d424bfb..ad800f0f74 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -86,6 +86,9 @@ #define HB_NO_LEGACY #endif +#ifdef HAVE_CONFIG_OVERRIDE_H +#include "config-override.h" +#endif /* Closure of options. */ @@ -117,7 +120,7 @@ #define HB_NO_CMAP_LEGACY_SUBTABLES #define HB_NO_FALLBACK_SHAPE #define HB_NO_OT_KERN -#define HB_NO_OT_LAYOUT_BLACKLIST +#define HB_NO_OT_LAYOUT_BLOCKLIST #define HB_NO_OT_SHAPE_FALLBACK #endif @@ -155,9 +158,5 @@ #endif #endif -#ifdef HAVE_CONFIG_OVERRIDE_H -#include "config-override.h" -#endif - #endif /* HB_CONFIG_HH */ diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index 7b6b2bd5ef..4b6c67c1ee 100644 --- a/thirdparty/harfbuzz/src/hb-coretext.cc +++ b/thirdparty/harfbuzz/src/hb-coretext.cc @@ -34,7 +34,6 @@ #include "hb-coretext.h" #include "hb-aat-layout.hh" -#include <math.h> /** @@ -190,7 +189,10 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) * reconfiguring the cascade list causes CoreText crashes. For details, see * crbug.com/549610 */ // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) { +#pragma GCC diagnostic pop CFStringRef fontName = CTFontCopyPostScriptName (ct_font); bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; CFRelease (fontName); @@ -330,6 +332,44 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return nullptr; } + if (font->coords) + { + CFMutableDictionaryRef variations = + CFDictionaryCreateMutable (kCFAllocatorDefault, + font->num_coords, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + for (unsigned i = 0; i < font->num_coords; i++) + { + if (font->coords[i] == 0.) continue; + + hb_ot_var_axis_info_t info; + unsigned int c = 1; + hb_ot_var_get_axis_infos (font->face, i, &c, &info); + CFDictionarySetValue (variations, + CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &info.tag), + CFNumberCreate (kCFAllocatorDefault, kCFNumberFloatType, &font->design_coords[i]) + ); + } + + CFDictionaryRef attributes = + CFDictionaryCreate (kCFAllocatorDefault, + (const void **) &kCTFontVariationAttribute, + (const void **) &variations, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CTFontDescriptorRef varDesc = CTFontDescriptorCreateWithAttributes (attributes); + CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0, nullptr, varDesc); + + CFRelease (ct_font); + CFRelease (attributes); + CFRelease (variations); + ct_font = new_ct_font; + } + return (hb_coretext_font_data_t *) ct_font; } @@ -346,7 +386,7 @@ retry: const hb_coretext_font_data_t *data = font->data.coretext; if (unlikely (!data)) return nullptr; - if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > .5) + if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > (CGFloat) .5) { /* XXX-MT-bug * Note that evaluating condition above can be dangerous if another thread @@ -402,7 +442,7 @@ hb_coretext_font_create (CTFontRef ct_font) } /** - * hb_coretext_face_get_ct_font: + * hb_coretext_font_get_ct_font: * @font: #hb_font_t to work upon * * Fetches the CTFontRef associated with the specified @@ -858,7 +898,7 @@ resize_and_retry: buffer->len = 0; uint32_t status_and = ~0, status_or = 0; - double advances_so_far = 0; + CGFloat advances_so_far = 0; /* For right-to-left runs, CoreText returns the glyphs positioned such that * any trailing whitespace is to the left of (0,0). Adjust coordinate system * to fix for that. Test with any RTL string with trailing spaces. @@ -880,10 +920,10 @@ resize_and_retry: status_or |= run_status; status_and &= run_status; DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status); - double run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr); + CGFloat run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr); if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) run_advance = -run_advance; - DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); + DEBUG_MSG (CORETEXT, run, "Run advance: %g", (double) run_advance); /* CoreText does automatic font fallback (AKA "cascading") for characters * not supported by the requested font, and provides no way to turn it off, @@ -1059,32 +1099,32 @@ resize_and_retry: hb_glyph_info_t *info = run_info; if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) { - hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult; + hb_position_t x_offset = round ((positions[0].x - advances_so_far) * x_mult); for (unsigned int j = 0; j < num_glyphs; j++) { - double advance; + CGFloat advance; if (likely (j + 1 < num_glyphs)) advance = positions[j + 1].x - positions[j].x; else /* last glyph */ advance = run_advance - (positions[j].x - positions[0].x); - info->mask = advance * x_mult; + info->mask = round (advance * x_mult); info->var1.i32 = x_offset; - info->var2.i32 = positions[j].y * y_mult; + info->var2.i32 = round (positions[j].y * y_mult); info++; } } else { - hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult; + hb_position_t y_offset = round ((positions[0].y - advances_so_far) * y_mult); for (unsigned int j = 0; j < num_glyphs; j++) { - double advance; + CGFloat advance; if (likely (j + 1 < num_glyphs)) advance = positions[j + 1].y - positions[j].y; else /* last glyph */ advance = run_advance - (positions[j].y - positions[0].y); - info->mask = advance * y_mult; - info->var1.i32 = positions[j].x * x_mult; + info->mask = round (advance * y_mult); + info->var1.i32 = round (positions[j].x * x_mult); info->var2.i32 = y_offset; info++; } diff --git a/thirdparty/harfbuzz/src/hb-debug.hh b/thirdparty/harfbuzz/src/hb-debug.hh index ec3a1ff211..f80c8980ba 100644 --- a/thirdparty/harfbuzz/src/hb-debug.hh +++ b/thirdparty/harfbuzz/src/hb-debug.hh @@ -307,7 +307,7 @@ struct hb_auto_trace_t _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1, "return %s (line %d)", - hb_printer_t<decltype (v)>().print (v), line); + hb_printer_t<hb_decay<decltype (v)>>().print (v), line); if (plevel) --*plevel; plevel = nullptr; returned = true; @@ -438,6 +438,10 @@ struct hb_no_trace_t { #define TRACE_SUBSET(this) hb_no_trace_t<bool> trace #endif +#ifndef HB_DEBUG_SUBSET_REPACK +#define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0) +#endif + #ifndef HB_DEBUG_DISPATCH #define HB_DEBUG_DISPATCH ( \ HB_DEBUG_APPLY + \ diff --git a/thirdparty/harfbuzz/src/hb-deprecated.h b/thirdparty/harfbuzz/src/hb-deprecated.h index 43f89a4c4e..a130d77f77 100644 --- a/thirdparty/harfbuzz/src/hb-deprecated.h +++ b/thirdparty/harfbuzz/src/hb-deprecated.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -53,11 +53,50 @@ HB_BEGIN_DECLS #ifndef HB_DISABLE_DEPRECATED +/** + * HB_SCRIPT_CANADIAN_ABORIGINAL: + * + * Use #HB_SCRIPT_CANADIAN_SYLLABICS instead: + * + * Deprecated: 0.9.20 + */ #define HB_SCRIPT_CANADIAN_ABORIGINAL HB_SCRIPT_CANADIAN_SYLLABICS +/** + * HB_BUFFER_FLAGS_DEFAULT: + * + * Use #HB_BUFFER_FLAG_DEFAULT instead. + * + * Deprecated: 0.9.20 + */ #define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT +/** + * HB_BUFFER_SERIALIZE_FLAGS_DEFAULT: + * + * Use #HB_BUFFER_SERIALIZE_FLAG_DEFAULT instead. + * + * Deprecated: 0.9.20 + */ #define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT +/** + * hb_font_get_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @unicode: The Unicode code point to query + * @variation_selector: The variation-selector code point to query + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the glyph ID for a specified Unicode code point + * font, with an optional variation selector. + * + * Return value: %true if data found, %false otherwise + * Deprecated: 1.2.3 + * + **/ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph, @@ -68,11 +107,13 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); -HB_EXTERN HB_DEPRECATED void -hb_set_invert (hb_set_t *set); - /** * hb_unicode_eastasian_width_func_t: + * @ufuncs: A Unicode-functions structure + * @unicode: The code point to query + * @user_data: User data pointer passed by the caller + * + * A virtual method for the #hb_unicode_funcs_t structure. * * Deprecated: 2.0.0 */ @@ -82,12 +123,12 @@ typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t /** * hb_unicode_funcs_set_eastasian_width_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @ufuncs: a Unicode-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * + * Sets the implementation function for #hb_unicode_eastasian_width_func_t. * * Since: 0.9.2 * Deprecated: 2.0.0 @@ -99,6 +140,10 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, /** * hb_unicode_eastasian_width: + * @ufuncs: a Unicode-function structure + * @unicode: The code point to query + * + * Don't use. Not used by HarfBuzz. * * Since: 0.9.2 * Deprecated: 2.0.0 @@ -112,7 +157,7 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, * hb_unicode_decompose_compatibility_func_t: * @ufuncs: a Unicode function structure * @u: codepoint to decompose - * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into + * @decomposed: address of codepoint array (of length #HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() * * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed. @@ -120,7 +165,7 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, * * If @u has no compatibility decomposition, zero should be returned. * - * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any + * The Unicode standard guarantees that a buffer of length #HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations * of this function type must ensure that they do not write past the provided array. * @@ -144,10 +189,12 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_ /** * hb_unicode_funcs_set_decompose_compatibility_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @ufuncs: A Unicode-functions structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore + * + * Sets the implementation function for #hb_unicode_decompose_compatibility_func_t. * * * @@ -165,16 +212,25 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t *decomposed); +/** + * hb_font_get_glyph_v_kerning_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the kerning-adjustment value for a glyph-pair in + * the specified font, for vertical text segments. + * + **/ typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t; /** * hb_font_funcs_set_glyph_v_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * - * + * Sets the implementation function for #hb_font_get_glyph_v_kerning_func_t. * * Since: 0.9.2 * Deprecated: 2.0.0 diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc index 92c956c032..8f6d73b639 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -32,6 +32,7 @@ #include "hb-directwrite.h" +#include "hb-ms-feature-ranges.hh" /** * SECTION:hb-directwrite @@ -42,24 +43,6 @@ * Functions for using HarfBuzz with DirectWrite fonts. **/ -/* Declare object creator for dynamic support of DWRITE */ -typedef HRESULT (* WINAPI t_DWriteCreateFactory)( - DWRITE_FACTORY_TYPE factoryType, - REFIID iid, - IUnknown **factory -); - -/* - * hb-directwrite uses new/delete syntatically but as we let users - * to override malloc/free, we will redefine new/delete so users - * won't need to do that by their own. - */ -void* operator new (size_t size) { return malloc (size); } -void* operator new [] (size_t size) { return malloc (size); } -void operator delete (void* pointer) { free (pointer); } -void operator delete [] (void* pointer) { free (pointer); } - - /* * DirectWrite font stream helpers */ @@ -154,7 +137,6 @@ public: struct hb_directwrite_face_data_t { - HMODULE dwrite_dll; IDWriteFactory *dwriteFactory; IDWriteFontFile *fontFile; DWriteFontFileStream *fontFileStream; @@ -176,33 +158,12 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) return nullptr; \ } HB_STMT_END - data->dwrite_dll = LoadLibrary (TEXT ("DWRITE")); - if (unlikely (!data->dwrite_dll)) - FAIL ("Cannot find DWrite.DLL"); - - t_DWriteCreateFactory p_DWriteCreateFactory; - -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - - p_DWriteCreateFactory = (t_DWriteCreateFactory) - GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); - -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - - if (unlikely (!p_DWriteCreateFactory)) - FAIL ("Cannot find DWriteCreateFactory()."); - HRESULT hr; // TODO: factory and fontFileLoader should be cached separately IDWriteFactory* dwriteFactory; - hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); + hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); if (unlikely (hr != S_OK)) FAIL ("Failed to run DWriteCreateFactory()."); @@ -266,8 +227,6 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); - if (data->dwrite_dll) - FreeLibrary (data->dwrite_dll); if (data) delete data; } @@ -552,13 +511,12 @@ protected: * shaper */ -static hb_bool_t -_hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features, - float lineWidth) +hb_bool_t +_hb_directwrite_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) { hb_face_t *face = font->face; const hb_directwrite_face_data_t *face_data = face->data.directwrite; @@ -611,8 +569,6 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, log_clusters[chars_len++] = cluster; /* Surrogates. */ } - // TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES - DWRITE_READING_DIRECTION readingDirection; readingDirection = buffer->props.direction ? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : @@ -623,7 +579,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, * but we never attempt to shape a word longer than 64K characters * in a single gfxShapedWord, so we cannot exceed that limit. */ - uint32_t textLength = buffer->len; + uint32_t textLength = chars_len; TextAnalysis analysis (textString, textLength, nullptr, readingDirection); TextAnalysis::Run *runHead; @@ -648,38 +604,54 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, mbstowcs ((wchar_t*) localeName, hb_language_to_string (buffer->props.language), 20); - // TODO: it does work but doesn't care about ranges - DWRITE_TYPOGRAPHIC_FEATURES typographic_features; - typographic_features.featureCount = num_features; + /* + * Set up features. + */ + static_assert ((sizeof (DWRITE_TYPOGRAPHIC_FEATURES) == sizeof (hb_ms_features_t)), ""); + static_assert ((sizeof (DWRITE_FONT_FEATURE) == sizeof (hb_ms_feature_t)), ""); + hb_vector_t<hb_ms_features_t *> range_features; + hb_vector_t<uint32_t> range_char_counts; if (num_features) { - typographic_features.features = new DWRITE_FONT_FEATURE[num_features]; - for (unsigned int i = 0; i < num_features; ++i) - { - typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG) - hb_uint32_swap (features[i].tag); - typographic_features.features[i].parameter = features[i].value; - } + hb_vector_t<hb_ms_feature_t> feature_records; + hb_vector_t<hb_ms_range_record_t> range_records; + if (hb_ms_setup_features (features, num_features, feature_records, range_records)) + hb_ms_make_feature_ranges (feature_records, + range_records, + 0, + chars_len, + log_clusters, + range_features, + range_char_counts); } - const DWRITE_TYPOGRAPHIC_FEATURES* dwFeatures; - dwFeatures = (const DWRITE_TYPOGRAPHIC_FEATURES*) &typographic_features; - const uint32_t featureRangeLengths[] = { textLength }; - // uint16_t* clusterMap; clusterMap = new uint16_t[textLength]; DWRITE_SHAPING_TEXT_PROPERTIES* textProperties; textProperties = new DWRITE_SHAPING_TEXT_PROPERTIES[textLength]; + retry_getglyphs: uint16_t* glyphIndices = new uint16_t[maxGlyphCount]; DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties; glyphProperties = new DWRITE_SHAPING_GLYPH_PROPERTIES[maxGlyphCount]; - hr = analyzer->GetGlyphs (textString, textLength, fontFace, false, - isRightToLeft, &runHead->mScript, localeName, - nullptr, &dwFeatures, featureRangeLengths, 1, - maxGlyphCount, clusterMap, textProperties, - glyphIndices, glyphProperties, &glyphCount); + hr = analyzer->GetGlyphs (textString, + chars_len, + fontFace, + false, + isRightToLeft, + &runHead->mScript, + localeName, + nullptr, + (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, + range_char_counts.arrayZ, + range_features.length, + maxGlyphCount, + clusterMap, + textProperties, + glyphIndices, + glyphProperties, + &glyphCount); if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) { @@ -715,101 +687,28 @@ retry_getglyphs: double x_mult = (double) font->x_scale / fontEmSize; double y_mult = (double) font->y_scale / fontEmSize; - hr = analyzer->GetGlyphPlacements (textString, clusterMap, textProperties, - textLength, glyphIndices, glyphProperties, - glyphCount, fontFace, fontEmSize, - false, isRightToLeft, &runHead->mScript, localeName, - &dwFeatures, featureRangeLengths, 1, - glyphAdvances, glyphOffsets); + hr = analyzer->GetGlyphPlacements (textString, + clusterMap, + textProperties, + chars_len, + glyphIndices, + glyphProperties, + glyphCount, + fontFace, + fontEmSize, + false, + isRightToLeft, + &runHead->mScript, + localeName, + (const DWRITE_TYPOGRAPHIC_FEATURES**) range_features.arrayZ, + range_char_counts.arrayZ, + range_features.length, + glyphAdvances, + glyphOffsets); if (FAILED (hr)) FAIL ("Analyzer failed to get glyph placements."); - IDWriteTextAnalyzer1* analyzer1; - analyzer->QueryInterface (&analyzer1); - - if (analyzer1 && lineWidth) - { - DWRITE_JUSTIFICATION_OPPORTUNITY* justificationOpportunities = - new DWRITE_JUSTIFICATION_OPPORTUNITY[maxGlyphCount]; - hr = analyzer1->GetJustificationOpportunities (fontFace, fontEmSize, runHead->mScript, - textLength, glyphCount, textString, - clusterMap, glyphProperties, - justificationOpportunities); - - if (FAILED (hr)) - FAIL ("Analyzer failed to get justification opportunities."); - - float* justifiedGlyphAdvances = new float[maxGlyphCount]; - DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = new DWRITE_GLYPH_OFFSET[glyphCount]; - hr = analyzer1->JustifyGlyphAdvances (lineWidth, glyphCount, justificationOpportunities, - glyphAdvances, glyphOffsets, justifiedGlyphAdvances, - justifiedGlyphOffsets); - - if (FAILED (hr)) FAIL ("Analyzer failed to get justify glyph advances."); - - DWRITE_SCRIPT_PROPERTIES scriptProperties; - hr = analyzer1->GetScriptProperties (runHead->mScript, &scriptProperties); - if (FAILED (hr)) FAIL ("Analyzer failed to get script properties."); - uint32_t justificationCharacter = scriptProperties.justificationCharacter; - - // if a script justificationCharacter is not space, it can have GetJustifiedGlyphs - if (justificationCharacter != 32) - { - uint16_t* modifiedClusterMap = new uint16_t[textLength]; - retry_getjustifiedglyphs: - uint16_t* modifiedGlyphIndices = new uint16_t[maxGlyphCount]; - float* modifiedGlyphAdvances = new float[maxGlyphCount]; - DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount]; - uint32_t actualGlyphsCount; - hr = analyzer1->GetJustifiedGlyphs (fontFace, fontEmSize, runHead->mScript, - textLength, glyphCount, maxGlyphCount, - clusterMap, glyphIndices, glyphAdvances, - justifiedGlyphAdvances, justifiedGlyphOffsets, - glyphProperties, &actualGlyphsCount, - modifiedClusterMap, modifiedGlyphIndices, - modifiedGlyphAdvances, modifiedGlyphOffsets); - - if (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)) - { - maxGlyphCount = actualGlyphsCount; - delete [] modifiedGlyphIndices; - delete [] modifiedGlyphAdvances; - delete [] modifiedGlyphOffsets; - - maxGlyphCount = actualGlyphsCount; - - goto retry_getjustifiedglyphs; - } - if (FAILED (hr)) - FAIL ("Analyzer failed to get justified glyphs."); - - delete [] clusterMap; - delete [] glyphIndices; - delete [] glyphAdvances; - delete [] glyphOffsets; - - glyphCount = actualGlyphsCount; - clusterMap = modifiedClusterMap; - glyphIndices = modifiedGlyphIndices; - glyphAdvances = modifiedGlyphAdvances; - glyphOffsets = modifiedGlyphOffsets; - - delete [] justifiedGlyphAdvances; - delete [] justifiedGlyphOffsets; - } - else - { - delete [] glyphAdvances; - delete [] glyphOffsets; - - glyphAdvances = justifiedGlyphAdvances; - glyphOffsets = justifiedGlyphOffsets; - } - - delete [] justificationOpportunities; - } - /* Ok, we've got everything we need, now compose output buffer, * very, *very*, carefully! */ @@ -870,43 +769,10 @@ retry_getglyphs: delete [] glyphAdvances; delete [] glyphOffsets; - if (num_features) - delete [] typographic_features.features; - /* Wow, done! */ return true; } -hb_bool_t -_hb_directwrite_shape (hb_shape_plan_t *shape_plan, - hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features) -{ - return _hb_directwrite_shape_full (shape_plan, font, buffer, - features, num_features, 0); -} - -HB_UNUSED static bool -_hb_directwrite_shape_experimental_width (hb_font_t *font, - hb_buffer_t *buffer, - const hb_feature_t *features, - unsigned int num_features, - float width) -{ - static const char *shapers = "directwrite"; - hb_shape_plan_t *shape_plan; - shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, - features, num_features, &shapers); - hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer, - features, num_features, width); - - buffer->unsafe_to_break_all (); - - return res; -} - struct _hb_directwrite_font_table_context { IDWriteFontFace *face; void *table_context; @@ -917,7 +783,7 @@ _hb_directwrite_table_data_release (void *data) { _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) data; context->face->ReleaseFontTable (context->table_context); - delete context; + hb_free (context); } static hb_blob_t * @@ -938,7 +804,7 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * return nullptr; } - _hb_directwrite_font_table_context *context = new _hb_directwrite_font_table_context; + _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) hb_malloc (sizeof (_hb_directwrite_font_table_context)); context->face = dw_face; context->table_context = table_context; @@ -957,6 +823,8 @@ _hb_directwrite_font_release (void *data) * hb_directwrite_face_create: * @font_face: a DirectWrite IDWriteFontFace object. * + * Constructs a new face object from the specified DirectWrite IDWriteFontFace. + * * Return value: #hb_face_t object corresponding to the given input * * Since: 2.4.0 @@ -974,6 +842,8 @@ hb_directwrite_face_create (IDWriteFontFace *font_face) * hb_directwrite_face_get_font_face: * @face: a #hb_face_t object * +* Gets the DirectWrite IDWriteFontFace associated with @face. +* * Return value: DirectWrite IDWriteFontFace object corresponding to the given input * * Since: 2.5.0 diff --git a/thirdparty/harfbuzz/src/hb-dispatch.hh b/thirdparty/harfbuzz/src/hb-dispatch.hh index 7eace86e54..4b2b65a8de 100644 --- a/thirdparty/harfbuzz/src/hb-dispatch.hh +++ b/thirdparty/harfbuzz/src/hb-dispatch.hh @@ -38,7 +38,6 @@ template <typename Context, typename Return=hb_empty_t, unsigned int MaxDebugDepth=0> struct hb_dispatch_context_t { - hb_dispatch_context_t () : debug_depth (0) {} private: /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ const Context* thiz () const { return static_cast<const Context *> (this); } @@ -54,7 +53,7 @@ struct hb_dispatch_context_t { return obj.dispatch (thiz (), hb_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; + unsigned debug_depth = 0; }; diff --git a/thirdparty/harfbuzz/src/hb-draw.cc b/thirdparty/harfbuzz/src/hb-draw.cc index 1a5f9c8c6b..c0af6ce013 100644 --- a/thirdparty/harfbuzz/src/hb-draw.cc +++ b/thirdparty/harfbuzz/src/hb-draw.cc @@ -191,7 +191,7 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *funcs) { if (!hb_object_destroy (funcs)) return; - free (funcs); + hb_free (funcs); } /** diff --git a/thirdparty/harfbuzz/src/hb-draw.h b/thirdparty/harfbuzz/src/hb-draw.h index 98eccf4c0c..bddc876399 100644 --- a/thirdparty/harfbuzz/src/hb-draw.h +++ b/thirdparty/harfbuzz/src/hb-draw.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index 33a788e7c5..2c0087370c 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -33,6 +33,7 @@ #include "hb-open-file.hh" #include "hb-ot-face.hh" #include "hb-ot-cmap-table.hh" +#include "hb-map.hh" /** @@ -89,8 +90,8 @@ DEFINE_NULL_INSTANCE (hb_face_t) = nullptr, /* destroy */ 0, /* index */ - HB_ATOMIC_INT_INIT (1000), /* upem */ - HB_ATOMIC_INT_INIT (0), /* num_glyphs */ + 1000, /* upem */ + 0, /* num_glyphs */ /* Zero for the rest is fine. */ }; @@ -100,15 +101,15 @@ DEFINE_NULL_INSTANCE (hb_face_t) = * hb_face_create_for_tables: * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): Table-referencing function * @user_data: A pointer to the user data - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * * Variant of hb_face_create(), built for those cases where it is more * convenient to provide data for individual tables instead of the whole font * data. With the caveat that hb_face_get_table_tags() does not currently work * with faces created this way. - * + * * Creates a new face object from the specified @user_data and @reference_table_func, - * with the @destroy callback. + * with the @destroy callback. * * Return value: (transfer full): The new face object * @@ -150,7 +151,7 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) { hb_face_for_data_closure_t *closure; - closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t)); + closure = (hb_face_for_data_closure_t *) hb_calloc (1, sizeof (hb_face_for_data_closure_t)); if (unlikely (!closure)) return nullptr; @@ -166,7 +167,7 @@ _hb_face_for_data_closure_destroy (void *data) hb_face_for_data_closure_t *closure = (hb_face_for_data_closure_t *) data; hb_blob_destroy (closure->blob); - free (closure); + hb_free (closure); } static hb_blob_t * @@ -235,7 +236,7 @@ hb_face_create (hb_blob_t *blob, * * Fetches the singleton empty face object. * - * Return value: (transfer full) The empty face object + * Return value: (transfer full): The empty face object * * Since: 0.9.2 **/ @@ -265,7 +266,7 @@ hb_face_reference (hb_face_t *face) /** * hb_face_destroy: (skip) * @face: A face object - * + * * Decreases the reference count on a face object. When the * reference count reaches zero, the face is destroyed, * freeing all memory. @@ -281,7 +282,7 @@ hb_face_destroy (hb_face_t *face) { hb_face_t::plan_node_t *next = node->next; hb_shape_plan_destroy (node->shape_plan); - free (node); + hb_free (node); node = next; } @@ -291,7 +292,7 @@ hb_face_destroy (hb_face_t *face) if (face->destroy) face->destroy (face->user_data); - free (face); + hb_free (face); } /** @@ -299,10 +300,10 @@ hb_face_destroy (hb_face_t *face) * @face: A face object * @key: The user-data key to set * @data: A pointer to the user data - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * - * Attaches a user-data key/data pair to the given face object. + * Attaches a user-data key/data pair to the given face object. * * Return value: %true if success, %false otherwise * @@ -360,7 +361,7 @@ hb_face_make_immutable (hb_face_t *face) * * Tests whether the given face object is immutable. * - * Return value: True is @face is immutable, false otherwise + * Return value: %true is @face is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -441,7 +442,7 @@ hb_face_set_index (hb_face_t *face, * * <note>Note: face indices within a collection are zero-based.</note> * - * Return value: The index of @face. + * Return value: The index of @face. * * Since: 0.9.2 **/ @@ -623,26 +624,26 @@ hb_face_collect_variation_unicodes (hb_face_t *face, struct hb_face_builder_data_t { - struct table_entry_t - { - int cmp (hb_tag_t t) const - { - if (t < tag) return -1; - if (t > tag) return -1; - return 0; - } - - hb_tag_t tag; - hb_blob_t *blob; - }; - - hb_vector_t<table_entry_t> tables; + hb_hashmap_t<hb_tag_t, hb_blob_t *> tables; }; +static int compare_entries (const void* pa, const void* pb) +{ + const auto& a = * (const hb_pair_t<hb_tag_t, hb_blob_t*> *) pa; + const auto& b = * (const hb_pair_t<hb_tag_t, hb_blob_t*> *) pb; + + /* Order by blob size first (smallest to largest) and then table tag */ + + if (a.second->length != b.second->length) + return a.second->length < b.second->length ? -1 : +1; + + return a.first < b.first ? -1 : a.first == b.first ? 0 : +1; +} + static hb_face_builder_data_t * _hb_face_builder_data_create () { - hb_face_builder_data_t *data = (hb_face_builder_data_t *) calloc (1, sizeof (hb_face_builder_data_t)); + hb_face_builder_data_t *data = (hb_face_builder_data_t *) hb_calloc (1, sizeof (hb_face_builder_data_t)); if (unlikely (!data)) return nullptr; @@ -656,25 +657,25 @@ _hb_face_builder_data_destroy (void *user_data) { hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data; - for (unsigned int i = 0; i < data->tables.length; i++) - hb_blob_destroy (data->tables[i].blob); + for (hb_blob_t* b : data->tables.values()) + hb_blob_destroy (b); data->tables.fini (); - free (data); + hb_free (data); } static hb_blob_t * _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data) { - unsigned int table_count = data->tables.length; + unsigned int table_count = data->tables.get_population (); unsigned int face_length = table_count * 16 + 12; - for (unsigned int i = 0; i < table_count; i++) - face_length += hb_ceil_to_4 (hb_blob_get_length (data->tables[i].blob)); + for (hb_blob_t* b : data->tables.values()) + face_length += hb_ceil_to_4 (hb_blob_get_length (b)); - char *buf = (char *) malloc (face_length); + char *buf = (char *) hb_malloc (face_length); if (unlikely (!buf)) return nullptr; @@ -682,20 +683,31 @@ _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data) c.propagate_error (data->tables); OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> (); - bool is_cff = data->tables.lsearch (HB_TAG ('C','F','F',' ')) || data->tables.lsearch (HB_TAG ('C','F','F','2')); + bool is_cff = (data->tables.has (HB_TAG ('C','F','F',' ')) + || data->tables.has (HB_TAG ('C','F','F','2'))); hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag; - bool ret = f->serialize_single (&c, sfnt_tag, data->tables.as_array ()); + // Sort the tags so that produced face is deterministic. + hb_vector_t<hb_pair_t <hb_tag_t, hb_blob_t*>> sorted_entries; + data->tables.iter () | hb_sink (sorted_entries); + if (unlikely (sorted_entries.in_error ())) + { + hb_free (buf); + return nullptr; + } + + sorted_entries.qsort (compare_entries); + bool ret = f->serialize_single (&c, sfnt_tag, + sorted_entries.iter()); c.end_serialize (); if (unlikely (!ret)) { - free (buf); + hb_free (buf); return nullptr; } - return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, free); + return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, hb_free); } static hb_blob_t * @@ -706,11 +718,7 @@ _hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void if (!tag) return _hb_face_builder_data_reference_blob (data); - hb_face_builder_data_t::table_entry_t *entry = data->tables.lsearch (tag); - if (entry) - return hb_blob_reference (entry->blob); - - return nullptr; + return hb_blob_reference (data->tables[tag]); } @@ -750,17 +758,21 @@ hb_face_builder_create () hb_bool_t hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) { + if (tag == HB_MAP_VALUE_INVALID) + return false; + if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy)) return false; hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data; - hb_face_builder_data_t::table_entry_t *entry = data->tables.push (); - if (data->tables.in_error()) + hb_blob_t* previous = data->tables.get (tag); + if (!data->tables.set (tag, hb_blob_reference (blob))) + { + hb_blob_destroy (blob); return false; + } - entry->tag = tag; - entry->blob = hb_blob_reference (blob); - + hb_blob_destroy (previous); return true; } diff --git a/thirdparty/harfbuzz/src/hb-face.h b/thirdparty/harfbuzz/src/hb-face.h index 3b18f7eef9..6ef2f8b886 100644 --- a/thirdparty/harfbuzz/src/hb-face.h +++ b/thirdparty/harfbuzz/src/hb-face.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -58,6 +58,19 @@ HB_EXTERN hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index); +/** + * hb_reference_table_func_t: + * @face: an #hb_face_t to reference table for + * @tag: the tag of the table to reference + * @user_data: User data pointer passed by the caller + * + * Callback function for hb_face_create_for_tables(). + * + * Return value: (transfer full): A pointer to the @tag table within @face + * + * Since: 0.9.2 + */ + typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); /* calls destroy() when not needing user_data anymore */ diff --git a/thirdparty/harfbuzz/src/hb-face.hh b/thirdparty/harfbuzz/src/hb-face.hh index f1b472ccf3..765f272858 100644 --- a/thirdparty/harfbuzz/src/hb-face.hh +++ b/thirdparty/harfbuzz/src/hb-face.hh @@ -81,7 +81,7 @@ struct hb_face_t return blob; } - HB_PURE_FUNC unsigned int get_upem () const + unsigned int get_upem () const { unsigned int ret = upem.get_relaxed (); if (unlikely (!ret)) diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index 5c8357ff28..fa8da96395 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -620,7 +620,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT - free (ffuncs); + hb_free (ffuncs); } /** @@ -628,7 +628,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) * @ffuncs: The font-functions structure * @key: The user-data key to set * @data: A pointer to the user data set - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified font-functions structure. @@ -690,7 +690,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) * * Tests whether a font-functions structure is immutable. * - * Return value: %true if @ffuncs is immutable, false otherwise + * Return value: %true if @ffuncs is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -753,10 +753,10 @@ hb_font_t::has_func (unsigned int i) * @font: #hb_font_t to work upon * @extents: (out): The font extents retrieved * - * Fetches the extents for a specified font, in horizontal + * Fetches the extents for a specified font, for horizontal * text segments. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 1.1.3 **/ @@ -772,10 +772,10 @@ hb_font_get_h_extents (hb_font_t *font, * @font: #hb_font_t to work upon * @extents: (out): The font extents retrieved * - * Fetches the extents for a specified font, in vertical + * Fetches the extents for a specified font, for vertical * text segments. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 1.1.3 **/ @@ -790,7 +790,7 @@ hb_font_get_v_extents (hb_font_t *font, * hb_font_get_glyph: * @font: #hb_font_t to work upon * @unicode: The Unicode code point to query - * @variation_selector: (optional): A variation-selector code point + * @variation_selector: A variation-selector code point * @glyph: (out): The glyph ID retrieved * * Fetches the glyph ID for a Unicode code point in the specified @@ -799,7 +799,7 @@ hb_font_get_v_extents (hb_font_t *font, * If @variation_selector is 0, calls hb_font_get_nominal_glyph(); * otherwise calls hb_font_get_variation_glyph(). * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -827,7 +827,7 @@ hb_font_get_glyph (hb_font_t *font, * for code points modified by variation selectors. For variation-selector * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph(). * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 1.2.3 **/ @@ -841,11 +841,17 @@ hb_font_get_nominal_glyph (hb_font_t *font, /** * hb_font_get_nominal_glyphs: - * @font: a font. - * + * @font: #hb_font_t to work upon + * @count: number of code points to query + * @first_unicode: The first Unicode code point to query + * @unicode_stride: The stride between successive code points + * @first_glyph: (out): The first glyph ID retrieved + * @glyph_stride: The stride between successive glyph IDs * + * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph + * IDs must be returned in a #hb_codepoint_t output parameter. * - * Return value: + * Return value: the number of code points processed * * Since: 2.6.3 **/ @@ -873,7 +879,7 @@ hb_font_get_nominal_glyphs (hb_font_t *font, * by the specified variation-selector code point, in the specified * font. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 1.2.3 **/ @@ -931,7 +937,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font, * @first_glyph: The first glyph ID to query * @glyph_stride: The stride between successive glyph IDs * @first_advance: (out): The first advance retrieved - * @advance_stride: (out): The stride between successive advances + * @advance_stride: The stride between successive advances * * Fetches the advances for a sequence of glyph IDs in the specified * font, for horizontal text segments. @@ -983,7 +989,7 @@ hb_font_get_glyph_v_advances (hb_font_t* font, * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for horizontal text segments. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1006,7 +1012,7 @@ hb_font_get_glyph_h_origin (hb_font_t *font, * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for vertical text segments. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1026,7 +1032,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font, * @right_glyph: The glyph ID of the right glyph in the glyph pair * * Fetches the kerning-adjustment value for a glyph-pair in - * the specified font, in horizontal text segments. + * the specified font, for horizontal text segments. * * <note>It handles legacy kerning only (as returned by the corresponding * #hb_font_funcs_t function).</note> @@ -1051,7 +1057,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair * * Fetches the kerning-adjustment value for a glyph-pair in - * the specified font, in vertical text segments. + * the specified font, for vertical text segments. * * <note>It handles legacy kerning only (as returned by the corresponding * #hb_font_funcs_t function).</note> @@ -1079,7 +1085,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, * Fetches the #hb_glyph_extents_t data for a glyph ID * in the specified font. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1102,7 +1108,7 @@ hb_font_get_glyph_extents (hb_font_t *font, * Fetches the (x,y) coordinates of a specified contour-point index * in the specified glyph, within the specified font. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1125,7 +1131,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font, * * Fetches the glyph-name string for a glyph ID in the specified @font. * - * Return value: %true if data found, zero otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1149,7 +1155,7 @@ hb_font_get_glyph_name (hb_font_t *font, * * <note>Note: @len == -1 means the name string is null-terminated.</note> * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1169,7 +1175,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, * hb_font_get_extents_for_direction: * @font: #hb_font_t to work upon * @direction: The direction of the text segment - * @extents: (out): The #hb_glyph_extents_t retrieved + * @extents: (out): The #hb_font_extents_t retrieved * * Fetches the extents for a font in a text segment of the * specified direction. @@ -1364,7 +1370,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1393,7 +1399,7 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1444,7 +1450,7 @@ hb_font_glyph_to_string (hb_font_t *font, * * <note>Note: @len == -1 means the string is null-terminated.</note> * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.2 **/ @@ -1538,8 +1544,8 @@ _hb_font_adopt_var_coords (hb_font_t *font, float *design_coords, unsigned int coords_length) { - free (font->coords); - free (font->design_coords); + hb_free (font->coords); + hb_free (font->design_coords); font->coords = coords; font->design_coords = design_coords; @@ -1580,8 +1586,8 @@ hb_font_create_sub_font (hb_font_t *parent) unsigned int num_coords = parent->num_coords; if (num_coords) { - int *coords = (int *) calloc (num_coords, sizeof (parent->coords[0])); - float *design_coords = (float *) calloc (num_coords, sizeof (parent->design_coords[0])); + int *coords = (int *) hb_calloc (num_coords, sizeof (parent->coords[0])); + float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0])); if (likely (coords && design_coords)) { memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0])); @@ -1590,8 +1596,8 @@ hb_font_create_sub_font (hb_font_t *parent) } else { - free (coords); - free (design_coords); + hb_free (coords); + hb_free (design_coords); } } @@ -1653,10 +1659,10 @@ hb_font_destroy (hb_font_t *font) hb_face_destroy (font->face); hb_font_funcs_destroy (font->klass); - free (font->coords); - free (font->design_coords); + hb_free (font->coords); + hb_free (font->design_coords); - free (font); + hb_free (font); } /** @@ -1664,12 +1670,12 @@ hb_font_destroy (hb_font_t *font) * @font: #hb_font_t to work upon * @key: The user-data key * @data: A pointer to the user data - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified font object. * - * Return value: + * Return value: %true if success, %false otherwise * * Since: 0.9.2 **/ @@ -1728,7 +1734,7 @@ hb_font_make_immutable (hb_font_t *font) * * Tests whether a font object is immutable. * - * Return value: %true if @font is immutable, false otherwise + * Return value: %true if @font is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -1828,9 +1834,9 @@ hb_font_get_face (hb_font_t *font) /** * hb_font_set_funcs: * @font: #hb_font_t to work upon - * @klass: (closure font_data) (destroy destroy) (scope notified): + * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure. * @font_data: Data to attach to @font - * @destroy: (optional): The function to call when @font_data is not needed anymore + * @destroy: (nullable): The function to call when @font_data is not needed anymore * * Replaces the font-functions structure attached to a font, updating * the font's user-data with @font-data and the @destroy callback. @@ -1867,7 +1873,7 @@ hb_font_set_funcs (hb_font_t *font, * hb_font_set_funcs_data: * @font: #hb_font_t to work upon * @font_data: (destroy destroy) (scope notified): Data to attach to @font - * @destroy: (optional): The function to call when @font_data is not needed anymore + * @destroy: (nullable): The function to call when @font_data is not needed anymore * * Replaces the user data attached to a font, updating the font's * @destroy callback. @@ -2046,29 +2052,30 @@ hb_font_set_variations (hb_font_t *font, return; } - unsigned int coords_length = hb_ot_var_get_axis_count (font->face); + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; - int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; - float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr; + int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; + float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; if (unlikely (coords_length && !(normalized && design_coords))) { - free (normalized); - free (design_coords); + hb_free (normalized); + hb_free (design_coords); return; } - const OT::fvar &fvar = *font->face->table.fvar; for (unsigned int i = 0; i < variations_length; i++) { - hb_ot_var_axis_info_t info; - if (hb_ot_var_find_axis_info (font->face, variations[i].tag, &info) && - info.axis_index < coords_length) - { - float v = variations[i].value; - design_coords[info.axis_index] = v; - normalized[info.axis_index] = fvar.normalize_axis_value (info.axis_index, v); - } + const auto tag = variations[i].tag; + const auto v = variations[i].value; + for (unsigned axis_index = 0; axis_index < coords_length; axis_index++) + if (axes[axis_index].axisTag == tag) + { + design_coords[axis_index] = v; + normalized[axis_index] = fvar.normalize_axis_value (axis_index, v); + } } font->face->table.avar->map_coords (normalized, coords_length); @@ -2094,13 +2101,13 @@ hb_font_set_var_coords_design (hb_font_t *font, if (hb_object_is_immutable (font)) return; - int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; - float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr; + int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; + float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; if (unlikely (coords_length && !(normalized && design_coords))) { - free (normalized); - free (design_coords); + hb_free (normalized); + hb_free (design_coords); return; } @@ -2129,13 +2136,13 @@ hb_font_set_var_named_instance (hb_font_t *font, unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr); - float *coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr; + float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; if (unlikely (coords_length && !coords)) return; hb_ot_var_named_instance_get_design_coords (font->face, instance_index, &coords_length, coords); hb_font_set_var_coords_design (font, coords, coords_length); - free (coords); + hb_free (coords); } /** @@ -2159,15 +2166,15 @@ hb_font_set_var_coords_normalized (hb_font_t *font, if (hb_object_is_immutable (font)) return; - int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; - int *unmapped = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; - float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (design_coords[0])) : nullptr; + int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; + int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr; + float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr; if (unlikely (coords_length && !(copy && unmapped && design_coords))) { - free (copy); - free (unmapped); - free (design_coords); + hb_free (copy); + hb_free (unmapped); + hb_free (design_coords); return; } @@ -2181,7 +2188,7 @@ hb_font_set_var_coords_normalized (hb_font_t *font, font->face->table.avar->unmap_coords (unmapped, coords_length); for (unsigned int i = 0; i < coords_length; ++i) design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]); - free (unmapped); + hb_free (unmapped); _hb_font_adopt_var_coords (font, copy, design_coords, coords_length); } @@ -2212,10 +2219,14 @@ hb_font_get_var_coords_normalized (hb_font_t *font, #ifdef HB_EXPERIMENTAL_API /** * hb_font_get_var_coords_design: + * @font: #hb_font_t to work upon + * @length: (out): number of coordinates * * Return value is valid as long as variation coordinates of the font * are not modified. * + * Return value: coordinates array + * * Since: EXPERIMENTAL */ const float * @@ -2257,7 +2268,7 @@ trampoline_create (FuncType func, { typedef hb_trampoline_t<FuncType> trampoline_t; - trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t)); + trampoline_t *trampoline = (trampoline_t *) hb_calloc (1, sizeof (trampoline_t)); if (unlikely (!trampoline)) return nullptr; @@ -2286,7 +2297,7 @@ trampoline_destroy (void *user_data) if (closure->destroy) closure->destroy (closure->user_data); - free (closure); + hb_free (closure); } typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t; @@ -2319,7 +2330,7 @@ hb_font_get_variation_glyph_trampoline (hb_font_t *font, * @ffuncs: The font-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): callback function * @user_data: data to pass to @func - * @destroy: (optional): function to call when @user_data is not needed anymore + * @destroy: (nullable): function to call when @user_data is not needed anymore * * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and * hb_font_funcs_set_variation_glyph_func() instead. diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h index 05f6c03f47..15dc126523 100644 --- a/thirdparty/harfbuzz/src/hb-font.h +++ b/thirdparty/harfbuzz/src/hb-font.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -37,7 +37,12 @@ HB_BEGIN_DECLS - +/** + * hb_font_t: + * + * Data type for holding fonts. + * + */ typedef struct hb_font_t hb_font_t; @@ -141,6 +146,16 @@ typedef struct hb_glyph_extents_t { /* func types */ +/** + * hb_font_get_font_extents_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @extents: (out): The font extents retrieved + * @user_data: User data pointer passed by the caller + * + * This method should retrieve the extents for a font. + * + **/ typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data, hb_font_extents_t *extents, void *user_data); @@ -150,7 +165,7 @@ typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *fon * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the extents for a font, in horizontal-direction + * This method should retrieve the extents for a font, for horizontal-direction * text segments. Extents must be returned in an #hb_glyph_extents output * parameter. * @@ -162,7 +177,7 @@ typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t; * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * - * This method should retrieve the extents for a font, in vertical-direction + * This method should retrieve the extents for a font, for vertical-direction * text segments. Extents must be returned in an #hb_glyph_extents output * parameter. * @@ -172,12 +187,19 @@ typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; /** * hb_font_get_nominal_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @unicode: The Unicode code point to query + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the nominal glyph ID for a specified Unicode code * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter. * + * Return value: %true if data found, %false otherwise + * **/ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t unicode, @@ -186,6 +208,12 @@ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *fo /** * hb_font_get_variation_glyph_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @unicode: The Unicode code point to query + * @variation_selector: The variation-selector code point to query + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * @@ -193,6 +221,8 @@ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *fo * followed by a specified Variation Selector code point. Glyph IDs must be * returned in a #hb_codepoint_t output parameter. * + * Return value: %true if data found, %false otherwise + * **/ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t unicode, hb_codepoint_t variation_selector, @@ -202,12 +232,22 @@ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void * /** * hb_font_get_nominal_glyphs_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @count: number of code points to query + * @first_unicode: The first Unicode code point to query + * @unicode_stride: The stride between successive code points + * @first_glyph: (out): The first glyph ID retrieved + * @glyph_stride: The stride between successive glyph IDs + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the nominal glyph IDs for a sequence of * Unicode code points. Glyph IDs must be returned in a #hb_codepoint_t * output parameter. + * + * Return value: the number of code points processed * **/ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data, @@ -220,12 +260,18 @@ typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void /** * hb_font_get_glyph_advance_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the advance for a specified glyph. The * method must return an #hb_position_t. * + * Return value: The advance of @glyph within @font + * **/ typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -257,6 +303,14 @@ typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t; /** * hb_font_get_glyph_advances_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @count: The number of glyph IDs in the sequence queried + * @first_glyph: The first glyph ID to query + * @glyph_stride: The stride between successive glyph IDs + * @first_advance: (out): The first advance retrieved + * @advance_stride: The stride between successive advances + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * @@ -295,12 +349,20 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; /** * hb_font_get_glyph_origin_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @x: (out): The X coordinate of the origin + * @y: (out): The Y coordinate of the origin + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the (X,Y) coordinates (in font units) of the * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. + * + * Return value: %true if data found, %false otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data, @@ -314,7 +376,7 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the (X,Y) coordinates (in font units) of the - * origin for a glyph, in horizontal-direction text segments. Each + * origin for a glyph, for horizontal-direction text segments. Each * coordinate must be returned in an #hb_position_t output parameter. * **/ @@ -326,25 +388,53 @@ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the (X,Y) coordinates (in font units) of the - * origin for a glyph, in vertical-direction text segments. Each coordinate + * origin for a glyph, for vertical-direction text segments. Each coordinate * must be returned in an #hb_position_t output parameter. * **/ typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; +/** + * hb_font_get_glyph_kerning_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @first_glyph: The glyph ID of the first glyph in the glyph pair + * @second_glyph: The glyph ID of the second glyph in the glyph pair + * @user_data: User data pointer passed by the caller + * + * This method should retrieve the kerning-adjustment value for a glyph-pair in + * the specified font, for horizontal text segments. + * + **/ typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, void *user_data); +/** + * hb_font_get_glyph_h_kerning_func_t: + * + * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. + * + * This method should retrieve the kerning-adjustment value for a glyph-pair in + * the specified font, for horizontal text segments. + * + **/ typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; /** * hb_font_get_glyph_extents_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @extents: (out): The #hb_glyph_extents_t retrieved + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the extents for a specified glyph. Extents must be * returned in an #hb_glyph_extents output parameter. + * + * Return value: %true if data found, %false otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, @@ -354,6 +444,13 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo /** * hb_font_get_glyph_contour_point_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @point_index: The contour-point index to query + * @x: (out): The X value retrieved for the contour point + * @y: (out): The Y value retrieved for the contour point + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * @@ -361,6 +458,8 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * + * Return value: %true if data found, %false otherwise + * **/ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, unsigned int point_index, @@ -370,12 +469,20 @@ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, vo /** * hb_font_get_glyph_name_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @glyph: The glyph ID to query + * @name: (out) (array length=size): Name string retrieved for the glyph ID + * @size: Length of the glyph-name string retrieved + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the glyph name that corresponds to a * glyph ID. The name should be returned in a string output parameter. * + * Return value: %true if data found, %false otherwise + * **/ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -384,12 +491,20 @@ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_ /** * hb_font_get_glyph_from_name_func_t: + * @font: #hb_font_t to work upon + * @font_data: @font user data pointer + * @name: (array length=len): The name string to query + * @len: The length of the name queried + * @glyph: (out): The glyph ID retrieved + * @user_data: User data pointer passed by the caller * * A virtual method for the #hb_font_funcs_t of an #hb_font_t object. * * This method should retrieve the glyph ID that corresponds to a glyph-name * string. * + * Return value: %true if data found, %false otherwise + * **/ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data, const char *name, int len, /* -1 means nul-terminated */ @@ -404,7 +519,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_font_h_extents_func_t. * @@ -420,7 +535,7 @@ hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_font_v_extents_func_t. * @@ -436,7 +551,7 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_nominal_glyph_func_t. * @@ -452,7 +567,7 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_nominal_glyphs_func_t. * @@ -468,7 +583,7 @@ hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_variation_glyph_func_t. * @@ -484,7 +599,7 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_h_advance_func_t. * @@ -500,7 +615,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_v_advance_func_t. * @@ -516,7 +631,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_h_advances_func_t. * @@ -532,7 +647,7 @@ hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_v_advances_func_t. * @@ -548,7 +663,7 @@ hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_h_origin_func_t. * @@ -564,7 +679,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_v_origin_func_t. * @@ -577,12 +692,12 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, /** * hb_font_funcs_set_glyph_h_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * + * @ffuncs: A font-function structure + * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign + * @user_data: Data to pass to @func + * @destroy: (nullable): The function to call when @user_data is not needed anymore * + * Sets the implementation function for #hb_font_get_glyph_h_kerning_func_t. * * Since: 0.9.2 **/ @@ -596,7 +711,7 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_extents_func_t. * @@ -612,7 +727,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_contour_point_func_t. * @@ -628,7 +743,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_name_func_t. * @@ -644,7 +759,7 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, * @ffuncs: A font-function structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_font_get_glyph_from_name_func_t. * diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index ab7d6146ce..97a2c82e68 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -84,14 +84,14 @@ struct hb_ft_font_t bool symbol; /* Whether selected cmap is symbol cmap. */ bool unref; /* Whether to destroy ft_face when done. */ - mutable hb_atomic_int_t cached_x_scale; + mutable int cached_x_scale; mutable hb_advance_cache_t advance_cache; }; static hb_ft_font_t * _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) { - hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t)); + hb_ft_font_t *ft_font = (hb_ft_font_t *) hb_calloc (1, sizeof (hb_ft_font_t)); if (unlikely (!ft_font)) return nullptr; ft_font->lock.init (); @@ -101,7 +101,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; - ft_font->cached_x_scale.set_relaxed (0); + ft_font->cached_x_scale = 0; ft_font->advance_cache.init (); return ft_font; @@ -125,7 +125,7 @@ _hb_ft_font_destroy (void *data) ft_font->lock.fini (); - free (ft_font); + hb_free (ft_font); } /** @@ -179,13 +179,13 @@ hb_ft_font_get_load_flags (hb_font_t *font) } /** - * hb_ft_get_face: + * hb_ft_font_get_face: * @font: #hb_font_t to work upon * * Fetches the FT_Face associated with the specified #hb_font_t * font object. * - * Return value: the FT_Face found + * Return value: (nullable): the FT_Face found or %NULL * * Since: 0.9.2 **/ @@ -202,11 +202,12 @@ hb_ft_font_get_face (hb_font_t *font) /** * hb_ft_font_lock_face: - * @font: - * + * @font: #hb_font_t to work upon * + * Gets the FT_Face associated with @font, This face will be kept around until + * you call hb_ft_font_unlock_face(). * - * Return value: + * Return value: (nullable): the FT_Face associated with @font or %NULL * Since: 2.6.5 **/ FT_Face @@ -224,11 +225,10 @@ hb_ft_font_lock_face (hb_font_t *font) /** * hb_ft_font_unlock_face: - * @font: - * + * @font: #hb_font_t to work upon * + * Releases an FT_Face previously obtained with hb_ft_font_lock_face(). * - * Return value: * Since: 2.6.5 **/ void @@ -335,10 +335,10 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, int load_flags = ft_font->load_flags; int mult = font->x_scale < 0 ? -1 : +1; - if (font->x_scale != ft_font->cached_x_scale.get ()) + if (font->x_scale != ft_font->cached_x_scale) { ft_font->advance_cache.clear (); - ft_font->cached_x_scale.set (font->x_scale); + ft_font->cached_x_scale = font->x_scale; } for (unsigned int i = 0; i < count; i++) @@ -561,9 +561,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, return true; } -#if HB_USE_ATEXIT -static void free_static_ft_funcs (); -#endif +static inline void free_static_ft_funcs (); static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft_font_funcs_lazy_loader_t> { @@ -591,21 +589,17 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft hb_font_funcs_make_immutable (funcs); -#if HB_USE_ATEXIT - atexit (free_static_ft_funcs); -#endif + hb_atexit (free_static_ft_funcs); return funcs; } } static_ft_funcs; -#if HB_USE_ATEXIT -static +static inline void free_static_ft_funcs () { static_ft_funcs.free_instance (); } -#endif static hb_font_funcs_t * _hb_ft_get_font_funcs () @@ -642,26 +636,26 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data if (error) return nullptr; - buffer = (FT_Byte *) malloc (length); + buffer = (FT_Byte *) hb_malloc (length); if (!buffer) return nullptr; error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length); if (error) { - free (buffer); + hb_free (buffer); return nullptr; } return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, - buffer, free); + buffer, hb_free); } /** * hb_ft_face_create: * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon - * @destroy: (optional): A callback to call when the face object is not needed anymore + * @destroy: (nullable): A callback to call when the face object is not needed anymore * * Creates an #hb_face_t face object from the specified FT_Face. * @@ -771,13 +765,13 @@ hb_ft_face_create_cached (FT_Face ft_face) /** * hb_ft_font_create: * @ft_face: (destroy destroy) (scope notified): FT_Face to work upon - * @destroy: (optional): A callback to call when the font object is not needed anymore + * @destroy: (nullable): A callback to call when the font object is not needed anymore * * Creates an #hb_font_t font object from the specified FT_Face. * * <note>Note: You must set the face size on @ft_face before calling - * hb_ft_font_create() on it. Otherwise, HarfBuzz will not pick up - * the face size.</note> + * hb_ft_font_create() on it. HarfBuzz assumes size is always set and will + * access `size` member of FT_Face unconditionally.</note> * * This variant of the function does not provide any life-cycle management. * @@ -814,7 +808,7 @@ hb_ft_font_create (FT_Face ft_face, } /** - * hb_ft_font_has_changed: + * hb_ft_font_changed: * @font: #hb_font_t to work upon * * Refreshes the state of @font when the underlying FT_Face has changed. @@ -846,8 +840,8 @@ hb_ft_font_changed (hb_font_t *font) FT_MM_Var *mm_var = nullptr; if (!FT_Get_MM_Var (ft_face, &mm_var)) { - FT_Fixed *ft_coords = (FT_Fixed *) calloc (mm_var->num_axis, sizeof (FT_Fixed)); - int *coords = (int *) calloc (mm_var->num_axis, sizeof (int)); + FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (mm_var->num_axis, sizeof (FT_Fixed)); + int *coords = (int *) hb_calloc (mm_var->num_axis, sizeof (int)); if (coords && ft_coords) { if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords)) @@ -866,12 +860,12 @@ hb_ft_font_changed (hb_font_t *font) hb_font_set_var_coords_normalized (font, nullptr, 0); } } - free (coords); - free (ft_coords); + hb_free (coords); + hb_free (ft_coords); #ifdef HAVE_FT_DONE_MM_VAR FT_Done_MM_Var (ft_face->glyph->library, mm_var); #else - free (mm_var); + hb_free (mm_var); #endif } #endif @@ -884,8 +878,8 @@ hb_ft_font_changed (hb_font_t *font) * Creates an #hb_font_t font object from the specified FT_Face. * * <note>Note: You must set the face size on @ft_face before calling - * hb_ft_font_create_references() on it. Otherwise, HarfBuzz will not pick up - * the face size.</note> + * hb_ft_font_create_referenced() on it. HarfBuzz assumes size is always set + * and will access `size` member of FT_Face unconditionally.</note> * * This is the preferred variant of the hb_ft_font_create* * function family, because it calls FT_Reference_Face() on @ft_face, @@ -905,9 +899,7 @@ hb_ft_font_create_referenced (FT_Face ft_face) return hb_ft_font_create (ft_face, _hb_ft_face_destroy); } -#if HB_USE_ATEXIT -static void free_static_ft_library (); -#endif +static inline void free_static_ft_library (); static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>, hb_ft_library_lazy_loader_t> @@ -918,9 +910,7 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<F if (FT_Init_FreeType (&l)) return nullptr; -#if HB_USE_ATEXIT - atexit (free_static_ft_library); -#endif + hb_atexit (free_static_ft_library); return l; } @@ -934,13 +924,11 @@ static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<F } } static_ft_library; -#if HB_USE_ATEXIT -static +static inline void free_static_ft_library () { static_ft_library.free_instance (); } -#endif static FT_Library get_ft_library () @@ -1020,13 +1008,13 @@ hb_ft_font_set_funcs (hb_font_t *font) const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); if (num_coords) { - FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed)); + FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { for (unsigned int i = 0; i < num_coords; i++) ft_coords[i] = coords[i] * 4; FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); - free (ft_coords); + hb_free (ft_coords); } } #endif diff --git a/thirdparty/harfbuzz/src/hb-gdi.cc b/thirdparty/harfbuzz/src/hb-gdi.cc index 3a67cef160..8e7589beac 100644 --- a/thirdparty/harfbuzz/src/hb-gdi.cc +++ b/thirdparty/harfbuzz/src/hb-gdi.cc @@ -50,16 +50,16 @@ _hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_dat length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length); if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc; - buffer = (char *) malloc (length); + buffer = (char *) hb_malloc (length); if (unlikely (!buffer)) goto fail_with_releasedc; length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length); if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc_and_free; ReleaseDC (nullptr, hdc); - return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free); + return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, hb_free); fail_with_releasedc_and_free: - free (buffer); + hb_free (buffer); fail_with_releasedc: ReleaseDC (nullptr, hdc); fail: @@ -70,6 +70,8 @@ fail: * hb_gdi_face_create: * @hfont: a HFONT object. * + * Constructs a new face object from the specified GDI HFONT. + * * Return value: #hb_face_t object corresponding to the given input * * Since: 2.6.0 diff --git a/thirdparty/harfbuzz/src/hb-glib.cc b/thirdparty/harfbuzz/src/hb-glib.cc index f93bb8853c..8ddc7ebad8 100644 --- a/thirdparty/harfbuzz/src/hb-glib.cc +++ b/thirdparty/harfbuzz/src/hb-glib.cc @@ -218,9 +218,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, } -#if HB_USE_ATEXIT -static void free_static_glib_funcs (); -#endif +static inline void free_static_glib_funcs (); static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_glib_unicode_funcs_lazy_loader_t> { @@ -237,21 +235,17 @@ static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader hb_unicode_funcs_make_immutable (funcs); -#if HB_USE_ATEXIT - atexit (free_static_glib_funcs); -#endif + hb_atexit (free_static_glib_funcs); return funcs; } } static_glib_funcs; -#if HB_USE_ATEXIT -static +static inline void free_static_glib_funcs () { static_glib_funcs.free_instance (); } -#endif /** * hb_glib_get_unicode_funcs: diff --git a/thirdparty/harfbuzz/src/hb-gobject-structs.cc b/thirdparty/harfbuzz/src/hb-gobject-structs.cc index 7c46e26400..540b11f911 100644 --- a/thirdparty/harfbuzz/src/hb-gobject-structs.cc +++ b/thirdparty/harfbuzz/src/hb-gobject-structs.cc @@ -80,12 +80,12 @@ hb_gobject_##name##_get_type () \ #define HB_DEFINE_VALUE_TYPE(name) \ static hb_##name##_t *_hb_##name##_reference (const hb_##name##_t *l) \ { \ - hb_##name##_t *c = (hb_##name##_t *) calloc (1, sizeof (hb_##name##_t)); \ + hb_##name##_t *c = (hb_##name##_t *) hb_calloc (1, sizeof (hb_##name##_t)); \ if (unlikely (!c)) return nullptr; \ *c = *l; \ return c; \ } \ - static void _hb_##name##_destroy (hb_##name##_t *l) { free (l); } \ + static void _hb_##name##_destroy (hb_##name##_t *l) { hb_free (l); } \ HB_DEFINE_BOXED_TYPE (name, _hb_##name##_reference, _hb_##name##_destroy) HB_DEFINE_OBJECT_TYPE (buffer) diff --git a/thirdparty/harfbuzz/src/hb-gobject-structs.h b/thirdparty/harfbuzz/src/hb-gobject-structs.h index 6fad8d7019..63467f80df 100644 --- a/thirdparty/harfbuzz/src/hb-gobject-structs.h +++ b/thirdparty/harfbuzz/src/hb-gobject-structs.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_GOBJECT_H_IN +#if !defined(HB_GOBJECT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-gobject.h> instead." #endif @@ -40,47 +40,22 @@ HB_BEGIN_DECLS /* Object types */ -/** - * hb_gobject_blob_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_blob_get_type (void); #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) -/** - * hb_gobject_buffer_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_buffer_get_type (void); #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) -/** - * hb_gobject_face_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_face_get_type (void); #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) -/** - * hb_gobject_font_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_font_get_type (void); #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) -/** - * hb_gobject_font_funcs_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_font_funcs_get_type (void); #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) @@ -97,11 +72,6 @@ HB_EXTERN GType hb_gobject_shape_plan_get_type (void); #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) -/** - * hb_gobject_unicode_funcs_get_type: - * - * Since: 0.9.2 - **/ HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void); #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index d8a72dc2f1..209207f1e5 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -88,7 +88,7 @@ static const void *hb_graphite2_get_table (const void *data, unsigned int tag, s { blob = face_data->face->reference_table (tag); - hb_graphite2_tablelist_t *p = (hb_graphite2_tablelist_t *) calloc (1, sizeof (hb_graphite2_tablelist_t)); + hb_graphite2_tablelist_t *p = (hb_graphite2_tablelist_t *) hb_calloc (1, sizeof (hb_graphite2_tablelist_t)); if (unlikely (!p)) { hb_blob_destroy (blob); return nullptr; @@ -123,15 +123,16 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face) } hb_blob_destroy (silf_blob); - hb_graphite2_face_data_t *data = (hb_graphite2_face_data_t *) calloc (1, sizeof (hb_graphite2_face_data_t)); + hb_graphite2_face_data_t *data = (hb_graphite2_face_data_t *) hb_calloc (1, sizeof (hb_graphite2_face_data_t)); if (unlikely (!data)) return nullptr; data->face = face; - data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll); + const gr_face_ops ops = {sizeof(gr_face_ops), &hb_graphite2_get_table, NULL}; + data->grface = gr_make_face_with_ops (data, &ops, gr_face_preloadAll); if (unlikely (!data->grface)) { - free (data); + hb_free (data); return nullptr; } @@ -148,12 +149,12 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data) hb_graphite2_tablelist_t *old = tlist; hb_blob_destroy (tlist->blob); tlist = tlist->next; - free (old); + hb_free (old); } gr_face_destroy (data->grface); - free (data); + hb_free (data); } /** @@ -195,6 +196,11 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED #ifndef HB_DISABLE_DEPRECATED /** * hb_graphite2_font_get_gr_font: + * @font: An #hb_font_t + * + * Always returns %NULL. Use hb_graphite2_face_get_gr_face() instead. + * + * Return value: (nullable): Graphite2 font associated with @font. * * Since: 0.9.10 * Deprecated: 1.4.2 @@ -284,7 +290,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, return true; } - buffer->ensure (glyph_count); + (void) buffer->ensure (glyph_count); scratch = buffer->get_scratch_buffer (&scratch_size); while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) + DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size) diff --git a/thirdparty/harfbuzz/src/hb-icu.cc b/thirdparty/harfbuzz/src/hb-icu.cc index 008a39e414..e46401f7a6 100644 --- a/thirdparty/harfbuzz/src/hb-icu.cc +++ b/thirdparty/harfbuzz/src/hb-icu.cc @@ -233,9 +233,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, } -#if HB_USE_ATEXIT -static void free_static_icu_funcs (); -#endif +static inline void free_static_icu_funcs (); static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_icu_unicode_funcs_lazy_loader_t> { @@ -257,21 +255,17 @@ static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ hb_unicode_funcs_make_immutable (funcs); -#if HB_USE_ATEXIT - atexit (free_static_icu_funcs); -#endif + hb_atexit (free_static_icu_funcs); return funcs; } } static_icu_funcs; -#if HB_USE_ATEXIT -static +static inline void free_static_icu_funcs () { static_icu_funcs.free_instance (); } -#endif /** * hb_icu_get_unicode_funcs: diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index 981c5c218c..b8c4472636 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -46,7 +46,7 @@ * TODO Document more. * * If iterator implementation implements operator!=, then can be - * used in range-based for loop. That comes free if the iterator + * used in range-based for loop. That already happens if the iterator * is random-access. Otherwise, the range-based for loop incurs * one traversal to find end(), which can be avoided if written * as a while-style for loop, or if iterator implements a faster @@ -922,7 +922,7 @@ HB_FUNCOBJ (hb_none); template <typename C, typename V, hb_requires (hb_is_iterable (C))> inline void -hb_fill (C& c, const V &v) +hb_fill (C&& c, const V &v) { for (auto i = hb_iter (c); i; i++) *i = v; diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh index 54bc60d4c8..010c2570d7 100644 --- a/thirdparty/harfbuzz/src/hb-machinery.hh +++ b/thirdparty/harfbuzz/src/hb-machinery.hh @@ -80,6 +80,11 @@ static inline Type& StructAfter(TObject &X) * Size checking */ +/* Size signifying variable-sized array */ +#ifndef HB_VAR_ARRAY +#define HB_VAR_ARRAY 1 +#endif + /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ void _instance_assertion_on_line_##_line () const \ @@ -237,14 +242,14 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> static const Stored* get_null () { return &Null (Stored); } static Stored *create (Data *data) { - Stored *p = (Stored *) calloc (1, sizeof (Stored)); + Stored *p = (Stored *) hb_calloc (1, sizeof (Stored)); if (likely (p)) p->init (data); return p; } static Stored *create () { - Stored *p = (Stored *) calloc (1, sizeof (Stored)); + Stored *p = (Stored *) hb_calloc (1, sizeof (Stored)); if (likely (p)) p->init (); return p; @@ -252,7 +257,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> static void destroy (Stored *p) { p->fini (); - free (p); + hb_free (p); } // private: diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc index f898bd8f92..9f1ac42846 100644 --- a/thirdparty/harfbuzz/src/hb-map.cc +++ b/thirdparty/harfbuzz/src/hb-map.cc @@ -109,7 +109,7 @@ hb_map_destroy (hb_map_t *map) map->fini_shallow (); - free (map); + hb_free (map); } /** @@ -117,7 +117,7 @@ hb_map_destroy (hb_map_t *map) * @map: A map * @key: The user-data key to set * @data: A pointer to the user data to set - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified map. @@ -162,7 +162,7 @@ hb_map_get_user_data (hb_map_t *map, * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, false otherwise + * Return value: %true if allocation succeeded, %false otherwise * * Since: 1.7.7 **/ @@ -188,6 +188,7 @@ hb_map_set (hb_map_t *map, hb_codepoint_t key, hb_codepoint_t value) { + /* Immutable-safe. */ map->set (key, value); } @@ -220,6 +221,7 @@ void hb_map_del (hb_map_t *map, hb_codepoint_t key) { + /* Immutable-safe. */ map->del (key); } @@ -230,7 +232,7 @@ hb_map_del (hb_map_t *map, * * Tests whether @key is an element of @map. * - * Return value: %true if @key is found in @map, false otherwise + * Return value: %true if @key is found in @map, %false otherwise * * Since: 1.7.7 **/ diff --git a/thirdparty/harfbuzz/src/hb-map.h b/thirdparty/harfbuzz/src/hb-map.h index 0c19ac8fb5..6a45a7bdd5 100644 --- a/thirdparty/harfbuzz/src/hb-map.h +++ b/thirdparty/harfbuzz/src/hb-map.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,7 +36,11 @@ HB_BEGIN_DECLS -/* +/** + * HB_MAP_VALUE_INVALID: + * + * Unset #hb_map_t value. + * * Since: 1.7.7 */ #define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1) diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index 92c1bd67e5..dcd5267d74 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -85,7 +85,7 @@ struct hb_hashmap_t } void fini_shallow () { - free (items); + hb_free (items); items = nullptr; population = occupancy = 0; } @@ -97,8 +97,6 @@ struct hb_hashmap_t void reset () { - if (unlikely (hb_object_is_immutable (this))) - return; successful = true; clear (); } @@ -111,7 +109,7 @@ struct hb_hashmap_t unsigned int power = hb_bit_storage (population * 2 + 8); unsigned int new_size = 1u << power; - item_t *new_items = (item_t *) malloc ((size_t) new_size * sizeof (item_t)); + item_t *new_items = (item_t *) hb_malloc ((size_t) new_size * sizeof (item_t)); if (unlikely (!new_items)) { successful = false; @@ -137,14 +135,14 @@ struct hb_hashmap_t old_items[i].hash, old_items[i].value); - free (old_items); + hb_free (old_items); return true; } - void set (K key, V value) + bool set (K key, V value) { - set_with_hash (key, hb_hash (key), value); + return set_with_hash (key, hb_hash (key), value); } V get (K key) const @@ -171,8 +169,8 @@ struct hb_hashmap_t void clear () { - if (unlikely (hb_object_is_immutable (this))) - return; + if (unlikely (!successful)) return; + if (items) for (auto &_ : hb_iter (items, mask + 1)) _.clear (); @@ -181,6 +179,7 @@ struct hb_hashmap_t } bool is_empty () const { return population == 0; } + explicit operator bool () const { return !is_empty (); } unsigned int get_population () const { return population; } @@ -214,20 +213,20 @@ struct hb_hashmap_t protected: - void set_with_hash (K key, uint32_t hash, V value) + bool set_with_hash (K key, uint32_t hash, V value) { - if (unlikely (!successful)) return; - if (unlikely (key == kINVALID)) return; - if ((occupancy + occupancy / 2) >= mask && !resize ()) return; + if (unlikely (!successful)) return false; + if (unlikely (key == kINVALID)) return true; + if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false; unsigned int i = bucket_for_hash (key, hash); if (value == vINVALID && items[i].key != key) - return; /* Trying to delete non-existent key. */ + return true; /* Trying to delete non-existent key. */ if (!items[i].is_unused ()) { occupancy--; - if (items[i].is_tombstone ()) + if (!items[i].is_tombstone ()) population--; } @@ -238,6 +237,8 @@ struct hb_hashmap_t occupancy++; if (!items[i].is_tombstone ()) population++; + + return true; } unsigned int bucket_for (K key) const diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index 4c0898b1b7..a714bc2bf0 100644 --- a/thirdparty/harfbuzz/src/hb-meta.hh +++ b/thirdparty/harfbuzz/src/hb-meta.hh @@ -49,6 +49,10 @@ template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>; using hb_true_type = hb_bool_constant<true>; using hb_false_type = hb_bool_constant<false>; +/* Static-assert as expression. */ +template <bool cond> struct static_assert_expr; +template <> struct static_assert_expr<true> : hb_false_type {}; +#define static_assert_expr(C) static_assert_expr<C>::value /* Basic type SFINAE. */ @@ -97,14 +101,14 @@ HB_FUNCOBJ (hb_addressof); template <typename T> static inline T hb_declval (); #define hb_declval(T) (hb_declval<T> ()) -template <typename T> struct hb_match_const : hb_type_identity_t<T>, hb_bool_constant<false>{}; -template <typename T> struct hb_match_const<const T> : hb_type_identity_t<T>, hb_bool_constant<true> {}; +template <typename T> struct hb_match_const : hb_type_identity_t<T>, hb_false_type {}; +template <typename T> struct hb_match_const<const T> : hb_type_identity_t<T>, hb_true_type {}; template <typename T> using hb_remove_const = typename hb_match_const<T>::type; template <typename T> using hb_add_const = const T; #define hb_is_const(T) hb_match_const<T>::value -template <typename T> struct hb_match_reference : hb_type_identity_t<T>, hb_bool_constant<false>{}; -template <typename T> struct hb_match_reference<T &> : hb_type_identity_t<T>, hb_bool_constant<true> {}; -template <typename T> struct hb_match_reference<T &&> : hb_type_identity_t<T>, hb_bool_constant<true> {}; +template <typename T> struct hb_match_reference : hb_type_identity_t<T>, hb_false_type {}; +template <typename T> struct hb_match_reference<T &> : hb_type_identity_t<T>, hb_true_type {}; +template <typename T> struct hb_match_reference<T &&> : hb_type_identity_t<T>, hb_true_type {}; template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type; template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity<T&>; template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity<T>; @@ -113,8 +117,8 @@ template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_t template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>; template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize)); #define hb_is_reference(T) hb_match_reference<T>::value -template <typename T> struct hb_match_pointer : hb_type_identity_t<T>, hb_bool_constant<false>{}; -template <typename T> struct hb_match_pointer<T *> : hb_type_identity_t<T>, hb_bool_constant<true> {}; +template <typename T> struct hb_match_pointer : hb_type_identity_t<T>, hb_false_type {}; +template <typename T> struct hb_match_pointer<T *> : hb_type_identity_t<T>, hb_true_type {}; template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type; template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>; template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>; @@ -220,6 +224,8 @@ struct hb_reference_wrapper<T&> }; +/* Type traits */ + template <typename T> using hb_is_integral = hb_bool_constant< hb_is_same (hb_decay<T>, char) || @@ -253,15 +259,15 @@ using hb_is_arithmetic = hb_bool_constant< #define hb_is_arithmetic(T) hb_is_arithmetic<T>::value -template <typename T> -using hb_is_signed = hb_conditional<hb_is_arithmetic (T), - hb_bool_constant<(T) -1 < (T) 0>, - hb_false_type>; +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> -using hb_is_unsigned = hb_conditional<hb_is_arithmetic (T), - hb_bool_constant<(T) 0 < (T) -1>, - hb_false_type>; +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; @@ -276,6 +282,7 @@ template <> struct hb_int_min<signed long> : hb_integral_constant<signed long, template <> struct hb_int_min<unsigned long> : hb_integral_constant<unsigned long, 0> {}; template <> struct hb_int_min<signed long long> : hb_integral_constant<signed long long, LLONG_MIN> {}; template <> struct hb_int_min<unsigned long long> : hb_integral_constant<unsigned long long, 0> {}; +template <typename T> struct hb_int_min<T *> : hb_integral_constant<T *, nullptr> {}; #define hb_int_min(T) hb_int_min<T>::value template <typename T> struct hb_int_max; template <> struct hb_int_max<char> : hb_integral_constant<char, CHAR_MAX> {}; @@ -292,6 +299,15 @@ template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigne #define hb_int_max(T) hb_int_max<T>::value +/* Class traits. */ + +#define HB_DELETE_COPY_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete +#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ + TypeName() = delete; \ + TypeName(const TypeName&) = delete; \ + void operator=(const TypeName&) = delete template <typename T, typename> struct _hb_is_destructible : hb_false_type {}; diff --git a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc new file mode 100644 index 0000000000..6d09b252d8 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc @@ -0,0 +1,177 @@ +/* + * Copyright © 2011,2012,2013 Google, Inc. + * Copyright © 2021 Khaled Hosny + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-ms-feature-ranges.hh" + +bool +hb_ms_setup_features (const hb_feature_t *features, + unsigned int num_features, + hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */ + hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */) +{ + feature_records.shrink(0); + range_records.shrink(0); + + /* Sort features by start/end events. */ + hb_vector_t<hb_ms_feature_event_t> feature_events; + for (unsigned int i = 0; i < num_features; i++) + { + hb_ms_active_feature_t feature; + feature.fea.tag_le = hb_uint32_swap (features[i].tag); + feature.fea.value = features[i].value; + feature.order = i; + + hb_ms_feature_event_t *event; + + event = feature_events.push (); + event->index = features[i].start; + event->start = true; + event->feature = feature; + + event = feature_events.push (); + event->index = features[i].end; + event->start = false; + event->feature = feature; + } + feature_events.qsort (); + /* Add a strategic final event. */ + { + hb_ms_active_feature_t feature; + feature.fea.tag_le = 0; + feature.fea.value = 0; + feature.order = num_features + 1; + + auto *event = feature_events.push (); + event->index = 0; /* This value does magic. */ + event->start = false; + event->feature = feature; + } + + /* Scan events and save features for each range. */ + hb_vector_t<hb_ms_active_feature_t> active_features; + unsigned int last_index = 0; + for (unsigned int i = 0; i < feature_events.length; i++) + { + auto *event = &feature_events[i]; + + if (event->index != last_index) + { + /* Save a snapshot of active features and the range. */ + auto *range = range_records.push (); + auto offset = feature_records.length; + + active_features.qsort (); + for (unsigned int j = 0; j < active_features.length; j++) + { + if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le) + { + feature_records.push (active_features[j].fea); + } + else + { + /* Overrides value for existing feature. */ + feature_records[feature_records.length - 1].value = active_features[j].fea.value; + } + } + + /* Will convert to pointer after all is ready, since feature_records.array + * may move as we grow it. */ + range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset); + range->features.num_features = feature_records.length - offset; + range->index_first = last_index; + range->index_last = event->index - 1; + + last_index = event->index; + } + + if (event->start) + { + active_features.push (event->feature); + } + else + { + auto *feature = active_features.find (&event->feature); + if (feature) + active_features.remove (feature - active_features.arrayZ); + } + } + + if (!range_records.length) /* No active feature found. */ + num_features = 0; + + /* Fixup the pointers. */ + for (unsigned int i = 0; i < range_records.length; i++) + { + auto *range = &range_records[i]; + range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features); + } + + return !!num_features; +} + +void +hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records, + hb_vector_t<hb_ms_range_record_t> &range_records, + unsigned int chars_offset, + unsigned int chars_len, + uint16_t *log_clusters, + hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */ + hb_vector_t<uint32_t> &range_counts /* OUT */) +{ + range_features.shrink (0); + range_counts.shrink (0); + + auto *last_range = &range_records[0]; + for (unsigned int i = chars_offset; i < chars_len; i++) + { + auto *range = last_range; + while (log_clusters[i] < range->index_first) + range--; + while (log_clusters[i] > range->index_last) + range++; + if (!range_features.length || + &range->features != range_features[range_features.length - 1]) + { + auto **features = range_features.push (); + auto *c = range_counts.push (); + if (unlikely (!features || !c)) + { + range_features.shrink (0); + range_counts.shrink (0); + break; + } + *features = &range->features; + *c = 1; + } + else + { + range_counts[range_counts.length - 1]++; + } + + last_range = range; + } +} diff --git a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh new file mode 100644 index 0000000000..401d1e1d97 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh @@ -0,0 +1,96 @@ +/* + * Copyright © 2011,2012,2013 Google, Inc. + * Copyright © 2021 Khaled Hosny + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_MS_FEATURE_RANGES_HH +#define HB_MS_FEATURE_RANGES_HH + +#include "hb.hh" + +typedef struct hb_ms_feature_t { + uint32_t tag_le; + uint32_t value; +} hb_ms_feature_t; + +typedef struct hb_ms_features_t { + hb_ms_feature_t *features; + uint32_t num_features; +} hb_ms_features_t; + +struct hb_ms_active_feature_t { + hb_ms_feature_t fea; + unsigned int order; + + HB_INTERNAL static int cmp (const void *pa, const void *pb) { + const auto *a = (const hb_ms_active_feature_t *) pa; + const auto *b = (const hb_ms_active_feature_t *) pb; + return a->fea.tag_le < b->fea.tag_le ? -1 : a->fea.tag_le > b->fea.tag_le ? 1 : + a->order < b->order ? -1 : a->order > b->order ? 1 : + a->fea.value < b->fea.value ? -1 : a->fea.value > b->fea.value ? 1 : + 0; + } + bool operator== (const hb_ms_active_feature_t *f) + { return cmp (this, f) == 0; } +}; + +struct hb_ms_feature_event_t { + unsigned int index; + bool start; + hb_ms_active_feature_t feature; + + HB_INTERNAL static int cmp (const void *pa, const void *pb) + { + const auto *a = (const hb_ms_feature_event_t *) pa; + const auto *b = (const hb_ms_feature_event_t *) pb; + return a->index < b->index ? -1 : a->index > b->index ? 1 : + a->start < b->start ? -1 : a->start > b->start ? 1 : + hb_ms_active_feature_t::cmp (&a->feature, &b->feature); + } +}; + +struct hb_ms_range_record_t { + hb_ms_features_t features; + unsigned int index_first; /* == start */ + unsigned int index_last; /* == end - 1 */ +}; + +HB_INTERNAL bool +hb_ms_setup_features (const hb_feature_t *features, + unsigned int num_features, + hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */ + hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */); + + +HB_INTERNAL void +hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records, + hb_vector_t<hb_ms_range_record_t> &range_records, + unsigned int chars_offset, + unsigned int chars_len, + uint16_t *log_clusters, + hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */ + hb_vector_t<uint32_t> &range_counts /* OUT */); + +#endif /* HB_MS_FEATURE_RANGES_HH */ diff --git a/thirdparty/harfbuzz/src/hb-mutex.hh b/thirdparty/harfbuzz/src/hb-mutex.hh index 56392d049b..a9227a741d 100644 --- a/thirdparty/harfbuzz/src/hb-mutex.hh +++ b/thirdparty/harfbuzz/src/hb-mutex.hh @@ -39,8 +39,7 @@ /* We need external help for these */ -#if defined(HB_MUTEX_IMPL_INIT) \ - && defined(hb_mutex_impl_init) \ +#if defined(hb_mutex_impl_init) \ && defined(hb_mutex_impl_lock) \ && defined(hb_mutex_impl_unlock) \ && defined(hb_mutex_impl_finish) @@ -52,7 +51,6 @@ #include <pthread.h> typedef pthread_mutex_t hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT PTHREAD_MUTEX_INITIALIZER #define hb_mutex_impl_init(M) pthread_mutex_init (M, nullptr) #define hb_mutex_impl_lock(M) pthread_mutex_lock (M) #define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M) @@ -62,7 +60,6 @@ typedef pthread_mutex_t hb_mutex_impl_t; #elif !defined(HB_NO_MT) && defined(_WIN32) typedef CRITICAL_SECTION hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT {0} #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0) #else @@ -73,28 +70,9 @@ typedef CRITICAL_SECTION hb_mutex_impl_t; #define hb_mutex_impl_finish(M) DeleteCriticalSection (M) -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD) -# include <sched.h> -# define HB_SCHED_YIELD() sched_yield () -#else -# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END -#endif - -/* This actually is not a totally awful implementation. */ -typedef volatile int hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT 0 -#define hb_mutex_impl_init(M) *(M) = 0 -#define hb_mutex_impl_lock(M) HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END -#define hb_mutex_impl_unlock(M) __sync_lock_release (M) -#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END - - #elif defined(HB_NO_MT) typedef int hb_mutex_impl_t; -#define HB_MUTEX_IMPL_INIT 0 #define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_lock(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END @@ -109,8 +87,6 @@ typedef int hb_mutex_impl_t; #endif -#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} - struct hb_mutex_t { hb_mutex_impl_t m; diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh index d09f858cde..db38a4dfd2 100644 --- a/thirdparty/harfbuzz/src/hb-null.hh +++ b/thirdparty/harfbuzz/src/hb-null.hh @@ -39,8 +39,11 @@ #define HB_NULL_POOL_SIZE 384 -/* Use SFINAE to sniff whether T has min_size; in which case return T::null_size, - * otherwise return sizeof(T). */ +/* Use SFINAE to sniff whether T has min_size; in which case return the larger + * of sizeof(T) and T::null_size, otherwise return sizeof(T). + * + * The main purpose of this is to let structs communicate that they are not nullable, + * by defining min_size but *not* null_size. */ /* The hard way... * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol @@ -49,8 +52,9 @@ template <typename T, typename> struct _hb_null_size : hb_integral_constant<unsigned, sizeof (T)> {}; template <typename T> -struct _hb_null_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::null_size> {}; - +struct _hb_null_size<T, hb_void_t<decltype (T::min_size)>> + : hb_integral_constant<unsigned, + (sizeof (T) > T::null_size ? sizeof (T) : T::null_size)> {}; template <typename T> using hb_null_size = _hb_null_size<T, void>; #define hb_null_size(T) hb_null_size<T>::value @@ -68,6 +72,14 @@ template <typename T> using hb_static_size = _hb_static_size<T, void>; #define hb_static_size(T) hb_static_size<T>::value +template <typename T, typename> +struct _hb_min_size : hb_integral_constant<unsigned, sizeof (T)> {}; +template <typename T> +struct _hb_min_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::min_size> {}; +template <typename T> +using hb_min_size = _hb_min_size<T, void>; +#define hb_min_size(T) hb_min_size<T>::value + /* * Null() diff --git a/thirdparty/harfbuzz/src/hb-object.hh b/thirdparty/harfbuzz/src/hb-object.hh index 39845a70e7..0e15cb12c4 100644 --- a/thirdparty/harfbuzz/src/hb-object.hh +++ b/thirdparty/harfbuzz/src/hb-object.hh @@ -140,10 +140,6 @@ struct hb_lockable_set_t * Reference-count. */ -#define HB_REFERENCE_COUNT_INERT_VALUE 0 -#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD -#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_INERT_VALUE)} - struct hb_reference_count_t { mutable hb_atomic_int_t ref_count; @@ -152,9 +148,9 @@ struct hb_reference_count_t int get_relaxed () const { return ref_count.get_relaxed (); } int inc () const { return ref_count.inc (); } int dec () const { return ref_count.dec (); } - void fini () { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); } + void fini () { ref_count.set_relaxed (-0x0000DEAD); } - bool is_inert () const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; } + bool is_inert () const { return !ref_count.get_relaxed (); } bool is_valid () const { return ref_count.get_relaxed () > 0; } }; @@ -197,15 +193,12 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - mutable hb_atomic_int_t writable; + mutable hb_atomic_int_t writable = 0; hb_atomic_ptr_t<hb_user_data_array_t> user_data; + + bool is_inert () const { return !ref_count.get_relaxed (); } }; -#define HB_OBJECT_HEADER_STATIC \ - { \ - HB_REFERENCE_COUNT_INIT, \ - HB_ATOMIC_INT_INIT (false), \ - HB_ATOMIC_PTR_INIT (nullptr) \ - } +#define HB_OBJECT_HEADER_STATIC {} /* @@ -224,7 +217,7 @@ static inline void hb_object_trace (const Type *obj, const char *function) template <typename Type> static inline Type *hb_object_create () { - Type *obj = (Type *) calloc (1, sizeof (Type)); + Type *obj = (Type *) hb_calloc (1, sizeof (Type)); if (unlikely (!obj)) return obj; @@ -241,11 +234,6 @@ static inline void hb_object_init (Type *obj) obj->header.user_data.init (); } template <typename Type> -static inline bool hb_object_is_inert (const Type *obj) -{ - return unlikely (obj->header.ref_count.is_inert ()); -} -template <typename Type> static inline bool hb_object_is_valid (const Type *obj) { return likely (obj->header.ref_count.is_valid ()); @@ -264,7 +252,7 @@ template <typename Type> static inline Type *hb_object_reference (Type *obj) { hb_object_trace (obj, HB_FUNC); - if (unlikely (!obj || hb_object_is_inert (obj))) + if (unlikely (!obj || obj->header.is_inert ())) return obj; assert (hb_object_is_valid (obj)); obj->header.ref_count.inc (); @@ -274,7 +262,7 @@ template <typename Type> static inline bool hb_object_destroy (Type *obj) { hb_object_trace (obj, HB_FUNC); - if (unlikely (!obj || hb_object_is_inert (obj))) + if (unlikely (!obj || obj->header.is_inert ())) return false; assert (hb_object_is_valid (obj)); if (obj->header.ref_count.dec () != 1) @@ -291,7 +279,7 @@ static inline void hb_object_fini (Type *obj) if (user_data) { user_data->fini (); - free (user_data); + hb_free (user_data); user_data = nullptr; } } @@ -302,7 +290,7 @@ static inline bool hb_object_set_user_data (Type *obj, hb_destroy_func_t destroy, hb_bool_t replace) { - if (unlikely (!obj || hb_object_is_inert (obj))) + if (unlikely (!obj || obj->header.is_inert ())) return false; assert (hb_object_is_valid (obj)); @@ -310,14 +298,14 @@ retry: hb_user_data_array_t *user_data = obj->header.user_data.get (); if (unlikely (!user_data)) { - user_data = (hb_user_data_array_t *) calloc (sizeof (hb_user_data_array_t), 1); + user_data = (hb_user_data_array_t *) hb_calloc (sizeof (hb_user_data_array_t), 1); if (unlikely (!user_data)) return false; user_data->init (); if (unlikely (!obj->header.user_data.cmpexch (nullptr, user_data))) { user_data->fini (); - free (user_data); + hb_free (user_data); goto retry; } } @@ -329,7 +317,7 @@ template <typename Type> static inline void *hb_object_get_user_data (Type *obj, hb_user_data_key_t *key) { - if (unlikely (!obj || hb_object_is_inert (obj))) + if (unlikely (!obj || obj->header.is_inert ())) return nullptr; assert (hb_object_is_valid (obj)); hb_user_data_array_t *user_data = obj->header.user_data.get (); diff --git a/thirdparty/harfbuzz/src/hb-open-file.hh b/thirdparty/harfbuzz/src/hb-open-file.hh index ac13dd23c3..6eee5827c1 100644 --- a/thirdparty/harfbuzz/src/hb-open-file.hh +++ b/thirdparty/harfbuzz/src/hb-open-file.hh @@ -35,7 +35,6 @@ namespace OT { - /* * * The OpenType Font File @@ -48,7 +47,7 @@ namespace OT { */ struct OpenTypeFontFile; -struct OffsetTable; +struct OpenTypeOffsetTable; struct TTCHeader; @@ -78,7 +77,7 @@ typedef struct TableRecord DEFINE_SIZE_STATIC (16); } OpenTypeTable; -typedef struct OffsetTable +typedef struct OpenTypeOffsetTable { friend struct OpenTypeFontFile; @@ -102,7 +101,13 @@ typedef struct OffsetTable { Tag t; t = tag; - return tables.bfind (t, table_index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); + /* Use lfind for small fonts; there are fonts that have unsorted table entries; + * those tend to work in other tools, so tolerate them. + * https://github.com/harfbuzz/harfbuzz/issues/3065 */ + if (tables.len < 16) + return tables.lfind (t, table_index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); + else + return tables.bfind (t, table_index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); } const TableRecord& get_table_by_tag (hb_tag_t tag) const { @@ -113,44 +118,53 @@ typedef struct OffsetTable public: - template <typename item_t> + template <typename Iterator, + hb_requires ((hb_is_source_of<Iterator, hb_pair_t<hb_tag_t, hb_blob_t *>>::value))> bool serialize (hb_serialize_context_t *c, hb_tag_t sfnt_tag, - hb_array_t<item_t> items) + Iterator it) { TRACE_SERIALIZE (this); /* Alloc 12 for the OTHeader. */ - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); /* Write sfntVersion (bytes 0..3). */ sfnt_version = sfnt_tag; /* Take space for numTables, searchRange, entrySelector, RangeShift * and the TableRecords themselves. */ - if (unlikely (!tables.serialize (c, items.length))) return_trace (false); + unsigned num_items = it.len (); + if (unlikely (!tables.serialize (c, num_items))) return_trace (false); const char *dir_end = (const char *) c->head; HBUINT32 *checksum_adjustment = nullptr; /* Write OffsetTables, alloc for and write actual table blobs. */ - for (unsigned int i = 0; i < tables.len; i++) + unsigned i = 0; + for (hb_pair_t<hb_tag_t, hb_blob_t*> entry : it) { - TableRecord &rec = tables.arrayZ[i]; - hb_blob_t *blob = items[i].blob; - rec.tag = items[i].tag; - rec.length = blob->length; - rec.offset.serialize (c, this); + hb_blob_t *blob = entry.second; + unsigned len = blob->length; /* Allocate room for the table and copy it. */ - char *start = (char *) c->allocate_size<void> (rec.length); + char *start = (char *) c->allocate_size<void> (len); if (unlikely (!start)) return false; - if (likely (rec.length)) - memcpy (start, blob->data, rec.length); + TableRecord &rec = tables.arrayZ[i]; + rec.tag = entry.first; + rec.length = len; + rec.offset = 0; + if (unlikely (!c->check_assign (rec.offset, + (unsigned) ((char *) start - (char *) this), + HB_SERIALIZE_ERROR_OFFSET_OVERFLOW))) + return_trace (false); + + if (likely (len)) + memcpy (start, blob->data, len); /* 4-byte alignment. */ c->align (4); const char *end = (const char *) c->head; - if (items[i].tag == HB_OT_TAG_head && + if (entry.first == HB_OT_TAG_head && (unsigned) (end - start) >= head::static_size) { head *h = (head *) start; @@ -159,6 +173,7 @@ typedef struct OffsetTable } rec.checkSum.set_for_data (start, end - start); + i++; } tables.qsort (); @@ -170,7 +185,7 @@ typedef struct OffsetTable /* The following line is a slower version of the following block. */ //checksum.set_for_data (this, (const char *) c->head - (const char *) this); checksum.set_for_data (this, dir_end - (const char *) this); - for (unsigned int i = 0; i < items.length; i++) + for (unsigned int i = 0; i < num_items; i++) { TableRecord &rec = tables.arrayZ[i]; checksum = checksum + rec.checkSum; @@ -218,7 +233,7 @@ struct TTCHeaderVersion1 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ - LArrayOf<LOffsetTo<OffsetTable>> + Array32Of<Offset32To<OpenTypeOffsetTable>> table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: @@ -295,7 +310,7 @@ struct ResourceRecord HBINT16 nameOffset; /* Offset from beginning of resource name list * to resource name, -1 means there is none. */ HBUINT8 attrs; /* Resource attributes */ - NNOffsetTo<LArrayOf<HBUINT8>, HBUINT24> + NNOffset24To<Array32Of<HBUINT8>> offset; /* Offset from beginning of data block to * data for this resource */ HBUINT32 reserved; /* Reserved for handle to resource */ @@ -330,7 +345,7 @@ struct ResourceTypeRecord protected: Tag tag; /* Resource type. */ HBUINT16 resCountM1; /* Number of resources minus 1. */ - NNOffsetTo<UnsizedArrayOf<ResourceRecord>> + NNOffset16To<UnsizedArrayOf<ResourceRecord>> resourcesZ; /* Offset from beginning of resource type list * to reference item list for this type. */ public: @@ -386,7 +401,7 @@ struct ResourceMap HBUINT32 reserved1; /* Reserved for handle to next resource map */ HBUINT16 resreved2; /* Reserved for file reference number */ HBUINT16 attrs; /* Resource fork attribute */ - NNOffsetTo<ArrayOfM1<ResourceTypeRecord>> + NNOffset16To<ArrayOfM1<ResourceTypeRecord>> typeList; /* Offset from beginning of map to * resource type list */ Offset16 nameList; /* Offset from beginning of map to @@ -418,10 +433,10 @@ struct ResourceForkHeader } protected: - LNNOffsetTo<UnsizedArrayOf<HBUINT8>> + NNOffset32To<UnsizedArrayOf<HBUINT8>> data; /* Offset from beginning of resource fork * to resource data */ - LNNOffsetTo<ResourceMap > + NNOffset32To<ResourceMap > map; /* Offset from beginning of resource fork * to resource map */ HBUINT32 dataLen; /* Length of resource data */ @@ -477,14 +492,15 @@ struct OpenTypeFontFile } } - template <typename item_t> + template <typename Iterator, + hb_requires ((hb_is_source_of<Iterator, hb_pair_t<hb_tag_t, hb_blob_t *>>::value))> bool serialize_single (hb_serialize_context_t *c, hb_tag_t sfnt_tag, - hb_array_t<item_t> items) + Iterator items) { TRACE_SERIALIZE (this); assert (sfnt_tag != TTCTag); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); return_trace (u.fontFace.serialize (c, sfnt_tag, items)); } diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index 99634b76f0..49653ce97e 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -53,14 +53,19 @@ namespace OT { */ /* Integer types in big-endian order and no alignment requirement */ -template <typename Type, unsigned int Size> +template <typename Type, + unsigned int Size = sizeof (Type)> struct IntType { typedef Type type; - typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type; - IntType& operator = (wide_type i) { v = i; return *this; } - operator wide_type () const { return v; } + IntType () = default; + explicit constexpr IntType (Type V) : v {V} {} + 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; } + bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } bool operator != (const IntType &o) const { return !(*this == o); } @@ -80,14 +85,21 @@ struct IntType return pb->cmp (*pa); } - template <typename Type2> + template <typename Type2, + hb_enable_if (hb_is_integral (Type2) && + sizeof (Type2) < sizeof (int) && + sizeof (Type) < sizeof (int))> int cmp (Type2 a) const { Type b = v; - if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int)) - return (int) a - (int) b; - else - return a < b ? -1 : a == b ? 0 : +1; + return (int) a - (int) b; + } + template <typename Type2, + hb_enable_if (hb_is_convertible (Type2, Type))> + int cmp (Type2 a) const + { + Type b = v; + return a < b ? -1 : a == b ? 0 : +1; } bool sanitize (hb_sanitize_context_t *c) const { @@ -100,12 +112,12 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; -typedef IntType<uint8_t, 1> HBUINT8; /* 8-bit unsigned integer. */ -typedef IntType<int8_t, 1> HBINT8; /* 8-bit signed integer. */ -typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */ -typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */ -typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */ -typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */ +typedef IntType<uint8_t> HBUINT8; /* 8-bit unsigned integer. */ +typedef IntType<int8_t> HBINT8; /* 8-bit signed integer. */ +typedef IntType<uint16_t> HBUINT16; /* 16-bit unsigned integer. */ +typedef IntType<int16_t> HBINT16; /* 16-bit signed integer. */ +typedef IntType<uint32_t> HBUINT32; /* 32-bit unsigned integer. */ +typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */ /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type. * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ @@ -163,8 +175,8 @@ struct Tag : HBUINT32 { Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; } /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ - operator const char* () const { return reinterpret_cast<const char *> (&this->v); } - operator char* () { return reinterpret_cast<char *> (&this->v); } + operator const char* () const { return reinterpret_cast<const char *> (this); } + operator char* () { return reinterpret_cast<char *> (this); } public: DEFINE_SIZE_STATIC (4); }; @@ -184,6 +196,12 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, Index); typedef Index NameID; +struct VarIdx : HBUINT32 { + static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu; + VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; } +}; +DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx); + /* Offset, Null offset = 0 */ template <typename Type, bool has_null=true> struct Offset : Type @@ -194,18 +212,12 @@ struct Offset : Type bool is_null () const { return has_null && 0 == *this; } - void *serialize (hb_serialize_context_t *c, const void *base) - { - void *t = c->start_embed<void> (); - c->check_assign (*this, (unsigned) ((char *) t - (char *) base)); - return t; - } - public: DEFINE_SIZE_STATIC (sizeof (Type)); }; typedef Offset<HBUINT16> Offset16; +typedef Offset<HBUINT24> Offset24; typedef Offset<HBUINT32> Offset32; @@ -275,7 +287,7 @@ struct _hb_has_null<Type, true> static Type *get_crap () { return &Crap (Type); } }; -template <typename Type, typename OffsetType=HBUINT16, bool has_null=true> +template <typename Type, typename OffsetType, bool has_null=true> struct OffsetTo : Offset<OffsetType, has_null> { HB_DELETE_COPY_ASSIGN (OffsetTo); @@ -307,10 +319,6 @@ struct OffsetTo : Offset<OffsetType, has_null> hb_enable_if (hb_is_convertible (Base, void *))> friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); } - Type& serialize (hb_serialize_context_t *c, const void *base) - { - return * (Type *) Offset<OffsetType>::serialize (c, base); - } template <typename ...Ts> bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src, @@ -334,6 +342,23 @@ struct OffsetTo : Offset<OffsetType, has_null> return ret; } + + template <typename ...Ts> + bool serialize_serialize (hb_serialize_context_t *c, Ts&&... ds) + { + *this = 0; + + Type* obj = c->push<Type> (); + bool ret = obj->serialize (c, hb_forward<Ts> (ds)...); + + if (ret) + c->add_link (*this, c->pop_pack ()); + else + c->pop_discard (); + + return ret; + } + /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */ /* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029 * Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&... @@ -366,7 +391,7 @@ struct OffsetTo : Offset<OffsetType, has_null> TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); if (unlikely (this->is_null ())) return_trace (true); - if (unlikely (!c->check_range (base, *this))) return_trace (false); + if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false); return_trace (true); } @@ -389,12 +414,14 @@ struct OffsetTo : Offset<OffsetType, has_null> DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; /* Partial specializations. */ -template <typename Type, bool has_null=true> -using LOffsetTo = OffsetTo<Type, HBUINT32, has_null>; -template <typename Type, typename OffsetType=HBUINT16> -using NNOffsetTo = OffsetTo<Type, OffsetType, false>; -template <typename Type> -using LNNOffsetTo = LOffsetTo<Type, false>; +template <typename Type, bool has_null=true> using Offset16To = OffsetTo<Type, HBUINT16, has_null>; +template <typename Type, bool has_null=true> using Offset24To = OffsetTo<Type, HBUINT24, has_null>; +template <typename Type, bool has_null=true> using Offset32To = OffsetTo<Type, HBUINT32, has_null>; + +template <typename Type, typename OffsetType> using NNOffsetTo = OffsetTo<Type, OffsetType, false>; +template <typename Type> using NNOffset16To = Offset16To<Type, false>; +template <typename Type> using NNOffset24To = Offset24To<Type, false>; +template <typename Type> using NNOffset32To = Offset32To<Type, false>; /* @@ -441,8 +468,10 @@ struct UnsizedArrayOf const Type &lsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const { return *as_array (len).lsearch (x, ¬_found); } template <typename T> - bool lfind (unsigned int len, const T &x, unsigned *pos = nullptr) const - { return as_array (len).lfind (x, pos); } + bool lfind (unsigned int len, const T &x, unsigned int *i = nullptr, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array (len).lfind (x, i, not_found, to_store); } void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) { as_array (len).qsort (start, end); } @@ -450,7 +479,7 @@ struct UnsizedArrayOf bool serialize (hb_serialize_context_t *c, unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend (*this, items_len))) return_trace (false); + if (unlikely (!c->extend (this, items_len))) return_trace (false); return_trace (true); } template <typename Iterator, @@ -501,11 +530,11 @@ struct UnsizedArrayOf /* Unsized array of offset's */ template <typename Type, typename OffsetType, bool has_null=true> -using UnsizedOffsetArrayOf = UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null>>; +using UnsizedArray16OfOffsetTo = UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null>>; /* Unsized array of offsets relative to the beginning of the array itself. */ template <typename Type, typename OffsetType, bool has_null=true> -struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null> +struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_null> { const Type& operator [] (int i_) const { @@ -526,7 +555,7 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null> bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const { TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null> + return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null> ::sanitize (c, count, this, hb_forward<Ts> (ds)...))); } }; @@ -550,14 +579,14 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf<Type> { return *as_array (len).bsearch (x, ¬_found); } template <typename T> bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr, - hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, unsigned int to_store = (unsigned int) -1) const { return as_array (len).bfind (x, i, not_found, to_store); } }; /* An array with a number of elements. */ -template <typename Type, typename LenType=HBUINT16> +template <typename Type, typename LenType> struct ArrayOf { typedef Type item_t; @@ -605,17 +634,32 @@ struct ArrayOf hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) { return as_array ().sub_array (start_offset, count); } - hb_success_t serialize (hb_serialize_context_t *c, unsigned items_len) + template <typename T> + Type &lsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().lsearch (x, ¬_found); } + template <typename T> + const Type &lsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().lsearch (x, ¬_found); } + template <typename T> + bool lfind (const T &x, unsigned int *i = nullptr, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array ().lfind (x, i, not_found, to_store); } + + void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array ().qsort (start, end); } + + HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); - c->check_assign (len, items_len); - if (unlikely (!c->extend (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); + if (unlikely (!c->extend (this))) return_trace (false); return_trace (true); } template <typename Iterator, hb_requires (hb_is_source_of (Iterator, Type))> - hb_success_t serialize (hb_serialize_context_t *c, Iterator items) + HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items) { TRACE_SERIALIZE (this); unsigned count = items.len (); @@ -631,7 +675,7 @@ struct ArrayOf { TRACE_SERIALIZE (this); len++; - if (unlikely (!len || !c->extend (*this))) + if (unlikely (!len || !c->extend (this))) { len--; return_trace (nullptr); @@ -644,7 +688,7 @@ struct ArrayOf TRACE_SERIALIZE (this); auto *out = c->start_embed (this); if (unlikely (!c->extend_min (out))) return_trace (nullptr); - c->check_assign (out->len, len); + c->check_assign (out->len, len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); if (unlikely (!as_array ().copy (c))) return_trace (nullptr); return_trace (out); } @@ -662,19 +706,6 @@ struct ArrayOf return_trace (true); } - template <typename T> - Type &lsearch (const T &x, Type ¬_found = Crap (Type)) - { return *as_array ().lsearch (x, ¬_found); } - template <typename T> - const Type &lsearch (const T &x, const Type ¬_found = Null (Type)) const - { return *as_array ().lsearch (x, ¬_found); } - template <typename T> - bool lfind (const T &x, unsigned *pos = nullptr) const - { return as_array ().lfind (x, pos); } - - void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) - { as_array ().qsort (start, end); } - bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -687,21 +718,18 @@ struct ArrayOf public: DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; -template <typename Type> -using LArrayOf = ArrayOf<Type, HBUINT32>; +template <typename Type> using Array16Of = ArrayOf<Type, HBUINT16>; +template <typename Type> using Array32Of = ArrayOf<Type, HBUINT32>; using PString = ArrayOf<HBUINT8, HBUINT8>; /* Array of Offset's */ -template <typename Type> -using OffsetArrayOf = ArrayOf<OffsetTo<Type, HBUINT16>>; -template <typename Type> -using LOffsetArrayOf = ArrayOf<OffsetTo<Type, HBUINT32>>; -template <typename Type> -using LOffsetLArrayOf = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>; +template <typename Type> using Array16OfOffset16To = ArrayOf<OffsetTo<Type, HBUINT16>, HBUINT16>; +template <typename Type> using Array16OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT16>; +template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>; /* Array of offsets relative to the beginning of the array itself. */ template <typename Type> -struct OffsetListOf : OffsetArrayOf<Type> +struct List16OfOffset16To : Array16OfOffset16To<Type> { const Type& operator [] (int i_) const { @@ -719,7 +747,7 @@ struct OffsetListOf : OffsetArrayOf<Type> bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct OffsetListOf<Type> *out = c->serializer->embed (*this); + struct List16OfOffset16To<Type> *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); unsigned int count = this->len; for (unsigned int i = 0; i < count; i++) @@ -731,7 +759,7 @@ struct OffsetListOf : OffsetArrayOf<Type> bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); - return_trace (OffsetArrayOf<Type>::sanitize (c, this, hb_forward<Ts> (ds)...)); + return_trace (Array16OfOffset16To<Type>::sanitize (c, this, hb_forward<Ts> (ds)...)); } }; @@ -774,9 +802,9 @@ struct HeadlessArrayOf bool serialize (hb_serialize_context_t *c, unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); - c->check_assign (lenP1, items_len + 1); - if (unlikely (!c->extend (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW); + if (unlikely (!c->extend (this))) return_trace (false); return_trace (true); } template <typename Iterator, @@ -847,6 +875,7 @@ struct ArrayOfM1 { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); + if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) 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)...))) @@ -870,7 +899,7 @@ struct ArrayOfM1 }; /* An array with sorted elements. Supports binary searching. */ -template <typename Type, typename LenType=HBUINT16> +template <typename Type, typename LenType> struct SortedArrayOf : ArrayOf<Type, LenType> { hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->len); } @@ -916,11 +945,14 @@ struct SortedArrayOf : ArrayOf<Type, LenType> { return *as_array ().bsearch (x, ¬_found); } template <typename T> bool bfind (const T &x, unsigned int *i = nullptr, - hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, unsigned int to_store = (unsigned int) -1) const { return as_array ().bfind (x, i, not_found, to_store); } }; +template <typename Type> using SortedArray16Of = SortedArrayOf<Type, HBUINT16>; +template <typename Type> using SortedArray32Of = SortedArrayOf<Type, HBUINT32>; + /* * Binary-search arrays */ diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh index e5286cd792..eaaf5e12ec 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh @@ -126,7 +126,7 @@ struct CFFIndex else { /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); this->count = byteArray.length; this->offSize = offSize_; if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1)))) @@ -183,7 +183,7 @@ struct CFFIndex else { serialize_header(c, + it | hb_map ([] (const byte_str_t &_) { return _.length; })); - for (const byte_str_t &_ : +it) + for (const auto &_ : +it) _.copy (c); } return_trace (true); @@ -214,7 +214,7 @@ struct CFFIndex unsigned off_size = calcOffSize (total); /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); this->count = it.len (); this->offSize = off_size; if (unlikely (!c->allocate_size<HBUINT8> (off_size * (it.len () + 1)))) @@ -335,7 +335,7 @@ struct CFFIndexOf : CFFIndex<COUNT> { TRACE_SERIALIZE (this); /* serialize CFFIndex header */ - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); this->count = dataArrayLen; this->offSize = offSize_; if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1)))) diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc b/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc index 66b9c8c907..3298fa35ae 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.cc @@ -426,7 +426,7 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph else { extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ()); - extents->width = font->em_scalef_x (bounds.max.x.to_real () - bounds.min.x.to_real ()); + extents->width = font->em_scalef_x (bounds.max.x.to_real ()) - extents->x_bearing; } if (bounds.min.y >= bounds.max.y) { @@ -436,7 +436,7 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph else { extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ()); - extents->height = font->em_scalef_y (bounds.min.y.to_real () - bounds.max.y.to_real ()); + extents->height = font->em_scalef_y (bounds.min.y.to_real ()) - extents->y_bearing; } return true; diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh index 7228f77727..5dd183e3a0 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh @@ -187,7 +187,7 @@ struct Encoding const hb_vector_t<code_pair_t>& supp_codes) { TRACE_SERIALIZE (this); - Encoding *dest = c->extend_min (*this); + Encoding *dest = c->extend_min (this); if (unlikely (!dest)) return_trace (false); dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0); switch (format) { @@ -457,7 +457,7 @@ struct Charset const hb_vector_t<code_pair_t>& sid_ranges) { TRACE_SERIALIZE (this); - Charset *dest = c->extend_min (*this); + Charset *dest = c->extend_min (this); if (unlikely (!dest)) return_trace (false); dest->format = format; switch (format) @@ -713,6 +713,7 @@ struct cff1_top_dict_opset_t : top_dict_opset_t<cff1_top_dict_val_t> case OpCode_Notice: case OpCode_Copyright: case OpCode_FullName: + case OpCode_FontName: case OpCode_FamilyName: case OpCode_Weight: case OpCode_PostScript: @@ -1390,7 +1391,7 @@ struct cff1 public: FixedVersion<HBUINT8> version; /* Version of CFF table. set to 0x0100u */ - OffsetTo<CFF1NameIndex, HBUINT8> nameIndex; /* headerSize = Offset to Name INDEX. */ + NNOffsetTo<CFF1NameIndex, HBUINT8> nameIndex; /* headerSize = Offset to Name INDEX. */ HBUINT8 offSize; /* offset size (unused?) */ public: diff --git a/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc b/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc index ac0feeee21..879b7cdb23 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-cff2-table.cc @@ -127,7 +127,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, else { extents->x_bearing = font->em_scalef_x (param.min_x.to_real ()); - extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ()); + extents->width = font->em_scalef_x (param.max_x.to_real ()) - extents->x_bearing; } if (param.min_y >= param.max_y) { @@ -137,7 +137,7 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font, else { extents->y_bearing = font->em_scalef_y (param.max_y.to_real ()); - extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ()); + extents->height = font->em_scalef_y (param.min_y.to_real ()) - extents->y_bearing; } return true; diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh index cc48379bb8..b904bb46a8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -49,6 +49,12 @@ struct CmapSubtableFormat0 *glyph = gid; return true; } + + unsigned get_language () const + { + return language; + } + void collect_unicodes (hb_set_t *out) const { for (unsigned int i = 0; i < 256; i++) @@ -95,7 +101,7 @@ struct CmapSubtableFormat4 HBUINT16 *endCode = c->start_embed<HBUINT16> (); hb_codepoint_t prev_endcp = 0xFFFF; - for (const hb_item_type<Iterator> _ : +it) + for (const auto& _ : +it) { if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first) { @@ -131,7 +137,7 @@ struct CmapSubtableFormat4 HBUINT16 *startCode = c->start_embed<HBUINT16> (); hb_codepoint_t prev_cp = 0xFFFF; - for (const hb_item_type<Iterator> _ : +it) + for (const auto& _ : +it) { if (prev_cp == 0xFFFF || prev_cp + 1u != _.first) { @@ -170,7 +176,7 @@ struct CmapSubtableFormat4 if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size) return nullptr; - for (const hb_item_type<Iterator> _ : +it) + for (const auto& _ : +it) { if (_.first == startCode[i]) { @@ -212,29 +218,24 @@ struct CmapSubtableFormat4 HBINT16 *idDelta, unsigned segcount) { + hb_hashmap_t<hb_codepoint_t, hb_codepoint_t> cp_to_gid; + + it | hb_sink (cp_to_gid); + HBUINT16 *idRangeOffset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount); if (unlikely (!c->check_success (idRangeOffset))) return nullptr; if (unlikely ((char *)idRangeOffset - (char *)idDelta != (int) segcount * (int) HBINT16::static_size)) return nullptr; - + hb_range (segcount) - | hb_filter ([&] (const unsigned _) { return idDelta[_] == 0; }) - | hb_apply ([&] (const unsigned i) - { - idRangeOffset[i] = 2 * (c->start_embed<HBUINT16> () - idRangeOffset - i); - - + it - | hb_filter ([&] (const hb_item_type<Iterator> _) { return _.first >= startCode[i] && _.first <= endCode[i]; }) - | hb_apply ([&] (const hb_item_type<Iterator> _) - { - HBUINT16 glyID; - glyID = _.second; - c->copy<HBUINT16> (glyID); - }) - ; - - - }) - ; + for (unsigned i : + hb_range (segcount) + | hb_filter ([&] (const unsigned _) { return idDelta[_] == 0; })) + { + idRangeOffset[i] = 2 * (c->start_embed<HBUINT16> () - idRangeOffset - i); + for (hb_codepoint_t cp = startCode[i]; cp <= endCode[i]; cp++) + { + HBUINT16 gid; + gid = cp_to_gid[cp]; + c->copy<HBUINT16> (gid); + } + } return idRangeOffset; } @@ -253,7 +254,7 @@ struct CmapSubtableFormat4 if (format4_iter.len () == 0) return; unsigned table_initpos = c->length (); - if (unlikely (!c->extend_min (*this))) return; + if (unlikely (!c->extend_min (this))) return; this->format = 4; //serialize endCode[] @@ -276,7 +277,17 @@ struct CmapSubtableFormat4 HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, format4_iter, endCode, startCode, idDelta, segcount); if (unlikely (!c->check_success (idRangeOffset))) return; - if (unlikely (!c->check_assign(this->length, c->length () - table_initpos))) return; + this->length = c->length () - table_initpos; + if ((long long) this->length != (long long) c->length () - table_initpos) + { + // Length overflowed. Discard the current object before setting the error condition, otherwise + // discard is a noop which prevents the higher level code from reverting the serializer to the + // pre-error state in cmap4 overflow handling code. + c->pop_discard (); + c->err (HB_SERIALIZE_ERROR_INT_OVERFLOW); + return; + } + this->segCountX2 = segcount * 2; this->entrySelector = hb_max (1u, hb_bit_storage (segcount)) - 1; this->searchRange = 2 * (1u << this->entrySelector); @@ -285,6 +296,11 @@ struct CmapSubtableFormat4 : 0; } + unsigned get_language () const + { + return language; + } + struct accelerator_t { accelerator_t () {} @@ -547,6 +563,12 @@ struct CmapSubtableTrimmed *glyph = gid; return true; } + + unsigned get_language () const + { + return language; + } + void collect_unicodes (hb_set_t *out) const { hb_codepoint_t start = startCharCode; @@ -606,6 +628,11 @@ struct CmapSubtableLongSegmented return true; } + unsigned get_language () const + { + return language; + } + void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const { for (unsigned int i = 0; i < this->groups.len; i++) @@ -670,7 +697,7 @@ struct CmapSubtableLongSegmented HBUINT16 reserved; /* Reserved; set to 0. */ HBUINT32 length; /* Byte length of this subtable. */ HBUINT32 language; /* Ignore. */ - SortedArrayOf<CmapSubtableLongGroup, HBUINT32> + SortedArray32Of<CmapSubtableLongGroup> groups; /* Groupings. */ public: DEFINE_SIZE_ARRAY (16, groups); @@ -691,12 +718,12 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> { if (it.len () == 0) return; unsigned table_initpos = c->length (); - if (unlikely (!c->extend_min (*this))) return; + if (unlikely (!c->extend_min (this))) return; hb_codepoint_t startCharCode = 0xFFFF, endCharCode = 0xFFFF; hb_codepoint_t glyphID = 0; - for (const hb_item_type<Iterator> _ : +it) + for (const auto& _ : +it) { if (startCharCode == 0xFFFF) { @@ -784,7 +811,7 @@ struct UnicodeValueRange DEFINE_SIZE_STATIC (4); }; -struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32> +struct DefaultUVS : SortedArray32Of<UnicodeValueRange> { void collect_unicodes (hb_set_t *out) const { @@ -850,7 +877,9 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32> } else { - if (unlikely (!c->check_assign (out->len, (c->length () - init_len) / UnicodeValueRange::static_size))) return nullptr; + if (unlikely (!c->check_assign (out->len, + (c->length () - init_len) / UnicodeValueRange::static_size, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) return nullptr; return out; } } @@ -876,23 +905,21 @@ struct UVSMapping DEFINE_SIZE_STATIC (5); }; -struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32> +struct NonDefaultUVS : SortedArray32Of<UVSMapping> { void collect_unicodes (hb_set_t *out) const { - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - out->add (arrayZ[i].unicodeValue); + for (const auto& a : as_array ()) + out->add (a.unicodeValue); } void collect_mapping (hb_set_t *unicodes, /* OUT */ hb_map_t *mapping /* OUT */) const { - unsigned count = len; - for (unsigned i = 0; i < count; i++) + for (const auto& a : as_array ()) { - hb_codepoint_t unicode = arrayZ[i].unicodeValue; - hb_codepoint_t glyphid = arrayZ[i].glyphID; + hb_codepoint_t unicode = a.unicodeValue; + hb_codepoint_t glyphid = a.glyphID; unicodes->add (unicode); mapping->set (unicode, glyphid); } @@ -1041,9 +1068,9 @@ struct VariationSelectorRecord } HBUINT24 varSelector; /* Variation selector. */ - LOffsetTo<DefaultUVS> + Offset32To<DefaultUVS> defaultUVS; /* Offset to Default UVS Table. May be 0. */ - LOffsetTo<NonDefaultUVS> + Offset32To<NonDefaultUVS> nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ public: DEFINE_SIZE_STATIC (11); @@ -1058,9 +1085,8 @@ struct CmapSubtableFormat14 void collect_variation_selectors (hb_set_t *out) const { - unsigned int count = record.len; - for (unsigned int i = 0; i < count; i++) - out->add (record.arrayZ[i].varSelector); + for (const auto& a : record.as_array ()) + out->add (a.varSelector); } void collect_variation_unicodes (hb_codepoint_t variation_selector, hb_set_t *out) const @@ -1076,7 +1102,7 @@ struct CmapSubtableFormat14 unsigned table_initpos = c->length (); const char* init_tail = c->tail; - if (unlikely (!c->extend_min (*this))) return; + if (unlikely (!c->extend_min (this))) return; this->format = 14; auto src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (base); @@ -1112,10 +1138,12 @@ struct CmapSubtableFormat14 return; int tail_len = init_tail - c->tail; - c->check_assign (this->length, c->length () - table_initpos + tail_len); + c->check_assign (this->length, c->length () - table_initpos + tail_len, + HB_SERIALIZE_ERROR_INT_OVERFLOW); c->check_assign (this->record.len, (c->length () - table_initpos - CmapSubtableFormat14::min_size) / - VariationSelectorRecord::static_size); + VariationSelectorRecord::static_size, + HB_SERIALIZE_ERROR_INT_OVERFLOW); /* Correct the incorrect write order by reversing the order of the variation records array. */ @@ -1180,7 +1208,7 @@ struct CmapSubtableFormat14 protected: HBUINT16 format; /* Format number is set to 14. */ HBUINT32 length; /* Byte length of this subtable. */ - SortedArrayOf<VariationSelectorRecord, HBUINT32> + SortedArray32Of<VariationSelectorRecord> record; /* Variation selector records; sorted * in increasing order of `varSelector'. */ public: @@ -1235,6 +1263,20 @@ struct CmapSubtable } } + unsigned get_language () const + { + switch (u.format) { + case 0: return u.format0 .get_language (); + case 4: return u.format4 .get_language (); + case 6: return u.format6 .get_language (); + case 10: return u.format10.get_language (); + case 12: return u.format12.get_language (); + case 13: return u.format13.get_language (); + case 14: + default: return 0; + } + } + template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, @@ -1338,7 +1380,7 @@ struct EncodingRecord HBUINT16 platformID; /* Platform ID. */ HBUINT16 encodingID; /* Platform-specific encoding ID. */ - LOffsetTo<CmapSubtable> + Offset32To<CmapSubtable> subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ public: DEFINE_SIZE_STATIC (8); @@ -1350,58 +1392,112 @@ struct cmap template<typename Iterator, typename EncodingRecIter, hb_requires (hb_is_iterator (EncodingRecIter))> - void serialize (hb_serialize_context_t *c, + bool serialize (hb_serialize_context_t *c, Iterator it, EncodingRecIter encodingrec_iter, const void *base, - const hb_subset_plan_t *plan) + const hb_subset_plan_t *plan, + bool drop_format_4 = false) { - if (unlikely (!c->extend_min ((*this)))) return; + if (unlikely (!c->extend_min ((*this)))) return false; this->version = 0; unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0; + auto snap = c->snapshot (); for (const EncodingRecord& _ : encodingrec_iter) { + if (c->in_error ()) + return false; + unsigned format = (base+_.subtable).u.format; - if (!plan->glyphs_requested->is_empty ()) + if (format != 4 && format != 12 && format != 14) continue; + + hb_set_t unicodes_set; + (base+_.subtable).collect_unicodes (&unicodes_set); + + if (!drop_format_4 && format == 4) { - hb_set_t unicodes_set; - hb_map_t cp_glyphid_map; - (base+_.subtable).collect_mapping (&unicodes_set, &cp_glyphid_map); - - auto table_iter = - + hb_zip (unicodes_set.iter(), unicodes_set.iter() | hb_map(cp_glyphid_map)) - | hb_filter (plan->_glyphset, hb_second) - | hb_filter ([plan] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& p) - { - return plan->unicodes->has (p.first) || - plan->glyphs_requested->has (p.second); - }) - | hb_map ([plan] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& p_org) - { - return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (p_org.first, plan->glyph_map->get(p_org.second)); - }) - ; - - if (format == 4) c->copy (_, table_iter, 4u, base, plan, &format4objidx); - else if (format == 12) c->copy (_, table_iter, 12u, base, plan, &format12objidx); - else if (format == 14) c->copy (_, table_iter, 14u, base, plan, &format14objidx); + c->copy (_, + it | hb_filter (unicodes_set, hb_first), 4u, base, plan, &format4objidx); + if (c->in_error () && c->only_overflow ()) + { + // cmap4 overflowed, reset and retry serialization without format 4 subtables. + c->revert (snap); + return serialize (c, it, + encodingrec_iter, + base, + plan, + true); + } } - /* when --gids option is not used, we iterate input unicodes instead of - * all codepoints in each subtable, which is more efficient */ - else + + else if (format == 12) { - hb_set_t unicodes_set; - (base+_.subtable).collect_unicodes (&unicodes_set); + if (_can_drop (_, unicodes_set, base, + it | hb_map (hb_first), encodingrec_iter)) continue; + c->copy (_, + it | hb_filter (unicodes_set, hb_first), 12u, base, plan, &format12objidx); + } + else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); + } + c->check_assign(this->encodingRecord.len, + (c->length () - cmap::min_size)/EncodingRecord::static_size, + HB_SERIALIZE_ERROR_INT_OVERFLOW); - if (format == 4) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 4u, base, plan, &format4objidx); - else if (format == 12) c->copy (_, + it | hb_filter (unicodes_set, hb_first), 12u, base, plan, &format12objidx); - else if (format == 14) c->copy (_, it, 14u, base, plan, &format14objidx); + // Fail if format 4 was dropped and there is no cmap12. + return !drop_format_4 || format12objidx; + } + + template<typename Iterator, typename EncodingRecordIterator, + hb_requires (hb_is_iterator (Iterator)), + hb_requires (hb_is_iterator (EncodingRecordIterator))> + bool _can_drop (const EncodingRecord& cmap12, + const hb_set_t& cmap12_unicodes, + const void* base, + Iterator subset_unicodes, + EncodingRecordIterator encoding_records) + { + for (auto cp : + subset_unicodes | hb_filter (cmap12_unicodes)) + { + if (cp >= 0x10000) return false; + } + + unsigned target_platform; + unsigned target_encoding; + unsigned target_language = (base+cmap12.subtable).get_language (); + + if (cmap12.platformID == 0 && cmap12.encodingID == 4) + { + target_platform = 0; + target_encoding = 3; + } else if (cmap12.platformID == 3 && cmap12.encodingID == 10) { + target_platform = 3; + target_encoding = 1; + } else { + return false; + } + + for (const auto& _ : encoding_records) + { + if (_.platformID != target_platform + || _.encodingID != target_encoding + || (base+_.subtable).get_language() != target_language) + continue; + + hb_set_t sibling_unicodes; + (base+_.subtable).collect_unicodes (&sibling_unicodes); + + auto cmap12 = + subset_unicodes | hb_filter (cmap12_unicodes); + auto sibling = + subset_unicodes | hb_filter (sibling_unicodes); + for (; cmap12 && sibling; cmap12++, sibling++) + { + unsigned a = *cmap12; + unsigned b = *sibling; + if (a != b) return false; } + + return !cmap12 && !sibling; } - c->check_assign(this->encodingRecord.len, (c->length () - cmap::min_size)/EncodingRecord::static_size); + return false; } void closure_glyphs (const hb_set_t *unicodes, @@ -1468,8 +1564,8 @@ struct cmap | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) { return (_.second != HB_MAP_VALUE_INVALID); }) ; - cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan); - return_trace (true); + + return_trace (cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan)); } const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const @@ -1697,7 +1793,7 @@ struct cmap protected: HBUINT16 version; /* Table version number (0). */ - SortedArrayOf<EncodingRecord> + SortedArray16Of<EncodingRecord> encodingRecord; /* Encoding tables. */ public: DEFINE_SIZE_ARRAY (4, encodingRecord); diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh index aaa1c37c64..6c31d1b53e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh @@ -455,8 +455,8 @@ struct IndexSubtableRecord unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length; // Set to invalid state to indicate filling glyphs is not yet started. - if (unlikely (!records->resize (records->length + 1))) - return_trace (c->serializer->check_success (false)); + if (unlikely (!c->serializer->check_success (records->resize (records->length + 1)))) + return_trace (false); (*records)[records->length - 1].firstGlyphIndex = 1; (*records)[records->length - 1].lastGlyphIndex = 0; @@ -510,7 +510,7 @@ struct IndexSubtableRecord HBGlyphID firstGlyphIndex; HBGlyphID lastGlyphIndex; - LOffsetTo<IndexSubtable> offsetToSubtable; + Offset32To<IndexSubtable> offsetToSubtable; public: DEFINE_SIZE_STATIC (8); }; @@ -567,8 +567,8 @@ struct IndexSubtableArray hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup; build_lookup (c, bitmap_size_context, &lookup); - if (unlikely (lookup.in_error ())) - return c->serializer->check_success (false); + if (unlikely (!c->serializer->propagate_error (lookup))) + return false; bitmap_size_context->size = 0; bitmap_size_context->num_tables = 0; @@ -672,7 +672,7 @@ struct BitmapSizeTable } protected: - LNNOffsetTo<IndexSubtableArray> + NNOffset32To<IndexSubtableArray> indexSubtableArrayOffset; HBUINT32 indexTablesSize; HBUINT32 numberOfIndexSubtables; @@ -697,7 +697,7 @@ struct BitmapSizeTable struct GlyphBitmapDataFormat17 { SmallGlyphMetrics glyphMetrics; - LArrayOf<HBUINT8> data; + Array32Of<HBUINT8> data; public: DEFINE_SIZE_ARRAY (9, data); }; @@ -705,14 +705,14 @@ struct GlyphBitmapDataFormat17 struct GlyphBitmapDataFormat18 { BigGlyphMetrics glyphMetrics; - LArrayOf<HBUINT8> data; + Array32Of<HBUINT8> data; public: DEFINE_SIZE_ARRAY (12, data); }; struct GlyphBitmapDataFormat19 { - LArrayOf<HBUINT8> data; + Array32Of<HBUINT8> data; public: DEFINE_SIZE_ARRAY (4, data); }; @@ -738,7 +738,7 @@ struct CBLC cbdt_prime->length, HB_MEMORY_MODE_WRITABLE, cbdt_prime->arrayZ, - free); + hb_free); cbdt_prime->init (); // Leak arrayZ to the blob. bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob); hb_blob_destroy (cbdt_prime_blob); @@ -798,7 +798,7 @@ struct CBLC protected: FixedVersion<> version; - LArrayOf<BitmapSizeTable> sizeTables; + Array32Of<BitmapSizeTable> sizeTables; public: DEFINE_SIZE_ARRAY (8, sizeTables); }; diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index 92a49bb4f4..007ff3f47b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -29,6 +29,7 @@ #define HB_OT_COLOR_COLR_TABLE_HH #include "hb-open-type.hh" +#include "hb-ot-layout-common.hh" /* * COLR -- Color @@ -36,9 +37,78 @@ */ #define HB_OT_TAG_COLR HB_TAG('C','O','L','R') +#ifndef COLRV1_MAX_NESTING_LEVEL +#define COLRV1_MAX_NESTING_LEVEL 100 +#endif + +#ifndef COLRV1_ENABLE_SUBSETTING +#define COLRV1_ENABLE_SUBSETTING 0 +#endif namespace OT { +struct COLR; +struct hb_colrv1_closure_context_t : + hb_dispatch_context_t<hb_colrv1_closure_context_t> +{ + template <typename T> + return_t dispatch (const T &obj) + { + if (unlikely (nesting_level_left == 0)) + return hb_empty_t (); + + if (paint_visited (&obj)) + return hb_empty_t (); + + nesting_level_left--; + obj.closurev1 (this); + nesting_level_left++; + return hb_empty_t (); + } + static return_t default_return_value () { return hb_empty_t (); } + + bool paint_visited (const void *paint) + { + hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base); + if (visited_paint.has (delta)) + return true; + + visited_paint.add (delta); + return false; + } + + const COLR* get_colr_table () const + { return reinterpret_cast<const COLR *> (base); } + + void add_glyph (unsigned glyph_id) + { glyphs->add (glyph_id); } + + void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers) + { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); } + + void add_palette_index (unsigned palette_index) + { palette_indices->add (palette_index); } + + public: + const void *base; + hb_set_t visited_paint; + hb_set_t *glyphs; + hb_set_t *layer_indices; + hb_set_t *palette_indices; + unsigned nesting_level_left; + + hb_colrv1_closure_context_t (const void *base_, + hb_set_t *glyphs_, + hb_set_t *layer_indices_, + hb_set_t *palette_indices_, + unsigned nesting_level_left_ = COLRV1_MAX_NESTING_LEVEL) : + base (base_), + glyphs (glyphs_), + layer_indices (layer_indices_), + palette_indices (palette_indices_), + nesting_level_left (nesting_level_left_) + {} +}; struct LayerRecord { @@ -90,6 +160,707 @@ struct BaseGlyphRecord DEFINE_SIZE_STATIC (6); }; +template <typename T> +struct Variable +{ + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + T value; + VarIdx varIdx; + public: + DEFINE_SIZE_STATIC (4 + T::static_size); +}; + +template <typename T> +struct NoVariable +{ + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + T value; + public: + DEFINE_SIZE_STATIC (T::static_size); +}; + +// Color structures + +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)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT16 paletteIndex; + Var<F2DOT14> alpha; + public: + DEFINE_SIZE_STATIC (2 + Var<F2DOT14>::static_size); +}; + +template <template<typename> class Var> +struct ColorStop +{ + 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)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + Var<F2DOT14> stopOffset; + ColorIndex<Var> color; + public: + DEFINE_SIZE_STATIC (Var<F2DOT14>::static_size + ColorIndex<Var>::static_size); +}; + +struct Extend : HBUINT8 +{ + enum { + EXTEND_PAD = 0, + EXTEND_REPEAT = 1, + EXTEND_REFLECT = 2, + }; + public: + DEFINE_SIZE_STATIC (1); +}; + +template <template<typename> class Var> +struct ColorLine +{ + 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 (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); + if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false); + + for (const auto& stop : stops.iter ()) + { + if (!stop.subset (c)) return_trace (false); + } + return_trace (true); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + stops.sanitize (c)); + } + + Extend extend; + Array16Of<ColorStop<Var>> stops; + public: + DEFINE_SIZE_ARRAY_SIZED (3, stops); +}; + +// Composition modes + +// Compositing modes are taken from https://www.w3.org/TR/compositing-1/ +// NOTE: a brief audit of major implementations suggests most support most +// or all of the specified modes. +struct CompositeMode : HBUINT8 +{ + enum { + // Porter-Duff modes + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators + COMPOSITE_CLEAR = 0, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_clear + COMPOSITE_SRC = 1, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_src + COMPOSITE_DEST = 2, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dst + COMPOSITE_SRC_OVER = 3, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcover + COMPOSITE_DEST_OVER = 4, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstover + COMPOSITE_SRC_IN = 5, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin + COMPOSITE_DEST_IN = 6, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin + COMPOSITE_SRC_OUT = 7, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout + COMPOSITE_DEST_OUT = 8, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout + COMPOSITE_SRC_ATOP = 9, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop + COMPOSITE_DEST_ATOP = 10, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop + COMPOSITE_XOR = 11, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor + COMPOSITE_PLUS = 12, // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus + + // Blend modes + // https://www.w3.org/TR/compositing-1/#blending + COMPOSITE_SCREEN = 13, // https://www.w3.org/TR/compositing-1/#blendingscreen + COMPOSITE_OVERLAY = 14, // https://www.w3.org/TR/compositing-1/#blendingoverlay + COMPOSITE_DARKEN = 15, // https://www.w3.org/TR/compositing-1/#blendingdarken + COMPOSITE_LIGHTEN = 16, // https://www.w3.org/TR/compositing-1/#blendinglighten + COMPOSITE_COLOR_DODGE = 17, // https://www.w3.org/TR/compositing-1/#blendingcolordodge + COMPOSITE_COLOR_BURN = 18, // https://www.w3.org/TR/compositing-1/#blendingcolorburn + COMPOSITE_HARD_LIGHT = 19, // https://www.w3.org/TR/compositing-1/#blendinghardlight + COMPOSITE_SOFT_LIGHT = 20, // https://www.w3.org/TR/compositing-1/#blendingsoftlight + COMPOSITE_DIFFERENCE = 21, // https://www.w3.org/TR/compositing-1/#blendingdifference + COMPOSITE_EXCLUSION = 22, // https://www.w3.org/TR/compositing-1/#blendingexclusion + COMPOSITE_MULTIPLY = 23, // https://www.w3.org/TR/compositing-1/#blendingmultiply + + // Modes that, uniquely, do not operate on components + // https://www.w3.org/TR/compositing-1/#blendingnonseparable + COMPOSITE_HSL_HUE = 24, // https://www.w3.org/TR/compositing-1/#blendinghue + COMPOSITE_HSL_SATURATION = 25, // https://www.w3.org/TR/compositing-1/#blendingsaturation + COMPOSITE_HSL_COLOR = 26, // https://www.w3.org/TR/compositing-1/#blendingcolor + COMPOSITE_HSL_LUMINOSITY = 27, // https://www.w3.org/TR/compositing-1/#blendingluminosity + }; + public: + DEFINE_SIZE_STATIC (1); +}; + +template <template<typename> class Var> +struct Affine2x3 +{ + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + Var<HBFixed> xx; + Var<HBFixed> yx; + Var<HBFixed> xy; + Var<HBFixed> yy; + Var<HBFixed> dx; + Var<HBFixed> dy; + public: + DEFINE_SIZE_STATIC (6 * Var<HBFixed>::static_size); +}; + +struct PaintColrLayers +{ + 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 (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers->get (firstLayerIndex), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + + return_trace (true); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT8 format; /* format = 1 */ + HBUINT8 numLayers; + HBUINT32 firstLayerIndex; /* index into COLRv1::layersV1 */ + 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); } + + 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)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ + ColorIndex<Var> color; + public: + DEFINE_SIZE_STATIC (1 + ColorIndex<Var>::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); + } + + 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->colorLine.serialize_subset (c, colorLine, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); + } + + 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; + public: + DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size); +}; + +template <template<typename> class Var> +struct PaintRadialGradient +{ + 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->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); + return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); + } + + 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; + public: + DEFINE_SIZE_STATIC (4 + 6 * Var<FWORD>::static_size); +}; + +template <template<typename> class Var> +struct PaintSweepGradient +{ + 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->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); + return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); + } + + 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; + public: + DEFINE_SIZE_STATIC (2 * Var<FWORD>::static_size + 2 * Var<HBFixed>::static_size); +}; + +struct Paint; +// Paint a non-COLR glyph, filled as indicated by paint. +struct PaintGlyph +{ + 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); + + if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid), + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + return_trace (out->paint.serialize_subset (c, paint, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && paint.sanitize (c, this)); + } + + HBUINT8 format; /* format = 10 */ + Offset24To<Paint> paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */ + HBUINT16 gid; + public: + DEFINE_SIZE_STATIC (6); +}; + +struct PaintColrGlyph +{ + 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 (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid), + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT8 format; /* format = 11 */ + HBUINT16 gid; + public: + DEFINE_SIZE_STATIC (3); +}; + +template <template<typename> class Var> +struct PaintTransform +{ + 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 = 12(noVar) or 13 (Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */ + Affine2x3<Var> transform; + public: + DEFINE_SIZE_STATIC (4 + Affine2x3<Var>::static_size); +}; + +template <template<typename> class Var> +struct PaintTranslate +{ + 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 = 14(noVar) or 15 (Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */ + Var<HBFixed> dx; + Var<HBFixed> dy; + public: + DEFINE_SIZE_STATIC (4 + Var<HBFixed>::static_size); +}; + +template <template<typename> class Var> +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 = 16 (noVar) or 17(Var) */ + Offset24To<Paint> src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */ + Var<HBFixed> angle; + Var<HBFixed> centerX; + Var<HBFixed> centerY; + public: + DEFINE_SIZE_STATIC (4 + 3 * Var<HBFixed>::static_size); +}; + +template <template<typename> class Var> +struct PaintSkew +{ + 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 PaintSkew table) to Paint subtable. */ + Var<HBFixed> xSkewAngle; + Var<HBFixed> ySkewAngle; + Var<HBFixed> centerX; + Var<HBFixed> centerY; + public: + DEFINE_SIZE_STATIC (4 + 4 * Var<HBFixed>::static_size); +}; + +struct PaintComposite +{ + 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); + + if (!out->src.serialize_subset (c, src, this)) return_trace (false); + return_trace (out->backdrop.serialize_subset (c, backdrop, this)); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + src.sanitize (c, this) && + backdrop.sanitize (c, this)); + } + + HBUINT8 format; /* format = 20 */ + 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. */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct Paint +{ + 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)...)); + 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; + } u; +}; + +struct BaseGlyphV1Record +{ + int cmp (hb_codepoint_t g) const + { return g < glyphId ? -1 : g > glyphId ? 1 : 0; } + + bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map, + const void* src_base, hb_subset_context_t *c) const + { + TRACE_SERIALIZE (this); + auto *out = s->embed (this); + if (unlikely (!out)) return_trace (false); + if (!s->check_assign (out->glyphId, glyph_map->get (glyphId), + HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + + return_trace (out->paint.serialize_subset (c, paint, src_base)); + } + + bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && paint.sanitize (c, base))); + } + + public: + HBGlyphID glyphId; /* Glyph ID of reference glyph */ + Offset32To<Paint> paint; /* Offset (from beginning of BaseGlyphV1Record array) to Paint, + * Typically PaintColrLayers */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct BaseGlyphV1List : SortedArray32Of<BaseGlyphV1Record> +{ + 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; + + for (const auto& _ : as_array ()) + { + unsigned gid = _.glyphId; + if (!glyphset->has (gid)) continue; + + if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++; + else return_trace (false); + } + + return_trace (out->len != 0); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (SortedArray32Of<BaseGlyphV1Record>::sanitize (c, this)); + } +}; + +struct LayerV1List : Array32OfOffset32To<Paint> +{ + const Paint& get_paint (unsigned i) const + { return this+(*this)[i]; } + + 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); + + for (const auto& _ : + hb_enumerate (*this) + | hb_filter (c->plan->colrv1_layers, hb_first)) + + { + auto *o = out->serialize_append (c->serializer); + if (unlikely (!o) || !o->serialize_subset (c, _.second, this)) + return_trace (false); + } + return_trace (true); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (Array32OfOffset32To<Paint>::sanitize (c, this)); + } +}; + struct COLR { static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR; @@ -131,6 +902,15 @@ struct COLR hb_set_t *related_ids /* OUT */) const { colr->closure_glyphs (glyph, related_ids); } + void closure_V0palette_indices (const hb_set_t *glyphs, + hb_set_t *palettes /* OUT */) const + { colr->closure_V0palette_indices (glyphs, palettes); } + + void closure_forV1 (hb_set_t *glyphset, + hb_set_t *layer_indices, + hb_set_t *palette_indices) const + { colr->closure_forV1 (glyphset, layer_indices, palette_indices); } + private: hb_blob_ptr_t<COLR> colr; }; @@ -147,21 +927,70 @@ struct COLR related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size); } + void closure_V0palette_indices (const hb_set_t *glyphs, + hb_set_t *palettes /* OUT */) const + { + if (!numBaseGlyphs || !numLayers) return; + hb_array_t<const BaseGlyphRecord> baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs); + hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers); + + for (const BaseGlyphRecord record : baseGlyphs) + { + if (!glyphs->has (record.glyphId)) continue; + hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx, + record.numLayers); + for (const LayerRecord layer : glyph_layers) + palettes->add (layer.colorIdx); + } + } + + void closure_forV1 (hb_set_t *glyphset, + hb_set_t *layer_indices, + hb_set_t *palette_indices) const + { + if (version != 1) return; + hb_set_t visited_glyphs; + + hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices); + const BaseGlyphV1List &baseglyphV1_records = this+baseGlyphsV1List; + + for (const BaseGlyphV1Record &baseglyphV1record: baseglyphV1_records.iter ()) + { + unsigned gid = baseglyphV1record.glyphId; + if (!glyphset->has (gid)) continue; + + const Paint &paint = &baseglyphV1_records+baseglyphV1record.paint; + paint.dispatch (&c); + } + hb_set_union (glyphset, &visited_glyphs); + } + + const LayerV1List& get_layerV1List () const + { return (this+layersV1); } + + const BaseGlyphV1List& get_baseglyphV1List () const + { return (this+baseGlyphsV1List); } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && - (this+layersZ).sanitize (c, numLayers))); + return_trace (c->check_struct (this) && + (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) && + (this+layersZ).sanitize (c, numLayers) && + (version == 0 || + (COLRV1_ENABLE_SUBSETTING && version == 1 && + baseGlyphsV1List.sanitize (c, this) && + layersV1.sanitize (c, this) && + varStore.sanitize (c, this)))); } template<typename BaseIterator, typename LayerIterator, hb_requires (hb_is_iterator (BaseIterator)), hb_requires (hb_is_iterator (LayerIterator))> - bool serialize (hb_serialize_context_t *c, - unsigned version, - BaseIterator base_it, - LayerIterator layer_it) + bool serialize_V0 (hb_serialize_context_t *c, + unsigned version, + BaseIterator base_it, + LayerIterator layer_it) { TRACE_SERIALIZE (this); if (unlikely (base_it.len () != layer_it.len ())) @@ -171,6 +1000,12 @@ struct COLR this->version = version; numLayers = 0; numBaseGlyphs = base_it.len (); + if (base_it.len () == 0) + { + baseGlyphsZ = 0; + layersZ = 0; + return_trace (true); + } baseGlyphsZ = COLR::min_size; layersZ = COLR::min_size + numBaseGlyphs * BaseGlyphRecord::min_size; @@ -198,6 +1033,14 @@ struct COLR return record; } + const BaseGlyphV1Record* get_base_glyphV1_record (hb_codepoint_t gid) const + { + const BaseGlyphV1Record* record = &(this+baseGlyphsV1List).bsearch ((unsigned) gid); + if ((record && (hb_codepoint_t) record->glyphId != gid)) + record = nullptr; + return record; + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -214,7 +1057,7 @@ struct COLR if (unlikely (!old_record)) return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord)); - BaseGlyphRecord new_record; + BaseGlyphRecord new_record = {}; new_record.glyphId = new_gid; new_record.numLayers = old_record->numLayers; return hb_pair_t<bool, BaseGlyphRecord> (true, new_record); @@ -245,6 +1088,7 @@ struct COLR if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid))) return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers); out_layers[i].glyphId = new_gid; + out_layers[i].colorIdx = c->plan->colr_palettes->get (layers[i].colorIdx); } return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers); @@ -253,23 +1097,45 @@ struct COLR | hb_map_retains_sorting (hb_second) ; - if (unlikely (!base_it || !layer_it || base_it.len () != layer_it.len ())) + if (version == 0 && (!base_it || !layer_it)) return_trace (false); COLR *colr_prime = c->serializer->start_embed<COLR> (); - return_trace (colr_prime->serialize (c->serializer, version, base_it, layer_it)); + bool ret = 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->in_error ()) return_trace (false); + //no more COLRv1 glyphs: downgrade to version 0 + c->serializer->revert (snap); + colr_prime->version = 0; + return_trace (true); + } + + if (!colr_prime->layersV1.serialize_subset (c, layersV1, this)) return_trace (false); + + colr_prime->varStore = 0; + //TODO: subset varStore once it's implemented in fonttools + return_trace (true); } protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ - LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord>> + NNOffset32To<SortedUnsizedArrayOf<BaseGlyphRecord>> baseGlyphsZ; /* Offset to Base Glyph records. */ - LNNOffsetTo<UnsizedArrayOf<LayerRecord>> + NNOffset32To<UnsizedArrayOf<LayerRecord>> layersZ; /* Offset to Layer Records. */ HBUINT16 numLayers; /* Number of Layer Records. */ + // Version-1 additions + Offset32To<BaseGlyphV1List> baseGlyphsV1List; + Offset32To<LayerV1List> layersV1; + Offset32To<VariationStore> varStore; public: - DEFINE_SIZE_STATIC (14); + DEFINE_SIZE_MIN (14); }; } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh b/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh new file mode 100644 index 0000000000..4124efe0b1 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh @@ -0,0 +1,101 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2020 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_COLR_COLRV1_CLOSURE_HH +#define HB_OT_COLR_COLRV1_CLOSURE_HH + +#include "hb-open-type.hh" +#include "hb-ot-layout-common.hh" +#include "hb-ot-color-colr-table.hh" + +/* + * COLR -- Color + * https://docs.microsoft.com/en-us/typography/opentype/spec/colr + */ +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 (); + for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) + { + const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i]; + paint.dispatch (c); + } +} + +HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const +{ + c->add_glyph (gid); + (this+paint).dispatch (c); +} + +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; + c->add_glyph (gid); + + const BaseGlyphV1List &baseglyphV1_list = colr_table->get_baseglyphV1List (); + (&baseglyphV1_list+baseglyphV1_record->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); +} + +template <template<typename> class Var> +HB_INTERNAL void PaintTranslate<Var>::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); +} + +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 PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const +{ + (this+src).dispatch (c); + (this+backdrop).dispatch (c); +} + +} /* namespace OT */ + + +#endif /* HB_OT_COLR_COLRV1_CLOSURE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh index fa7d3207be..a9deeba9a7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-cpal-table.hh @@ -39,7 +39,6 @@ */ #define HB_OT_TAG_CPAL HB_TAG('C','P','A','L') - namespace OT { @@ -74,6 +73,44 @@ struct CPALV1Tail } public: + bool serialize (hb_serialize_context_t *c, + unsigned palette_count, + unsigned color_count, + const void *base, + const hb_map_t *color_index_map) const + { + TRACE_SERIALIZE (this); + auto *out = c->allocate_size<CPALV1Tail> (static_size); + if (unlikely (!out)) return_trace (false); + + out->paletteFlagsZ = 0; + if (paletteFlagsZ) + out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count); + + out->paletteLabelsZ = 0; + if (paletteLabelsZ) + out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count); + + const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count); + if (colorLabelsZ) + { + c->push (); + for (const auto _ : colorLabels) + { + if (!color_index_map->has (_)) continue; + NameID new_color_idx; + new_color_idx = color_index_map->get (_); + if (!c->copy<NameID> (new_color_idx)) + { + c->pop_discard (); + return_trace (false); + } + } + c->add_link (out->colorLabelsZ, c->pop_pack ()); + } + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, const void *base, unsigned int palette_count, @@ -87,15 +124,17 @@ struct CPALV1Tail } protected: - LNNOffsetTo<UnsizedArrayOf<HBUINT32>> + // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets + // here. Currently they are needed since UnsizedArrayOf doesn't define null_size + NNOffset32To<UnsizedArrayOf<HBUINT32>> paletteFlagsZ; /* Offset from the beginning of CPAL table to * the Palette Type Array. Set to 0 if no array * is provided. */ - LNNOffsetTo<UnsizedArrayOf<NameID>> + NNOffset32To<UnsizedArrayOf<NameID>> paletteLabelsZ; /* Offset from the beginning of CPAL table to * the palette labels array. Set to 0 if no * array is provided. */ - LNNOffsetTo<UnsizedArrayOf<NameID>> + NNOffset32To<UnsizedArrayOf<NameID>> colorLabelsZ; /* Offset from the beginning of CPAL table to * the color labels array. Set to 0 * if no array is provided. */ @@ -157,6 +196,84 @@ struct CPAL } public: + bool serialize (hb_serialize_context_t *c, + const hb_array_t<const BGRAColor> &color_records, + const hb_array_t<const HBUINT16> &color_record_indices, + const hb_map_t &color_record_index_map, + const hb_set_t &retained_color_record_indices) const + { + TRACE_SERIALIZE (this); + + for (const auto idx : color_record_indices) + { + HBUINT16 new_idx; + if (idx == 0) new_idx = 0; + else new_idx = color_record_index_map.get (idx); + if (!c->copy<HBUINT16> (new_idx)) return_trace (false); + } + + c->push (); + for (const auto _ : retained_color_record_indices.iter ()) + { + if (!c->copy<BGRAColor> (color_records[_])) + { + c->pop_discard (); + return_trace (false); + } + } + c->add_link (colorRecordsZ, c->pop_pack ()); + return_trace (true); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_map_t *color_index_map = c->plan->colr_palettes; + if (color_index_map->is_empty ()) return_trace (false); + + hb_set_t retained_color_indices; + for (const auto _ : color_index_map->keys ()) + { + if (_ == 0xFFFF) continue; + retained_color_indices.add (_); + } + if (retained_color_indices.is_empty ()) return_trace (false); + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + out->version = version; + out->numColors = retained_color_indices.get_population (); + out->numPalettes = numPalettes; + + const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes); + hb_map_t color_record_index_map; + hb_set_t retained_color_record_indices; + + unsigned record_count = 0; + for (const auto first_color_record_idx : colorRecordIndices) + { + for (unsigned retained_color_idx : retained_color_indices.iter ()) + { + unsigned color_record_idx = first_color_record_idx + retained_color_idx; + if (color_record_index_map.has (color_record_idx)) continue; + color_record_index_map.set (color_record_idx, record_count); + retained_color_record_indices.add (color_record_idx); + record_count++; + } + } + + out->numColorRecords = record_count; + const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords); + if (!out->serialize (c->serializer, color_records, colorRecordIndices, color_record_index_map, retained_color_record_indices)) + return_trace (false); + + if (version == 1) + return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map)); + + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -173,7 +290,7 @@ struct CPAL HBUINT16 numPalettes; /* Number of palettes in the table. */ HBUINT16 numColorRecords; /* Total number of color records, combined for * all palettes. */ - LNNOffsetTo<UnsizedArrayOf<BGRAColor>> + NNOffset32To<UnsizedArrayOf<BGRAColor>> colorRecordsZ; /* Offset from the beginning of CPAL table to * the first ColorRecord. */ UnsizedArrayOf<HBUINT16> diff --git a/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh index 09da11597d..d2911f19e6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh @@ -145,7 +145,7 @@ struct SBIXStrike auto* out = c->serializer->start_embed<SBIXStrike> (); if (unlikely (!out)) return_trace (false); auto snap = c->serializer->snapshot (); - if (unlikely (!c->serializer->extend (*out, num_output_glyphs + 1))) return_trace (false); + if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false); out->ppem = ppem; out->resolution = resolution; HBUINT32 head; @@ -185,7 +185,7 @@ struct SBIXStrike HBUINT16 resolution; /* The device pixel density (in PPI) for which this * strike was designed. (E.g., 96 PPI, 192 PPI.) */ protected: - UnsizedArrayOf<LOffsetTo<SBIXGlyph>> + UnsizedArrayOf<Offset32To<SBIXGlyph>> imageOffsetsZ; /* Offset from the beginning of the strike data header * to bitmap data for an individual glyph ID. */ public: @@ -352,11 +352,11 @@ struct sbix { TRACE_SERIALIZE (this); - auto *out = c->serializer->start_embed<LOffsetLArrayOf<SBIXStrike>> (); + auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> (); if (unlikely (!out)) return_trace (false); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - hb_vector_t<LOffsetTo<SBIXStrike>*> new_strikes; + hb_vector_t<Offset32To<SBIXStrike>*> new_strikes; hb_vector_t<hb_serialize_context_t::objidx_t> objidxs; for (int i = strikes.len - 1; i >= 0; --i) { @@ -400,7 +400,7 @@ struct sbix HBUINT16 version; /* Table version number — set to 1 */ HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. * Bits 2 to 15: reserved (set to 0). */ - LOffsetLArrayOf<SBIXStrike> + Array32OfOffset32To<SBIXStrike> strikes; /* Offsets from the beginning of the 'sbix' * table to data for each individual bitmap strike. */ public: diff --git a/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh index 1cc40ae53f..e022ef43b7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh @@ -62,7 +62,7 @@ struct SVGDocumentIndexEntry * this index entry. */ HBUINT16 endGlyphID; /* The last glyph ID in the range described by * this index entry. Must be >= startGlyphID. */ - LNNOffsetTo<UnsizedArrayOf<HBUINT8>> + NNOffset32To<UnsizedArrayOf<HBUINT8>> svgDoc; /* Offset from the beginning of the SVG Document Index * to an SVG document. Must be non-zero. */ HBUINT32 svgDocLength; /* Length of the SVG document. @@ -107,7 +107,7 @@ struct SVG protected: HBUINT16 version; /* Table version (starting at 0). */ - LOffsetTo<SortedArrayOf<SVGDocumentIndexEntry>> + Offset32To<SortedArray16Of<SVGDocumentIndexEntry>> svgDocEntries; /* Offset (relative to the start of the SVG table) to the * SVG Documents Index. Must be non-zero. */ /* Array of SVG Document Index Entries. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-color.cc b/thirdparty/harfbuzz/src/hb-ot-color.cc index 0e7203a88b..4170b71317 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color.cc +++ b/thirdparty/harfbuzz/src/hb-ot-color.cc @@ -37,9 +37,6 @@ #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-svg-table.hh" -#include <stdlib.h> -#include <string.h> - /** * SECTION:hb-ot-color @@ -64,7 +61,7 @@ * * Tests whether a face includes a `CPAL` color-palette table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.1.0 */ @@ -195,7 +192,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * * Tests whether a face includes any `COLR` color layers. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.1.0 */ @@ -242,7 +239,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * * Tests whether a face includes any `SVG` glyph images. * - * Return value: true if data found, false otherwise. + * Return value: %true if data found, %false otherwise. * * Since: 2.1.0 */ @@ -280,7 +277,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) * * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables). * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.1.0 */ diff --git a/thirdparty/harfbuzz/src/hb-ot-color.h b/thirdparty/harfbuzz/src/hb-ot-color.h index 4f37a4386f..c23ce4de44 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color.h +++ b/thirdparty/harfbuzz/src/hb-ot-color.h @@ -26,7 +26,7 @@ * Google Author(s): Sascha Brawer, Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -66,6 +66,8 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face, * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color * palette is appropriate to use when displaying the font on a dark background such as black. * + * Flags that describe the properties of color palette. + * * Since: 2.1.0 */ typedef enum { /*< flags >*/ @@ -95,6 +97,8 @@ hb_ot_color_has_layers (hb_face_t *face); /** * hb_ot_color_layer_t: + * @glyph: the glyph ID of the layer + * @color_index: the palette color index of the layer * * Pairs of glyph and color index. * diff --git a/thirdparty/harfbuzz/src/hb-ot-deprecated.h b/thirdparty/harfbuzz/src/hb-ot-deprecated.h index 2e75deef2d..ce6b6fef11 100644 --- a/thirdparty/harfbuzz/src/hb-ot-deprecated.h +++ b/thirdparty/harfbuzz/src/hb-ot-deprecated.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -41,6 +41,13 @@ HB_BEGIN_DECLS /* https://github.com/harfbuzz/harfbuzz/issues/1734 */ +/** + * HB_MATH_GLYPH_PART_FLAG_EXTENDER: + * + * Use #HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER instead. + * + * Deprecated: 2.5.1 + */ #define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER @@ -71,6 +78,8 @@ hb_ot_tag_from_language (hb_language_t language); /** * HB_OT_VAR_NO_AXIS_INDEX: * + * Do not use. + * * Since: 1.4.2 * Deprecated: 2.2.0 */ @@ -78,6 +87,13 @@ hb_ot_tag_from_language (hb_language_t language); /** * hb_ot_var_axis_t: + * @tag: axis tag + * @name_id: axis name identifier + * @min_value: minimum value of the axis + * @default_value: default value of the axis + * @max_value: maximum value of the axis + * + * Use #hb_ot_var_axis_info_t instead. * * Since: 1.4.2 * Deprecated: 2.2.0 diff --git a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh index 367e143fdf..ffbbb1bc53 100644 --- a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh @@ -40,7 +40,7 @@ /* This lists font tables that the hb_face_t will contain and lazily * load. Don't add a table unless it's used though. This is not - * exactly free. */ + * exactly zero-cost. */ /* v--- Add new tables in the right place here. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index fae7b5b65a..5c044c1c4f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -253,9 +253,7 @@ hb_ot_get_font_v_extents (hb_font_t *font, _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap); } -#if HB_USE_ATEXIT -static void free_static_ot_funcs (); -#endif +static inline void free_static_ot_funcs (); static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t> { @@ -281,21 +279,17 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot hb_font_funcs_make_immutable (funcs); -#if HB_USE_ATEXIT - atexit (free_static_ot_funcs); -#endif + hb_atexit (free_static_ot_funcs); return funcs; } } static_ot_funcs; -#if HB_USE_ATEXIT -static +static inline void free_static_ot_funcs () { static_ot_funcs.free_instance (); } -#endif static hb_font_funcs_t * _hb_ot_get_font_funcs () diff --git a/thirdparty/harfbuzz/src/hb-ot-font.h b/thirdparty/harfbuzz/src/hb-ot-font.h index 80eaa54b1a..e7959d1ae2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.h +++ b/thirdparty/harfbuzz/src/hb-ot-font.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-gasp-table.hh b/thirdparty/harfbuzz/src/hb-ot-gasp-table.hh index 4f291924af..f2a9cad464 100644 --- a/thirdparty/harfbuzz/src/hb-ot-gasp-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-gasp-table.hh @@ -71,7 +71,7 @@ struct gasp protected: HBUINT16 version; /* Version number (set to 1) */ - ArrayOf<GaspRange> + Array16Of<GaspRange> gaspRanges; /* Number of records to follow * Sorted by ppem */ public: diff --git a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh index 5470bd96da..ff7b9b2d25 100644 --- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh @@ -45,6 +45,10 @@ namespace OT { */ #define HB_OT_TAG_loca HB_TAG('l','o','c','a') +#ifndef HB_MAX_COMPOSITE_OPERATIONS +#define HB_MAX_COMPOSITE_OPERATIONS 100000 +#endif + struct loca { @@ -98,7 +102,7 @@ struct glyf 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 *) calloc (entry_size, num_offsets); + char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets); if (unlikely (!loca_prime_data)) return false; @@ -115,7 +119,7 @@ struct glyf entry_size * num_offsets, HB_MEMORY_MODE_WRITABLE, loca_prime_data, - free); + hb_free); bool result = plan->add_table (HB_OT_TAG_loca, loca_blob) && _add_head_and_set_loca_version (plan, use_short_loca); @@ -186,7 +190,7 @@ struct glyf | hb_map (&SubsetGlyph::padded_size) ; - if (c->serializer->in_error ()) return_trace (false); + if (unlikely (c->serializer->in_error ())) return_trace (false); return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, padded_offsets))); } @@ -209,10 +213,15 @@ struct glyf if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) return subset_glyph; - subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); - if (plan->drop_hints) subset_glyph.drop_hints_bytes (); - else subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); - + if (new_gid == 0 && + !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + subset_glyph.source_glyph = Glyph (); + else + subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + subset_glyph.drop_hints_bytes (); + else + subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); return subset_glyph; }) | hb_sink (glyphs) @@ -281,6 +290,11 @@ struct glyf hb_codepoint_t get_glyph_index () const { return glyphIndex; } void drop_instructions_flag () { flags = (uint16_t) flags & ~WE_HAVE_INSTRUCTIONS; } + void set_overlaps_flag () + { + flags = (uint16_t) flags | OVERLAP_COMPOUND; + } + bool has_instructions () const { return flags & WE_HAVE_INSTRUCTIONS; } bool has_more () const { return flags & MORE_COMPONENTS; } @@ -383,9 +397,12 @@ struct glyf { typedef const CompositeGlyphChain *__item_t__; composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) : - glyph (glyph_), current (current_) - { if (!check_range (current)) current = nullptr; } - composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {} + glyph (glyph_), current (nullptr), current_size (0) + { + set_next (current_); + } + + composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), current_size (0) {} const CompositeGlyphChain &__item__ () const { return *current; } bool __more__ () const { return current; } @@ -393,23 +410,36 @@ struct glyf { if (!current->has_more ()) { current = nullptr; return; } - const CompositeGlyphChain *possible = &StructAfter<CompositeGlyphChain, - CompositeGlyphChain> (*current); - if (!check_range (possible)) { current = nullptr; return; } - current = possible; + set_next (&StructAtOffset<CompositeGlyphChain> (current, current_size)); } bool operator != (const composite_iter_t& o) const { return glyph != o.glyph || current != o.current; } - bool check_range (const CompositeGlyphChain *composite) const + + void set_next (const CompositeGlyphChain *composite) { - return glyph.check_range (composite, CompositeGlyphChain::min_size) - && glyph.check_range (composite, composite->get_size ()); + if (!glyph.check_range (composite, CompositeGlyphChain::min_size)) + { + current = nullptr; + current_size = 0; + return; + } + unsigned size = composite->get_size (); + if (!glyph.check_range (composite, size)) + { + current = nullptr; + current_size = 0; + return; + } + + current = composite; + current_size = size; } private: hb_bytes_t glyph; __item_t__ current; + unsigned current_size; }; enum phantom_point_index_t @@ -427,14 +457,14 @@ struct glyf { enum simple_glyph_flag_t { - FLAG_ON_CURVE = 0x01, - FLAG_X_SHORT = 0x02, - FLAG_Y_SHORT = 0x04, - FLAG_REPEAT = 0x08, - FLAG_X_SAME = 0x10, - FLAG_Y_SAME = 0x20, - FLAG_RESERVED1 = 0x40, - FLAG_RESERVED2 = 0x80 + FLAG_ON_CURVE = 0x01, + FLAG_X_SHORT = 0x02, + FLAG_Y_SHORT = 0x04, + FLAG_REPEAT = 0x08, + FLAG_X_SAME = 0x10, + FLAG_Y_SAME = 0x20, + FLAG_OVERLAP_SIMPLE = 0x40, + FLAG_RESERVED2 = 0x80 }; private: @@ -495,8 +525,8 @@ struct glyf const Glyph trim_padding () const { /* based on FontTools _g_l_y_f.py::trim */ - const char *glyph = bytes.arrayZ; - const char *glyph_end = glyph + bytes.length; + const uint8_t *glyph = (uint8_t*) bytes.arrayZ; + const uint8_t *glyph_end = glyph + bytes.length; /* simple glyph w/contours, possibly trimmable */ glyph += instruction_len_offset (); @@ -553,6 +583,17 @@ struct glyf dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length); } + void set_overlaps_flag () + { + if (unlikely (!header.numberOfContours)) return; + + unsigned flags_offset = length (instructions_length ()); + if (unlikely (length (flags_offset + 1) > bytes.length)) return; + + HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset); + first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE; + } + static bool read_points (const HBUINT8 *&p /* IN/OUT */, contour_point_vector_t &points_ /* IN/OUT */, const hb_bytes_t &bytes, @@ -666,6 +707,12 @@ struct glyf /* Chop instructions off the end */ void drop_hints_bytes (hb_bytes_t &dest_start) const { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); } + + void set_overlaps_flag () + { + const_cast<CompositeGlyphChain &> (StructAfter<CompositeGlyphChain, GlyphHeader> (header)) + .set_overlaps_flag (); + } }; enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE }; @@ -695,6 +742,15 @@ struct glyf } } + void set_overlaps_flag () + { + switch (type) { + case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return; + case SIMPLE: SimpleGlyph (*header, bytes).set_overlaps_flag (); return; + default: return; + } + } + void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const { switch (type) { @@ -886,7 +942,7 @@ struct glyf { if (gid >= num_glyphs) return false; - /* Making this alloc free is not that easy + /* Making this allocfree is not that easy https://github.com/harfbuzz/harfbuzz/issues/2095 mostly because of gvar handling in VF fonts, perhaps a separate path for non-VF fonts can be considered */ @@ -944,9 +1000,9 @@ struct glyf return; } extents->x_bearing = font->em_scalef_x (min_x); - extents->width = font->em_scalef_x (max_x - min_x); + extents->width = font->em_scalef_x (max_x) - extents->x_bearing; extents->y_bearing = font->em_scalef_y (max_y); - extents->height = font->em_scalef_y (min_y - max_y); + extents->height = font->em_scalef_y (min_y) - extents->y_bearing; } protected: @@ -1045,18 +1101,28 @@ struct glyf return needs_padding_removal ? glyph.trim_padding () : glyph; } - void - add_gid_and_children (hb_codepoint_t gid, hb_set_t *gids_to_retain, - unsigned int depth = 0) const + unsigned + add_gid_and_children (hb_codepoint_t gid, + hb_set_t *gids_to_retain, + unsigned depth = 0, + unsigned operation_count = 0) const { - if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return; + if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count; + if (unlikely (operation_count++ > HB_MAX_COMPOSITE_OPERATIONS)) return operation_count; /* Check if is already visited */ - if (gids_to_retain->has (gid)) return; + if (gids_to_retain->has (gid)) return operation_count; gids_to_retain->add (gid); - for (auto &item : glyph_for_gid (gid).get_composite_iterator ()) - add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth); + auto it = glyph_for_gid (gid).get_composite_iterator (); + while (it) + { + auto item = *(it++); + operation_count += + add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count); + } + + return operation_count; } #ifdef HB_EXPERIMENTAL_API @@ -1230,7 +1296,11 @@ struct glyf const_cast<CompositeGlyphChain &> (_).set_glyph_index (new_gid); } - if (plan->drop_hints) Glyph (dest_glyph).drop_hints (); + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + Glyph (dest_glyph).drop_hints (); + + if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG) + Glyph (dest_glyph).set_overlaps_flag (); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh index c9c391bad5..dea2b7e29a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hdmx-table.hh @@ -52,7 +52,7 @@ struct DeviceRecord unsigned length = it.len (); - if (unlikely (!c->extend (*this, length))) return_trace (false); + if (unlikely (!c->extend (this, length))) return_trace (false); this->pixelSize = pixelSize; this->maxWidth = @@ -110,7 +110,7 @@ struct hdmx for (const hb_item_type<Iterator>& _ : +it) c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second); - return_trace (c->successful); + return_trace (c->successful ()); } diff --git a/thirdparty/harfbuzz/src/hb-ot-head-table.hh b/thirdparty/harfbuzz/src/hb-ot-head-table.hh index 5613a96dbf..ac588e3af6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-head-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-head-table.hh @@ -43,7 +43,7 @@ namespace OT { struct head { - friend struct OffsetTable; + friend struct OpenTypeOffsetTable; static constexpr hb_tag_t tableTag = HB_OT_TAG_head; diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index d06c0fa4a4..4038329938 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -146,7 +146,7 @@ struct hmtxvmtx _mtx.fini (); - if (unlikely (c->serializer->ran_out_of_room || c->serializer->in_error ())) + if (unlikely (c->serializer->in_error ())) return_trace (false); // Amend header num hmetrics diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh index 4df0d942ce..492947751e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh @@ -103,7 +103,7 @@ struct BaseCoordFormat3 protected: HBUINT16 format; /* Format identifier--format = 3 */ FWORD coordinate; /* X or Y value, in design units */ - OffsetTo<Device> + Offset16To<Device> deviceTable; /* Offset to Device table for X or * Y value, from beginning of * BaseCoord table (may be NULL). */ @@ -173,11 +173,11 @@ struct FeatMinMaxRecord protected: Tag tag; /* 4-byte feature identification tag--must * match feature tag in FeatureList */ - OffsetTo<BaseCoord> + Offset16To<BaseCoord> minCoord; /* Offset to BaseCoord table that defines * the minimum extent value, from beginning * of MinMax table (may be NULL) */ - OffsetTo<BaseCoord> + Offset16To<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines * the maximum extent value, from beginning * of MinMax table (may be NULL) */ @@ -212,15 +212,15 @@ struct MinMax } protected: - OffsetTo<BaseCoord> + Offset16To<BaseCoord> minCoord; /* Offset to BaseCoord table that defines * minimum extent value, from the beginning * of MinMax table (may be NULL) */ - OffsetTo<BaseCoord> + Offset16To<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines * maximum extent value, from the beginning * of MinMax table (may be NULL) */ - SortedArrayOf<FeatMinMaxRecord> + SortedArray16Of<FeatMinMaxRecord> featMinMaxRecords; /* Array of FeatMinMaxRecords, in alphabetical * order by featureTableTag */ @@ -247,7 +247,7 @@ struct BaseValues Index defaultIndex; /* Index number of default baseline for this * script — equals index position of baseline tag * in baselineTags array of the BaseTagList */ - OffsetArrayOf<BaseCoord> + Array16OfOffset16To<BaseCoord> baseCoords; /* Number of BaseCoord tables defined — should equal * baseTagCount in the BaseTagList * @@ -275,7 +275,7 @@ struct BaseLangSysRecord protected: Tag baseLangSysTag; /* 4-byte language system identification tag */ - OffsetTo<MinMax> + Offset16To<MinMax> minMax; /* Offset to MinMax table, from beginning * of BaseScript table */ public: @@ -305,13 +305,13 @@ struct BaseScript } protected: - OffsetTo<BaseValues> + Offset16To<BaseValues> baseValues; /* Offset to BaseValues table, from beginning * of BaseScript table (may be NULL) */ - OffsetTo<MinMax> + Offset16To<MinMax> defaultMinMax; /* Offset to MinMax table, from beginning of * BaseScript table (may be NULL) */ - SortedArrayOf<BaseLangSysRecord> + SortedArray16Of<BaseLangSysRecord> baseLangSysRecords; /* Number of BaseLangSysRecords * defined — may be zero (0) */ @@ -339,7 +339,7 @@ struct BaseScriptRecord protected: Tag baseScriptTag; /* 4-byte script identification tag */ - OffsetTo<BaseScript> + Offset16To<BaseScript> baseScript; /* Offset to BaseScript table, from beginning * of BaseScriptList */ @@ -364,7 +364,7 @@ struct BaseScriptList } protected: - SortedArrayOf<BaseScriptRecord> + SortedArray16Of<BaseScriptRecord> baseScriptRecords; public: @@ -426,12 +426,12 @@ struct Axis } protected: - OffsetTo<SortedArrayOf<Tag>> + Offset16To<SortedArray16Of<Tag>> baseTagList; /* Offset to BaseTagList table, from beginning * of Axis table (may be NULL) * Array of 4-byte baseline identification tags — must * be in alphabetical order */ - OffsetTo<BaseScriptList> + Offset16To<BaseScriptList> baseScriptList; /* Offset to BaseScriptList table, from beginning * of Axis table * Array of BaseScriptRecords, in alphabetical order @@ -501,11 +501,11 @@ struct BASE protected: FixedVersion<>version; /* Version of the BASE table */ - OffsetTo<Axis>hAxis; /* Offset to horizontal Axis table, from beginning + Offset16To<Axis>hAxis; /* Offset to horizontal Axis table, from beginning * of BASE table (may be NULL) */ - OffsetTo<Axis>vAxis; /* Offset to vertical Axis table, from beginning + Offset16To<Axis>vAxis; /* Offset to vertical Axis table, from beginning * of BASE table (may be NULL) */ - LOffsetTo<VariationStore> + Offset32To<VariationStore> varStore; /* Offset to the table of Item Variation * Store--from beginning of BASE * header (may be NULL). Introduced diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 6ab950a322..65f499a00d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -88,12 +88,66 @@ static inline void ClassDef_serialize (hb_serialize_context_t *c, Iterator it); static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, - const hb_set_t &glyphset, const hb_map_t &gid_klass_map, hb_sorted_vector_t<HBGlyphID> &glyphs, const hb_set_t &klasses, + bool use_class_zero, hb_map_t *klass_map /*INOUT*/); + +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_, + const hb_map_t *duplicate_feature_map_, + hb_set_t *new_collected_feature_indexes_) + :table (table_), + script_langsys_map (script_langsys_map_), + duplicate_feature_map (duplicate_feature_map_), + new_feature_indexes (new_collected_feature_indexes_), + script_count (0),langsys_count (0) {} + + bool visitedScript (const void *s) + { + if (script_count++ > HB_MAX_SCRIPTS) + return true; + + return visited (s, visited_script); + } + + bool visitedLangsys (const void *l) + { + if (langsys_count++ > HB_MAX_LANGSYS) + return true; + + return visited (l, visited_langsys); + } + + private: + template <typename T> + bool visited (const T *p, hb_set_t &visited_set) + { + hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table); + if (visited_set.has (delta)) + return true; + + visited_set.add (delta); + return false; + } + + public: + const void *table; + hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map; + const hb_map_t *duplicate_feature_map; + hb_set_t *new_feature_indexes; + + private: + hb_set_t visited_script; + hb_set_t visited_langsys; + unsigned script_count; + unsigned langsys_count; +}; + struct hb_subset_layout_context_t : hb_dispatch_context_t<hb_subset_layout_context_t, hb_empty_t, HB_DEBUG_SUBSET> { @@ -125,16 +179,21 @@ struct hb_subset_layout_context_t : hb_subset_context_t *subset_context; const hb_tag_t table_tag; const hb_map_t *lookup_index_map; + const hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *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_map_t *feature_map_) : + hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_, + hb_map_t *feature_index_map_) : subset_context (c_), table_tag (tag_), lookup_index_map (lookup_map_), - feature_index_map (feature_map_), + script_langsys_map (script_langsys_map_), + feature_index_map (feature_index_map_), + cur_script_index (0xFFFFu), script_count (0), langsys_count (0), feature_index_count (0), @@ -325,7 +384,7 @@ struct Record } Tag tag; /* 4-byte Tag identifier */ - OffsetTo<Type> + Offset16To<Type> offset; /* Offset from beginning of object holding * the Record */ public: @@ -333,11 +392,11 @@ struct Record }; template <typename Type> -struct RecordArrayOf : SortedArrayOf<Record<Type>> +struct RecordArrayOf : SortedArray16Of<Record<Type>> { - const OffsetTo<Type>& get_offset (unsigned int i) const + const Offset16To<Type>& get_offset (unsigned int i) const { return (*this)[i].offset; } - OffsetTo<Type>& get_offset (unsigned int i) + Offset16To<Type>& get_offset (unsigned int i) { return (*this)[i].offset; } const Tag& get_tag (unsigned int i) const { return (*this)[i].tag; } @@ -356,7 +415,7 @@ struct RecordArrayOf : SortedArrayOf<Record<Type>> } bool find_index (hb_tag_t tag, unsigned int *index) const { - return this->bfind (tag, index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); + return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); } }; @@ -407,6 +466,30 @@ struct RecordListOfFeature : RecordListOf<Feature> } }; +struct Script; +struct RecordListOfScript : RecordListOf<Script> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + for (auto _ : + hb_zip (*this, hb_range (count))) + { + auto snap = c->serializer->snapshot (); + l->cur_script_index = _.second; + bool ret = _.first.subset (l, this); + if (!ret) c->serializer->revert (snap); + else out->len++; + } + + return_trace (true); + } +}; + struct RangeRecord { int cmp (hb_codepoint_t g) const @@ -434,7 +517,7 @@ struct RangeRecord DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord); -struct IndexArray : ArrayOf<Index> +struct IndexArray : Array16Of<Index> { bool intersects (const hb_map_t *indexes) const { return hb_any (*this, indexes); } @@ -474,7 +557,7 @@ struct IndexArray : ArrayOf<Index> void add_indexes_to (hb_set_t* output /* OUT */) const { - output->add_array (arrayZ, len); + output->add_array (as_array ()); } }; @@ -506,18 +589,46 @@ struct LangSys return_trace (c->embed (*this)); } - bool operator == (const LangSys& o) const + bool compare (const LangSys& o, const hb_map_t *feature_index_map) const { - if (featureIndex.len != o.featureIndex.len || - reqFeatureIndex != o.reqFeatureIndex) + if (reqFeatureIndex != o.reqFeatureIndex) + return false; + + auto iter = + + hb_iter (featureIndex) + | hb_filter (feature_index_map) + | hb_map (feature_index_map) + ; + + auto o_iter = + + hb_iter (o.featureIndex) + | hb_filter (feature_index_map) + | hb_map (feature_index_map) + ; + + if (iter.len () != o_iter.len ()) return false; - for (const auto _ : + hb_zip (featureIndex, o.featureIndex)) + for (const auto _ : + hb_zip (iter, o_iter)) if (_.first != _.second) return false; return true; } + void collect_features (hb_prune_langsys_context_t *c) const + { + if (!has_required_feature () && !get_feature_count ()) return; + if (c->visitedLangsys (this)) return; + if (has_required_feature () && + c->duplicate_feature_map->has (reqFeatureIndex)) + c->new_feature_indexes->add (get_required_feature_index ()); + + + hb_iter (featureIndex) + | hb_filter (c->duplicate_feature_map) + | hb_sink (c->new_feature_indexes) + ; + } + bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l, const Tag *tag = nullptr) const @@ -581,6 +692,49 @@ struct Script bool has_default_lang_sys () const { return defaultLangSys != 0; } const LangSys& get_default_lang_sys () const { return this+defaultLangSys; } + void prune_langsys (hb_prune_langsys_context_t *c, + unsigned script_index) const + { + if (!has_default_lang_sys () && !get_lang_sys_count ()) return; + if (c->visitedScript (this)) return; + + if (!c->script_langsys_map->has (script_index)) + { + hb_set_t* empty_set = hb_set_create (); + if (unlikely (!c->script_langsys_map->set (script_index, empty_set))) + { + hb_set_destroy (empty_set); + return; + } + } + + unsigned langsys_count = get_lang_sys_count (); + if (has_default_lang_sys ()) + { + //only collect features from non-redundant langsys + const LangSys& d = get_default_lang_sys (); + d.collect_features (c); + + for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + { + const LangSys& l = this+_.first.offset; + if (l.compare (d, c->duplicate_feature_map)) continue; + + l.collect_features (c); + c->script_langsys_map->get (script_index)->add (_.second); + } + } + else + { + for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + { + const LangSys& l = this+_.first.offset; + l.collect_features (c); + c->script_langsys_map->get (script_index)->add (_.second); + } + } + } + bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l, const Tag *tag) const @@ -609,16 +763,17 @@ struct Script } } - + langSys.iter () - | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) - | hb_filter ([&] (const Record<LangSys>& record) - { - const LangSys& d = this+defaultLangSys; - const LangSys& l = this+record.offset; - return !(l == d); - }) - | hb_apply (subset_record_array (l, &(out->langSys), this)) - ; + const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index); + if (active_langsys) + { + unsigned count = langSys.len; + + hb_zip (langSys, hb_range (count)) + | hb_filter (active_langsys, hb_second) + | hb_map (hb_first) + | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) + | hb_apply (subset_record_array (l, &(out->langSys), this)) + ; + } return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB); } @@ -631,7 +786,7 @@ struct Script } protected: - OffsetTo<LangSys> + Offset16To<LangSys> defaultLangSys; /* Offset to DefaultLangSys table--from * beginning of Script table--may be Null */ RecordArrayOf<LangSys> @@ -641,7 +796,7 @@ struct Script DEFINE_SIZE_ARRAY_SIZED (4, langSys); }; -typedef RecordListOf<Script> ScriptList; +typedef RecordListOfScript ScriptList; /* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */ @@ -856,7 +1011,7 @@ struct FeatureParamsCharacterVariants * user-interface labels for the * feature parameters. (Must be zero * if numParameters is zero.) */ - ArrayOf<HBUINT24> + Array16Of<HBUINT24> characters; /* Array of the Unicode Scalar Value * of the characters for which this * feature provides glyph variants. @@ -953,7 +1108,7 @@ struct Feature auto *out = c->serializer->start_embed (*this); if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - bool subset_featureParams = out->featureParams.serialize_subset (c, featureParams, this, tag); + out->featureParams.serialize_subset (c, featureParams, this, tag); auto it = + hb_iter (lookupIndex) @@ -962,8 +1117,9 @@ struct Feature ; out->lookupIndex.serialize (c->serializer, l, it); - return_trace (bool (it) || subset_featureParams - || (tag && *tag == HB_TAG ('p', 'r', 'e', 'f'))); + // The decision to keep or drop this feature is already made before we get here + // so always retain it. + return_trace (true); } bool sanitize (hb_sanitize_context_t *c, @@ -998,7 +1154,7 @@ struct Feature unsigned int new_offset_int = orig_offset - (((char *) this) - ((char *) closure->list_base)); - OffsetTo<FeatureParams> new_offset; + Offset16To<FeatureParams> new_offset; /* Check that it would not overflow. */ new_offset = new_offset_int; if (new_offset == new_offset_int && @@ -1010,7 +1166,7 @@ struct Feature return_trace (true); } - OffsetTo<FeatureParams> + Offset16To<FeatureParams> featureParams; /* Offset to Feature Parameters table (if one * has been defined for the feature), relative * to the beginning of the Feature Table; = Null @@ -1049,11 +1205,11 @@ struct Lookup unsigned int get_subtable_count () const { return subTable.len; } template <typename TSubTable> - const OffsetArrayOf<TSubTable>& get_subtables () const - { return reinterpret_cast<const OffsetArrayOf<TSubTable> &> (subTable); } + const Array16OfOffset16To<TSubTable>& get_subtables () const + { return reinterpret_cast<const Array16OfOffset16To<TSubTable> &> (subTable); } template <typename TSubTable> - OffsetArrayOf<TSubTable>& get_subtables () - { return reinterpret_cast<OffsetArrayOf<TSubTable> &> (subTable); } + Array16OfOffset16To<TSubTable>& get_subtables () + { return reinterpret_cast<Array16OfOffset16To<TSubTable> &> (subTable); } template <typename TSubTable> const TSubTable& get_subtable (unsigned int i) const @@ -1106,13 +1262,13 @@ struct Lookup unsigned int num_subtables) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); lookupType = lookup_type; lookupFlag = lookup_props & 0xFFFFu; if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - if (unlikely (!c->extend (*this))) return_trace (false); + if (unlikely (!c->extend (this))) return_trace (false); HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); markFilteringSet = lookup_props >> 16; } @@ -1128,13 +1284,21 @@ struct Lookup out->lookupType = lookupType; out->lookupFlag = lookupFlag; - const hb_set_t *glyphset = c->plan->glyphset (); + const hb_set_t *glyphset = c->plan->glyphset_gsub (); unsigned int lookup_type = get_type (); + hb_iter (get_subtables <TSubTable> ()) - | hb_filter ([this, glyphset, lookup_type] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); }) + | hb_filter ([this, glyphset, lookup_type] (const Offset16To<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); }) | hb_apply (subset_offset_array (c, out->get_subtables<TSubTable> (), this, lookup_type)) ; + if (lookupFlag & LookupFlag::UseMarkFilteringSet) + { + if (unlikely (!c->serializer->extend (out))) return_trace (false); + const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); + HBUINT16 &outMarkFilteringSet = StructAfter<HBUINT16> (out->subTable); + outMarkFilteringSet = markFilteringSet; + } + return_trace (true); } @@ -1179,7 +1343,7 @@ struct Lookup private: HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */ HBUINT16 lookupFlag; /* Lookup qualifiers */ - ArrayOf<Offset16> + Array16Of<Offset16> subTable; /* Array of SubTables */ /*HBUINT16 markFilteringSetX[HB_VAR_ARRAY];*//* Index (base 0) into GDEF mark glyph sets * structure. This field is only present if bit @@ -1188,10 +1352,10 @@ struct Lookup DEFINE_SIZE_ARRAY (6, subTable); }; -typedef OffsetListOf<Lookup> LookupList; +typedef List16OfOffset16To<Lookup> LookupList; template <typename TLookup> -struct LookupOffsetList : OffsetListOf<TLookup> +struct LookupOffsetList : List16OfOffset16To<TLookup> { bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l) const @@ -1212,7 +1376,7 @@ struct LookupOffsetList : OffsetListOf<TLookup> bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (OffsetListOf<TLookup>::sanitize (c, this)); + return_trace (List16OfOffset16To<TLookup>::sanitize (c, this)); } }; @@ -1229,7 +1393,7 @@ struct CoverageFormat1 unsigned int get_coverage (hb_codepoint_t glyph_id) const { unsigned int i; - glyphArray.bfind (glyph_id, &i, HB_BFIND_NOT_FOUND_STORE, NOT_COVERED); + glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED); return i; } @@ -1250,18 +1414,25 @@ struct CoverageFormat1 bool intersects (const hb_set_t *glyphs) const { /* TODO Speed up, using hb_set_next() and bsearch()? */ - unsigned int count = glyphArray.len; - for (unsigned int i = 0; i < count; i++) - if (glyphs->has (glyphArray[i])) + for (const auto& g : glyphArray.as_array ()) + if (glyphs->has (g)) return true; return false; } bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { return glyphs->has (glyphArray[index]); } + void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const + { + unsigned count = glyphArray.len; + for (unsigned i = 0; i < count; i++) + if (glyphs->has (glyphArray[i])) + intersect_glyphs->add (glyphArray[i]); + } + template <typename set_t> bool collect_coverage (set_t *glyphs) const - { return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len); } + { return glyphs->add_sorted_array (glyphArray.as_array ()); } public: /* Older compilers need this to be public. */ @@ -1283,7 +1454,7 @@ struct CoverageFormat1 protected: HBUINT16 coverageFormat; /* Format identifier--format = 1 */ - SortedArrayOf<HBGlyphID> + SortedArray16Of<HBGlyphID> glyphArray; /* Array of GlyphIDs--in numerical order */ public: DEFINE_SIZE_ARRAY (4, glyphArray); @@ -1307,7 +1478,7 @@ struct CoverageFormat2 bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!glyphs)) { @@ -1356,18 +1527,17 @@ struct CoverageFormat2 bool intersects (const hb_set_t *glyphs) const { /* TODO Speed up, using hb_set_next() and bsearch()? */ - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].intersects (glyphs)) + /* TODO(iter) Rewrite as dagger. */ + for (const auto& range : rangeRecord.as_array ()) + if (range.intersects (glyphs)) return true; return false; } bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { - unsigned int i; - unsigned int count = rangeRecord.len; - for (i = 0; i < count; i++) { - const RangeRecord &range = rangeRecord[i]; + /* TODO(iter) Rewrite as dagger. */ + for (const auto& range : rangeRecord.as_array ()) + { if (range.value <= index && index < (unsigned int) range.value + (range.last - range.first) && range.intersects (glyphs)) @@ -1378,6 +1548,16 @@ struct CoverageFormat2 return false; } + void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const + { + for (const auto& range : rangeRecord.as_array ()) + { + if (!range.intersects (glyphs)) continue; + for (hb_codepoint_t g = range.first; g <= range.last; g++) + if (glyphs->has (g)) intersect_glyphs->add (g); + } + } + template <typename set_t> bool collect_coverage (set_t *glyphs) const { @@ -1444,7 +1624,7 @@ struct CoverageFormat2 protected: HBUINT16 coverageFormat; /* Format identifier--format = 2 */ - SortedArrayOf<RangeRecord> + SortedArray16Of<RangeRecord> rangeRecord; /* Array of glyph ranges--ordered by * Start GlyphID. rangeCount entries * long */ @@ -1477,7 +1657,7 @@ struct Coverage bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); unsigned count = 0; unsigned num_ranges = 0; @@ -1502,7 +1682,7 @@ struct Coverage 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 it = @@ -1560,6 +1740,16 @@ struct Coverage } } + void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const + { + switch (u.format) + { + case 1: return u.format1.intersected_coverage_glyphs (glyphs, intersect_glyphs); + case 2: return u.format2.intersected_coverage_glyphs (glyphs, intersect_glyphs); + default:return ; + } + } + struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> { static constexpr bool is_sorted_iterator = true; @@ -1641,10 +1831,10 @@ Coverage_serialize (hb_serialize_context_t *c, { c->start_embed<Coverage> ()->serialize (c, it); } static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, - const hb_set_t &glyphset, const hb_map_t &gid_klass_map, hb_sorted_vector_t<HBGlyphID> &glyphs, const hb_set_t &klasses, + bool use_class_zero, hb_map_t *klass_map /*INOUT*/) { if (!klass_map) @@ -1656,7 +1846,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, /* any glyph not assigned a class value falls into Class zero (0), * if any glyph assigned to class 0, remapping must start with 0->0*/ - if (glyphset.get_population () > gid_klass_map.get_population ()) + if (!use_class_zero) klass_map->set (0, 0); unsigned idx = klass_map->has (0) ? 1 : 0; @@ -1700,10 +1890,11 @@ struct ClassDefFormat1 Iterator it) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!it)) { + classFormat = 1; startGlyph = 0; classValue.len = 0; return_trace (true); @@ -1726,10 +1917,13 @@ struct ClassDefFormat1 } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/, + bool keep_empty_table = true, + bool use_class_zero = true, + const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->_glyphset_gsub; + 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; @@ -1738,9 +1932,12 @@ struct ClassDefFormat1 hb_codepoint_t start = startGlyph; hb_codepoint_t end = start + classValue.len; + for (const hb_codepoint_t gid : + hb_range (start, end) - | hb_filter (glyphset)) + | hb_filter (glyphset)) { + if (glyph_filter && !glyph_filter->has(gid)) continue; + unsigned klass = classValue[gid - start]; if (!klass) continue; @@ -1749,9 +1946,13 @@ struct ClassDefFormat1 orig_klasses.add (klass); } - ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map, - glyphs, orig_klasses, klass_map); - return_trace ((bool) glyphs); + unsigned glyph_count = glyph_filter + ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter)) + : glyphset.get_population (); + use_class_zero = use_class_zero && glyph_count <= gid_org_klass_map.get_population (); + ClassDef_remap_and_serialize (c->serializer, gid_org_klass_map, + glyphs, orig_klasses, use_class_zero, klass_map); + return_trace (keep_empty_table || (bool) glyphs); } bool sanitize (hb_sanitize_context_t *c) const @@ -1784,7 +1985,7 @@ struct ClassDefFormat1 } template <typename set_t> - bool collect_class (set_t *glyphs, unsigned int klass) const + bool collect_class (set_t *glyphs, unsigned klass) const { unsigned int count = classValue.len; for (unsigned int i = 0; i < count; i++) @@ -1802,7 +2003,7 @@ struct ClassDefFormat1 if (classValue[iter - start]) return true; return false; } - bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const + bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const { unsigned int count = classValue.len; if (klass == 0) @@ -1815,16 +2016,38 @@ struct ClassDefFormat1 if (hb_set_next (glyphs, &g)) return true; /* Fall through. */ } + /* TODO Speed up, using set overlap first? */ + /* TODO(iter) Rewrite as dagger. */ + HBUINT16 k {klass}; + const HBUINT16 *arr = classValue.arrayZ; for (unsigned int i = 0; i < count; i++) - if (classValue[i] == klass && glyphs->has (startGlyph + i)) + if (arr[i] == k && glyphs->has (startGlyph + i)) return true; return false; } + void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const + { + unsigned count = classValue.len; + if (klass == 0) + { + hb_codepoint_t endGlyph = startGlyph + count -1; + for (hb_codepoint_t g : glyphs->iter ()) + if (g < startGlyph || g > endGlyph) + intersect_glyphs->add (g); + + return; + } + + for (unsigned i = 0; i < count; i++) + if (classValue[i] == klass && glyphs->has (startGlyph + i)) + intersect_glyphs->add (startGlyph + i); + } + protected: HBUINT16 classFormat; /* Format identifier--format = 1 */ HBGlyphID startGlyph; /* First GlyphID of the classValueArray */ - ArrayOf<HBUINT16> + Array16Of<HBUINT16> classValue; /* Array of Class Values--one per GlyphID */ public: DEFINE_SIZE_ARRAY (6, classValue); @@ -1846,10 +2069,11 @@ struct ClassDefFormat2 Iterator it) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!it)) { + classFormat = 2; rangeRecord.len = 0; return_trace (true); } @@ -1895,10 +2119,13 @@ struct ClassDefFormat2 } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/, + bool keep_empty_table = true, + bool use_class_zero = true, + const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->_glyphset_gsub; + 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; @@ -1915,15 +2142,20 @@ struct ClassDefFormat2 for (hb_codepoint_t g = start; g < end; g++) { if (!glyphset.has (g)) continue; + if (glyph_filter && !glyph_filter->has (g)) continue; glyphs.push (glyph_map[g]); gid_org_klass_map.set (glyph_map[g], klass); orig_klasses.add (klass); } } - ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map, - glyphs, orig_klasses, klass_map); - return_trace ((bool) glyphs); + unsigned glyph_count = glyph_filter + ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter)) + : glyphset.get_population (); + use_class_zero = use_class_zero && glyph_count <= gid_org_klass_map.get_population (); + ClassDef_remap_and_serialize (c->serializer, gid_org_klass_map, + glyphs, orig_klasses, use_class_zero, klass_map); + return_trace (keep_empty_table || (bool) glyphs); } bool sanitize (hb_sanitize_context_t *c) const @@ -1961,11 +2193,14 @@ struct ClassDefFormat2 /* TODO Speed up, using hb_set_next() and bsearch()? */ unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].intersects (glyphs)) + { + const auto& range = rangeRecord[i]; + if (range.intersects (glyphs) && range.value) return true; + } return false; } - bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const + bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const { unsigned int count = rangeRecord.len; if (klass == 0) @@ -1984,15 +2219,67 @@ struct ClassDefFormat2 return true; /* Fall through. */ } + /* TODO Speed up, using set overlap first? */ + /* TODO(iter) Rewrite as dagger. */ + HBUINT16 k {klass}; + const RangeRecord *arr = rangeRecord.arrayZ; for (unsigned int i = 0; i < count; i++) - if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) + if (arr[i].value == k && arr[i].intersects (glyphs)) return true; return false; } + void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const + { + unsigned count = rangeRecord.len; + if (klass == 0) + { + hb_codepoint_t g = HB_SET_VALUE_INVALID; + for (unsigned int i = 0; i < count; i++) + { + if (!hb_set_next (glyphs, &g)) + break; + while (g != HB_SET_VALUE_INVALID && g < rangeRecord[i].first) + { + intersect_glyphs->add (g); + hb_set_next (glyphs, &g); + } + g = rangeRecord[i].last; + } + while (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) + intersect_glyphs->add (g); + + return; + } + + hb_codepoint_t g = HB_SET_VALUE_INVALID; + for (unsigned int i = 0; i < count; i++) + { + if (rangeRecord[i].value != klass) continue; + + if (g != HB_SET_VALUE_INVALID) + { + if (g >= rangeRecord[i].first && + g <= rangeRecord[i].last) + intersect_glyphs->add (g); + if (g > rangeRecord[i].last) + continue; + } + + g = rangeRecord[i].first - 1; + while (hb_set_next (glyphs, &g)) + { + if (g >= rangeRecord[i].first && g <= rangeRecord[i].last) + intersect_glyphs->add (g); + else if (g > rangeRecord[i].last) + break; + } + } + } + protected: HBUINT16 classFormat; /* Format identifier--format = 2 */ - SortedArrayOf<RangeRecord> + SortedArray16Of<RangeRecord> rangeRecord; /* Array of glyph ranges--ordered by * Start GlyphID */ public: @@ -2021,19 +2308,20 @@ struct ClassDef template<typename Iterator, hb_requires (hb_is_iterator (Iterator))> - bool serialize (hb_serialize_context_t *c, Iterator it) + bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + + auto it = + it_with_class_zero | hb_filter (hb_second); unsigned format = 2; if (likely (it)) { hb_codepoint_t glyph_min = (*it).first; - hb_codepoint_t glyph_max = + it - | hb_map (hb_first) - | hb_reduce (hb_max, 0u); + hb_codepoint_t glyph_max = glyph_min; + unsigned num_glyphs = 0; unsigned num_ranges = 1; hb_codepoint_t prev_gid = glyph_min; unsigned prev_klass = (*it).second; @@ -2042,7 +2330,9 @@ struct ClassDef { hb_codepoint_t cur_gid = gid_klass_pair.first; unsigned cur_klass = gid_klass_pair.second; - if (cur_gid == glyph_min || !cur_klass) continue; + num_glyphs++; + if (cur_gid == glyph_min) continue; + if (cur_gid > glyph_max) glyph_max = cur_gid; if (cur_gid != prev_gid + 1 || cur_klass != prev_klass) num_ranges++; @@ -2051,7 +2341,7 @@ struct ClassDef prev_klass = cur_klass; } - if (1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) + if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) format = 1; } u.format = format; @@ -2065,12 +2355,15 @@ struct ClassDef } bool subset (hb_subset_context_t *c, - hb_map_t *klass_map = nullptr /*OUT*/) const + hb_map_t *klass_map = nullptr /*OUT*/, + bool keep_empty_table = true, + bool use_class_zero = true, + const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (u.format1.subset (c, klass_map)); - case 2: return_trace (u.format2.subset (c, klass_map)); + case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); default:return_trace (false); } } @@ -2127,6 +2420,15 @@ struct ClassDef } } + void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const + { + switch (u.format) { + case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + default:return; + } + } + protected: union { HBUINT16 format; /* Format identifier */ @@ -2214,19 +2516,19 @@ struct VarRegionList bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - axesZ.sanitize (c, (unsigned int) axisCount * (unsigned int) regionCount)); + return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); } bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t ®ion_map) { TRACE_SERIALIZE (this); - VarRegionList *out = c->allocate_min<VarRegionList> (); - if (unlikely (!out)) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); axisCount = src->axisCount; regionCount = region_map.get_population (); - if (unlikely (!c->allocate_size<VarRegionList> (get_size () - min_size))) return_trace (false); - unsigned int region_count = src->get_region_count (); + if (unlikely (hb_unsigned_mul_overflows (axisCount * regionCount, + VarRegionAxis::static_size))) return_trace (false); + if (unlikely (!c->extend (this))) return_trace (false); + unsigned int region_count = src->regionCount; for (unsigned int r = 0; r < regionCount; r++) { unsigned int backward = region_map.backward (r); @@ -2238,11 +2540,11 @@ struct VarRegionList } unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; } - unsigned int get_region_count () const { return regionCount; } - protected: + public: HBUINT16 axisCount; HBUINT16 regionCount; + protected: UnsizedArrayOf<VarRegionAxis> axesZ; public: @@ -2258,7 +2560,10 @@ struct VarData { return shortCount + regionIndices.len; } unsigned int get_size () const - { return itemCount * get_row_size (); } + { return min_size + - regionIndices.min_size + regionIndices.get_size () + + itemCount * get_row_size (); + } float get_delta (unsigned int inner, const int *coords, unsigned int coord_count, @@ -2292,10 +2597,10 @@ struct VarData return delta; } - void get_scalars (const int *coords, unsigned int coord_count, - const VarRegionList ®ions, - float *scalars /*OUT */, - unsigned int num_scalars) const + void get_region_scalars (const int *coords, unsigned int coord_count, + const VarRegionList ®ions, + float *scalars /*OUT */, + unsigned int num_scalars) const { unsigned count = hb_min (num_scalars, regionIndices.len); for (unsigned int i = 0; i < count; i++) @@ -2321,7 +2626,7 @@ struct VarData const hb_bimap_t ®ion_map) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); itemCount = inner_map.get_next_value (); /* Optimize short count */ @@ -2363,9 +2668,7 @@ struct VarData shortCount = new_short_count; regionIndices.len = new_ri_count; - unsigned int size = regionIndices.get_size () - HBUINT16::static_size/*regionIndices.len*/ + (get_row_size () * itemCount); - if (unlikely (!c->allocate_size<HBUINT8> (size))) - return_trace (false); + if (unlikely (!c->extend (this))) return_trace (false); for (r = 0; r < ri_count; r++) if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]]; @@ -2380,16 +2683,16 @@ struct VarData return_trace (true); } - void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_inc_bimap_t &inner_map) const + void collect_region_refs (hb_set_t ®ion_indices, const hb_inc_bimap_t &inner_map) const { for (unsigned int r = 0; r < regionIndices.len; r++) { unsigned int region = regionIndices[r]; - if (region_map.has (region)) continue; + if (region_indices.has (region)) continue; for (unsigned int i = 0; i < inner_map.get_next_value (); i++) if (get_item_delta (inner_map.backward (i), r) != 0) { - region_map.add (region); + region_indices.add (region); break; } } @@ -2424,7 +2727,7 @@ struct VarData protected: HBUINT16 itemCount; HBUINT16 shortCount; - ArrayOf<HBUINT16> regionIndices; + Array16Of<HBUINT16> regionIndices; /*UnsizedArrayOf<HBUINT8>bytesX;*/ public: DEFINE_SIZE_ARRAY (6, regionIndices); @@ -2432,6 +2735,7 @@ struct VarData struct VariationStore { + private: float get_delta (unsigned int outer, unsigned int inner, const int *coords, unsigned int coord_count) const { @@ -2447,6 +2751,7 @@ struct VariationStore this+regions); } + public: float get_delta (unsigned int index, const int *coords, unsigned int coord_count) const { @@ -2473,32 +2778,48 @@ struct VariationStore const hb_array_t <hb_inc_bimap_t> &inner_maps) { TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + unsigned int set_count = 0; for (unsigned int i = 0; i < inner_maps.length; i++) - if (inner_maps[i].get_population () > 0) set_count++; + if (inner_maps[i].get_population ()) + set_count++; - unsigned int size = min_size + HBUINT32::static_size * set_count; - if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false); format = 1; - hb_inc_bimap_t region_map; + const auto &src_regions = src+src->regions; + + hb_set_t region_indices; for (unsigned int i = 0; i < inner_maps.length; i++) - (src+src->dataSets[i]).collect_region_refs (region_map, inner_maps[i]); - region_map.sort (); + (src+src->dataSets[i]).collect_region_refs (region_indices, inner_maps[i]); - if (unlikely (!regions.serialize (c, this) - .serialize (c, &(src+src->regions), region_map))) return_trace (false); + if (region_indices.in_error ()) + return_trace (false); + + region_indices.del_range ((src_regions).regionCount, hb_set_t::INVALID); + + /* TODO use constructor when our data-structures support that. */ + hb_inc_bimap_t region_map; + + hb_iter (region_indices) + | hb_apply ([®ion_map] (unsigned _) { region_map.add(_); }) + ; + if (region_map.in_error()) + return_trace (false); + + if (unlikely (!regions.serialize_serialize (c, &src_regions, region_map))) + return_trace (false); - /* TODO: The following code could be simplified when - * OffsetListOf::subset () can take a custom param to be passed to VarData::serialize () - */ dataSets.len = set_count; + if (unlikely (!c->extend (dataSets))) return_trace (false); + + /* TODO: The following code could be simplified when + * List16OfOffset16To::subset () can take a custom param to be passed to VarData::serialize () */ unsigned int set_index = 0; for (unsigned int i = 0; i < inner_maps.length; i++) { - if (inner_maps[i].get_population () == 0) continue; - if (unlikely (!dataSets[set_index++].serialize (c, this) - .serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map))) + if (!inner_maps[i].get_population ()) continue; + if (unlikely (!dataSets[set_index++] + .serialize_serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map))) return_trace (false); } @@ -2543,13 +2864,13 @@ struct VariationStore && varstore_prime->dataSets); } - unsigned int get_region_index_count (unsigned int ivs) const - { return (this+dataSets[ivs]).get_region_index_count (); } + unsigned int get_region_index_count (unsigned int major) const + { return (this+dataSets[major]).get_region_index_count (); } - void get_scalars (unsigned int ivs, - const int *coords, unsigned int coord_count, - float *scalars /*OUT*/, - unsigned int num_scalars) const + void get_region_scalars (unsigned int major, + const int *coords, unsigned int coord_count, + float *scalars /*OUT*/, + unsigned int num_scalars) const { #ifdef HB_NO_VAR for (unsigned i = 0; i < num_scalars; i++) @@ -2557,18 +2878,19 @@ struct VariationStore return; #endif - (this+dataSets[ivs]).get_scalars (coords, coord_count, this+regions, - &scalars[0], num_scalars); + (this+dataSets[major]).get_region_scalars (coords, coord_count, + this+regions, + &scalars[0], num_scalars); } unsigned int get_sub_table_count () const { return dataSets.len; } protected: HBUINT16 format; - LOffsetTo<VarRegionList> regions; - LOffsetArrayOf<VarData> dataSets; + Offset32To<VarRegionList> regions; + Array16OfOffset32To<VarData> dataSets; public: - DEFINE_SIZE_ARRAY (8, dataSets); + DEFINE_SIZE_ARRAY_SIZED (8, dataSets); }; /* @@ -2669,7 +2991,8 @@ struct ConditionSet + conditions.iter () | hb_apply (subset_offset_array (c, out->conditions, this)) ; - return_trace (true); + + return_trace (bool (out->conditions)); } bool sanitize (hb_sanitize_context_t *c) const @@ -2679,7 +3002,7 @@ struct ConditionSet } protected: - LOffsetArrayOf<Condition> conditions; + Array16OfOffset32To<Condition> conditions; public: DEFINE_SIZE_ARRAY (2, conditions); }; @@ -2704,6 +3027,12 @@ struct FeatureTableSubstitutionRecord bool subset (hb_subset_layout_context_t *c, const void *base) const { TRACE_SUBSET (this); + if (!c->feature_index_map->has (featureIndex)) { + // Feature that is being substituted is not being retained, so we don't + // need this. + return_trace (false); + } + auto *out = c->subset_context->serializer->embed (this); if (unlikely (!out)) return_trace (false); @@ -2720,7 +3049,7 @@ struct FeatureTableSubstitutionRecord protected: HBUINT16 featureIndex; - LOffsetTo<Feature> feature; + Offset32To<Feature> feature; public: DEFINE_SIZE_STATIC (6); }; @@ -2756,6 +3085,15 @@ struct FeatureTableSubstitution record.closure_features (this, lookup_indexes, feature_indexes); } + bool intersects_features (const hb_map_t *feature_index_map) const + { + for (const FeatureTableSubstitutionRecord& record : substitutions) + { + if (feature_index_map->has (record.featureIndex)) return true; + } + return false; + } + bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l) const { @@ -2769,7 +3107,8 @@ struct FeatureTableSubstitution + substitutions.iter () | hb_apply (subset_record_array (l, &(out->substitutions), this)) ; - return_trace (true); + + return_trace (bool (out->substitutions)); } bool sanitize (hb_sanitize_context_t *c) const @@ -2782,7 +3121,7 @@ struct FeatureTableSubstitution protected: FixedVersion<> version; /* Version--0x00010000u */ - ArrayOf<FeatureTableSubstitutionRecord> + Array16Of<FeatureTableSubstitutionRecord> substitutions; public: DEFINE_SIZE_ARRAY (6, substitutions); @@ -2806,6 +3145,11 @@ struct FeatureVariationRecord (base+substitutions).closure_features (lookup_indexes, feature_indexes); } + bool intersects_features (const void *base, const hb_map_t *feature_index_map) const + { + return (base+substitutions).intersects_features (feature_index_map); + } + bool subset (hb_subset_layout_context_t *c, const void *base) const { TRACE_SUBSET (this); @@ -2826,9 +3170,9 @@ struct FeatureVariationRecord } protected: - LOffsetTo<ConditionSet> + Offset32To<ConditionSet> conditions; - LOffsetTo<FeatureTableSubstitution> + Offset32To<FeatureTableSubstitution> substitutions; public: DEFINE_SIZE_STATIC (8); @@ -2892,9 +3236,18 @@ struct FeatureVariations out->version.major = version.major; out->version.minor = version.minor; - + varRecords.iter () - | hb_apply (subset_record_array (l, &(out->varRecords), this)) - ; + int keep_up_to = -1; + for (int i = varRecords.len - 1; i >= 0; i--) { + if (varRecords[i].intersects_features (this, l->feature_index_map)) { + keep_up_to = i; + break; + } + } + + unsigned count = (unsigned) (keep_up_to + 1); + for (unsigned i = 0; i < count; i++) { + subset_record_array (l, &(out->varRecords), this) (varRecords[i]); + } return_trace (bool (out->varRecords)); } @@ -2908,7 +3261,7 @@ struct FeatureVariations protected: FixedVersion<> version; /* Version--0x00010000u */ - LArrayOf<FeatureVariationRecord> + Array32Of<FeatureVariationRecord> varRecords; public: DEFINE_SIZE_ARRAY_SIZED (8, varRecords); @@ -3021,22 +3374,20 @@ struct VariationDevice if (unlikely (!out)) return_trace (nullptr); if (!layout_variation_idx_map || layout_variation_idx_map->is_empty ()) return_trace (out); - unsigned org_idx = (outerIndex << 16) + innerIndex; - if (!layout_variation_idx_map->has (org_idx)) + /* TODO Just get() and bail if NO_VARIATION. Needs to setup the map to return that. */ + if (!layout_variation_idx_map->has (varIdx)) { c->revert (snap); return_trace (nullptr); } - unsigned new_idx = layout_variation_idx_map->get (org_idx); - out->outerIndex = new_idx >> 16; - out->innerIndex = new_idx & 0xFFFF; + unsigned new_idx = layout_variation_idx_map->get (varIdx); + out->varIdx = new_idx; return_trace (out); } void record_variation_index (hb_set_t *layout_variation_indices) const { - unsigned var_idx = (outerIndex << 16) + innerIndex; - layout_variation_indices->add (var_idx); + layout_variation_indices->add (varIdx); } bool sanitize (hb_sanitize_context_t *c) const @@ -3049,12 +3400,11 @@ struct VariationDevice float get_delta (hb_font_t *font, const VariationStore &store) const { - return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords); + return store.get_delta (varIdx, font->coords, font->num_coords); } protected: - HBUINT16 outerIndex; - HBUINT16 innerIndex; + VarIdx varIdx; HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */ public: DEFINE_SIZE_STATIC (6); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh index 437e760f64..31a4a3e84c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh @@ -42,7 +42,7 @@ namespace OT { */ /* Array of contour point indices--in increasing numerical order */ -struct AttachPoint : ArrayOf<HBUINT16> +struct AttachPoint : Array16Of<HBUINT16> { bool subset (hb_subset_context_t *c) const { @@ -98,8 +98,7 @@ struct AttachList | hb_map (glyph_map) | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -110,10 +109,10 @@ struct AttachList } protected: - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table -- from * beginning of AttachList table */ - OffsetArrayOf<AttachPoint> + Array16OfOffset16To<AttachPoint> attachPoint; /* Array of AttachPoint tables * in Coverage Index order */ public: @@ -220,7 +219,7 @@ struct CaretValueFormat3 protected: HBUINT16 caretValueFormat; /* Format identifier--format = 3 */ FWORD coordinate; /* X or Y value, in design units */ - OffsetTo<Device> + Offset16To<Device> deviceTable; /* Offset to Device table for X or Y * value--from beginning of CaretValue * table */ @@ -329,7 +328,7 @@ struct LigGlyph void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { - for (const OffsetTo<CaretValue>& offset : carets.iter ()) + for (const Offset16To<CaretValue>& offset : carets.iter ()) (this+offset).collect_variation_indices (c->layout_variation_indices); } @@ -340,7 +339,7 @@ struct LigGlyph } protected: - OffsetArrayOf<CaretValue> + Array16OfOffset16To<CaretValue> carets; /* Offset array of CaretValue tables * --from beginning of LigGlyph table * --in increasing coordinate order */ @@ -386,8 +385,7 @@ struct LigCaretList | hb_map (glyph_map) | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -408,10 +406,10 @@ struct LigCaretList } protected: - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of LigCaretList table */ - OffsetArrayOf<LigGlyph> + Array16OfOffset16To<LigGlyph> ligGlyph; /* Array of LigGlyph tables * in Coverage Index order */ public: @@ -432,7 +430,7 @@ struct MarkGlyphSetsFormat1 out->format = format; bool ret = true; - for (const LOffsetTo<Coverage>& offset : coverage.iter ()) + for (const Offset32To<Coverage>& offset : coverage.iter ()) { auto *o = out->coverage.serialize_append (c->serializer); if (unlikely (!o)) @@ -460,7 +458,7 @@ struct MarkGlyphSetsFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - ArrayOf<LOffsetTo<Coverage>> + Array16Of<Offset32To<Coverage>> coverage; /* Array of long offsets to mark set * coverage tables */ public: @@ -643,10 +641,10 @@ struct GDEF auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this); + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); bool subset_markglyphsetsdef = true; if (version.to_int () >= 0x00010002u) @@ -687,28 +685,28 @@ struct GDEF protected: FixedVersion<>version; /* Version of the GDEF table--currently * 0x00010003u */ - OffsetTo<ClassDef> + Offset16To<ClassDef> glyphClassDef; /* Offset to class definition table * for glyph type--from beginning of * GDEF header (may be Null) */ - OffsetTo<AttachList> + Offset16To<AttachList> attachList; /* Offset to list of glyphs with * attachment points--from beginning * of GDEF header (may be Null) */ - OffsetTo<LigCaretList> + Offset16To<LigCaretList> ligCaretList; /* Offset to list of positioning points * for ligature carets--from beginning * of GDEF header (may be Null) */ - OffsetTo<ClassDef> + Offset16To<ClassDef> markAttachClassDef; /* Offset to class definition table for * mark attachment type--from beginning * of GDEF header (may be Null) */ - OffsetTo<MarkGlyphSets> + Offset16To<MarkGlyphSets> markGlyphSetsDef; /* Offset to the table of mark set * definitions--from beginning of GDEF * header (may be NULL). Introduced * in version 0x00010002. */ - LOffsetTo<VariationStore> + Offset32To<VariationStore> varStore; /* Offset to the table of Item Variation * Store--from beginning of GDEF * header (may be NULL). Introduced diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index 2217d298fb..1e305518f5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -89,20 +89,22 @@ struct ValueFormat : HBUINT16 HBINT16 yAdvance; /* Vertical adjustment for advance--in * design units (only used for vertical * writing) */ - OffsetTo<Device> xPlaDevice; /* Offset to Device table for + Offset16To<Device> xPlaDevice; /* Offset to Device table for * horizontal placement--measured from * beginning of PosTable (may be NULL) */ - OffsetTo<Device> yPlaDevice; /* Offset to Device table for vertical + Offset16To<Device> yPlaDevice; /* Offset to Device table for vertical * placement--measured from beginning * of PosTable (may be NULL) */ - OffsetTo<Device> xAdvDevice; /* Offset to Device table for + Offset16To<Device> xAdvDevice; /* Offset to Device table for * horizontal advance--measured from * beginning of PosTable (may be NULL) */ - OffsetTo<Device> yAdvDevice; /* Offset to Device table for vertical + Offset16To<Device> yAdvDevice; /* Offset to Device table for vertical * advance--measured from beginning of * PosTable (may be NULL) */ #endif + IntType& operator = (uint16_t i) { v = i; return *this; } + unsigned int get_len () const { return hb_popcount ((unsigned int) *this); } unsigned int get_size () const { return get_len () * Value::static_size; } @@ -160,16 +162,40 @@ struct ValueFormat : HBUINT16 return ret; } - void serialize_copy (hb_serialize_context_t *c, const void *base, - const Value *values, const hb_map_t *layout_variation_idx_map) const + unsigned int get_effective_format (const Value *values) const + { + unsigned int format = *this; + for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) { + if (format & flag) should_drop (*values++, (Flags) flag, &format); + } + + return format; + } + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + unsigned int get_effective_format (Iterator it) const { + unsigned int new_format = 0; + + for (const hb_array_t<const Value>& values : it) + new_format = new_format | get_effective_format (&values); + + return new_format; + } + + void copy_values (hb_serialize_context_t *c, + unsigned int new_format, + const void *base, + const Value *values, + const hb_map_t *layout_variation_idx_map) const { unsigned int format = *this; if (!format) return; - if (format & xPlacement) c->copy (*values++); - if (format & yPlacement) c->copy (*values++); - if (format & xAdvance) c->copy (*values++); - if (format & yAdvance) c->copy (*values++); + if (format & xPlacement) copy_value (c, new_format, xPlacement, *values++); + if (format & yPlacement) copy_value (c, new_format, yPlacement, *values++); + if (format & xAdvance) copy_value (c, new_format, xAdvance, *values++); + if (format & yAdvance) copy_value (c, new_format, yAdvance, *values++); if (format & xPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); if (format & yPlaDevice) copy_device (c, base, values++, layout_variation_idx_map); @@ -177,6 +203,16 @@ struct ValueFormat : HBUINT16 if (format & yAdvDevice) copy_device (c, base, values++, layout_variation_idx_map); } + void copy_value (hb_serialize_context_t *c, + unsigned int new_format, + Flags flag, + Value value) const + { + // Filter by new format. + if (!(new_format & flag)) return; + c->copy (value); + } + void collect_variation_indices (hb_collect_variation_indices_context_t *c, const void *base, const hb_array_t<const Value>& values) const @@ -232,14 +268,14 @@ struct ValueFormat : HBUINT16 return true; } - static inline OffsetTo<Device>& get_device (Value* value) + static inline Offset16To<Device>& get_device (Value* value) { - return *static_cast<OffsetTo<Device> *> (value); + return *static_cast<Offset16To<Device> *> (value); } - static inline const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr) + static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr) { if (worked) *worked |= bool (*value); - return *static_cast<const OffsetTo<Device> *> (value); + return *static_cast<const Offset16To<Device> *> (value); } bool copy_device (hb_serialize_context_t *c, const void *base, @@ -317,13 +353,21 @@ struct ValueFormat : HBUINT16 return_trace (true); } + + private: + + void should_drop (Value value, Flags flag, unsigned int* format) const + { + if (value) return; + *format = *format & ~flag; + } + }; -template<typename Iterator> +template<typename Iterator, typename SrcLookup> static void SinglePos_serialize (hb_serialize_context_t *c, - const void *src, + const SrcLookup *src, Iterator it, - ValueFormat valFormat, const hb_map_t *layout_variation_idx_map); @@ -346,7 +390,10 @@ struct AnchorFormat1 AnchorFormat1* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); - return_trace (c->embed<AnchorFormat1> (this)); + AnchorFormat1* out = c->embed<AnchorFormat1> (this); + if (!out) return_trace (out); + out->format = 1; + return_trace (out); } protected: @@ -447,11 +494,11 @@ struct AnchorFormat3 HBUINT16 format; /* Format identifier--format = 3 */ FWORD xCoordinate; /* Horizontal value--in design units */ FWORD yCoordinate; /* Vertical value--in design units */ - OffsetTo<Device> + Offset16To<Device> xDeviceTable; /* Offset to Device table for X * coordinate-- from beginning of * Anchor table (may be NULL) */ - OffsetTo<Device> + Offset16To<Device> yDeviceTable; /* Offset to Device table for Y * coordinate-- from beginning of * Anchor table (may be NULL) */ @@ -485,14 +532,22 @@ struct Anchor } } - Anchor* copy (hb_serialize_context_t *c, const hb_map_t *layout_variation_idx_map) const + bool subset (hb_subset_context_t *c) const { - TRACE_SERIALIZE (this); + TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (reinterpret_cast<Anchor *> (u.format1.copy (c))); - case 2: return_trace (reinterpret_cast<Anchor *> (u.format2.copy (c))); - case 3: return_trace (reinterpret_cast<Anchor *> (u.format3.copy (c, layout_variation_idx_map))); - default:return_trace (nullptr); + case 1: return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer)))); + case 2: + if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + // AnchorFormat 2 just containins extra hinting information, so + // if hints are being dropped convert to format 1. + return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer)))); + } + return_trace (bool (reinterpret_cast<Anchor *> (u.format2.copy (c->serializer)))); + case 3: return_trace (bool (reinterpret_cast<Anchor *> (u.format3.copy (c->serializer, + c->plan->layout_variation_idx_map)))); + default:return_trace (false); } } @@ -541,26 +596,24 @@ struct AnchorMatrix } template <typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - bool serialize (hb_serialize_context_t *c, - unsigned num_rows, - AnchorMatrix const *offset_matrix, - const hb_map_t *layout_variation_idx_map, - Iterator index_iter) + hb_requires (hb_is_iterator (Iterator))> + bool subset (hb_subset_context_t *c, + unsigned num_rows, + Iterator index_iter) const { - TRACE_SERIALIZE (this); + TRACE_SUBSET (this); + + auto *out = c->serializer->start_embed (this); + if (!index_iter) return_trace (false); - if (unlikely (!c->extend_min ((*this)))) return_trace (false); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - this->rows = num_rows; + out->rows = num_rows; for (const unsigned i : index_iter) { - auto *offset = c->embed (offset_matrix->matrixZ[i]); + auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - offset->serialize_copy (c, offset_matrix->matrixZ[i], - offset_matrix, c->to_bias (this), - hb_serialize_context_t::Head, - layout_variation_idx_map); + offset->serialize_subset (c, matrixZ[i], this); } return_trace (true); @@ -579,7 +632,7 @@ struct AnchorMatrix } HBUINT16 rows; /* Number of rows */ - UnsizedArrayOf<OffsetTo<Anchor>> + UnsizedArrayOf<Offset16To<Anchor>> matrixZ; /* Matrix of offsets to Anchor tables-- * from beginning of AnchorMatrix table */ public: @@ -598,18 +651,16 @@ struct MarkRecord return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } - MarkRecord *copy (hb_serialize_context_t *c, - const void *src_base, - unsigned dst_bias, - const hb_map_t *klass_mapping, - const hb_map_t *layout_variation_idx_map) const + MarkRecord *subset (hb_subset_context_t *c, + const void *src_base, + const hb_map_t *klass_mapping) const { - TRACE_SERIALIZE (this); - auto *out = c->embed (this); + TRACE_SUBSET (this); + auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (nullptr); out->klass = klass_mapping->get (klass); - out->markAnchor.serialize_copy (c, markAnchor, src_base, dst_bias, hb_serialize_context_t::Head, layout_variation_idx_map); + out->markAnchor.serialize_subset (c, markAnchor, src_base); return_trace (out); } @@ -621,14 +672,14 @@ struct MarkRecord protected: HBUINT16 klass; /* Class defined for this mark */ - OffsetTo<Anchor> + Offset16To<Anchor> markAnchor; /* Offset to Anchor table--from * beginning of MarkArray table */ public: DEFINE_SIZE_STATIC (4); }; -struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */ +struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage order */ { bool apply (hb_ot_apply_context_t *c, unsigned int mark_index, unsigned int glyph_index, @@ -637,7 +688,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; - const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index); + const MarkRecord &record = Array16Of<MarkRecord>::operator[](mark_index); unsigned int mark_class = record.klass; const Anchor& mark_anchor = this + record.markAnchor; @@ -664,25 +715,42 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde return_trace (true); } - template<typename Iterator, - hb_requires (hb_is_source_of (Iterator, MarkRecord))> - bool serialize (hb_serialize_context_t *c, - const hb_map_t *klass_mapping, - const hb_map_t *layout_variation_idx_map, - const void *base, - Iterator it) + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool subset (hb_subset_context_t *c, + Iterator coverage, + const hb_map_t *klass_mapping) const { - TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); - if (unlikely (!c->check_assign (len, it.len ()))) return_trace (false); - c->copy_all (it, base, c->to_bias (this), klass_mapping, layout_variation_idx_map); + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto* out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + auto mark_iter = + + hb_zip (coverage, this->iter ()) + | hb_filter (glyphset, hb_first) + | hb_map (hb_second) + ; + + unsigned new_length = 0; + for (const auto& mark_record : mark_iter) { + if (unlikely (!mark_record.subset (c, this, klass_mapping))) + return_trace (false); + new_length++; + } + + if (unlikely (!c->serializer->check_assign (out->len, new_length, + HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) + return_trace (false); + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (ArrayOf<MarkRecord>::sanitize (c, this)); + return_trace (Array16Of<MarkRecord>::sanitize (c, this)); } }; @@ -713,6 +781,8 @@ struct SinglePosFormat1 const Coverage &get_coverage () const { return this+coverage; } + ValueFormat get_value_format () const { return valueFormat; } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); @@ -727,35 +797,39 @@ struct SinglePosFormat1 } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + typename SrcLookup, + hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, - const void *src, + const SrcLookup *src, Iterator it, - ValueFormat valFormat, + ValueFormat newFormat, const hb_map_t *layout_variation_idx_map) { - auto out = c->extend_min (*this); - if (unlikely (!out)) return; - if (unlikely (!c->check_assign (valueFormat, valFormat))) return; + if (unlikely (!c->extend_min (this))) return; + if (unlikely (!c->check_assign (valueFormat, + newFormat, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) return; - + it - | hb_map (hb_second) - | hb_apply ([&] (hb_array_t<const Value> _) - { valFormat.serialize_copy (c, src, &_, layout_variation_idx_map); }) - ; + for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second)) + { + src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); + // Only serialize the first entry in the iterator, the rest are assumed to + // be the same. + break; + } auto glyphs = + it | hb_map_retains_sorting (hb_first) ; - coverage.serialize (c, this).serialize (c, glyphs); + coverage.serialize_serialize (c, glyphs); } 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 it = @@ -766,7 +840,7 @@ struct SinglePosFormat1 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, valueFormat, c->plan->layout_variation_idx_map); + SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map); return_trace (ret); } @@ -780,7 +854,7 @@ struct SinglePosFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat; /* Defines the types of data in the @@ -823,6 +897,8 @@ struct SinglePosFormat2 const Coverage &get_coverage () const { return this+coverage; } + ValueFormat get_value_format () const { return valueFormat; } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); @@ -841,22 +917,23 @@ struct SinglePosFormat2 } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + typename SrcLookup, + hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, - const void *src, + const SrcLookup *src, Iterator it, - ValueFormat valFormat, + ValueFormat newFormat, const hb_map_t *layout_variation_idx_map) { - auto out = c->extend_min (*this); + auto out = c->extend_min (this); if (unlikely (!out)) return; - if (unlikely (!c->check_assign (valueFormat, valFormat))) return; - if (unlikely (!c->check_assign (valueCount, it.len ()))) return; + if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return; + if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return; + it | hb_map (hb_second) | hb_apply ([&] (hb_array_t<const Value> _) - { valFormat.serialize_copy (c, src, &_, layout_variation_idx_map); }) + { src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_map); }) ; auto glyphs = @@ -864,13 +941,13 @@ struct SinglePosFormat2 | hb_map_retains_sorting (hb_first) ; - coverage.serialize (c, this).serialize (c, glyphs); + coverage.serialize_serialize (c, glyphs); } 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; unsigned sub_length = valueFormat.get_len (); @@ -888,7 +965,7 @@ struct SinglePosFormat2 ; bool ret = bool (it); - SinglePos_serialize (c->serializer, this, it, valueFormat, c->plan->layout_variation_idx_map); + SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_map); return_trace (ret); } @@ -902,7 +979,7 @@ struct SinglePosFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat; /* Defines the types of data in the @@ -932,24 +1009,37 @@ struct SinglePos template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + typename SrcLookup, + hb_requires (hb_is_iterator (Iterator))> void serialize (hb_serialize_context_t *c, - const void *src, + const SrcLookup* src, Iterator glyph_val_iter_pairs, - ValueFormat valFormat, const hb_map_t *layout_variation_idx_map) { if (unlikely (!c->extend_min (u.format))) return; unsigned format = 2; + ValueFormat new_format = src->get_value_format (); - if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs); + if (glyph_val_iter_pairs) + { + format = get_format (glyph_val_iter_pairs); + new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second)); + } u.format = format; switch (u.format) { - case 1: u.format1.serialize (c, src, glyph_val_iter_pairs, valFormat, layout_variation_idx_map); - return; - case 2: u.format2.serialize (c, src, glyph_val_iter_pairs, valFormat, layout_variation_idx_map); - return; + case 1: u.format1.serialize (c, + src, + glyph_val_iter_pairs, + new_format, + layout_variation_idx_map); + return; + case 2: u.format2.serialize (c, + src, + glyph_val_iter_pairs, + new_format, + layout_variation_idx_map); + return; default:return; } } @@ -974,14 +1064,13 @@ struct SinglePos } u; }; -template<typename Iterator> +template<typename Iterator, typename SrcLookup> static void SinglePos_serialize (hb_serialize_context_t *c, - const void *src, + const SrcLookup *src, Iterator it, - ValueFormat valFormat, const hb_map_t *layout_variation_idx_map) -{ c->start_embed<SinglePos> ()->serialize (c, src, it, valFormat, layout_variation_idx_map); } +{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_map); } struct PairValueRecord @@ -991,26 +1080,35 @@ struct PairValueRecord int cmp (hb_codepoint_t k) const { return secondGlyph.cmp (k); } - struct serialize_closure_t + struct context_t { const void *base; const ValueFormat *valueFormats; + const ValueFormat *newFormats; unsigned len1; /* valueFormats[0].get_len() */ const hb_map_t *glyph_map; const hb_map_t *layout_variation_idx_map; }; - bool serialize (hb_serialize_context_t *c, - serialize_closure_t *closure) const + bool subset (hb_subset_context_t *c, + context_t *closure) const { TRACE_SERIALIZE (this); - auto *out = c->start_embed (*this); - if (unlikely (!c->extend_min (out))) return_trace (false); + auto *s = c->serializer; + auto *out = s->start_embed (*this); + if (unlikely (!s->extend_min (out))) return_trace (false); out->secondGlyph = (*closure->glyph_map)[secondGlyph]; - closure->valueFormats[0].serialize_copy (c, closure->base, &values[0], closure->layout_variation_idx_map); - closure->valueFormats[1].serialize_copy (c, closure->base, &values[closure->len1], closure->layout_variation_idx_map); + closure->valueFormats[0].copy_values (s, + closure->newFormats[0], + closure->base, &values[0], + closure->layout_variation_idx_map); + closure->valueFormats[1].copy_values (s, + closure->newFormats[1], + closure->base, + &values[closure->len1], + closure->layout_variation_idx_map); return_trace (true); } @@ -1030,6 +1128,21 @@ struct PairValueRecord valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); } + bool intersects (const hb_set_t& glyphset) const + { + return glyphset.has(secondGlyph); + } + + const Value* get_values_1 () const + { + return &values[0]; + } + + const Value* get_values_2 (ValueFormat format1) const + { + return &values[format1.get_len ()]; + } + protected: HBGlyphID secondGlyph; /* GlyphID of second glyph in the * pair--first glyph is listed in the @@ -1120,7 +1233,8 @@ struct PairSet } bool subset (hb_subset_context_t *c, - const ValueFormat valueFormats[2]) const + const ValueFormat valueFormats[2], + const ValueFormat newFormats[2]) const { TRACE_SUBSET (this); auto snap = c->serializer->snapshot (); @@ -1129,17 +1243,18 @@ struct PairSet if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->len = 0; - 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; unsigned len1 = valueFormats[0].get_len (); unsigned len2 = valueFormats[1].get_len (); unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); - PairValueRecord::serialize_closure_t closure = + PairValueRecord::context_t context = { this, valueFormats, + newFormats, len1, &glyph_map, c->plan->layout_variation_idx_map @@ -1150,7 +1265,7 @@ struct PairSet for (unsigned i = 0; i < count; i++) { if (glyphset.has (record->secondGlyph) - && record->serialize (c->serializer, &closure)) num++; + && record->subset (c, &context)) num++; record = &StructAtOffset<const PairValueRecord> (record, record_size); } @@ -1198,7 +1313,7 @@ struct PairPosFormat1 + hb_zip (this+coverage, pairSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([glyphs, this] (const OffsetTo<PairSet> &_) + | hb_map ([glyphs, this] (const Offset16To<PairSet> &_) { return (this+_).intersects (glyphs, valueFormat); }) | hb_any ; @@ -1250,7 +1365,7 @@ struct PairPosFormat1 { 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); @@ -1258,17 +1373,23 @@ struct PairPosFormat1 out->format = format; out->valueFormat[0] = valueFormat[0]; out->valueFormat[1] = valueFormat[1]; + if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + { + hb_pair_t<unsigned, unsigned> newFormats = compute_effective_value_formats (glyphset); + out->valueFormat[0] = newFormats.first; + out->valueFormat[1] = newFormats.second; + } hb_sorted_vector_t<hb_codepoint_t> new_coverage; + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) - | hb_filter ([this, c, out] (const OffsetTo<PairSet>& _) + | hb_filter ([this, c, out] (const Offset16To<PairSet>& _) { 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); + bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat); if (!ret) { out->pairSet.pop (); @@ -1282,12 +1403,41 @@ struct PairPosFormat1 | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } + + hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const + { + unsigned len1 = valueFormat[0].get_len (); + unsigned len2 = valueFormat[1].get_len (); + unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); + + unsigned format1 = 0; + unsigned format2 = 0; + for (const Offset16To<PairSet>& _ : + + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second)) + { + const PairSet& set = (this + _); + const PairValueRecord *record = &set.firstPairValueRecord; + + for (unsigned i = 0; i < set.len; i++) + { + if (record->intersects (glyphset)) + { + format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ()); + format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0])); + } + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + } + + return hb_pair (format1, format2); + } + + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1308,7 +1458,7 @@ struct PairPosFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat[2]; /* [0] Defines the types of data in @@ -1317,7 +1467,7 @@ struct PairPosFormat1 /* [1] Defines the types of data in * ValueRecord2--for the second glyph * in the pair--may be zero (0) */ - OffsetArrayOf<PairSet> + Array16OfOffset16To<PairSet> pairSet; /* Array of PairSet tables * ordered by Coverage Index */ public: @@ -1335,18 +1485,35 @@ struct PairPosFormat2 void closure_lookups (hb_closure_lookups_context_t *c) const {} void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { + if (!intersects (c->glyph_set)) return; if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return; + hb_set_t klass1_glyphs, klass2_glyphs; + if (!(this+classDef1).collect_coverage (&klass1_glyphs)) return; + if (!(this+classDef2).collect_coverage (&klass2_glyphs)) return; + hb_set_t class1_set, class2_set; - for (const unsigned cp : c->glyph_set->iter ()) + for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage)) + { + if (!klass1_glyphs.has (cp)) class1_set.add (0); + else + { + unsigned klass1 = (this+classDef1).get (cp); + class1_set.add (klass1); + } + } + + class2_set.add (0); + for (const unsigned cp : + c->glyph_set->iter () | hb_filter (klass2_glyphs)) { - unsigned klass1 = (this+classDef1).get (cp); unsigned klass2 = (this+classDef2).get (cp); - class1_set.add (klass1); class2_set.add (klass2); } - if (class1_set.is_empty () || class2_set.is_empty ()) return; + if (class1_set.is_empty () + || class2_set.is_empty () + || (class2_set.get_population() == 1 && class2_set.has(0))) + return; unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); @@ -1411,37 +1578,36 @@ struct PairPosFormat2 auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->format = format; - out->valueFormat1 = valueFormat1; - out->valueFormat2 = valueFormat2; hb_map_t klass1_map; - out->classDef1.serialize_subset (c, classDef1, this, &klass1_map); + out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, true, &(this + coverage)); out->class1Count = klass1_map.get_population (); hb_map_t klass2_map; - out->classDef2.serialize_subset (c, classDef2, this, &klass2_map); + out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, true, false); out->class2Count = klass2_map.get_population (); unsigned len1 = valueFormat1.get_len (); unsigned len2 = valueFormat2.get_len (); - + hb_range ((unsigned) class1Count) - | hb_filter (klass1_map) - | hb_apply ([&] (const unsigned class1_idx) - { - + hb_range ((unsigned) class2Count) - | hb_filter (klass2_map) - | hb_apply ([&] (const unsigned class2_idx) - { - unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); - valueFormat1.serialize_copy (c->serializer, this, &values[idx], c->plan->layout_variation_idx_map); - valueFormat2.serialize_copy (c->serializer, this, &values[idx + len1], c->plan->layout_variation_idx_map); - }) - ; - }) - ; + hb_pair_t<unsigned, unsigned> newFormats = hb_pair (valueFormat1, valueFormat2); + if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + newFormats = compute_effective_value_formats (klass1_map, klass2_map); + + out->valueFormat1 = newFormats.first; + out->valueFormat2 = newFormats.second; - const hb_set_t &glyphset = *c->plan->_glyphset_gsub; + for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) + { + for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) + { + unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + valueFormat1.copy_values (c->serializer, newFormats.first, this, &values[idx], c->plan->layout_variation_idx_map); + valueFormat2.copy_values (c->serializer, newFormats.second, this, &values[idx + len1], c->plan->layout_variation_idx_map); + } + } + + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto it = @@ -1450,10 +1616,34 @@ struct PairPosFormat2 | hb_map_retains_sorting (glyph_map) ; - out->coverage.serialize (c->serializer, out).serialize (c->serializer, it); + out->coverage.serialize_serialize (c->serializer, it); return_trace (out->class1Count && out->class2Count && bool (it)); } + + hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_map_t& klass1_map, + const hb_map_t& klass2_map) const + { + unsigned len1 = valueFormat1.get_len (); + unsigned len2 = valueFormat2.get_len (); + + unsigned format1 = 0; + unsigned format2 = 0; + + for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map)) + { + for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map)) + { + unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2); + format1 = format1 | valueFormat1.get_effective_format (&values[idx]); + format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]); + } + } + + return hb_pair (format1, format2); + } + + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1476,7 +1666,7 @@ struct PairPosFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat1; /* ValueRecord definition--for the @@ -1485,11 +1675,11 @@ struct PairPosFormat2 ValueFormat valueFormat2; /* ValueRecord definition--for the * second glyph of the pair--may be * zero (0) */ - OffsetTo<ClassDef> + Offset16To<ClassDef> classDef1; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the first glyph of the pair */ - OffsetTo<ClassDef> + Offset16To<ClassDef> classDef2; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the second glyph of the pair */ @@ -1544,26 +1734,24 @@ struct EntryExitRecord (src_base+exitAnchor).collect_variation_indices (c); } - EntryExitRecord* copy (hb_serialize_context_t *c, - const void *src_base, - const void *dst_base, - const hb_map_t *layout_variation_idx_map) const + EntryExitRecord* subset (hb_subset_context_t *c, + const void *src_base) const { TRACE_SERIALIZE (this); - auto *out = c->embed (this); + auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (nullptr); - out->entryAnchor.serialize_copy (c, entryAnchor, src_base, c->to_bias (dst_base), hb_serialize_context_t::Head, layout_variation_idx_map); - out->exitAnchor.serialize_copy (c, exitAnchor, src_base, c->to_bias (dst_base), hb_serialize_context_t::Head, layout_variation_idx_map); + out->entryAnchor.serialize_subset (c, entryAnchor, src_base); + out->exitAnchor.serialize_subset (c, exitAnchor, src_base); return_trace (out); } protected: - OffsetTo<Anchor> + Offset16To<Anchor> entryAnchor; /* Offset to EntryAnchor table--from * beginning of CursivePos * subtable--may be NULL */ - OffsetTo<Anchor> + Offset16To<Anchor> exitAnchor; /* Offset to ExitAnchor table--from * beginning of CursivePos * subtable--may be NULL */ @@ -1692,7 +1880,7 @@ struct CursivePosFormat1 else pos[child].x_offset = x_offset; - /* If parent was attached to child, break them free. + /* If parent was attached to child, separate them. * https://github.com/harfbuzz/harfbuzz/issues/2469 */ if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain())) @@ -1704,31 +1892,30 @@ struct CursivePosFormat1 template <typename Iterator, hb_requires (hb_is_iterator (Iterator))> - void serialize (hb_serialize_context_t *c, + void serialize (hb_subset_context_t *c, Iterator it, - const void *src_base, - const hb_map_t *layout_variation_idx_map) + const void *src_base) { - if (unlikely (!c->extend_min ((*this)))) return; + if (unlikely (!c->serializer->extend_min ((*this)))) return; this->format = 1; this->entryExitRecord.len = it.len (); for (const EntryExitRecord& entry_record : + it | hb_map (hb_second)) - c->copy (entry_record, src_base, this, layout_variation_idx_map); + entry_record.subset (c, src_base); auto glyphs = + it | hb_map_retains_sorting (hb_first) ; - coverage.serialize (c, this).serialize (c, glyphs); + coverage.serialize_serialize (c->serializer, glyphs); } 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); @@ -1742,7 +1929,7 @@ struct CursivePosFormat1 ; bool ret = bool (it); - out->serialize (c->serializer, it, this, c->plan->layout_variation_idx_map); + out->serialize (c, it, this); return_trace (ret); } @@ -1754,10 +1941,10 @@ struct CursivePosFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ - ArrayOf<EntryExitRecord> + Array16Of<EntryExitRecord> entryExitRecord; /* Array of EntryExit records--in * Coverage Index order */ public: @@ -1904,7 +2091,7 @@ struct MarkBasePosFormat1 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); @@ -1929,13 +2116,12 @@ struct MarkBasePosFormat1 | hb_sink (new_coverage) ; - if (!out->markCoverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ())) + if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->markArray.serialize (c->serializer, out) - .serialize (c->serializer, &klass_mapping, c->plan->layout_variation_idx_map, &(this+markArray), + mark_iter - | hb_map (hb_second)); + out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping); unsigned basecount = (this+baseArray).rows; auto base_iter = @@ -1950,8 +2136,7 @@ struct MarkBasePosFormat1 | hb_sink (new_coverage) ; - if (!out->baseCoverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ())) + if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); hb_sorted_vector_t<unsigned> base_indexes; @@ -1964,8 +2149,10 @@ struct MarkBasePosFormat1 | hb_sink (base_indexes) ; } - out->baseArray.serialize (c->serializer, out) - .serialize (c->serializer, base_iter.len (), &(this+baseArray), c->plan->layout_variation_idx_map, base_indexes.iter ()); + + out->baseArray.serialize_subset (c, baseArray, this, + base_iter.len (), + base_indexes.iter ()); return_trace (true); } @@ -1982,17 +2169,17 @@ struct MarkBasePosFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> markCoverage; /* Offset to MarkCoverage table--from * beginning of MarkBasePos subtable */ - OffsetTo<Coverage> + Offset16To<Coverage> baseCoverage; /* Offset to BaseCoverage table--from * beginning of MarkBasePos subtable */ HBUINT16 classCount; /* Number of classes defined for marks */ - OffsetTo<MarkArray> + Offset16To<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkBasePos subtable */ - OffsetTo<BaseArray> + Offset16To<BaseArray> baseArray; /* Offset to BaseArray table--from * beginning of MarkBasePos subtable */ public: @@ -2025,10 +2212,42 @@ typedef AnchorMatrix LigatureAttach; /* component-major-- * mark-minor-- * ordered by class--zero-based. */ -typedef OffsetListOf<LigatureAttach> LigatureArray; - /* Array of LigatureAttach - * tables ordered by - * LigatureCoverage Index */ +/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ +struct LigatureArray : List16OfOffset16To<LigatureAttach> +{ + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + for (const auto _ : + hb_zip (coverage, *this) + | hb_filter (glyphset, hb_first)) + { + auto *matrix = out->serialize_append (c->serializer); + if (unlikely (!matrix)) return_trace (false); + + const LigatureAttach& src = (this + _.second); + auto indexes = + + hb_range (src.rows * class_count) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) + ; + matrix->serialize_subset (c, + _.second, + this, + src.rows, + indexes); + } + return_trace (this->len); + } +}; struct MarkLigPosFormat1 { @@ -2130,8 +2349,50 @@ struct MarkLigPosFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + 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); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->format = format; + + hb_map_t klass_mapping; + Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping); + + if (!klass_mapping.get_population ()) return_trace (false); + out->classCount = klass_mapping.get_population (); + + auto mark_iter = + + hb_zip (this+markCoverage, this+markArray) + | hb_filter (glyphset, hb_first) + ; + + auto new_mark_coverage = + + mark_iter + | hb_map_retains_sorting (hb_first) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage)) + return_trace (false); + + out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping); + + auto new_ligature_coverage = + + hb_iter (this + ligatureCoverage) + | hb_filter (glyphset) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) + return_trace (false); + + out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), classCount, &klass_mapping); + + return_trace (true); } bool sanitize (hb_sanitize_context_t *c) const @@ -2146,24 +2407,25 @@ struct MarkLigPosFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> markCoverage; /* Offset to Mark Coverage table--from * beginning of MarkLigPos subtable */ - OffsetTo<Coverage> + Offset16To<Coverage> ligatureCoverage; /* Offset to Ligature Coverage * table--from beginning of MarkLigPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - OffsetTo<MarkArray> + Offset16To<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkLigPos subtable */ - OffsetTo<LigatureArray> + Offset16To<LigatureArray> ligatureArray; /* Offset to LigatureArray table--from * beginning of MarkLigPos subtable */ public: DEFINE_SIZE_STATIC (12); }; + struct MarkLigPos { template <typename context_t, typename ...Ts> @@ -2288,7 +2550,7 @@ struct MarkMarkPosFormat1 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); @@ -2313,13 +2575,12 @@ struct MarkMarkPosFormat1 | hb_sink (new_coverage) ; - if (!out->mark1Coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ())) + if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->mark1Array.serialize (c->serializer, out) - .serialize (c->serializer, &klass_mapping, c->plan->layout_variation_idx_map, &(this+mark1Array), + mark1_iter - | hb_map (hb_second)); + out->mark1Array.serialize_subset (c, mark1Array, this, + (this+mark1Coverage).iter (), + &klass_mapping); unsigned mark2count = (this+mark2Array).rows; auto mark2_iter = @@ -2334,8 +2595,7 @@ struct MarkMarkPosFormat1 | hb_sink (new_coverage) ; - if (!out->mark2Coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ())) + if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); hb_sorted_vector_t<unsigned> mark2_indexes; @@ -2348,8 +2608,8 @@ struct MarkMarkPosFormat1 | hb_sink (mark2_indexes) ; } - out->mark2Array.serialize (c->serializer, out) - .serialize (c->serializer, mark2_iter.len (), &(this+mark2Array), c->plan->layout_variation_idx_map, mark2_indexes.iter ()); + + out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ()); return_trace (true); } @@ -2366,19 +2626,19 @@ struct MarkMarkPosFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> mark1Coverage; /* Offset to Combining Mark1 Coverage * table--from beginning of MarkMarkPos * subtable */ - OffsetTo<Coverage> + Offset16To<Coverage> mark2Coverage; /* Offset to Combining Mark2 Coverage * table--from beginning of MarkMarkPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - OffsetTo<MarkArray> + Offset16To<MarkArray> mark1Array; /* Offset to Mark1Array table--from * beginning of MarkMarkPos subtable */ - OffsetTo<Mark2Array> + Offset16To<Mark2Array> mark2Array; /* Offset to Mark2Array table--from * beginning of MarkMarkPos subtable */ public: @@ -2567,7 +2827,7 @@ struct GPOS : GSUBGPOS bool subset (hb_subset_context_t *c) const { - hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_features); + hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features); return GSUBGPOS::subset<PosLookup> (&l); } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index 2f41d67819..393ada1351 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -46,14 +46,19 @@ struct SingleSubstFormat1 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + bool may_have_non_1to1 () const + { return false; } + void closure (hb_closure_context_t *c) const { unsigned d = deltaGlyphID; + + hb_iter (this+coverage) - | hb_filter (*c->glyphs) + | hb_filter (c->parent_active_glyphs ()) | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) | hb_sink (c->output) ; + } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -95,9 +100,9 @@ struct SingleSubstFormat1 unsigned delta) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); - if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); - c->check_assign (deltaGlyphID, delta); + if (unlikely (!c->extend_min (this))) return_trace (false); + if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false); + c->check_assign (deltaGlyphID, delta, HB_SERIALIZE_ERROR_INT_OVERFLOW); return_trace (true); } @@ -133,7 +138,7 @@ struct SingleSubstFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ HBUINT16 deltaGlyphID; /* Add to original GlyphID to get @@ -147,13 +152,17 @@ struct SingleSubstFormat2 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + bool may_have_non_1to1 () const + { return false; } + void closure (hb_closure_context_t *c) const { + hb_zip (this+coverage, substitute) - | hb_filter (*c->glyphs, hb_first) + | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_sink (c->output) ; + } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -200,9 +209,9 @@ struct SingleSubstFormat2 + it | hb_map_retains_sorting (hb_first) ; - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false); - if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); + if (unlikely (!coverage.serialize_serialize (c, glyphs))) return_trace (false); return_trace (true); } @@ -233,10 +242,10 @@ struct SingleSubstFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - ArrayOf<HBGlyphID> + Array16Of<HBGlyphID> substitute; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: @@ -334,9 +343,14 @@ struct Sequence unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; + unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); - for (unsigned int i = 0; i < count; i++) { - _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); + for (unsigned int i = 0; i < count; i++) + { + /* If is attached to a ligature, don't disturb that. + * https://github.com/harfbuzz/harfbuzz/issues/3069 */ + if (!lig_id) + _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); c->output_glyph_for_component (substitute.arrayZ[i], klass); } c->buffer->skip_glyph (); @@ -356,7 +370,7 @@ struct Sequence 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; if (!intersects (&glyphset)) return_trace (false); @@ -377,7 +391,7 @@ struct Sequence } protected: - ArrayOf<HBGlyphID> + Array16Of<HBGlyphID> substitute; /* String of GlyphIDs to substitute */ public: DEFINE_SIZE_ARRAY (2, substitute); @@ -388,10 +402,13 @@ struct MultipleSubstFormat1 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { + hb_zip (this+coverage, sequence) - | hb_filter (*c->glyphs, hb_first) + | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) | hb_apply ([c] (const Sequence &_) { _.closure (c); }) @@ -431,23 +448,23 @@ struct MultipleSubstFormat1 hb_array_t<const HBGlyphID> substitute_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!sequence.serialize (c, glyphs.length))) return_trace (false); for (unsigned int i = 0; i < glyphs.length; i++) { unsigned int substitute_len = substitute_len_list[i]; - if (unlikely (!sequence[i].serialize (c, this) - .serialize (c, substitute_glyphs_list.sub_array (0, substitute_len)))) + if (unlikely (!sequence[i] + .serialize_serialize (c, substitute_glyphs_list.sub_array (0, substitute_len)))) return_trace (false); substitute_glyphs_list += substitute_len; } - return_trace (coverage.serialize (c, this).serialize (c, glyphs)); + return_trace (coverage.serialize_serialize (c, glyphs)); } 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); @@ -462,8 +479,7 @@ struct MultipleSubstFormat1 | hb_map (glyph_map) | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -475,10 +491,10 @@ struct MultipleSubstFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - OffsetArrayOf<Sequence> + Array16OfOffset16To<Sequence> sequence; /* Array of Sequence tables * ordered by Coverage Index */ public: @@ -547,7 +563,12 @@ struct AlternateSet /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */ if (alt_index == HB_OT_MAP_MAX_VALUE && c->random) + { + /* 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 (); alt_index = c->random_number () % count + 1; + } if (unlikely (alt_index > count || alt_index == 0)) return_trace (false); @@ -582,7 +603,7 @@ struct AlternateSet 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 it = @@ -603,7 +624,7 @@ struct AlternateSet } protected: - ArrayOf<HBGlyphID> + Array16Of<HBGlyphID> alternates; /* Array of alternate GlyphIDs--in * arbitrary order */ public: @@ -615,14 +636,18 @@ struct AlternateSubstFormat1 bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } + bool may_have_non_1to1 () const + { return false; } + void closure (hb_closure_context_t *c) const { + hb_zip (this+coverage, alternateSet) - | hb_filter (c->glyphs, hb_first) + | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) ; + } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -666,23 +691,23 @@ struct AlternateSubstFormat1 hb_array_t<const HBGlyphID> alternate_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!alternateSet.serialize (c, glyphs.length))) return_trace (false); for (unsigned int i = 0; i < glyphs.length; i++) { unsigned int alternate_len = alternate_len_list[i]; - if (unlikely (!alternateSet[i].serialize (c, this) - .serialize (c, alternate_glyphs_list.sub_array (0, alternate_len)))) + if (unlikely (!alternateSet[i] + .serialize_serialize (c, alternate_glyphs_list.sub_array (0, alternate_len)))) return_trace (false); alternate_glyphs_list += alternate_len; } - return_trace (coverage.serialize (c, this).serialize (c, glyphs)); + return_trace (coverage.serialize_serialize (c, glyphs)); } 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); @@ -697,8 +722,7 @@ struct AlternateSubstFormat1 | hb_map (glyph_map) | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -710,10 +734,10 @@ struct AlternateSubstFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - OffsetArrayOf<AlternateSet> + Array16OfOffset16To<AlternateSet> alternateSet; /* Array of AlternateSet tables * ordered by Coverage Index */ public: @@ -831,7 +855,7 @@ struct Ligature Iterator components /* Starting from second */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); ligGlyph = ligature; if (unlikely (!component.serialize (c, components))) return_trace (false); return_trace (true); @@ -840,7 +864,7 @@ struct Ligature 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; if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false); @@ -930,15 +954,14 @@ struct LigatureSet hb_array_t<const HBGlyphID> &component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false); for (unsigned int i = 0; i < ligatures.length; i++) { unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0); - if (unlikely (!ligature[i].serialize (c, this) - .serialize (c, - ligatures[i], - component_list.sub_array (0, component_count)))) + if (unlikely (!ligature[i].serialize_serialize (c, + ligatures[i], + component_list.sub_array (0, component_count)))) return_trace (false); component_list += component_count; } @@ -965,7 +988,7 @@ struct LigatureSet } protected: - OffsetArrayOf<Ligature> + Array16OfOffset16To<Ligature> ligature; /* Array LigatureSet tables * ordered by preference */ public: @@ -980,20 +1003,24 @@ struct LigatureSubstFormat1 + hb_zip (this+coverage, ligatureSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([this, glyphs] (const OffsetTo<LigatureSet> &_) + | hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_) { return (this+_).intersects (glyphs); }) | hb_any ; } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { + hb_zip (this+coverage, ligatureSet) - | hb_filter (*c->glyphs, hb_first) + | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) | hb_apply ([c] (const LigatureSet &_) { _.closure (c); }) ; + } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -1039,26 +1066,26 @@ struct LigatureSubstFormat1 hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!ligatureSet.serialize (c, first_glyphs.length))) return_trace (false); for (unsigned int i = 0; i < first_glyphs.length; i++) { unsigned int ligature_count = ligature_per_first_glyph_count_list[i]; - if (unlikely (!ligatureSet[i].serialize (c, this) - .serialize (c, - ligatures_list.sub_array (0, ligature_count), - component_count_list.sub_array (0, ligature_count), - component_list))) return_trace (false); + if (unlikely (!ligatureSet[i] + .serialize_serialize (c, + ligatures_list.sub_array (0, ligature_count), + component_count_list.sub_array (0, ligature_count), + component_list))) return_trace (false); ligatures_list += ligature_count; component_count_list += ligature_count; } - return_trace (coverage.serialize (c, this).serialize (c, first_glyphs)); + return_trace (coverage.serialize_serialize (c, first_glyphs)); } 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); @@ -1073,8 +1100,7 @@ struct LigatureSubstFormat1 | hb_map (glyph_map) | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -1086,10 +1112,10 @@ struct LigatureSubstFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - OffsetArrayOf<LigatureSet> + Array16OfOffset16To<LigatureSet> ligatureSet; /* Array LigatureSet tables * ordered by Coverage Index */ public: @@ -1157,7 +1183,7 @@ struct ReverseChainSingleSubstFormat1 if (!(this+coverage).intersects (glyphs)) return false; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); unsigned int count; @@ -1174,15 +1200,18 @@ struct ReverseChainSingleSubstFormat1 return true; } + bool may_have_non_1to1 () const + { return false; } + void closure (hb_closure_context_t *c) const { if (!intersects (c->glyphs)) return; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); - const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); + hb_zip (this+coverage, substitute) - | hb_filter (*c->glyphs, hb_first) + | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_sink (c->output) ; @@ -1200,12 +1229,12 @@ struct ReverseChainSingleSubstFormat1 for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; - const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -1224,8 +1253,8 @@ struct ReverseChainSingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); - const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); if (unlikely (index >= substitute.len)) return_trace (false); @@ -1250,11 +1279,80 @@ struct ReverseChainSingleSubstFormat1 return_trace (false); } + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize_coverage_offset_array (hb_subset_context_t *c, Iterator it) const + { + TRACE_SERIALIZE (this); + auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> (); + + if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) + return_trace (false); + + for (auto& offset : it) { + auto *o = out->serialize_append (c->serializer); + if (unlikely (!o) || !o->serialize_subset (c, offset, this)) + return_trace (false); + } + + return_trace (true); + } + + template<typename Iterator, typename BacktrackIterator, typename LookaheadIterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_pair_t)), + hb_requires (hb_is_iterator (BacktrackIterator)), + hb_requires (hb_is_iterator (LookaheadIterator))> + bool serialize (hb_subset_context_t *c, + Iterator coverage_subst_iter, + BacktrackIterator backtrack_iter, + LookaheadIterator lookahead_iter) const + { + TRACE_SERIALIZE (this); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->check_success (out))) return_trace (false); + if (unlikely (!c->serializer->embed (this->format))) return_trace (false); + if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false); + + 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 substitutes = + + coverage_subst_iter + | hb_map (hb_second) + ; + + auto glyphs = + + coverage_subst_iter + | hb_map_retains_sorting (hb_first) + ; + if (unlikely (! c->serializer->check_success (substitute_out->serialize (c->serializer, substitutes)))) + return_trace (false); + + if (unlikely (!out->coverage.serialize_serialize (c->serializer, glyphs))) + return_trace (false); + return_trace (true); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - // TODO(subset) - return_trace (false); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + 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); + + 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 + { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) + ; + + return_trace (bool (it) && serialize (c, it, backtrack.iter (), lookahead.iter ())); } bool sanitize (hb_sanitize_context_t *c) const @@ -1262,27 +1360,27 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead); + const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); return_trace (substitute.sanitize (c)); } protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - OffsetArrayOf<Coverage> + Array16OfOffset16To<Coverage> backtrack; /* Array of coverage tables * in backtracking sequence, in glyph * sequence order */ - OffsetArrayOf<Coverage> + Array16OfOffset16To<Coverage> lookaheadX; /* Array of coverage tables * in lookahead sequence, in glyph * sequence order */ - ArrayOf<HBGlyphID> + Array16Of<HBGlyphID> substituteX; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: @@ -1388,6 +1486,12 @@ struct SubstLookup : Lookup return lookup_type_is_reverse (type); } + bool may_have_non_1to1 () const + { + hb_have_non_1to1_context_t c; + return dispatch (&c); + } + bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); @@ -1455,10 +1559,6 @@ struct SubstLookup : Lookup static inline bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); - SubTable& serialize_subtable (hb_serialize_context_t *c, - unsigned int i) - { return get_subtables<SubTable> ()[i].serialize (c, this); } - bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, hb_sorted_array_t<const HBGlyphID> glyphs, @@ -1466,8 +1566,13 @@ struct SubstLookup : Lookup { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); - return_trace (serialize_subtable (c, 0).u.single. - serialize (c, hb_zip (glyphs, substitutes))); + if (c->push<SubTable> ()->u.single.serialize (c, hb_zip (glyphs, substitutes))) + { + c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ()); + return_trace (true); + } + c->pop_discard (); + return_trace (false); } bool serialize_multiple (hb_serialize_context_t *c, @@ -1478,11 +1583,17 @@ struct SubstLookup : Lookup { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false); - return_trace (serialize_subtable (c, 0).u.multiple. - serialize (c, - glyphs, - substitute_len_list, - substitute_glyphs_list)); + if (c->push<SubTable> ()->u.multiple. + serialize (c, + glyphs, + substitute_len_list, + substitute_glyphs_list)) + { + c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ()); + return_trace (true); + } + c->pop_discard (); + return_trace (false); } bool serialize_alternate (hb_serialize_context_t *c, @@ -1493,11 +1604,18 @@ struct SubstLookup : Lookup { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false); - return_trace (serialize_subtable (c, 0).u.alternate. - serialize (c, - glyphs, - alternate_len_list, - alternate_glyphs_list)); + + if (c->push<SubTable> ()->u.alternate. + serialize (c, + glyphs, + alternate_len_list, + alternate_glyphs_list)) + { + c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ()); + return_trace (true); + } + c->pop_discard (); + return_trace (false); } bool serialize_ligature (hb_serialize_context_t *c, @@ -1510,24 +1628,32 @@ struct SubstLookup : Lookup { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false); - return_trace (serialize_subtable (c, 0).u.ligature. - serialize (c, - first_glyphs, - ligature_per_first_glyph_count_list, - ligatures_list, - component_count_list, - component_list)); + if (c->push<SubTable> ()->u.ligature. + serialize (c, + first_glyphs, + ligature_per_first_glyph_count_list, + ligatures_list, + component_count_list, + component_list)) + { + c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ()); + return_trace (true); + } + c->pop_discard (); + return_trace (false); } template <typename context_t> static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); - static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index) + static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index); + + static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index) { if (!c->should_visit_lookup (lookup_index)) return hb_empty_t (); - hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index); + hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, covered_seq_indices, seq_index, end_index); /* While in theory we should flush here, it will cause timeouts because a recursive * lookup can keep growing the glyph set. Skip, and outer loop will retry up to @@ -1564,7 +1690,7 @@ struct GSUB : GSUBGPOS bool subset (hb_subset_context_t *c) const { - hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_features); + hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features); return GSUBGPOS::subset<SubstLookup> (&l); } @@ -1600,6 +1726,14 @@ template <typename context_t> return l.dispatch (c); } +/*static*/ typename hb_closure_context_t::return_t SubstLookup::closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index) +{ + const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index); + if (l.may_have_non_1to1 ()) + hb_set_add_range (covered_seq_indices, seq_index, end_index); + return l.dispatch (c); +} + /*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index) { const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index cb95e6dcd5..626abc5577 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -52,23 +52,32 @@ struct hb_intersects_context_t : const hb_set_t *glyphs; hb_intersects_context_t (const hb_set_t *glyphs_) : - glyphs (glyphs_) {} + glyphs (glyphs_) {} +}; + +struct hb_have_non_1to1_context_t : + hb_dispatch_context_t<hb_have_non_1to1_context_t, bool> +{ + template <typename T> + return_t dispatch (const T &obj) { return obj.may_have_non_1to1 (); } + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } }; struct hb_closure_context_t : hb_dispatch_context_t<hb_closure_context_t> { - typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); + typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indicies, unsigned seq_index, unsigned end_index); template <typename T> return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); } static return_t default_return_value () { return hb_empty_t (); } - void recurse (unsigned int lookup_index) + void recurse (unsigned lookup_index, hb_set_t *covered_seq_indicies, unsigned seq_index, unsigned end_index) { if (unlikely (nesting_level_left == 0 || !recurse_func)) return; nesting_level_left--; - recurse_func (this, lookup_index); + recurse_func (this, lookup_index, covered_seq_indicies, seq_index, end_index); nesting_level_left++; } @@ -83,36 +92,90 @@ struct hb_closure_context_t : if (is_lookup_done (lookup_index)) return false; - done_lookups->set (lookup_index, glyphs->get_population ()); return true; } bool is_lookup_done (unsigned int lookup_index) { - if (done_lookups->in_error ()) + if (done_lookups_glyph_count->in_error () || + done_lookups_glyph_set->in_error ()) return true; /* Have we visited this lookup with the current set of glyphs? */ - return done_lookups->get (lookup_index) == glyphs->get_population (); + if (done_lookups_glyph_count->get (lookup_index) != glyphs->get_population ()) + { + done_lookups_glyph_count->set (lookup_index, glyphs->get_population ()); + + if (!done_lookups_glyph_set->get (lookup_index)) + { + hb_set_t* empty_set = hb_set_create (); + if (unlikely (!done_lookups_glyph_set->set (lookup_index, empty_set))) + { + hb_set_destroy (empty_set); + return true; + } + } + + hb_set_clear (done_lookups_glyph_set->get (lookup_index)); + } + + hb_set_t *covered_glyph_set = done_lookups_glyph_set->get (lookup_index); + if (unlikely (covered_glyph_set->in_error ())) + return true; + if (parent_active_glyphs ()->is_subset (*covered_glyph_set)) + return true; + + hb_set_union (covered_glyph_set, parent_active_glyphs ()); + return false; + } + + hb_set_t* parent_active_glyphs () + { + if (active_glyphs_stack.length < 1) + return glyphs; + + return active_glyphs_stack.tail (); + } + + void push_cur_active_glyphs (hb_set_t* cur_active_glyph_set) + { + active_glyphs_stack.push (cur_active_glyph_set); + } + + bool pop_cur_done_glyphs () + { + if (active_glyphs_stack.length < 1) + return false; + + active_glyphs_stack.pop (); + return true; } hb_face_t *face; hb_set_t *glyphs; + hb_set_t *cur_intersected_glyphs; hb_set_t output[1]; + hb_vector_t<hb_set_t *> active_glyphs_stack; recurse_func_t recurse_func; unsigned int nesting_level_left; hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, - hb_map_t *done_lookups_, + 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_, unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), + cur_intersected_glyphs (cur_intersected_glyphs_), recurse_func (nullptr), nesting_level_left (nesting_level_left_), - done_lookups (done_lookups_), + done_lookups_glyph_count (done_lookups_glyph_count_), + done_lookups_glyph_set (done_lookups_glyph_set_), lookup_count (0) - {} + { + push_cur_active_glyphs (glyphs_); + } ~hb_closure_context_t () { flush (); } @@ -120,16 +183,21 @@ struct hb_closure_context_t : void flush () { - hb_set_del_range (output, face->get_num_glyphs (), hb_set_get_max (output)); /* Remove invalid glyphs. */ + hb_set_del_range (output, face->get_num_glyphs (), HB_SET_VALUE_INVALID); /* Remove invalid glyphs. */ hb_set_union (glyphs, output); hb_set_clear (output); + active_glyphs_stack.pop (); + active_glyphs_stack.fini (); } private: - hb_map_t *done_lookups; + hb_map_t *done_lookups_glyph_count; + hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set; unsigned int lookup_count; }; + + struct hb_closure_lookups_context_t : hb_dispatch_context_t<hb_closure_lookups_context_t> { @@ -146,7 +214,6 @@ struct hb_closure_lookups_context_t : if (is_lookup_visited (lookup_index)) return; - set_lookup_visited (lookup_index); nesting_level_left--; recurse_func (this, lookup_index); nesting_level_left++; @@ -163,10 +230,10 @@ struct hb_closure_lookups_context_t : bool is_lookup_visited (unsigned lookup_index) { - if (lookup_count++ > HB_MAX_LOOKUP_INDICES) + if (unlikely (lookup_count++ > HB_MAX_LOOKUP_INDICES)) return true; - if (visited_lookups->in_error ()) + if (unlikely (visited_lookups->in_error ())) return true; return visited_lookups->has (lookup_index); @@ -660,7 +727,7 @@ struct hb_ot_apply_context_t : void replace_glyph (hb_codepoint_t glyph_index) const { _set_glyph_props (glyph_index); - buffer->replace_glyph (glyph_index); + (void) buffer->replace_glyph (glyph_index); } void replace_glyph_inplace (hb_codepoint_t glyph_index) const { @@ -671,13 +738,13 @@ struct hb_ot_apply_context_t : unsigned int class_guess) const { _set_glyph_props (glyph_index, class_guess, true); - buffer->replace_glyph (glyph_index); + (void) buffer->replace_glyph (glyph_index); } void output_glyph_for_component (hb_codepoint_t glyph_index, unsigned int class_guess) const { _set_glyph_props (glyph_index, class_guess, false, true); - buffer->output_glyph (glyph_index); + (void) buffer->output_glyph (glyph_index); } }; @@ -738,12 +805,14 @@ struct hb_get_subtables_context_t : typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data); +typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs); typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data); struct ContextClosureFuncs { intersects_func_t intersects; + intersected_glyphs_func_t intersected_glyphs; }; struct ContextCollectGlyphsFuncs { @@ -766,10 +835,29 @@ static inline bool intersects_class (const hb_set_t *glyphs, const HBUINT16 &val } static inline bool intersects_coverage (const hb_set_t *glyphs, const HBUINT16 &value, const void *data) { - const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; + const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; return (data+coverage).intersects (glyphs); } + +static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs) +{ + unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value]; + intersected_glyphs->add (g); +} +static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs) +{ + const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); + class_def.intersected_class_glyphs (glyphs, value, intersected_glyphs); +} +static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs) +{ + Offset16To<Coverage> coverage; + coverage = value; + (data+coverage).intersected_coverage_glyphs (glyphs, intersected_glyphs); +} + + static inline bool array_is_subset_of (const hb_set_t *glyphs, unsigned int count, const HBUINT16 values[], @@ -793,7 +881,7 @@ static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const } static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { - const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; + const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; (data+coverage).collect_coverage (glyphs); } static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, @@ -821,7 +909,7 @@ static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, } static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) { - const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; + const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; } @@ -1044,7 +1132,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, hb_min (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); } - buffer->next_glyph (); + (void) buffer->next_glyph (); } last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); @@ -1147,10 +1235,79 @@ struct LookupRecord DEFINE_SIZE_STATIC (4); }; +enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 }; + +static void context_closure_recurse_lookups (hb_closure_context_t *c, + unsigned inputCount, const HBUINT16 input[], + unsigned lookupCount, + const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */, + unsigned value, + ContextFormat context_format, + const void *data, + intersected_glyphs_func_t intersected_glyphs_func) +{ + hb_set_t *covered_seq_indicies = hb_set_create (); + for (unsigned int i = 0; i < lookupCount; i++) + { + unsigned seqIndex = lookupRecord[i].sequenceIndex; + if (seqIndex >= inputCount) continue; + + hb_set_t *pos_glyphs = nullptr; + + if (hb_set_is_empty (covered_seq_indicies) || !hb_set_has (covered_seq_indicies, seqIndex)) + { + pos_glyphs = hb_set_create (); + if (seqIndex == 0) + { + switch (context_format) { + case ContextFormat::SimpleContext: + pos_glyphs->add (value); + break; + case ContextFormat::ClassBasedContext: + intersected_glyphs_func (c->cur_intersected_glyphs, data, value, pos_glyphs); + break; + case ContextFormat::CoverageBasedContext: + hb_set_set (pos_glyphs, c->cur_intersected_glyphs); + break; + } + } + else + { + const void *input_data = input; + unsigned input_value = seqIndex - 1; + if (context_format != ContextFormat::SimpleContext) + { + input_data = data; + input_value = input[seqIndex - 1]; + } + + intersected_glyphs_func (c->glyphs, input_data, input_value, pos_glyphs); + } + } + + hb_set_add (covered_seq_indicies, seqIndex); + if (pos_glyphs) + c->push_cur_active_glyphs (pos_glyphs); + + unsigned endIndex = inputCount; + if (context_format == ContextFormat::CoverageBasedContext) + endIndex += 1; + + c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex); + + if (pos_glyphs) { + c->pop_cur_done_glyphs (); + hb_set_destroy (pos_glyphs); + } + } + + hb_set_destroy (covered_seq_indicies); +} + template <typename context_t> static inline void recurse_lookups (context_t *c, - unsigned int lookupCount, - const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) + unsigned int lookupCount, + const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */) { for (unsigned int i = 0; i < lookupCount; i++) c->recurse (lookupRecord[i].lookupListIndex); @@ -1188,7 +1345,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, /* Don't recurse to ourself at same position. * Note that this test is too naive, it doesn't catch longer loops. */ - if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) + if (unlikely (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)) continue; if (unlikely (!buffer->move_to (match_positions[idx]))) @@ -1226,7 +1383,8 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, * mean that n match positions where removed, as there might * have been marks and default-ignorables in the sequence. We * should instead drop match positions between current-position - * and current-position + n instead. + * and current-position + n instead. Though, am not sure which + * one is better. Both cases have valid uses. Sigh. * * It should be possible to construct tests for both of these cases. */ @@ -1272,7 +1430,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, match_positions[next] += delta; } - buffer->move_to (end); + (void) buffer->move_to (end); return_trace (true); } @@ -1284,6 +1442,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, struct ContextClosureLookupContext { ContextClosureFuncs funcs; + ContextFormat context_format; const void *intersects_data; }; @@ -1314,13 +1473,19 @@ static inline void context_closure_lookup (hb_closure_context_t *c, const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], + unsigned value, /* Index of first glyph in Coverage or Class value in ClassDef table */ ContextClosureLookupContext &lookup_context) { if (context_intersects (c->glyphs, inputCount, input, lookup_context)) - recurse_lookups (c, - lookupCount, lookupRecord); + context_closure_recurse_lookups (c, + inputCount, input, + lookupCount, lookupRecord, + value, + lookup_context.context_format, + lookup_context.intersects_data, + lookup_context.funcs.intersected_glyphs); } static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, @@ -1377,7 +1542,7 @@ struct Rule lookup_context); } - void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const + void closure (hb_closure_context_t *c, unsigned value, ContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; @@ -1386,12 +1551,14 @@ struct Rule context_closure_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, - lookup_context); + value, lookup_context); } - void closure_lookups (hb_closure_lookups_context_t *c) const + void closure_lookups (hb_closure_lookups_context_t *c, + ContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; + if (!intersects (c->glyphs, lookup_context)) return; const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (inputZ.as_array (inputCount ? inputCount - 1 : 0)); @@ -1451,7 +1618,14 @@ 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); } @@ -1509,7 +1683,7 @@ struct RuleSet ; } - void closure (hb_closure_context_t *c, + void closure (hb_closure_context_t *c, unsigned value, ContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; @@ -1517,18 +1691,17 @@ struct RuleSet return + hb_iter (rule) | hb_map (hb_add (this)) - | hb_apply ([&] (const Rule &_) { _.closure (c, lookup_context); }) + | hb_apply ([&] (const Rule &_) { _.closure (c, value, lookup_context); }) ; } - void closure_lookups (hb_closure_lookups_context_t *c) const + void closure_lookups (hb_closure_lookups_context_t *c, + ContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; - - return + hb_iter (rule) | hb_map (hb_add (this)) - | hb_apply ([&] (const Rule &_) { _.closure_lookups (c); }) + | hb_apply ([&] (const Rule &_) { _.closure_lookups (c, lookup_context); }) ; } @@ -1576,7 +1749,7 @@ struct RuleSet auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - for (const OffsetTo<Rule>& _ : rule) + for (const Offset16To<Rule>& _ : rule) { if (!_) continue; auto *o = out->rule.serialize_append (c->serializer); @@ -1603,7 +1776,7 @@ struct RuleSet } protected: - OffsetArrayOf<Rule> + Array16OfOffset16To<Rule> rule; /* Array of Rule tables * ordered by preference */ public: @@ -1616,7 +1789,8 @@ struct ContextFormat1 bool intersects (const hb_set_t *glyphs) const { struct ContextClosureLookupContext lookup_context = { - {intersects_glyph}, + {intersects_glyph, intersected_glyph}, + ContextFormat::SimpleContext, nullptr }; @@ -1630,26 +1804,40 @@ struct ContextFormat1 ; } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { + c->cur_intersected_glyphs->clear (); + get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs); + struct ContextClosureLookupContext lookup_context = { - {intersects_glyph}, + {intersects_glyph, intersected_glyph}, + ContextFormat::SimpleContext, nullptr }; - + hb_zip (this+coverage, ruleSet) - | hb_filter (*c->glyphs, hb_first) - | hb_map (hb_second) - | hb_map (hb_add (this)) - | hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); }) + + hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len)) + | hb_filter (c->parent_active_glyphs (), hb_first) + | hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const RuleSet&> (_.first, this+ruleSet[_.second]); }) + | hb_apply ([&] (const hb_pair_t<unsigned, const RuleSet&>& _) { _.second.closure (c, _.first, lookup_context); }) ; } void closure_lookups (hb_closure_lookups_context_t *c) const { - + hb_iter (ruleSet) + struct ContextClosureLookupContext lookup_context = { + {intersects_glyph, intersected_glyph}, + ContextFormat::SimpleContext, + nullptr + }; + + + hb_zip (this+coverage, ruleSet) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); }) + | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c, lookup_context); }) ; } @@ -1700,7 +1888,7 @@ struct ContextFormat1 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); @@ -1717,8 +1905,7 @@ struct ContextFormat1 | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -1730,10 +1917,10 @@ struct ContextFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - OffsetArrayOf<RuleSet> + Array16OfOffset16To<RuleSet> ruleSet; /* Array of RuleSet tables * ordered by Coverage Index */ public: @@ -1751,7 +1938,8 @@ struct ContextFormat2 const ClassDef &class_def = this+classDef; struct ContextClosureLookupContext lookup_context = { - {intersects_class}, + {intersects_class, intersected_class_glyphs}, + ContextFormat::ClassBasedContext, &class_def }; @@ -1766,35 +1954,59 @@ struct ContextFormat2 ; } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { if (!(this+coverage).intersects (c->glyphs)) return; + c->cur_intersected_glyphs->clear (); + get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs); + const ClassDef &class_def = this+classDef; struct ContextClosureLookupContext lookup_context = { - {intersects_class}, + {intersects_class, intersected_class_glyphs}, + ContextFormat::ClassBasedContext, &class_def }; return + hb_enumerate (ruleSet) | hb_filter ([&] (unsigned _) - { return class_def.intersects_class (c->glyphs, _); }, + { return class_def.intersects_class (c->cur_intersected_glyphs, _); }, hb_first) - | hb_map (hb_second) - | hb_map (hb_add (this)) - | hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); }) + | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<RuleSet>&> _) + { + const RuleSet& rule_set = this+_.second; + rule_set.closure (c, _.first, lookup_context); + }) ; } void closure_lookups (hb_closure_lookups_context_t *c) const { + if (!(this+coverage).intersects (c->glyphs)) + return; + + const ClassDef &class_def = this+classDef; + + struct ContextClosureLookupContext lookup_context = { + {intersects_class, intersected_class_glyphs}, + ContextFormat::ClassBasedContext, + &class_def + }; + + hb_iter (ruleSet) | hb_map (hb_add (this)) - | hb_apply ([&] (const RuleSet &_) { _.closure_lookups (c); }) - ; + | hb_enumerate + | hb_filter ([&] (const hb_pair_t<unsigned, const RuleSet &> p) + { return class_def.intersects_class (c->glyphs, p.first); }) + | hb_map (hb_second) + | hb_apply ([&] (const RuleSet & _) + { _.closure_lookups (c, lookup_context); }); } void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {} @@ -1860,8 +2072,8 @@ struct ContextFormat2 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; - for (const hb_pair_t<unsigned, const OffsetTo<RuleSet>&> _ : + hb_enumerate (ruleSet) - | hb_filter (klass_map, hb_first)) + for (const auto& _ : + hb_enumerate (ruleSet) + | hb_filter (klass_map, hb_first)) { auto *o = out->ruleSet.serialize_append (c->serializer); if (unlikely (!o)) @@ -1897,13 +2109,13 @@ struct ContextFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - OffsetTo<ClassDef> + Offset16To<ClassDef> classDef; /* Offset to glyph ClassDef table--from * beginning of table */ - OffsetArrayOf<RuleSet> + Array16OfOffset16To<RuleSet> ruleSet; /* Array of RuleSet tables * ordered by class */ public: @@ -1919,7 +2131,8 @@ struct ContextFormat3 return false; struct ContextClosureLookupContext lookup_context = { - {intersects_coverage}, + {intersects_coverage, intersected_coverage_glyphs}, + ContextFormat::CoverageBasedContext, this }; return context_intersects (glyphs, @@ -1927,24 +2140,33 @@ struct ContextFormat3 lookup_context); } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { if (!(this+coverageZ[0]).intersects (c->glyphs)) return; + c->cur_intersected_glyphs->clear (); + get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs); + const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); struct ContextClosureLookupContext lookup_context = { - {intersects_coverage}, + {intersects_coverage, intersected_coverage_glyphs}, + ContextFormat::CoverageBasedContext, this }; context_closure_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, - lookup_context); + 0, lookup_context); } void closure_lookups (hb_closure_lookups_context_t *c) const { + if (!intersects (c->glyphs)) + return; const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); recurse_lookups (c, lookupCount, lookupRecord); } @@ -2008,9 +2230,10 @@ struct ContextFormat3 auto coverages = coverageZ.as_array (glyphCount); - for (const OffsetTo<Coverage>& offset : coverages) + for (const Offset16To<Coverage>& offset : coverages) { - auto *o = c->serializer->allocate_size<OffsetTo<Coverage>> (OffsetTo<Coverage>::static_size); + /* TODO(subset) This looks like should not be necessary to write this way. */ + auto *o = c->serializer->allocate_size<Offset16To<Coverage>> (Offset16To<Coverage>::static_size); if (unlikely (!o)) return_trace (false); if (!o->serialize_subset (c, offset, this)) return_trace (false); } @@ -2018,7 +2241,14 @@ struct ContextFormat3 const LookupRecord *lookupRecord = &StructAfter<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); } @@ -2041,7 +2271,7 @@ struct ContextFormat3 HBUINT16 glyphCount; /* Number of glyphs in the input glyph * sequence */ HBUINT16 lookupCount; /* Number of LookupRecords */ - UnsizedArrayOf<OffsetTo<Coverage>> + UnsizedArrayOf<Offset16To<Coverage>> coverageZ; /* Array of offsets to Coverage * table in glyph sequence order */ /*UnsizedArrayOf<LookupRecord> @@ -2081,6 +2311,7 @@ struct Context struct ChainContextClosureLookupContext { ContextClosureFuncs funcs; + ContextFormat context_format; const void *intersects_data[3]; }; @@ -2125,6 +2356,7 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, const HBUINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], + unsigned value, ChainContextClosureLookupContext &lookup_context) { if (chain_context_intersects (c->glyphs, @@ -2132,8 +2364,13 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, inputCount, input, lookaheadCount, lookahead, lookup_context)) - recurse_lookups (c, - lookupCount, lookupRecord); + context_closure_recurse_lookups (c, + inputCount, input, + lookupCount, lookupRecord, + value, + lookup_context.context_format, + lookup_context.intersects_data[1], + lookup_context.funcs.intersected_glyphs); } static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, @@ -2214,7 +2451,7 @@ struct ChainRule bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const { const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2222,29 +2459,32 @@ struct ChainRule lookup_context); } - void closure (hb_closure_context_t *c, + void closure (hb_closure_context_t *c, unsigned value, ChainContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, lookahead.len, lookahead.arrayZ, lookup.len, lookup.arrayZ, + value, lookup_context); } - void closure_lookups (hb_closure_lookups_context_t *c) const + void closure_lookups (hb_closure_lookups_context_t *c, + ChainContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; + if (!intersects (c->glyphs, lookup_context)) return; const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); recurse_lookups (c, lookup.len, lookup.arrayZ); } @@ -2252,8 +2492,8 @@ struct ChainRule ChainContextCollectGlyphsLookupContext &lookup_context) const { const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2266,8 +2506,8 @@ struct ChainRule ChainContextApplyLookupContext &lookup_context) const { const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); return chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2279,8 +2519,8 @@ struct ChainRule { TRACE_APPLY (this); const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2296,11 +2536,7 @@ struct ChainRule { c->copy (len); for (const auto g : it) - { - HBUINT16 gid; - gid = g; - c->copy (gid); - } + c->copy ((HBUINT16) g); } ChainRule* copy (hb_serialize_context_t *c, @@ -2322,18 +2558,25 @@ struct ChainRule serialize_array (c, input.lenP1, + input.iter () | hb_map (mapping)); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); if (lookahead_map) mapping = lookahead_map; serialize_array (c, lookahead.len, + lookahead.iter () | hb_map (mapping)); - const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead); - HBUINT16 lookupCount; - lookupCount = lookupRecord.len; - if (!c->copy (lookupCount)) return_trace (nullptr); + const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); - for (unsigned i = 0; i < (unsigned) lookupCount; i++) + HBUINT16* lookupCount = c->embed (&(lookupRecord.len)); + if (!lookupCount) return_trace (nullptr); + + 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); } @@ -2347,11 +2590,11 @@ struct ChainRule TRACE_SUBSET (this); const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); if (!backtrack_map) { - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); if (!hb_all (backtrack, glyphset) || !hb_all (input, glyphset) || !hb_all (lookahead, glyphset)) @@ -2378,24 +2621,24 @@ struct ChainRule if (!backtrack.sanitize (c)) return_trace (false); const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); if (!input.sanitize (c)) return_trace (false); - const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input); + const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); if (!lookahead.sanitize (c)) return_trace (false); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); return_trace (lookup.sanitize (c)); } protected: - ArrayOf<HBUINT16> + Array16Of<HBUINT16> backtrack; /* Array of backtracking values * (to be matched before the input * sequence) */ HeadlessArrayOf<HBUINT16> inputX; /* Array of input values (start with * second glyph) */ - ArrayOf<HBUINT16> + Array16Of<HBUINT16> lookaheadX; /* Array of lookahead values's (to be * matched after the input sequence) */ - ArrayOf<LookupRecord> + Array16Of<LookupRecord> lookupX; /* Array of LookupRecords--in * design order) */ public: @@ -2413,25 +2656,25 @@ struct ChainRuleSet | hb_any ; } - void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const + void closure (hb_closure_context_t *c, unsigned value, ChainContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; return + hb_iter (rule) | hb_map (hb_add (this)) - | hb_apply ([&] (const ChainRule &_) { _.closure (c, lookup_context); }) + | hb_apply ([&] (const ChainRule &_) { _.closure (c, value, lookup_context); }) ; } - void closure_lookups (hb_closure_lookups_context_t *c) const + void closure_lookups (hb_closure_lookups_context_t *c, + ChainContextClosureLookupContext &lookup_context) const { if (unlikely (c->lookup_limit_exceeded ())) return; - return + hb_iter (rule) | hb_map (hb_add (this)) - | hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c); }) + | hb_apply ([&] (const ChainRule &_) { _.closure_lookups (c, lookup_context); }) ; } @@ -2478,7 +2721,7 @@ struct ChainRuleSet auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - for (const OffsetTo<ChainRule>& _ : rule) + for (const Offset16To<ChainRule>& _ : rule) { if (!_) continue; auto *o = out->rule.serialize_append (c->serializer); @@ -2509,7 +2752,7 @@ struct ChainRuleSet } protected: - OffsetArrayOf<ChainRule> + Array16OfOffset16To<ChainRule> rule; /* Array of ChainRule tables * ordered by preference */ public: @@ -2521,7 +2764,8 @@ struct ChainContextFormat1 bool intersects (const hb_set_t *glyphs) const { struct ChainContextClosureLookupContext lookup_context = { - {intersects_glyph}, + {intersects_glyph, intersected_glyph}, + ContextFormat::SimpleContext, {nullptr, nullptr, nullptr} }; @@ -2535,26 +2779,40 @@ struct ChainContextFormat1 ; } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { + c->cur_intersected_glyphs->clear (); + get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs); + struct ChainContextClosureLookupContext lookup_context = { - {intersects_glyph}, + {intersects_glyph, intersected_glyph}, + ContextFormat::SimpleContext, {nullptr, nullptr, nullptr} }; - + hb_zip (this+coverage, ruleSet) - | hb_filter (*c->glyphs, hb_first) - | hb_map (hb_second) - | hb_map (hb_add (this)) - | hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); }) + + hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len)) + | hb_filter (c->parent_active_glyphs (), hb_first) + | hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const ChainRuleSet&> (_.first, this+ruleSet[_.second]); }) + | hb_apply ([&] (const hb_pair_t<unsigned, const ChainRuleSet&>& _) { _.second.closure (c, _.first, lookup_context); }) ; } void closure_lookups (hb_closure_lookups_context_t *c) const { - + hb_iter (ruleSet) + struct ChainContextClosureLookupContext lookup_context = { + {intersects_glyph, intersected_glyph}, + ContextFormat::SimpleContext, + {nullptr, nullptr, nullptr} + }; + + + hb_zip (this+coverage, ruleSet) + | hb_filter (*c->glyphs, hb_first) + | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c); }) + | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c, lookup_context); }) ; } @@ -2604,7 +2862,7 @@ struct ChainContextFormat1 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); @@ -2621,8 +2879,7 @@ struct ChainContextFormat1 | hb_sink (new_coverage) ; - out->coverage.serialize (c->serializer, out) - .serialize (c->serializer, new_coverage.iter ()); + out->coverage.serialize_serialize (c->serializer, new_coverage.iter ()); return_trace (bool (new_coverage)); } @@ -2634,10 +2891,10 @@ struct ChainContextFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - OffsetArrayOf<ChainRuleSet> + Array16OfOffset16To<ChainRuleSet> ruleSet; /* Array of ChainRuleSet tables * ordered by Coverage Index */ public: @@ -2656,7 +2913,8 @@ struct ChainContextFormat2 const ClassDef &lookahead_class_def = this+lookaheadClassDef; struct ChainContextClosureLookupContext lookup_context = { - {intersects_class}, + {intersects_class, intersected_class_glyphs}, + ContextFormat::ClassBasedContext, {&backtrack_class_def, &input_class_def, &lookahead_class_def} @@ -2672,17 +2930,25 @@ struct ChainContextFormat2 | hb_any ; } + + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { if (!(this+coverage).intersects (c->glyphs)) return; + c->cur_intersected_glyphs->clear (); + get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs); + const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; struct ChainContextClosureLookupContext lookup_context = { - {intersects_class}, + {intersects_class, intersected_class_glyphs}, + ContextFormat::ClassBasedContext, {&backtrack_class_def, &input_class_def, &lookahead_class_def} @@ -2691,19 +2957,41 @@ struct ChainContextFormat2 return + hb_enumerate (ruleSet) | hb_filter ([&] (unsigned _) - { return input_class_def.intersects_class (c->glyphs, _); }, + { return input_class_def.intersects_class (c->cur_intersected_glyphs, _); }, hb_first) - | hb_map (hb_second) - | hb_map (hb_add (this)) - | hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); }) + | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<ChainRuleSet>&> _) + { + const ChainRuleSet& chainrule_set = this+_.second; + chainrule_set.closure (c, _.first, lookup_context); + }) ; } void closure_lookups (hb_closure_lookups_context_t *c) const { + if (!(this+coverage).intersects (c->glyphs)) + return; + + const ClassDef &backtrack_class_def = this+backtrackClassDef; + const ClassDef &input_class_def = this+inputClassDef; + const ClassDef &lookahead_class_def = this+lookaheadClassDef; + + struct ChainContextClosureLookupContext lookup_context = { + {intersects_class, intersected_class_glyphs}, + ContextFormat::ClassBasedContext, + {&backtrack_class_def, + &input_class_def, + &lookahead_class_def} + }; + + hb_iter (ruleSet) | hb_map (hb_add (this)) - | hb_apply ([&] (const ChainRuleSet &_) { _.closure_lookups (c); }) + | hb_enumerate + | hb_filter([&] (unsigned klass) + { return input_class_def.intersects_class (c->glyphs, klass); }, hb_first) + | hb_map (hb_second) + | hb_apply ([&] (const ChainRuleSet &_) + { _.closure_lookups (c, lookup_context); }) ; } @@ -2779,25 +3067,24 @@ struct ChainContextFormat2 out->coverage.serialize_subset (c, coverage, this); hb_map_t backtrack_klass_map; - out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map); - if (unlikely (!c->serializer->check_success (!backtrack_klass_map.in_error ()))) - return_trace (false); - - // subset inputClassDef based on glyphs survived in Coverage subsetting hb_map_t input_klass_map; - out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map); - if (unlikely (!c->serializer->check_success (!input_klass_map.in_error ()))) - return_trace (false); - hb_map_t lookahead_klass_map; + + out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, &backtrack_klass_map); + // TODO: subset inputClassDef based on glyphs survived in Coverage subsetting + out->inputClassDef.serialize_subset (c, inputClassDef, this, &input_klass_map); out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map); - if (unlikely (!c->serializer->check_success (!lookahead_klass_map.in_error ()))) + + if (unlikely (!c->serializer->propagate_error (backtrack_klass_map, + input_klass_map, + lookahead_klass_map))) return_trace (false); - unsigned non_zero_index = 0, index = 0; + 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; - for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet) + 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)) { @@ -2812,19 +3099,20 @@ struct ChainContextFormat2 &backtrack_klass_map, &input_klass_map, &lookahead_klass_map)) + { + last_non_zero = c->serializer->snapshot (); non_zero_index = index; + } index++; } if (!ret) return_trace (ret); - //prune empty trailing ruleSets - --index; - while (index > non_zero_index) - { - out->ruleSet.pop (); - index--; + // prune empty trailing ruleSets + if (index > non_zero_index) { + c->serializer->revert (last_non_zero); + out->ruleSet.len = non_zero_index + 1; } return_trace (bool (out->ruleSet)); @@ -2842,22 +3130,22 @@ struct ChainContextFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - OffsetTo<Coverage> + Offset16To<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - OffsetTo<ClassDef> + Offset16To<ClassDef> backtrackClassDef; /* Offset to glyph ClassDef table * containing backtrack sequence * data--from beginning of table */ - OffsetTo<ClassDef> + Offset16To<ClassDef> inputClassDef; /* Offset to glyph ClassDef * table containing input sequence * data--from beginning of table */ - OffsetTo<ClassDef> + Offset16To<ClassDef> lookaheadClassDef; /* Offset to glyph ClassDef table * containing lookahead sequence * data--from beginning of table */ - OffsetArrayOf<ChainRuleSet> + Array16OfOffset16To<ChainRuleSet> ruleSet; /* Array of ChainRuleSet tables * ordered by class */ public: @@ -2868,14 +3156,15 @@ struct ChainContextFormat3 { bool intersects (const hb_set_t *glyphs) const { - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); if (!(this+input[0]).intersects (glyphs)) return false; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); struct ChainContextClosureLookupContext lookup_context = { - {intersects_coverage}, + {intersects_coverage, intersected_coverage_glyphs}, + ContextFormat::CoverageBasedContext, {this, this, this} }; return chain_context_intersects (glyphs, @@ -2885,17 +3174,24 @@ struct ChainContextFormat3 lookup_context); } + bool may_have_non_1to1 () const + { return true; } + void closure (hb_closure_context_t *c) const { - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); if (!(this+input[0]).intersects (c->glyphs)) return; - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + c->cur_intersected_glyphs->clear (); + get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs); + + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); struct ChainContextClosureLookupContext lookup_context = { - {intersects_coverage}, + {intersects_coverage, intersected_coverage_glyphs}, + ContextFormat::CoverageBasedContext, {this, this, this} }; chain_context_closure_lookup (c, @@ -2903,14 +3199,17 @@ struct ChainContextFormat3 input.len, (const HBUINT16 *) input.arrayZ + 1, lookahead.len, (const HBUINT16 *) lookahead.arrayZ, lookup.len, lookup.arrayZ, - lookup_context); + 0, lookup_context); } void closure_lookups (hb_closure_lookups_context_t *c) const { - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + if (!intersects (c->glyphs)) + return; + + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); recurse_lookups (c, lookup.len, lookup.arrayZ); } @@ -2918,12 +3217,12 @@ struct ChainContextFormat3 void collect_glyphs (hb_collect_glyphs_context_t *c) const { - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); (this+input[0]).collect_coverage (c->input); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); struct ChainContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, {this, this, this} @@ -2938,9 +3237,9 @@ struct ChainContextFormat3 bool would_apply (hb_would_apply_context_t *c) const { - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {match_coverage}, {this, this, this} @@ -2954,20 +3253,20 @@ struct ChainContextFormat3 const Coverage &get_coverage () const { - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); return this+input[0]; } bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {match_coverage}, {this, this, this} @@ -2984,15 +3283,18 @@ struct ChainContextFormat3 bool serialize_coverage_offsets (hb_subset_context_t *c, Iterator it, const void* base) const { TRACE_SERIALIZE (this); - auto *out = c->serializer->start_embed<OffsetArrayOf<Coverage>> (); + auto *out = c->serializer->start_embed<Array16OfOffset16To<Coverage>> (); - if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) return_trace (false); + if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) + return_trace (false); - + it - | hb_apply (subset_offset_array (c, *out, base)) - ; + for (auto& offset : it) { + auto *o = out->serialize_append (c->serializer); + if (unlikely (!o) || !o->serialize_subset (c, offset, base)) + return_trace (false); + } - return_trace (out->len); + return_trace (true); } bool subset (hb_subset_context_t *c) const @@ -3006,22 +3308,30 @@ struct ChainContextFormat3 if (!serialize_coverage_offsets (c, backtrack.iter (), this)) return_trace (false); - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); if (!serialize_coverage_offsets (c, input.iter (), this)) return_trace (false); - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); if (!serialize_coverage_offsets (c, lookahead.iter (), this)) return_trace (false); - const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead); + 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 = lookupRecord.len; + lookupCount = lookup_indices.get_population (); if (!c->serializer->copy (lookupCount)) return_trace (false); - 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 (!c->serializer->copy (lookupRecord[i], lookup_map)) return_trace (false); + for (unsigned i : lookup_indices.iter ()) + { + if (!c->serializer->copy (lookupRecord[i], lookup_map)) + return_trace (false); + } return_trace (true); } @@ -3030,30 +3340,30 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (!backtrack.sanitize (c, this)) return_trace (false); - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); + const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); if (!input.sanitize (c, this)) return_trace (false); if (!input.len) return_trace (false); /* To be consistent with Context. */ - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); + const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); if (!lookahead.sanitize (c, this)) return_trace (false); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); + const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); return_trace (lookup.sanitize (c)); } protected: HBUINT16 format; /* Format identifier--format = 3 */ - OffsetArrayOf<Coverage> + Array16OfOffset16To<Coverage> backtrack; /* Array of coverage tables * in backtracking sequence, in glyph * sequence order */ - OffsetArrayOf<Coverage> + Array16OfOffset16To<Coverage> inputX ; /* Array of coverage * tables in input sequence, in glyph * sequence order */ - OffsetArrayOf<Coverage> + Array16OfOffset16To<Coverage> lookaheadX; /* Array of coverage tables * in lookahead sequence, in glyph * sequence order */ - ArrayOf<LookupRecord> + Array16Of<LookupRecord> lookupX; /* Array of LookupRecords--in * design order) */ public: @@ -3092,7 +3402,7 @@ struct ExtensionFormat1 template <typename X> const X& get_subtable () const - { return this + reinterpret_cast<const LOffsetTo<typename T::SubTable> &> (extensionOffset); } + { return this + reinterpret_cast<const Offset32To<typename T::SubTable> &> (extensionOffset); } template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const @@ -3113,6 +3423,24 @@ struct ExtensionFormat1 extensionLookupType != T::SubTable::Extension); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + out->format = format; + out->extensionLookupType = extensionLookupType; + + const auto& src_offset = + reinterpret_cast<const Offset32To<typename T::SubTable> &> (extensionOffset); + auto& dest_offset = + reinterpret_cast<Offset32To<typename T::SubTable> &> (out->extensionOffset); + + return_trace (dest_offset.serialize_subset (c, src_offset, this, get_type ())); + } + protected: HBUINT16 format; /* Format identifier. Set to 1. */ HBUINT16 extensionLookupType; /* Lookup type of subtable referenced @@ -3143,6 +3471,18 @@ struct Extension } } + // Specialization of dispatch for subset. dispatch() normally just + // dispatches to the sub table this points too, but for subset + // we need to run subset on this subtable too. + template <typename ...Ts> + typename hb_subset_context_t::return_t dispatch (hb_subset_context_t *c, Ts&&... ds) const + { + switch (u.format) { + case 1: return u.format1.subset (c); + default: return c->default_return_value (); + } + } + template <typename context_t, typename ...Ts> typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const { @@ -3280,6 +3620,20 @@ struct GSUBGPOS hb_set_subtract (lookup_indexes, &inactive_lookups); } + void prune_langsys (const hb_map_t *duplicate_feature_map, + hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *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); + + unsigned count = get_script_count (); + for (unsigned script_index = 0; script_index < count; script_index++) + { + const Script& s = get_script (script_index); + s.prune_langsys (&c, script_index); + } + } + template <typename TLookup> bool subset (hb_subset_layout_context_t *c) const { @@ -3288,15 +3642,15 @@ struct GSUBGPOS if (unlikely (!out)) return_trace (false); typedef LookupOffsetList<TLookup> TLookupList; - reinterpret_cast<OffsetTo<TLookupList> &> (out->lookupList) + reinterpret_cast<Offset16To<TLookupList> &> (out->lookupList) .serialize_subset (c->subset_context, - reinterpret_cast<const OffsetTo<TLookupList> &> (lookupList), + reinterpret_cast<const Offset16To<TLookupList> &> (lookupList), this, c); - reinterpret_cast<OffsetTo<RecordListOfFeature> &> (out->featureList) + reinterpret_cast<Offset16To<RecordListOfFeature> &> (out->featureList) .serialize_subset (c->subset_context, - reinterpret_cast<const OffsetTo<RecordListOfFeature> &> (featureList), + reinterpret_cast<const Offset16To<RecordListOfFeature> &> (featureList), this, c); @@ -3320,20 +3674,99 @@ struct GSUBGPOS return_trace (true); } - void closure_features (const hb_map_t *lookup_indexes, /* IN */ - hb_set_t *feature_indexes /* OUT */) const + void find_duplicate_features (const hb_map_t *lookup_indices, + const hb_set_t *feature_indices, + hb_map_t *duplicate_feature_map /* OUT */) const { - unsigned int feature_count = hb_min (get_feature_count (), (unsigned) HB_MAX_FEATURES); - for (unsigned i = 0; i < feature_count; i++) + //find out duplicate features after subset + unsigned prev = 0xFFFFu; + for (unsigned i : feature_indices->iter ()) { + if (prev == 0xFFFFu) + { + 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) + { + duplicate_feature_map->set (i, i); + prev = i; + continue; + } + const Feature& f = get_feature (i); - if ((!f.featureParams.is_null ()) || f.intersects_lookup_indexes (lookup_indexes)) - feature_indexes->add (i); + const Feature& prev_f = get_feature (prev); + + auto f_iter = + + hb_iter (f.lookupIndex) + | hb_filter (lookup_indices) + ; + + auto prev_iter = + + hb_iter (prev_f.lookupIndex) + | hb_filter (lookup_indices) + ; + + if (f_iter.len () != prev_iter.len ()) + { + duplicate_feature_map->set (i, i); + prev = i; + continue; + } + + 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 + { + duplicate_feature_map->set (i, i); + prev = i; + } } + } + + void prune_features (const hb_map_t *lookup_indices, /* IN */ + hb_set_t *feature_indices /* IN/OUT */) const + { #ifndef HB_NO_VAR + // This is the set of feature indices which have alternate versions defined + // if the FeatureVariation's table and the alternate version(s) intersect the + // set of lookup indices. + hb_set_t alternate_feature_indices; if (version.to_int () >= 0x00010001u) - (this+featureVars).closure_features (lookup_indexes, feature_indexes); + (this+featureVars).closure_features (lookup_indices, &alternate_feature_indices); + if (unlikely (alternate_feature_indices.in_error())) + { + feature_indices->err (); + return; + } #endif + + for (unsigned i : feature_indices->iter()) + { + const Feature& f = get_feature (i); + hb_tag_t tag = get_feature_tag (i); + if (tag == HB_TAG ('p', 'r', 'e', 'f')) + // Note: Never ever drop feature 'pref', even if it's empty. + // HarfBuzz chooses shaper for Khmer based on presence of this + // feature. See thread at: + // http://lists.freedesktop.org/archives/harfbuzz/2012-November/002660.html + continue; + + if (f.featureParams.is_null () + && !f.intersects_lookup_indexes (lookup_indices) +#ifndef HB_NO_VAR + && !alternate_feature_indices.has (i) +#endif + ) + feature_indices->del (i); + } } unsigned int get_size () const @@ -3346,12 +3779,12 @@ struct GSUBGPOS bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - typedef OffsetListOf<TLookup> TLookupList; + typedef List16OfOffset16To<TLookup> TLookupList; if (unlikely (!(version.sanitize (c) && likely (version.major == 1) && scriptList.sanitize (c, this) && featureList.sanitize (c, this) && - reinterpret_cast<const OffsetTo<TLookupList> &> (lookupList).sanitize (c, this)))) + reinterpret_cast<const Offset16To<TLookupList> &> (lookupList).sanitize (c, this)))) return_trace (false); #ifndef HB_NO_VAR @@ -3376,7 +3809,7 @@ struct GSUBGPOS this->lookup_count = table->get_lookup_count (); - this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t)); + this->accels = (hb_ot_layout_lookup_accelerator_t *) hb_calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t)); if (unlikely (!this->accels)) { this->lookup_count = 0; @@ -3392,7 +3825,7 @@ struct GSUBGPOS { for (unsigned int i = 0; i < this->lookup_count; i++) this->accels[i].fini (); - free (this->accels); + hb_free (this->accels); this->table.destroy (); } @@ -3404,13 +3837,13 @@ struct GSUBGPOS protected: FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000u */ - OffsetTo<ScriptList> + Offset16To<ScriptList> scriptList; /* ScriptList table */ - OffsetTo<FeatureList> + Offset16To<FeatureList> featureList; /* FeatureList table */ - OffsetTo<LookupList> + Offset16To<LookupList> lookupList; /* LookupList table */ - LOffsetTo<FeatureVariations> + Offset32To<FeatureVariations> featureVars; /* Offset to Feature Variations table--from beginning of table * (may be NULL). Introduced diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh index ffd2bf4574..3b2293dff0 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-jstf-table.hh @@ -45,7 +45,7 @@ typedef IndexArray JstfModList; * JstfMax -- Justification Maximum Table */ -typedef OffsetListOf<PosLookup> JstfMax; +typedef List16OfOffset16To<PosLookup> JstfMax; /* @@ -71,43 +71,43 @@ struct JstfPriority } protected: - OffsetTo<JstfModList> + Offset16To<JstfModList> shrinkageEnableGSUB; /* Offset to Shrinkage Enable GSUB * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> shrinkageDisableGSUB; /* Offset to Shrinkage Disable GSUB * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> shrinkageEnableGPOS; /* Offset to Shrinkage Enable GPOS * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> shrinkageDisableGPOS; /* Offset to Shrinkage Disable GPOS * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfMax> + Offset16To<JstfMax> shrinkageJstfMax; /* Offset to Shrinkage JstfMax table-- * from beginning of JstfPriority table * --may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> extensionEnableGSUB; /* Offset to Extension Enable GSUB * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> extensionDisableGSUB; /* Offset to Extension Disable GSUB * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> extensionEnableGPOS; /* Offset to Extension Enable GPOS * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfModList> + Offset16To<JstfModList> extensionDisableGPOS; /* Offset to Extension Disable GPOS * JstfModList table--from beginning of * JstfPriority table--may be NULL */ - OffsetTo<JstfMax> + Offset16To<JstfMax> extensionJstfMax; /* Offset to Extension JstfMax table-- * from beginning of JstfPriority table * --may be NULL */ @@ -121,13 +121,13 @@ struct JstfPriority * JstfLangSys -- Justification Language System Table */ -struct JstfLangSys : OffsetListOf<JstfPriority> +struct JstfLangSys : List16OfOffset16To<JstfPriority> { bool sanitize (hb_sanitize_context_t *c, const Record_sanitize_closure_t * = nullptr) const { TRACE_SANITIZE (this); - return_trace (OffsetListOf<JstfPriority>::sanitize (c)); + return_trace (List16OfOffset16To<JstfPriority>::sanitize (c)); } }; @@ -136,7 +136,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority> * ExtenderGlyphs -- Extender Glyph Table */ -typedef SortedArrayOf<HBGlyphID> ExtenderGlyphs; +typedef SortedArray16Of<HBGlyphID> ExtenderGlyphs; /* @@ -174,10 +174,10 @@ struct JstfScript } protected: - OffsetTo<ExtenderGlyphs> + Offset16To<ExtenderGlyphs> extenderGlyphs; /* Offset to ExtenderGlyph table--from beginning * of JstfScript table-may be NULL */ - OffsetTo<JstfLangSys> + Offset16To<JstfLangSys> defaultLangSys; /* Offset to DefaultJstfLangSys table--from * beginning of JstfScript table--may be Null */ RecordArrayOf<JstfLangSys> diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index f25f0f9e23..0454af2063 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -76,7 +76,7 @@ * Tests whether a face includes any kerning data in the 'kern' table. * Does NOT test for kerning lookups in the GPOS table. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ bool @@ -92,7 +92,7 @@ hb_ot_layout_has_kerning (hb_face_t *face) * Tests whether a face includes any state-machine kerning in the 'kern' table. * Does NOT examine the GPOS table. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ bool @@ -112,7 +112,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face) * * Does NOT examine the GPOS table. * - * Return value: %true is data found, false otherwise + * Return value: %true is data found, %false otherwise * **/ bool @@ -131,7 +131,9 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + if (!buffer->message (font, "start table kern")) return; kern.apply (&c); + (void) buffer->message (font, "end table kern"); } #endif @@ -144,7 +146,7 @@ bool OT::GDEF::is_blocklisted (hb_blob_t *blob, hb_face_t *face) const { -#ifdef HB_NO_OT_LAYOUT_BLACKLIST +#ifdef HB_NO_OT_LAYOUT_BLOCKLIST return false; #endif /* The ugly business of blocklisting individual fonts' tables happen here! @@ -268,7 +270,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, * * Tests whether a face has any glyph classes defined in its GDEF table. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ hb_bool_t @@ -322,7 +324,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, * @face: The #hb_face_t to work on * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first attachment point to retrieve - * @point_count: (inout) (allow-none): Input = the maximum number of attachment points to return; + * @point_count: (inout) (optional): Input = the maximum number of attachment points to return; * Output = the actual number of attachment points returned (may be zero) * @point_array: (out) (array length=point_count): The array of attachment points found for the query * @@ -331,6 +333,8 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, * * Useful if the client program wishes to cache the list. * + * Return value: Total number of attachment points for @glyph. + * **/ unsigned int hb_ot_layout_get_attach_points (hb_face_t *face, @@ -350,13 +354,15 @@ hb_ot_layout_get_attach_points (hb_face_t *face, * @direction: The #hb_direction_t text direction to use * @glyph: The #hb_codepoint_t code point to query * @start_offset: offset of the first caret position to retrieve - * @caret_count: (inout) (allow-none): Input = the maximum number of caret positions to return; + * @caret_count: (inout) (optional): Input = the maximum number of caret positions to return; * Output = the actual number of caret positions returned (may be zero) * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query * * Fetches a list of the caret positions defined for a ligature glyph in the GDEF * table of the font. The list returned will begin at the offset provided. * + * Return value: Total number of ligature caret positions for @glyph. + * **/ unsigned int hb_ot_layout_get_ligature_carets (hb_font_t *font, @@ -379,7 +385,7 @@ bool OT::GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED, hb_face_t *face) const { -#ifdef HB_NO_OT_LAYOUT_BLACKLIST +#ifdef HB_NO_OT_LAYOUT_BLOCKLIST return false; #endif return false; @@ -389,7 +395,7 @@ bool OT::GPOS::is_blocklisted (hb_blob_t *blob HB_UNUSED, hb_face_t *face HB_UNUSED) const { -#ifdef HB_NO_OT_LAYOUT_BLACKLIST +#ifdef HB_NO_OT_LAYOUT_BLOCKLIST return false; #endif return false; @@ -410,15 +416,17 @@ get_gsubgpos_table (hb_face_t *face, /** * hb_ot_layout_table_get_script_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first script tag to retrieve - * @script_count: (inout) (allow-none): Input = the maximum number of script tags to return; + * @script_count: (inout) (optional): Input = the maximum number of script tags to return; * Output = the actual number of script tags returned (may be zero) * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query * * Fetches a list of all scripts enumerated in the specified face's GSUB table * or GPOS table. The list returned will begin at the offset provided. * + * Return value: Total number of script tags. + * **/ unsigned int hb_ot_layout_table_get_script_tags (hb_face_t *face, @@ -437,14 +445,14 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, /** * hb_ot_layout_table_find_script: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_tag: #hb_tag_t of the script tag requested * @script_index: (out): The index of the requested script tag * * Fetches the index if a given script tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the script is found, false otherwise + * Return value: %true if the script is found, %false otherwise * **/ hb_bool_t @@ -481,7 +489,7 @@ hb_ot_layout_table_find_script (hb_face_t *face, /** * hb_ot_layout_table_choose_script: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_tags: Array of #hb_tag_t script tags * @script_index: (out): The index of the requested script tag * @chosen_script: (out): #hb_tag_t of the script tag requested @@ -504,11 +512,22 @@ hb_ot_layout_table_choose_script (hb_face_t *face, /** * hb_ot_layout_table_select_script: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_count: Number of script tags in the array * @script_tags: Array of #hb_tag_t script tags - * @script_index: (out): The index of the requested script - * @chosen_script: (out): #hb_tag_t of the requested script + * @script_index: (out) (optional): The index of the requested script + * @chosen_script: (out) (optional): #hb_tag_t of the requested script + * + * Selects an OpenType script for @table_tag from the @script_tags array. + * + * If the table does not have any of the requested scripts, then `DFLT`, + * `dflt`, and `latn` tags are tried in that order. If the table still does not + * have any of these scripts, @script_index and @chosen_script are set to + * #HB_OT_LAYOUT_NO_SCRIPT_INDEX. + * + * Return value: + * %true if one of the requested scripts is selected, %false if a fallback + * script is selected or if no scripts are selected. * * Since: 2.0.0 **/ @@ -566,14 +585,16 @@ hb_ot_layout_table_select_script (hb_face_t *face, /** * hb_ot_layout_table_get_feature_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table * * Fetches a list of all feature tags in the given face's GSUB or GPOS table. * + * Return value: Total number of feature tags. + * **/ unsigned int hb_ot_layout_table_get_feature_tags (hb_face_t *face, @@ -591,14 +612,14 @@ 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 + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_tag: The #hb_tag_t og 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 * or GPOS table. * - * Return value: %true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise **/ bool hb_ot_layout_table_find_feature (hb_face_t *face, @@ -626,16 +647,18 @@ hb_ot_layout_table_find_feature (hb_face_t *face, /** * hb_ot_layout_script_get_language_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @start_offset: offset of the first language tag to retrieve - * @language_count: (inout) (allow-none): Input = the maximum number of language tags to return; + * @language_count: (inout) (optional): Input = the maximum number of language tags to return; * Output = the actual number of language tags returned (may be zero) * @language_tags: (out) (array length=language_count): Array of language tags found in the table * * Fetches a list of language tags in the given face's GSUB or GPOS table, underneath * the specified script index. The list returned will begin at the offset provided. * + * Return value: Total number of language tags. + * **/ unsigned int hb_ot_layout_script_get_language_tags (hb_face_t *face, @@ -655,7 +678,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, /** * hb_ot_layout_script_find_language: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_tag: The #hb_tag_t of the requested language * @language_index: The index of the requested language @@ -663,7 +686,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script tag. * - * Return value: %true if the language tag is found, false otherwise + * Return value: %true if the language tag is found, %false otherwise * * Since: ?? * Deprecated: ?? @@ -688,7 +711,7 @@ hb_ot_layout_script_find_language (hb_face_t *face, /** * hb_ot_layout_script_select_language: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_count: The number of languages in the specified script * @language_tags: The array of language tags @@ -697,7 +720,7 @@ hb_ot_layout_script_find_language (hb_face_t *face, * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script index. * - * Return value: %true if the language tag is found, false otherwise + * Return value: %true if the language tag is found, %false otherwise * * Since: 2.0.0 **/ @@ -731,7 +754,7 @@ hb_ot_layout_script_select_language (hb_face_t *face, /** * hb_ot_layout_language_get_required_feature_index: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @feature_index: (out): The index of the requested feature @@ -739,7 +762,7 @@ hb_ot_layout_script_select_language (hb_face_t *face, * Fetches the index of a requested feature in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise * **/ hb_bool_t @@ -761,7 +784,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, /** * hb_ot_layout_language_get_required_feature: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @feature_index: (out): The index of the requested feature @@ -770,7 +793,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise * * Since: 0.9.30 **/ @@ -796,17 +819,19 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, /** * hb_ot_layout_language_get_feature_indexes: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; * Output: the actual number of feature tags returned (may be zero) * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query * * Fetches a list of all features in the specified face's GSUB table * or GPOS table, underneath the specified script and language. The list * returned will begin at the offset provided. + * + * Return value: Total number of features. **/ unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, @@ -827,11 +852,11 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, /** * hb_ot_layout_language_get_feature_tags: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @start_offset: offset of the first feature tag to retrieve - * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return; + * @feature_count: (inout) (optional): Input = the maximum number of feature tags to return; * Output = the actual number of feature tags returned (may be zero) * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query * @@ -839,6 +864,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, * or GPOS table, underneath the specified script and language. The list * returned will begin at the offset provided. * + * Return value: Total number of feature tags. **/ unsigned int hb_ot_layout_language_get_feature_tags (hb_face_t *face, @@ -868,7 +894,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, /** * hb_ot_layout_language_find_feature: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @script_index: The index of the requested script tag * @language_index: The index of the requested language tag * @feature_tag: #hb_tag_t of the feature tag requested @@ -877,7 +903,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, * Fetches the index of a given feature tag in the specified face's GSUB table * or GPOS table, underneath the specified script and language. * - * Return value: %true if the feature is found, false otherwise + * Return value: %true if the feature is found, %false otherwise * **/ hb_bool_t @@ -910,10 +936,10 @@ hb_ot_layout_language_find_feature (hb_face_t *face, /** * hb_ot_layout_feature_get_lookups: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the requested feature * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query * @@ -921,6 +947,8 @@ hb_ot_layout_language_find_feature (hb_face_t *face, * the specified face's GSUB table or GPOS table. The list returned will * begin at the offset provided. * + * Return value: Total number of lookups. + * * Since: 0.9.7 **/ unsigned int @@ -944,11 +972,13 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, /** * hb_ot_layout_table_get_lookup_count: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * * Fetches the total number of lookups enumerated in the specified * face's GSUB table or GPOS table. * + * Return value: Total number of lookups. + * * Since: 0.9.22 **/ unsigned int @@ -963,10 +993,46 @@ struct hb_collect_features_context_t { hb_collect_features_context_t (hb_face_t *face, hb_tag_t table_tag, - hb_set_t *feature_indexes_) + hb_set_t *feature_indices_, + const hb_tag_t *features) + : g (get_gsubgpos_table (face, table_tag)), - feature_indexes (feature_indexes_), - script_count (0),langsys_count (0), feature_index_count (0) {} + feature_indices (feature_indices_), + has_feature_filter (false), + script_count (0),langsys_count (0), feature_index_count (0) + { + compute_feature_filter (features); + } + + void compute_feature_filter (const hb_tag_t *features) + { + if (features == nullptr) + { + has_feature_filter = false; + return; + } + + has_feature_filter = true; + for (; *features; features++) + { + hb_tag_t tag = *features; + unsigned index; + g.find_feature_index (tag, &index); + if (index == OT::Index::NOT_FOUND_INDEX) continue; + + 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; + feature_indices_filter.add(i); + } + } + } bool visited (const OT::Script &s) { @@ -1015,7 +1081,9 @@ struct hb_collect_features_context_t public: const OT::GSUBGPOS &g; - hb_set_t *feature_indexes; + hb_set_t *feature_indices; + hb_set_t feature_indices_filter; + bool has_feature_filter; private: hb_set_t visited_script; @@ -1027,37 +1095,31 @@ struct hb_collect_features_context_t static void langsys_collect_features (hb_collect_features_context_t *c, - const OT::LangSys &l, - const hb_tag_t *features) + const OT::LangSys &l) { if (c->visited (l)) return; - if (!features) + if (!c->has_feature_filter) { /* All features. */ if (l.has_required_feature () && !c->visited_feature_indices (1)) - c->feature_indexes->add (l.get_required_feature_index ()); + c->feature_indices->add (l.get_required_feature_index ()); + // TODO(garretrieger): filter out indices >= feature count? if (!c->visited_feature_indices (l.featureIndex.len)) - l.add_feature_indexes_to (c->feature_indexes); + l.add_feature_indexes_to (c->feature_indices); } else { - /* Ugh. Any faster way? */ - for (; *features; features++) + if (c->feature_indices_filter.is_empty()) return; + unsigned int num_features = l.get_feature_count (); + for (unsigned int i = 0; i < num_features; i++) { - hb_tag_t feature_tag = *features; - unsigned int num_features = l.get_feature_count (); - for (unsigned int i = 0; i < num_features; i++) - { - unsigned int feature_index = l.get_feature_index (i); + unsigned int feature_index = l.get_feature_index (i); + if (!c->feature_indices_filter.has (feature_index)) continue; - if (feature_tag == c->g.get_feature_tag (feature_index)) - { - c->feature_indexes->add (feature_index); - break; - } - } + c->feature_indices->add (feature_index); + c->feature_indices_filter.del (feature_index); } } } @@ -1065,8 +1127,7 @@ langsys_collect_features (hb_collect_features_context_t *c, static void script_collect_features (hb_collect_features_context_t *c, const OT::Script &s, - const hb_tag_t *languages, - const hb_tag_t *features) + const hb_tag_t *languages) { if (c->visited (s)) return; @@ -1075,14 +1136,13 @@ script_collect_features (hb_collect_features_context_t *c, /* All languages. */ if (s.has_default_lang_sys ()) langsys_collect_features (c, - s.get_default_lang_sys (), - features); + s.get_default_lang_sys ()); + unsigned int count = s.get_lang_sys_count (); for (unsigned int language_index = 0; language_index < count; language_index++) langsys_collect_features (c, - s.get_lang_sys (language_index), - features); + s.get_lang_sys (language_index)); } else { @@ -1091,8 +1151,8 @@ script_collect_features (hb_collect_features_context_t *c, unsigned int language_index; if (s.find_lang_sys_index (*languages, &language_index)) langsys_collect_features (c, - s.get_lang_sys (language_index), - features); + s.get_lang_sys (language_index)); + } } } @@ -1101,7 +1161,7 @@ script_collect_features (hb_collect_features_context_t *c, /** * hb_ot_layout_collect_features: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @scripts: The array of scripts to collect features for * @languages: The array of languages to collect features for * @features: The array of features to collect @@ -1123,7 +1183,7 @@ hb_ot_layout_collect_features (hb_face_t *face, const hb_tag_t *features, hb_set_t *feature_indexes /* OUT */) { - hb_collect_features_context_t c (face, table_tag, feature_indexes); + hb_collect_features_context_t c (face, table_tag, feature_indexes, features); if (!scripts) { /* All scripts. */ @@ -1131,8 +1191,7 @@ hb_ot_layout_collect_features (hb_face_t *face, for (unsigned int script_index = 0; script_index < count; script_index++) script_collect_features (&c, c.g.get_script (script_index), - languages, - features); + languages); } else { @@ -1142,8 +1201,7 @@ hb_ot_layout_collect_features (hb_face_t *face, if (c.g.find_script_index (*scripts, &script_index)) script_collect_features (&c, c.g.get_script (script_index), - languages, - features); + languages); } } } @@ -1152,7 +1210,7 @@ hb_ot_layout_collect_features (hb_face_t *face, /** * hb_ot_layout_collect_lookups: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @scripts: The array of scripts to collect lookups for * @languages: The array of languages to collect lookups for * @features: The array of features to collect lookups for @@ -1191,7 +1249,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face, /** * hb_ot_layout_lookup_collect_glyphs: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @lookup_index: The index of the feature lookup to query * @glyphs_before: (out): Array of glyphs preceding the substitution range * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup @@ -1243,7 +1301,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, /** * hb_ot_layout_table_find_feature_variations: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @coords: The variation coordinates to query * @num_coords: The number of variation coordinates * @variations_index: (out): The array of feature variations found for the query @@ -1251,6 +1309,8 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, * Fetches a list of feature variations in the specified face's GSUB table * or GPOS table, at the specified variation coordinates. * + * Return value: %true if feature variations were found, %false otherwise. + * **/ hb_bool_t hb_ot_layout_table_find_feature_variations (hb_face_t *face, @@ -1268,11 +1328,11 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, /** * hb_ot_layout_feature_with_variations_get_lookups: * @face: #hb_face_t to work upon - * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS + * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @feature_index: The index of the feature to query * @variations_index: The index of the feature variation to query * @start_offset: offset of the first lookup to retrieve - * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return; + * @lookup_count: (inout) (optional): Input = the maximum number of lookups to return; * Output = the actual number of lookups returned (may be zero) * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query * @@ -1280,6 +1340,8 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face, * the specified face's GSUB table or GPOS table, enabled at the specified * variations index. The list returned will begin at the offset provided. * + * Return value: Total number of lookups. + * **/ unsigned int hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, @@ -1310,7 +1372,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, * * Tests whether the specified face includes any GSUB substitutions. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * **/ hb_bool_t @@ -1326,12 +1388,13 @@ hb_ot_layout_has_substitution (hb_face_t *face) * @lookup_index: The index of the lookup to query * @glyphs: The sequence of glyphs to query for substitution * @glyphs_length: The length of the glyph sequence - * @zero_context: #hb_bool_t indicating whether substitutions should be context-free + * @zero_context: #hb_bool_t indicating whether pre-/post-context are disallowed + * in substitutions * * Tests whether a specified lookup in the specified face would * trigger a substitution on the given glyph sequence. * - * Return value: %true if a substitution would be triggered, false otherwise + * Return value: %true if a substitution would be triggered, %false otherwise * * Since: 0.9.7 **/ @@ -1432,12 +1495,17 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, hb_set_t *glyphs /* OUT */) { - hb_map_t done_lookups; - OT::hb_closure_context_t c (face, glyphs, &done_lookups); + 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; + 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); l.closure (&c, lookup_index); + + for (auto _ : done_lookups_glyph_set.iter ()) + hb_set_destroy (_.second); } /** @@ -1456,8 +1524,10 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, const hb_set_t *lookups, hb_set_t *glyphs /* OUT */) { - hb_map_t done_lookups; - OT::hb_closure_context_t c (face, glyphs, &done_lookups); + 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; + 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; unsigned int iteration_count = 0; @@ -1477,6 +1547,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, } } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && glyphs_length != glyphs->get_population ()); + + for (auto _ : done_lookups_glyph_set.iter ()) + hb_set_destroy (_.second); } /* @@ -1488,7 +1561,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, * hb_ot_layout_has_positioning: * @face: #hb_face_t to work upon * - * Return value: %true if the face has GPOS data, false otherwise + * Tests whether the specified face includes any GPOS positioning. + * + * Return value: %true if the face has GPOS data, %false otherwise * **/ hb_bool_t @@ -1561,7 +1636,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) * For more information on this distinction, see the [`size` feature documentation]( * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size). * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 0.9.10 **/ @@ -1610,22 +1685,22 @@ hb_ot_layout_get_size_params (hb_face_t *face, * @face: #hb_face_t to work upon * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. - * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * @label_id: (out) (optional): The ‘name’ table name ID that specifies a string * for a user-interface label for this feature. (May be NULL.) - * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * @tooltip_id: (out) (optional): The ‘name’ table name ID that specifies a string * that an application can use for tooltip text for this * feature. (May be NULL.) - * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text + * @sample_id: (out) (optional): The ‘name’ table name ID that specifies sample text * that illustrates the effect of this feature. (May be NULL.) - * @num_named_parameters: (out) (allow-none): Number of named parameters. (May be zero.) - * @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify + * @num_named_parameters: (out) (optional): Number of named parameters. (May be zero.) + * @first_param_id: (out) (optional): The first ‘name’ table name ID used to specify * strings for user-interface labels for the feature * parameters. (Must be zero if numParameters is zero.) * * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or * "Character Variant" ('cvXX') features. * - * Return value: %true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.0.0 **/ @@ -1685,7 +1760,7 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face, * @table_tag: table tag to query, "GSUB" or "GPOS". * @feature_index: index of feature to query. * @start_offset: offset of the first character to retrieve - * @char_count: (inout) (allow-none): Input = the maximum number of characters to return; + * @char_count: (inout) (optional): Input = the maximum number of characters to return; * Output = the actual number of characters returned (may be zero) * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. * The Unicode codepoints of the characters for which this feature provides @@ -1769,7 +1844,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, if (applied) ret = true; else - buffer->next_glyph (); + (void) buffer->next_glyph (); } return ret; } @@ -1811,27 +1886,20 @@ apply_string (OT::hb_ot_apply_context_t *c, if (likely (!lookup.is_reverse ())) { /* in/out forward substitution/positioning */ - if (Proxy::table_index == 0u) + if (!Proxy::inplace) buffer->clear_output (); + buffer->idx = 0; + apply_forward (c, accel); - bool ret; - ret = apply_forward (c, accel); - if (ret) - { - if (!Proxy::inplace) - buffer->swap_buffers (); - else - assert (!buffer->has_separate_output ()); - } + if (!Proxy::inplace) + buffer->swap_buffers (); } else { /* in-place backward substitution/positioning */ - if (Proxy::table_index == 0u) - buffer->remove_output (); + assert (!buffer->have_output); buffer->idx = buffer->len - 1; - apply_backward (c, accel); } } @@ -1847,7 +1915,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, OT::hb_ot_apply_context_t c (table_index, font, buffer); c.set_recurse_func (Proxy::Lookup::apply_recurse_func); - for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) { + for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) + { const stage_map_t *stage = &stages[table_index][stage_index]; for (; i < stage->last_lookup; i++) { @@ -1857,11 +1926,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, c.set_lookup_mask (lookups[table_index][i].mask); c.set_auto_zwj (lookups[table_index][i].auto_zwj); c.set_auto_zwnj (lookups[table_index][i].auto_zwnj); - if (lookups[table_index][i].random) - { - c.set_random (true); - buffer->unsafe_to_break_all (); - } + c.set_random (lookups[table_index][i].random); + apply_string<Proxy> (&c, proxy.table.get_lookup (lookup_index), proxy.accels[lookup_index]); @@ -1869,10 +1935,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, } if (stage->pause_func) - { - buffer->clear_output (); stage->pause_func (plan, font, buffer); - } } } @@ -1907,12 +1970,12 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, * @baseline_tag: a baseline tag * @direction: text direction. * @script_tag: script tag. - * @language_tag: language tag. + * @language_tag: language tag, currently unused. * @coord: (out): baseline value if found. * * Fetches a baseline value from the face. * - * Return value: if found baseline value in the font. + * Return value: %true if found baseline value in the font. * * Since: 2.6.0 **/ @@ -1964,14 +2027,14 @@ struct hb_get_glyph_alternates_dispatch_t : * @lookup_index: index of the feature lookup to query. * @glyph: a glyph id. * @start_offset: starting offset. - * @alternate_count: (inout) (allow-none): Input = the maximum number of alternate glyphs to return; + * @alternate_count: (inout) (optional): Input = the maximum number of alternate glyphs to return; * Output = the actual number of alternate glyphs returned (may be zero). * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. * Alternate glyphs associated with the glyph id. * * Fetches alternates of a glyph from a given GSUB lookup index. * - * Return value: total number of alternates found in the specific lookup index for the given glyph id. + * Return value: Total number of alternates found in the specific lookup index for the given glyph id. * * Since: 2.6.8 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.h b/thirdparty/harfbuzz/src/hb-ot-layout.h index 545d5f7fc4..d47ba0fc92 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.h +++ b/thirdparty/harfbuzz/src/hb-ot-layout.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -38,10 +38,35 @@ HB_BEGIN_DECLS +/** + * HB_OT_TAG_BASE: + * + * OpenType [Baseline Table](https://docs.microsoft.com/en-us/typography/opentype/spec/base). + */ #define HB_OT_TAG_BASE HB_TAG('B','A','S','E') +/** + * HB_OT_TAG_GDEF: + * + * OpenType [Glyph Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gdef). + */ #define HB_OT_TAG_GDEF HB_TAG('G','D','E','F') +/** + * HB_OT_TAG_GSUB: + * + * OpenType [Glyph Substitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub). + */ #define HB_OT_TAG_GSUB HB_TAG('G','S','U','B') +/** + * HB_OT_TAG_GPOS: + * + * OpenType [Glyph Positioning Table](https://docs.microsoft.com/en-us/typography/opentype/spec/gpos). + */ #define HB_OT_TAG_GPOS HB_TAG('G','P','O','S') +/** + * HB_OT_TAG_JSTF: + * + * OpenType [Justification Table](https://docs.microsoft.com/en-us/typography/opentype/spec/jstf). + */ #define HB_OT_TAG_JSTF HB_TAG('J','S','T','F') @@ -49,18 +74,34 @@ HB_BEGIN_DECLS * Script & Language tags. */ +/** + * HB_OT_TAG_DEFAULT_SCRIPT: + * + * OpenType script tag, `DFLT`, for features that are not script-specific. + * + */ #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') +/** + * HB_OT_TAG_DEFAULT_LANGUAGE: + * + * OpenType language tag, `dflt`. Not a valid language tag, but some fonts + * mistakenly use it. + */ #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') /** * HB_OT_MAX_TAGS_PER_SCRIPT: * + * Maximum number of OpenType tags that can correspond to a give #hb_script_t. + * * Since: 2.0.0 **/ #define HB_OT_MAX_TAGS_PER_SCRIPT 3u /** * HB_OT_MAX_TAGS_PER_LANGUAGE: * + * Maximum number of OpenType tags that can correspond to a give #hb_language_t. + * * Since: 2.0.0 **/ #define HB_OT_MAX_TAGS_PER_LANGUAGE 3u @@ -144,9 +185,29 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, * GSUB/GPOS feature query and enumeration interface */ +/** + * HB_OT_LAYOUT_NO_SCRIPT_INDEX: + * + * Special value for script index indicating unsupported script. + */ #define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu +/** + * HB_OT_LAYOUT_NO_FEATURE_INDEX: + * + * Special value for feature index indicating unsupported feature. + */ #define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu +/** + * HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX: + * + * Special value for language index indicating default or unsupported language. + */ #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu +/** + * HB_OT_LAYOUT_NO_VARIATIONS_INDEX: + * + * Special value for variations index indicating unsupported variation. + */ #define HB_OT_LAYOUT_NO_VARIATIONS_INDEX 0xFFFFFFFFu HB_EXTERN unsigned int @@ -433,7 +494,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, * @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered. * In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered. * - * Baseline tags from https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags + * Baseline tags from [Baseline Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags) registry. * * Since: 2.6.0 */ @@ -446,6 +507,7 @@ typedef enum { HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT = HB_TAG ('i','d','t','p'), HB_OT_LAYOUT_BASELINE_TAG_MATH = HB_TAG ('m','a','t','h'), + /*< private >*/ _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_layout_baseline_tag_t; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index f3bb15581a..bcc014ee98 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -314,20 +314,20 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) hb_unicode_funcs_t::NOT_SPACE; } -static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); +static inline bool _hb_glyph_info_substituted (const hb_glyph_info_t *info); static inline bool _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && - !_hb_glyph_info_ligated (info); + !_hb_glyph_info_substituted (info); } static inline bool _hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info) { return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN)) == UPROPS_MASK_IGNORABLE) && - !_hb_glyph_info_ligated (info); + !_hb_glyph_info_substituted (info); } static inline void _hb_glyph_info_unhide (hb_glyph_info_t *info) diff --git a/thirdparty/harfbuzz/src/hb-ot-map.cc b/thirdparty/harfbuzz/src/hb-ot-map.cc index e4bb4b6366..12ceea5785 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.cc +++ b/thirdparty/harfbuzz/src/hb-ot-map.cc @@ -54,7 +54,6 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, face = face_; props = *props_; - /* Fetch script/language indices for GSUB/GPOS. We need these later to skip * features not available in either table and not waste precious bits for them. */ @@ -63,12 +62,28 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT]; hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE]; - hb_ot_tags_from_script_and_language (props.script, props.language, &script_count, script_tags, &language_count, language_tags); + hb_ot_tags_from_script_and_language (props.script, + props.language, + &script_count, + script_tags, + &language_count, + language_tags); - for (unsigned int table_index = 0; table_index < 2; table_index++) { + for (unsigned int table_index = 0; table_index < 2; table_index++) + { hb_tag_t table_tag = table_tags[table_index]; - found_script[table_index] = (bool) hb_ot_layout_table_select_script (face, table_tag, script_count, script_tags, &script_index[table_index], &chosen_script[table_index]); - hb_ot_layout_script_select_language (face, table_tag, script_index[table_index], language_count, language_tags, &language_index[table_index]); + found_script[table_index] = (bool) hb_ot_layout_table_select_script (face, + table_tag, + script_count, + script_tags, + &script_index[table_index], + &chosen_script[table_index]); + hb_ot_layout_script_select_language (face, + table_tag, + script_index[table_index], + language_count, + language_tags, + &language_index[table_index]); } } @@ -150,9 +165,8 @@ void hb_ot_map_builder_t::compile (hb_ot_map_t &m, const hb_ot_shape_plan_key_t &key) { - static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), ""); - unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1; - unsigned int global_bit_shift = hb_popcount (HB_GLYPH_FLAG_DEFINED); + unsigned int global_bit_shift = 8 * sizeof (hb_mask_t) - 1; + unsigned int global_bit_mask = 1u << global_bit_shift; m.global_mask = global_bit_mask; @@ -205,7 +219,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, /* Allocate bits now */ - unsigned int next_bit = global_bit_shift + 1; + static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), ""); + unsigned int next_bit = hb_popcount (HB_GLYPH_FLAG_DEFINED) + 1; for (unsigned int i = 0; i < feature_infos.length; i++) { @@ -220,7 +235,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, /* Limit bits per feature. */ bits_needed = hb_min (HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value)); - if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) + if (!info->max_value || next_bit + bits_needed >= global_bit_shift) continue; /* Feature disabled, or not enough bits. */ @@ -274,7 +289,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } map->_1_mask = (1u << map->shift) & map->mask; map->needs_fallback = !found; - } feature_infos.shrink (0); /* Done with these */ diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh index 26aa080603..5916ad29f2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh @@ -49,7 +49,7 @@ struct MathValueRecord protected: HBINT16 value; /* The X or Y value in design units */ - OffsetTo<Device> deviceTable; /* Offset to the device table - from the + Offset16To<Device> deviceTable; /* Offset to the device table - from the * beginning of parent table. May be NULL. * Suggested format for device table is 1. */ @@ -181,11 +181,11 @@ struct MathItalicsCorrectionInfo } protected: - OffsetTo<Coverage> coverage; /* Offset to Coverage table - + Offset16To<Coverage> coverage; /* Offset to Coverage table - * from the beginning of * MathItalicsCorrectionInfo * table. */ - ArrayOf<MathValueRecord> italicsCorrection; /* Array of MathValueRecords + Array16Of<MathValueRecord> italicsCorrection; /* Array of MathValueRecords * defining italics correction * values for each * covered glyph. */ @@ -214,11 +214,11 @@ struct MathTopAccentAttachment } protected: - OffsetTo<Coverage> topAccentCoverage; /* Offset to Coverage table - + Offset16To<Coverage> topAccentCoverage; /* Offset to Coverage table - * from the beginning of * MathTopAccentAttachment * table. */ - ArrayOf<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords + Array16Of<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords * defining top accent * attachment points for each * covered glyph. */ @@ -320,7 +320,7 @@ struct MathKernInfoRecord protected: /* Offset to MathKern table for each corner - * from the beginning of MathKernInfo table. May be NULL. */ - OffsetTo<MathKern> mathKern[4]; + Offset16To<MathKern> mathKern[4]; public: DEFINE_SIZE_STATIC (8); @@ -346,12 +346,12 @@ struct MathKernInfo } protected: - OffsetTo<Coverage> + Offset16To<Coverage> mathKernCoverage; /* Offset to Coverage table - * from the beginning of the * MathKernInfo table. */ - ArrayOf<MathKernInfoRecord> + Array16Of<MathKernInfoRecord> mathKernInfoRecords; /* Array of MathKernInfoRecords, * per-glyph information for @@ -395,22 +395,22 @@ struct MathGlyphInfo protected: /* Offset to MathItalicsCorrectionInfo table - * from the beginning of MathGlyphInfo table. */ - OffsetTo<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo; + Offset16To<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo; /* Offset to MathTopAccentAttachment table - * from the beginning of MathGlyphInfo table. */ - OffsetTo<MathTopAccentAttachment> mathTopAccentAttachment; + Offset16To<MathTopAccentAttachment> mathTopAccentAttachment; /* Offset to coverage table for Extended Shape glyphs - * from the beginning of MathGlyphInfo table. When the left or right glyph of * a box is an extended shape variant, the (ink) box (and not the default * position defined by values in MathConstants table) should be used for * vertical positioning purposes. May be NULL.. */ - OffsetTo<Coverage> extendedShapeCoverage; + Offset16To<Coverage> extendedShapeCoverage; /* Offset to MathKernInfo table - * from the beginning of MathGlyphInfo table. */ - OffsetTo<MathKernInfo> mathKernInfo; + Offset16To<MathKernInfo> mathKernInfo; public: DEFINE_SIZE_STATIC (8); @@ -532,7 +532,7 @@ struct MathGlyphAssembly /* Italics correction of this * MathGlyphAssembly. Should not * depend on the assembly size. */ - ArrayOf<MathGlyphPartRecord> + Array16Of<MathGlyphPartRecord> partRecords; /* Array of part records, from * left to right and bottom to * top. */ @@ -572,10 +572,10 @@ struct MathGlyphConstruction protected: /* Offset to MathGlyphAssembly table for this shape - from the beginning of MathGlyphConstruction table. May be NULL. */ - OffsetTo<MathGlyphAssembly> glyphAssembly; + Offset16To<MathGlyphAssembly> glyphAssembly; /* MathGlyphVariantRecords for alternative variants of the glyphs. */ - ArrayOf<MathGlyphVariantRecord> mathGlyphVariantRecord; + Array16Of<MathGlyphVariantRecord> mathGlyphVariantRecord; public: DEFINE_SIZE_ARRAY (4, mathGlyphVariantRecord); @@ -636,7 +636,7 @@ struct MathVariants { bool vertical = HB_DIRECTION_IS_VERTICAL (direction); unsigned int count = vertical ? vertGlyphCount : horizGlyphCount; - const OffsetTo<Coverage> &coverage = vertical ? vertGlyphCoverage + const Offset16To<Coverage> &coverage = vertical ? vertGlyphCoverage : horizGlyphCoverage; unsigned int index = (this+coverage).get_coverage (glyph); @@ -653,11 +653,11 @@ struct MathVariants /* Minimum overlap of connecting * glyphs during glyph construction, * in design units. */ - OffsetTo<Coverage> vertGlyphCoverage; + Offset16To<Coverage> vertGlyphCoverage; /* Offset to Coverage table - * from the beginning of MathVariants * table. */ - OffsetTo<Coverage> horizGlyphCoverage; + Offset16To<Coverage> horizGlyphCoverage; /* Offset to Coverage table - * from the beginning of MathVariants * table. */ @@ -671,7 +671,7 @@ struct MathVariants /* Array of offsets to MathGlyphConstruction tables - from the beginning of the MathVariants table, for shapes growing in vertical/horizontal direction. */ - UnsizedArrayOf<OffsetTo<MathGlyphConstruction>> + UnsizedArrayOf<Offset16To<MathGlyphConstruction>> glyphConstruction; public: @@ -711,11 +711,11 @@ struct MATH protected: FixedVersion<>version; /* Version of the MATH table * initially set to 0x00010000u */ - OffsetTo<MathConstants> + Offset16To<MathConstants> mathConstants; /* MathConstants table */ - OffsetTo<MathGlyphInfo> + Offset16To<MathGlyphInfo> mathGlyphInfo; /* MathGlyphInfo table */ - OffsetTo<MathVariants> + Offset16To<MathVariants> mathVariants; /* MathVariants table */ public: diff --git a/thirdparty/harfbuzz/src/hb-ot-math.cc b/thirdparty/harfbuzz/src/hb-ot-math.cc index 9d8c6e735a..5781d25f2a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math.cc +++ b/thirdparty/harfbuzz/src/hb-ot-math.cc @@ -56,7 +56,7 @@ * * Tests whether a face has a `MATH` table. * - * Return value: true if the table is found, false otherwise + * Return value: %true if the table is found, %false otherwise * * Since: 1.3.3 **/ @@ -142,7 +142,7 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, * * Tests whether the given glyph index is an extended shape in the face. * - * Return value: true if the glyph is an extended shape, false otherwise + * Return value: %true if the glyph is an extended shape, %false otherwise * * Since: 1.3.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-math.h b/thirdparty/harfbuzz/src/hb-ot-math.h index ad864a762d..d3ffa19d85 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math.h +++ b/thirdparty/harfbuzz/src/hb-ot-math.h @@ -24,7 +24,7 @@ * Igalia Author(s): Frédéric Wang */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -40,18 +40,89 @@ HB_BEGIN_DECLS * MATH */ +/** + * HB_OT_TAG_MATH: + * + * OpenType [Mathematical Typesetting Table](https://docs.microsoft.com/en-us/typography/opentype/spec/math). + * + * Since: 1.3.3 + */ #define HB_OT_TAG_MATH HB_TAG('M','A','T','H') -/* Use with hb_buffer_set_script() for math shaping. */ +/** + * HB_OT_MATH_SCRIPT: + * + * OpenType script tag for math shaping, for use with + * Use with hb_buffer_set_script(). + * + * Since: 1.3.3 + */ #define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h') /* Types */ /** * hb_ot_math_constant_t: + * @HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN: scriptPercentScaleDown + * @HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN: scriptScriptPercentScaleDown + * @HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT: delimitedSubFormulaMinHeight + * @HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT: displayOperatorMinHeight + * @HB_OT_MATH_CONSTANT_MATH_LEADING: mathLeading + * @HB_OT_MATH_CONSTANT_AXIS_HEIGHT: axisHeight + * @HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT: accentBaseHeight + * @HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT: flattenedAccentBaseHeight + * @HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN: subscriptShiftDown + * @HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX: subscriptTopMax + * @HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN: subscriptBaselineDropMin + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP: superscriptShiftUp + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED: superscriptShiftUpCramped + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN: superscriptBottomMin + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX: superscriptBaselineDropMax + * @HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN: subSuperscriptGapMin + * @HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT: superscriptBottomMaxWithSubscript + * @HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT: spaceAfterScript + * @HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN: upperLimitGapMin + * @HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN: upperLimitBaselineRiseMin + * @HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN: lowerLimitGapMin + * @HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN: lowerLimitBaselineDropMin + * @HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP: stackTopShiftUp + * @HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP: stackTopDisplayStyleShiftUp + * @HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN: stackBottomShiftDown + * @HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN: stackBottomDisplayStyleShiftDown + * @HB_OT_MATH_CONSTANT_STACK_GAP_MIN: stackGapMin + * @HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN: stackDisplayStyleGapMin + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP: stretchStackTopShiftUp + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN: stretchStackBottomShiftDown + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN: stretchStackGapAboveMin + * @HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN: stretchStackGapBelowMin + * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP: fractionNumeratorShiftUp + * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP: fractionNumeratorDisplayStyleShiftUp + * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN: fractionDenominatorShiftDown + * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN: fractionDenominatorDisplayStyleShiftDown + * @HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN: fractionNumeratorGapMin + * @HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN: fractionNumDisplayStyleGapMin + * @HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS: fractionRuleThickness + * @HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN: fractionDenominatorGapMin + * @HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN: fractionDenomDisplayStyleGapMin + * @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP: skewedFractionHorizontalGap + * @HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP: skewedFractionVerticalGap + * @HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP: overbarVerticalGap + * @HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS: overbarRuleThickness + * @HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER: overbarExtraAscender + * @HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP: underbarVerticalGap + * @HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS: underbarRuleThickness + * @HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER: underbarExtraDescender + * @HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP: radicalVerticalGap + * @HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP: radicalDisplayStyleVerticalGap + * @HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS: radicalRuleThickness + * @HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER: radicalExtraAscender + * @HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE: radicalKernBeforeDegree + * @HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE: radicalKernAfterDegree + * @HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT: radicalDegreeBottomRaisePercent * - * The 'MATH' table constants specified at - * https://docs.microsoft.com/en-us/typography/opentype/spec/math + * The 'MATH' table constants, refer to + * [OpenType documentation](https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathconstants-table) + * For more explanations. * * Since: 1.3.3 */ @@ -116,6 +187,10 @@ typedef enum { /** * hb_ot_math_kern_t: + * @HB_OT_MATH_KERN_TOP_RIGHT: The top right corner of the glyph. + * @HB_OT_MATH_KERN_TOP_LEFT: The top left corner of the glyph. + * @HB_OT_MATH_KERN_BOTTOM_RIGHT: The bottom right corner of the glyph. + * @HB_OT_MATH_KERN_BOTTOM_LEFT: The bottom left corner of the glyph. * * The math kerning-table types defined for the four corners * of a glyph. @@ -145,6 +220,8 @@ typedef struct hb_ot_math_glyph_variant_t { /** * hb_ot_math_glyph_part_flags_t: + * @HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER: This is an extender glyph part that + * can be repeated to reach the desired length. * * Flags for math glyph parts. * diff --git a/thirdparty/harfbuzz/src/hb-ot-maxp-table.hh b/thirdparty/harfbuzz/src/hb-ot-maxp-table.hh index 929956d12b..3a019ef782 100644 --- a/thirdparty/harfbuzz/src/hb-ot-maxp-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-maxp-table.hh @@ -107,7 +107,7 @@ struct maxp maxpV1Tail *dest_v1 = c->serializer->embed<maxpV1Tail> (src_v1); if (unlikely (!dest_v1)) return_trace (false); - if (c->plan->drop_hints) + if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING) drop_hint_fields (dest_v1); } diff --git a/thirdparty/harfbuzz/src/hb-ot-meta-table.hh b/thirdparty/harfbuzz/src/hb-ot-meta-table.hh index 1225e26ce1..e31447f8fc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-meta-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-meta-table.hh @@ -56,7 +56,7 @@ struct DataMap protected: Tag tag; /* A tag indicating the type of metadata. */ - LNNOffsetTo<UnsizedArrayOf<HBUINT8>> + NNOffset32To<UnsizedArrayOf<HBUINT8>> dataZ; /* Offset in bytes from the beginning of the * metadata table to the data for this tag. */ HBUINT32 dataLength; /* Length of the data. The data is not required to @@ -113,7 +113,7 @@ struct meta * Offset from the beginning of the table to the data. * Per OT specification: * Reserved. Not used; should be set to 0. */ - LArrayOf<DataMap> + Array32Of<DataMap> dataMaps;/* Array of data map records. */ public: DEFINE_SIZE_ARRAY (16, dataMaps); diff --git a/thirdparty/harfbuzz/src/hb-ot-meta.cc b/thirdparty/harfbuzz/src/hb-ot-meta.cc index 54a0e10f9b..35c8eb523f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-meta.cc +++ b/thirdparty/harfbuzz/src/hb-ot-meta.cc @@ -41,9 +41,11 @@ * hb_ot_meta_get_entry_tags: * @face: a face object * @start_offset: iteration's start offset - * @entries_count:(inout) (allow-none): buffer size as input, filled size as output + * @entries_count:(inout) (optional): buffer size as input, filled size as output * @entries: (out caller-allocates) (array length=entries_count): entries tags buffer * + * Fetches all available feature types. + * * Return value: Number of all available feature types. * * Since: 2.6.0 diff --git a/thirdparty/harfbuzz/src/hb-ot-meta.h b/thirdparty/harfbuzz/src/hb-ot-meta.h index 0278d84148..7748eb4958 100644 --- a/thirdparty/harfbuzz/src/hb-ot-meta.h +++ b/thirdparty/harfbuzz/src/hb-ot-meta.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -54,6 +54,7 @@ typedef enum { HB_OT_META_TAG_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'), HB_OT_META_TAG_SUPPORTED_LANGUAGES = HB_TAG ('s','l','n','g'), + /*< private >*/ _HB_OT_META_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_meta_tag_t; diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc index 3065ea2adf..72aeff82d6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc +++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc @@ -119,11 +119,11 @@ _get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag) /** * hb_ot_metrics_get_position: - * @font: a #hb_font_t object. + * @font: an #hb_font_t object. * @metrics_tag: tag of metrics value you like to fetch. * @position: (out) (optional): result of metrics value from the font. * - * It fetches metrics value corresponding to a given tag from a font. + * Fetches metrics value corresponding to @metrics_tag from @font. * * Returns: Whether found the requested metrics in the font. * Since: 2.6.0 @@ -193,10 +193,13 @@ hb_ot_metrics_get_position (hb_font_t *font, #ifndef HB_NO_VAR /** * hb_ot_metrics_get_variation: - * @font: - * @metrics_tag: + * @font: an #hb_font_t object. + * @metrics_tag: tag of metrics value you like to fetch. + * + * Fetches metrics value corresponding to @metrics_tag from @font with the + * current font variation settings applied. * - * Returns: + * Returns: The requested metric value. * * Since: 2.6.0 **/ @@ -208,10 +211,13 @@ hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag) /** * hb_ot_metrics_get_x_variation: - * @font: - * @metrics_tag: + * @font: an #hb_font_t object. + * @metrics_tag: tag of metrics value you like to fetch. * - * Returns: + * Fetches horizontal metrics value corresponding to @metrics_tag from @font + * with the current font variation settings applied. + * + * Returns: The requested metric value. * * Since: 2.6.0 **/ @@ -223,10 +229,13 @@ hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag) /** * hb_ot_metrics_get_y_variation: - * @font: - * @metrics_tag: + * @font: an #hb_font_t object. + * @metrics_tag: tag of metrics value you like to fetch. + * + * Fetches vertical metrics value corresponding to @metrics_tag from @font with + * the current font variation settings applied. * - * Returns: + * Returns: The requested metric value. * * Since: 2.6.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.h b/thirdparty/harfbuzz/src/hb-ot-metrics.h index 42c7363c03..5841fc8b0f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-metrics.h +++ b/thirdparty/harfbuzz/src/hb-ot-metrics.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -66,7 +66,8 @@ HB_BEGIN_DECLS * @HB_OT_METRICS_TAG_UNDERLINE_SIZE: underline size. * @HB_OT_METRICS_TAG_UNDERLINE_OFFSET: underline offset. * - * From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags + * Metric tags corresponding to [MVAR Value + * Tags](https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags) * * Since: 2.6.0 **/ @@ -100,6 +101,7 @@ typedef enum { HB_OT_METRICS_TAG_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'), HB_OT_METRICS_TAG_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'), + /*< private >*/ _HB_OT_METRICS_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_metrics_tag_t; diff --git a/thirdparty/harfbuzz/src/hb-ot-name-table.hh b/thirdparty/harfbuzz/src/hb-ot-name-table.hh index ece3c28466..c17bb4abb8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-name-table.hh @@ -149,7 +149,7 @@ struct NameRecord HBUINT16 languageID; /* Language ID. */ HBUINT16 nameID; /* Name ID. */ HBUINT16 length; /* String length (in bytes). */ - NNOffsetTo<UnsizedArrayOf<HBUINT8>> + NNOffset16To<UnsizedArrayOf<HBUINT8>> offset; /* String offset from start of storage area (in bytes). */ public: DEFINE_SIZE_STATIC (12); @@ -214,7 +214,7 @@ struct name this->format = 0; this->count = it.len (); - NameRecord *name_records = (NameRecord *) calloc (it.len (), NameRecord::static_size); + NameRecord *name_records = (NameRecord *) hb_calloc (it.len (), NameRecord::static_size); if (unlikely (!name_records)) return_trace (false); hb_array_t<NameRecord> records (name_records, it.len ()); @@ -228,9 +228,10 @@ struct name records.qsort (); c->copy_all (records, src_string_pool); - free (records.arrayZ); + hb_free (records.arrayZ); - if (unlikely (c->ran_out_of_room)) return_trace (false); + + if (unlikely (c->ran_out_of_room ())) return_trace (false); this->stringOffset = c->length (); @@ -248,7 +249,11 @@ struct name + nameRecordZ.as_array (count) | hb_filter (c->plan->name_ids, &NameRecord::nameID) | hb_filter (c->plan->name_languages, &NameRecord::languageID) - | hb_filter ([&] (const NameRecord& namerecord) { return c->plan->name_legacy || namerecord.isUnicode (); }) + | hb_filter ([&] (const NameRecord& namerecord) { + return + (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY) + || namerecord.isUnicode (); + }) ; name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset)); @@ -357,7 +362,7 @@ struct name /* We only implement format 0 for now. */ HBUINT16 format; /* Format selector (=0/1). */ HBUINT16 count; /* Number of name records. */ - NNOffsetTo<UnsizedArrayOf<HBUINT8>> + NNOffset16To<UnsizedArrayOf<HBUINT8>> stringOffset; /* Offset to start of string storage (from start of table). */ UnsizedArrayOf<NameRecord> nameRecordZ; /* The name records where count is the number of records. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-name.cc b/thirdparty/harfbuzz/src/hb-ot-name.cc index 10122b8c2e..eff46ef227 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name.cc +++ b/thirdparty/harfbuzz/src/hb-ot-name.cc @@ -46,7 +46,7 @@ /** * hb_ot_name_list_names: * @face: font face. - * @num_entries: (out) (allow-none): number of returned entries. + * @num_entries: (out) (optional): number of returned entries. * * Enumerates all available name IDs and language combinations. Returned * array is owned by the @face and should not be modified. It can be @@ -150,13 +150,14 @@ hb_ot_name_get_utf (hb_face_t *face, * @face: font face. * @name_id: OpenType name identifier to fetch. * @language: language to fetch the name for. - * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * @text_size: (inout) (optional): input size of @text buffer, and output size of * text written to buffer. * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. * * Fetches a font name from the OpenType 'name' table. * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed. - * Returns string in UTF-8 encoding. + * Returns string in UTF-8 encoding. A NUL terminator is always written + * for convenience, and isn't included in the output @text_size. * * Returns: full length of the requested string, or 0 if not found. * Since: 2.1.0 @@ -177,13 +178,14 @@ hb_ot_name_get_utf8 (hb_face_t *face, * @face: font face. * @name_id: OpenType name identifier to fetch. * @language: language to fetch the name for. - * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * @text_size: (inout) (optional): input size of @text buffer, and output size of * text written to buffer. * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. * * Fetches a font name from the OpenType 'name' table. * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed. - * Returns string in UTF-16 encoding. + * Returns string in UTF-16 encoding. A NUL terminator is always written + * for convenience, and isn't included in the output @text_size. * * Returns: full length of the requested string, or 0 if not found. * Since: 2.1.0 @@ -203,13 +205,14 @@ hb_ot_name_get_utf16 (hb_face_t *face, * @face: font face. * @name_id: OpenType name identifier to fetch. * @language: language to fetch the name for. - * @text_size: (inout) (allow-none): input size of @text buffer, and output size of + * @text_size: (inout) (optional): input size of @text buffer, and output size of * text written to buffer. * @text: (out caller-allocates) (array length=text_size): buffer to write fetched name into. * * Fetches a font name from the OpenType 'name' table. * If @language is #HB_LANGUAGE_INVALID, English ("en") is assumed. - * Returns string in UTF-32 encoding. + * Returns string in UTF-32 encoding. A NUL terminator is always written + * for convenience, and isn't included in the output @text_size. * * Returns: full length of the requested string, or 0 if not found. * Since: 2.1.0 diff --git a/thirdparty/harfbuzz/src/hb-ot-name.h b/thirdparty/harfbuzz/src/hb-ot-name.h index 6f3fcd2427..9359014c8a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name.h +++ b/thirdparty/harfbuzz/src/hb-ot-name.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh index 7d31b712c4..f0035e2f04 100644 --- a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh @@ -30,7 +30,6 @@ #include "hb-open-type.hh" #include "hb-ot-os2-unicode-ranges.hh" -#include "hb-ot-cmap-table.hh" #include "hb-set.hh" @@ -172,34 +171,17 @@ struct OS2 TRACE_SUBSET (this); OS2 *os2_prime = c->serializer->embed (this); if (unlikely (!os2_prime)) return_trace (false); + if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) + return_trace (true); - hb_set_t unicodes; - if (!c->plan->glyphs_requested->is_empty ()) - { - hb_map_t unicode_glyphid_map; - - OT::cmap::accelerator_t cmap; - cmap.init (c->plan->source); - cmap.collect_mapping (&unicodes, &unicode_glyphid_map); - cmap.fini (); - - if (c->plan->unicodes->is_empty ()) unicodes.clear (); - else hb_set_set (&unicodes, c->plan->unicodes); - - + unicode_glyphid_map.iter () - | hb_filter (c->plan->glyphs_requested, hb_second) - | hb_map (hb_first) - | hb_sink (unicodes) - ; - } /* when --gids option is not used, no need to do collect_mapping that is * iterating all codepoints in each subtable, which is not efficient */ uint16_t min_cp, max_cp; - find_min_and_max_codepoint (unicodes.is_empty () ? c->plan->unicodes : &unicodes, &min_cp, &max_cp); + find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp); os2_prime->usFirstCharIndex = min_cp; os2_prime->usLastCharIndex = max_cp; - _update_unicode_ranges (unicodes.is_empty () ? c->plan->unicodes : &unicodes, os2_prime->ulUnicodeRange); + _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange); return_trace (true); } diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh new file mode 100644 index 0000000000..94450eb53a --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh @@ -0,0 +1,130 @@ +/* + * 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_POST_TABLE_V2SUBSET_HH +#define HB_OT_POST_TABLE_V2SUBSET_HH + +#include "hb-open-type.hh" +#include "hb-ot-post-table.hh" + +/* + * post -- PostScript + * https://docs.microsoft.com/en-us/typography/opentype/spec/post + */ + +namespace OT { +template<typename Iterator> +HB_INTERNAL bool postV2Tail::serialize (hb_serialize_context_t *c, + Iterator it, + const void* _post) const +{ + TRACE_SERIALIZE (this); + auto *out = c->start_embed (this); + if (unlikely (!c->check_success (out))) return_trace (false); + if (!out->glyphNameIndex.serialize (c, + it + | hb_map (hb_second))) + return_trace (false); + + hb_set_t copied_indices; + for (const auto& _ : + it ) + { + unsigned glyph_id = _.first; + unsigned new_index = _.second; + + if (new_index < 258) continue; + if (copied_indices.has (new_index)) continue; + copied_indices.add (new_index); + + hb_bytes_t s = reinterpret_cast<const post::accelerator_t*> (_post)->find_glyph_name (glyph_id); + HBUINT8 *o = c->allocate_size<HBUINT8> (HBUINT8::static_size * (s.length + 1)); + if (unlikely (!o)) return_trace (false); + if (!c->check_assign (o[0], s.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); + memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length); + } + + return_trace (true); +} + +HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const +{ + TRACE_SUBSET (this); + + const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map; + unsigned num_glyphs = c->plan->num_output_glyphs (); + hb_map_t old_new_index_map, old_gid_new_index_map; + unsigned i = 0; + + post::accelerator_t _post; + _post.init (c->plan->source); + + for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++) + { + hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid); + unsigned old_index = glyphNameIndex[old_gid]; + + unsigned new_index; + if (old_index <= 257) new_index = old_index; + else if (old_new_index_map.has (old_index)) new_index = old_new_index_map.get (old_index); + 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++) + { + 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; } + old_new_index_map.set (old_index, new_index); + } + old_gid_new_index_map.set (old_gid, new_index); + } + + auto index_iter = + + hb_range (num_glyphs) + | hb_map (reverse_glyph_map) + | hb_map_retains_sorting ([&](hb_codepoint_t old_gid) + { + unsigned new_index = old_gid_new_index_map.get (old_gid); + return hb_pair_t<unsigned, unsigned> (old_gid, new_index); + }) + ; + + bool ret = serialize (c->serializer, index_iter, &_post); + _post.fini (); + return_trace (ret); +} + +} /* namespace OT */ +#endif /* HB_OT_POST_TABLE_V2SUBSET_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index 8586331cd4..39de671707 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -55,8 +55,15 @@ struct postV2Tail return_trace (glyphNameIndex.sanitize (c)); } + template<typename Iterator> + bool serialize (hb_serialize_context_t *c, + Iterator it, + const void* _post) const; + + bool subset (hb_subset_context_t *c) const; + protected: - ArrayOf<HBUINT16> glyphNameIndex; /* This is not an offset, but is the + Array16Of<HBUINT16> glyphNameIndex; /* This is not an offset, but is the * ordinal number of the glyph in 'post' * string tables. */ /*UnsizedArrayOf<HBUINT8> @@ -71,13 +78,18 @@ struct post { static constexpr hb_tag_t tableTag = HB_OT_TAG_post; - void serialize (hb_serialize_context_t *c) const + bool serialize (hb_serialize_context_t *c, bool glyph_names) const { + TRACE_SERIALIZE (this); post *post_prime = c->allocate_min<post> (); - if (unlikely (!post_prime)) return; + if (unlikely (!post_prime)) return_trace (false); memcpy (post_prime, this, post::min_size); - post_prime->version.major = 3; // Version 3 does not have any glyph names. + if (!glyph_names) + return_trace (c->check_assign (post_prime->version.major, 3, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names. + + return_trace (true); } bool subset (hb_subset_context_t *c) const @@ -86,14 +98,19 @@ struct post post *post_prime = c->serializer->start_embed<post> (); if (unlikely (!post_prime)) return_trace (false); - serialize (c->serializer); - if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false); + bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES; + if (!serialize (c->serializer, glyph_names)) + return_trace (false); + + if (glyph_names && version.major == 2) + return_trace (v2X.subset (c)); return_trace (true); } struct accelerator_t { + friend struct postV2Tail; void init (hb_face_t *face) { index_to_offset.init (); @@ -118,7 +135,7 @@ struct post void fini () { index_to_offset.fini (); - free (gids_sorted_by_name.get ()); + hb_free (gids_sorted_by_name.get ()); table.destroy (); } @@ -149,7 +166,7 @@ struct post if (unlikely (!gids)) { - gids = (uint16_t *) malloc (count * sizeof (gids[0])); + gids = (uint16_t *) hb_malloc (count * sizeof (gids[0])); if (unlikely (!gids)) return false; /* Anything better?! */ @@ -159,7 +176,7 @@ struct post if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids))) { - free (gids); + hb_free (gids); goto retry; } } @@ -237,7 +254,7 @@ struct post private: uint32_t version; - const ArrayOf<HBUINT16> *glyphNameIndex; + const Array16Of<HBUINT16> *glyphNameIndex; hb_vector_t<uint32_t> index_to_offset; const uint8_t *pool; hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name; 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 244e967b12..2b3b134ae3 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh @@ -208,11 +208,11 @@ struct ManifestLookup { public: OT::Tag tag; - OT::OffsetTo<OT::SubstLookup> lookupOffset; + OT::Offset16To<OT::SubstLookup> lookupOffset; public: DEFINE_SIZE_STATIC (6); }; -typedef OT::ArrayOf<ManifestLookup> Manifest; +typedef OT::Array16Of<ManifestLookup> Manifest; static bool arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUSED, @@ -290,7 +290,7 @@ static arabic_fallback_plan_t * arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, hb_font_t *font) { - arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t)); + arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_calloc (1, sizeof (arabic_fallback_plan_t)); if (unlikely (!fallback_plan)) return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t)); @@ -308,7 +308,7 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, return fallback_plan; assert (fallback_plan->num_lookups == 0); - free (fallback_plan); + hb_free (fallback_plan); return const_cast<arabic_fallback_plan_t *> (&Null (arabic_fallback_plan_t)); } @@ -323,10 +323,10 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) { fallback_plan->accel_array[i].fini (); if (fallback_plan->free_lookups) - free (fallback_plan->lookup_array[i]); + hb_free (fallback_plan->lookup_array[i]); } - free (fallback_plan); + hb_free (fallback_plan); } static void diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh index c022d4bb06..e6339ee72b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-13.0.0.txt - * # Date: 2020-01-31, 23:55:00 GMT [KW, RP] - * # Scripts-13.0.0.txt - * # Date: 2020-01-22, 00:07:43 GMT + * # ArabicShaping-14.0.0.txt + * # Date: 2021-05-21, 01:54:00 GMT [KW, RP] + * # Scripts-14.0.0.txt + * # Date: 2021-07-10, 00:35:31 GMT */ #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_JOINING_LIST_HH @@ -29,6 +29,7 @@ has_arabic_joining (hb_script_t script) case HB_SCRIPT_MANICHAEAN: case HB_SCRIPT_MONGOLIAN: case HB_SCRIPT_NKO: + case HB_SCRIPT_OLD_UYGHUR: case HB_SCRIPT_PHAGS_PA: case HB_SCRIPT_PSALTER_PAHLAVI: case HB_SCRIPT_SOGDIAN: diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh index 70ffe623c0..c158964f2c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-13.0.0.txt - * # Date: 2020-01-31, 23:55:00 GMT [KW, RP] - * # Blocks-13.0.0.txt - * # Date: 2019-07-10, 19:06:00 GMT [KW] + * # ArabicShaping-14.0.0.txt + * # Date: 2021-05-21, 01:54:00 GMT [KW, RP] + * # Blocks-14.0.0.txt + * # Date: 2021-01-22, 23:29:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -75,13 +75,17 @@ static const uint8_t joining_table[] = /* Syriac Supplement */ - /* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X, + + /* Arabic Extended-B */ + + /* 0860 */ R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R, + /* 0880 */ R,R,R,C,C,C,D,U,U,D,D,D,D,D,R,X,U,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* Arabic Extended-A */ - /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,D,D, - /* 08C0 */ D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,D,D,D,D,R,D,D,D,D,D,D, + /* 08C0 */ D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 08E0 */ X,X,U, #define joining_offset_0x1806u 739 @@ -137,23 +141,28 @@ static const uint8_t joining_table[] = /* Sogdian */ /* 10F20 */ D,D,D,R,D,D,D,D,D,D,D,D,D,D,D,D, - /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R, + /* 10F40 */ D,D,D,D,D,U,X,X,X,X,X,X,X,X,X,X,X,D,D,D,R,X,X,X,X,X,X,X,X,X,X,X, + /* 10F60 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + + /* Old Uyghur */ -#define joining_offset_0x10fb0u 1219 + /* 10F60 */ D,D,D,D,R,R,D,D,D,D,D,D,D,D,D,D, + /* 10F80 */ D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 10FA0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* Chorasmian */ /* 10FA0 */ D,U,D,D,R,R,R,U,D,R,R,D,D,R,D,D, /* 10FC0 */ U,D,R,R,D,U,U,U,U,R,D,L, -#define joining_offset_0x110bdu 1247 +#define joining_offset_0x110bdu 1338 /* Kaithi */ /* 110A0 */ U,X,X, /* 110C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,U, -#define joining_offset_0x1e900u 1264 +#define joining_offset_0x1e900u 1355 /* Adlam */ @@ -161,7 +170,7 @@ static const uint8_t joining_table[] = /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1E940 */ D,D,D,D,X,X,X,X,X,X,X,T, -}; /* Table items: 1340; occupancy: 57% */ +}; /* Table items: 1431; occupancy: 57% */ static unsigned int @@ -189,8 +198,7 @@ joining_type (hb_codepoint_t u) if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u]; if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D23u)) return joining_table[u - 0x10D00u + joining_offset_0x10d00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F54u)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x10FCBu)) return joining_table[u - 0x10FB0u + joining_offset_0x10fb0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10FCBu)) return joining_table[u - 0x10F30u + joining_offset_0x10f30u]; break; case 0x11u: diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh index b15e145f2f..41e3dd38ab 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh @@ -142,7 +142,7 @@ OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \ - /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */ + /* static_assert_expr (len(FromGlyphs) == len(ToGlyphs)) */ #define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \ OT_SUBLOOKUP(Name, 1, \ @@ -151,7 +151,7 @@ OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \ - /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */ + /* static_assert_expr (len(FirstGlyphs) == len(LigatureSetOffsets)) */ #define OT_LIGATURE_SET(Name, LigatureSetOffsets) \ OT_UARRAY(Name, OT_LIST(LigatureSetOffsets)) diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc index 1e93f0efd5..1f8c1410fc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc @@ -33,7 +33,7 @@ /* buffer var allocations */ -#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ +#define arabic_shaping_action() complex_var_u8_auxiliary() /* arabic shaping action */ #define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 @@ -259,7 +259,7 @@ struct arabic_shape_plan_t void * data_create_arabic (const hb_ot_shape_plan_t *plan) { - arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t)); + arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) hb_calloc (1, sizeof (arabic_shape_plan_t)); if (unlikely (!arabic_plan)) return nullptr; @@ -282,7 +282,7 @@ data_destroy_arabic (void *data) arabic_fallback_plan_destroy (arabic_plan->fallback_plan); - free (data); + hb_free (data); } static void diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc index f5915f43ae..0d84a76b85 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc @@ -80,7 +80,7 @@ struct hangul_shape_plan_t static void * data_create_hangul (const hb_ot_shape_plan_t *plan) { - hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t)); + hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) hb_calloc (1, sizeof (hangul_shape_plan_t)); if (unlikely (!hangul_plan)) return nullptr; @@ -93,7 +93,7 @@ data_create_hangul (const hb_ot_shape_plan_t *plan) static void data_destroy_hangul (void *data) { - free (data); + hb_free (data); } /* Constants for algorithmic hangul syllable [de]composition. */ @@ -119,7 +119,7 @@ data_destroy_hangul (void *data) #define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu)) /* buffer var allocations */ -#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */ +#define hangul_shaping_feature() complex_var_u8_auxiliary() /* hangul jamo shaping feature */ static bool is_zero_width_char (hb_font_t *font, @@ -205,7 +205,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, { /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */ buffer->unsafe_to_break_from_outbuffer (start, buffer->idx); - buffer->next_glyph (); + if (unlikely (!buffer->next_glyph ())) break; if (!is_zero_width_char (font, u)) { buffer->merge_out_clusters (start, end + 1); @@ -218,23 +218,25 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, else { /* No valid syllable as base for tone mark; try to insert dotted circle. */ - if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) && - font->has_glyph (0x25CCu)) + if (!(buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE) && + font->has_glyph (0x25CCu)) { hb_codepoint_t chars[2]; - if (!is_zero_width_char (font, u)) { + if (!is_zero_width_char (font, u)) + { chars[0] = u; chars[1] = 0x25CCu; - } else { + } else + { chars[0] = 0x25CCu; chars[1] = u; } - buffer->replace_glyphs (1, 2, chars); + (void) buffer->replace_glyphs (1, 2, chars); } else { /* No dotted circle available in the font; just leave tone mark untouched. */ - buffer->next_glyph (); + (void) buffer->next_glyph (); } } start = end = buffer->out_len; @@ -271,9 +273,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex; if (font->has_glyph (s)) { - buffer->replace_glyphs (t ? 3 : 2, 1, &s); - if (unlikely (!buffer->successful)) - return; + (void) buffer->replace_glyphs (t ? 3 : 2, 1, &s); end = start + 1; continue; } @@ -285,17 +285,19 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, * Set jamo features on the individual glyphs, and advance past them. */ buffer->cur().hangul_shaping_feature() = LJMO; - buffer->next_glyph (); + (void) buffer->next_glyph (); buffer->cur().hangul_shaping_feature() = VJMO; - buffer->next_glyph (); + (void) buffer->next_glyph (); if (t) { buffer->cur().hangul_shaping_feature() = TJMO; - buffer->next_glyph (); + (void) buffer->next_glyph (); end = start + 3; } else end = start + 2; + if (unlikely (!buffer->successful)) + break; if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) buffer->merge_out_clusters (start, end); continue; @@ -321,9 +323,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t new_s = s + new_tindex; if (font->has_glyph (new_s)) { - buffer->replace_glyphs (2, 1, &new_s); - if (unlikely (!buffer->successful)) - return; + (void) buffer->replace_glyphs (2, 1, &new_s); end = start + 1; continue; } @@ -347,19 +347,18 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, (!tindex || font->has_glyph (decomposed[2]))) { unsigned int s_len = tindex ? 3 : 2; - buffer->replace_glyphs (1, s_len, decomposed); + (void) buffer->replace_glyphs (1, s_len, decomposed); /* If we decomposed an LV because of a non-combining T following, * we want to include this T in the syllable. */ if (has_glyph && !tindex) { - buffer->next_glyph (); + (void) buffer->next_glyph (); s_len++; } - if (unlikely (!buffer->successful)) - return; + break; /* We decomposed S: apply jamo features to the individual glyphs * that are now in buffer->out_info. @@ -383,17 +382,15 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED, if (has_glyph) { - /* We didn't decompose the S, so just advance past it. */ + /* We didn't decompose the S, so just advance past it and fall through. */ end = start + 1; - buffer->next_glyph (); - continue; } } /* Didn't find a recognizable syllable, so we leave end <= start; * this will prevent tone-mark reordering happening. */ - buffer->next_glyph (); + (void) buffer->next_glyph (); } buffer->swap_buffers (); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh index 670b6bf486..74bf3ca0fa 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh @@ -31,8 +31,37 @@ #include "hb.hh" +enum indic_syllable_type_t { + indic_consonant_syllable, + indic_vowel_syllable, + indic_standalone_cluster, + indic_symbol_cluster, + indic_broken_cluster, + indic_non_indic_cluster, +}; + -#line 36 "hb-ot-shape-complex-indic-machine.hh" +#line 45 "hb-ot-shape-complex-indic-machine.hh" +#define indic_syllable_machine_ex_A 10u +#define indic_syllable_machine_ex_C 1u +#define indic_syllable_machine_ex_CM 17u +#define indic_syllable_machine_ex_CS 19u +#define indic_syllable_machine_ex_DOTTEDCIRCLE 12u +#define indic_syllable_machine_ex_H 4u +#define indic_syllable_machine_ex_M 7u +#define indic_syllable_machine_ex_N 3u +#define indic_syllable_machine_ex_PLACEHOLDER 11u +#define indic_syllable_machine_ex_RS 13u +#define indic_syllable_machine_ex_Ra 16u +#define indic_syllable_machine_ex_Repha 15u +#define indic_syllable_machine_ex_SM 8u +#define indic_syllable_machine_ex_Symbol 18u +#define indic_syllable_machine_ex_V 2u +#define indic_syllable_machine_ex_ZWJ 6u +#define indic_syllable_machine_ex_ZWNJ 5u + + +#line 65 "hb-ot-shape-complex-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, @@ -384,18 +413,18 @@ static const int indic_syllable_machine_error = -1; static const int indic_syllable_machine_en_main = 39; -#line 36 "hb-ot-shape-complex-indic-machine.rl" +#line 46 "hb-ot-shape-complex-indic-machine.rl" -#line 93 "hb-ot-shape-complex-indic-machine.rl" +#line 102 "hb-ot-shape-complex-indic-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -407,7 +436,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 411 "hb-ot-shape-complex-indic-machine.hh" +#line 440 "hb-ot-shape-complex-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -415,7 +444,7 @@ find_syllables_indic (hb_buffer_t *buffer) act = 0; } -#line 113 "hb-ot-shape-complex-indic-machine.rl" +#line 122 "hb-ot-shape-complex-indic-machine.rl" p = 0; @@ -423,7 +452,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 427 "hb-ot-shape-complex-indic-machine.hh" +#line 456 "hb-ot-shape-complex-indic-machine.hh" { int _slen; int _trans; @@ -437,7 +466,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 441 "hb-ot-shape-complex-indic-machine.hh" +#line 470 "hb-ot-shape-complex-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -460,64 +489,64 @@ _eof_trans: {te = p+1;} break; case 11: -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {te = p+1;{ found_syllable (non_indic_cluster); }} +#line 98 "hb-ot-shape-complex-indic-machine.rl" + {te = p+1;{ found_syllable (indic_non_indic_cluster); }} break; case 13: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_consonant_syllable); }} break; case 14: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (vowel_syllable); }} +#line 94 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_vowel_syllable); }} break; case 17: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (standalone_cluster); }} +#line 95 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_standalone_cluster); }} break; case 19: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} +#line 96 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_symbol_cluster); }} break; case 15: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} +#line 97 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_broken_cluster); }} break; case 16: -#line 89 "hb-ot-shape-complex-indic-machine.rl" - {te = p;p--;{ found_syllable (non_indic_cluster); }} +#line 98 "hb-ot-shape-complex-indic-machine.rl" + {te = p;p--;{ found_syllable (indic_non_indic_cluster); }} break; case 1: -#line 84 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} break; case 3: -#line 85 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (vowel_syllable); }} +#line 94 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} break; case 7: -#line 86 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (standalone_cluster); }} +#line 95 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} break; case 8: -#line 87 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (symbol_cluster); }} +#line 96 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} break; case 4: -#line 88 "hb-ot-shape-complex-indic-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} +#line 97 "hb-ot-shape-complex-indic-machine.rl" + {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }} break; case 6: #line 1 "NONE" { switch( act ) { case 1: - {{p = ((te))-1;} found_syllable (consonant_syllable); } + {{p = ((te))-1;} found_syllable (indic_consonant_syllable); } break; case 5: - {{p = ((te))-1;} found_syllable (broken_cluster); } + {{p = ((te))-1;} found_syllable (indic_broken_cluster); } break; case 6: - {{p = ((te))-1;} found_syllable (non_indic_cluster); } + {{p = ((te))-1;} found_syllable (indic_non_indic_cluster); } break; } } @@ -525,22 +554,22 @@ _eof_trans: case 18: #line 1 "NONE" {te = p+1;} -#line 84 "hb-ot-shape-complex-indic-machine.rl" +#line 93 "hb-ot-shape-complex-indic-machine.rl" {act = 1;} break; case 5: #line 1 "NONE" {te = p+1;} -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 97 "hb-ot-shape-complex-indic-machine.rl" {act = 5;} break; case 12: #line 1 "NONE" {te = p+1;} -#line 89 "hb-ot-shape-complex-indic-machine.rl" +#line 98 "hb-ot-shape-complex-indic-machine.rl" {act = 6;} break; -#line 544 "hb-ot-shape-complex-indic-machine.hh" +#line 573 "hb-ot-shape-complex-indic-machine.hh" } _again: @@ -549,7 +578,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 553 "hb-ot-shape-complex-indic-machine.hh" +#line 582 "hb-ot-shape-complex-indic-machine.hh" } if ( ++p != pe ) @@ -565,7 +594,7 @@ _again: } -#line 121 "hb-ot-shape-complex-indic-machine.rl" +#line 130 "hb-ot-shape-complex-indic-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc index a150fd2486..326aa9f96e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-13.0.0.txt - * # Date: 2019-07-22, 19:55:00 GMT [KW, RP] - * # IndicPositionalCategory-13.0.0.txt - * # Date: 2019-07-23, 00:01:00 GMT [KW, RP] - * # Blocks-13.0.0.txt - * # Date: 2019-07-10, 19:06:00 GMT [KW] + * # IndicSyllabicCategory-14.0.0.txt + * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] + * # IndicPositionalCategory-14.0.0.txt + * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] + * # Blocks-14.0.0.txt + * # Date: 2021-01-22, 23:29:00 GMT [KW] */ #include "hb.hh" @@ -27,9 +27,9 @@ #define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 91 chars; Bindu */ #define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ #define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 59 chars; Cantillation_Mark */ -#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2195 chars; Consonant */ -#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 12 chars; Consonant_Dead */ -#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 67 chars; Consonant_Final */ +#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2206 chars; Consonant */ +#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 14 chars; Consonant_Dead */ +#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 70 chars; Consonant_Final */ #define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ #define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */ #define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ @@ -38,18 +38,18 @@ #define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 3 chars; Consonant_Preceding_Repha */ #define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 10 chars; Consonant_Prefixed */ #define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 94 chars; Consonant_Subjoined */ -#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ +#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 1 chars; Consonant_Succeeding_Repha */ #define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 8 chars; Consonant_With_Stacker */ #define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */ #define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 12 chars; Invisible_Stacker */ #define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ #define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ #define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ -#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 31 chars; Nukta */ +#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 32 chars; Nukta */ #define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 491 chars; Number */ #define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ #define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ -#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 23 chars; Pure_Killer */ +#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 25 chars; Pure_Killer */ #define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ #define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */ #define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ @@ -57,18 +57,18 @@ #define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 27 chars; Virama */ #define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 35 chars; Visarga */ #define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ -#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 683 chars; Vowel_Dependent */ -#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 484 chars; Vowel_Independent */ +#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 686 chars; Vowel_Dependent */ +#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 486 chars; Vowel_Independent */ -#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 351 chars; Bottom */ +#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 352 chars; Bottom */ #define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */ #define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 4 chars; Bottom_And_Right */ #define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 64 chars; Left */ #define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 22 chars; Left_And_Right */ #define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ #define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ -#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 288 chars; Right */ -#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 415 chars; Top */ +#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 290 chars; Right */ +#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 418 chars; Top */ #define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ #define IMC_TBL INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_LEFT /* 2 chars; Top_And_Bottom_And_Left */ #define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ @@ -82,7 +82,7 @@ #define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M) -static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { +static const uint16_t indic_table[] = { #define indic_offset_0x0028u 0 @@ -231,11 +231,11 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(A,x), _(M,T), _(M,T), + /* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,T), _(M,T), /* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T), /* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x), /* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x), - /* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(CD,x), _(x,x), _(x,x), /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), @@ -254,7 +254,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR), /* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x), /* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), - /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x), + /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(C,x), _(x,x), /* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), @@ -402,9 +402,9 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x), -}; /* Table items: 1792; occupancy: 70% */ +}; /* Table items: 1792; occupancy: 71% */ -INDIC_TABLE_ELEMENT_TYPE +uint16_t hb_indic_get_categories (hb_codepoint_t u) { switch (u >> 12) diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc index 652ef47040..0983a32848 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.cc @@ -29,6 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-complex-indic.hh" +#include "hb-ot-shape-complex-indic-machine.hh" #include "hb-ot-shape-complex-vowel-constraints.hh" #include "hb-ot-layout.hh" @@ -105,7 +106,8 @@ indic_features[] = { /* * Basic features. - * These features are applied in order, one at a time, after initial_reordering. + * These features are applied in order, one at a time, after initial_reordering, + * constrained to the syllable. */ {HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS}, {HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS}, @@ -120,8 +122,8 @@ indic_features[] = {HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS}, /* * Other features. - * These features are applied all at once, after final_reordering - * but before clearing syllables. + * These features are applied all at once, after final_reordering, constrained + * to the syllable. * Default Bengali font in Windows for example has intermixed * lookups for init,pres,abvs,blws features. */ @@ -256,7 +258,7 @@ struct indic_shape_plan_t static void * data_create_indic (const hb_ot_shape_plan_t *plan) { - indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t)); + indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) hb_calloc (1, sizeof (indic_shape_plan_t)); if (unlikely (!indic_plan)) return nullptr; @@ -299,7 +301,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan) static void data_destroy_indic (void *data) { - free (data); + hb_free (data); } static indic_position_t @@ -337,19 +339,6 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan, return POS_BASE_C; } - -enum indic_syllable_type_t { - indic_consonant_syllable, - indic_vowel_syllable, - indic_standalone_cluster, - indic_symbol_cluster, - indic_broken_cluster, - indic_non_indic_cluster, -}; - -#include "hb-ot-shape-complex-indic-machine.hh" - - static void setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, @@ -764,7 +753,28 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * We could use buffer->sort() for this, if there was no special * reordering of pre-base stuff happening later... * We don't want to merge_clusters all of that, which buffer->sort() - * would. + * would. Here's a concrete example: + * + * Assume there's a pre-base consonant and explicit Halant before base, + * followed by a prebase-reordering (left) Matra: + * + * C,H,ZWNJ,B,M + * + * At this point in reordering we would have: + * + * M,C,H,ZWNJ,B + * + * whereas in final reordering we will bring the Matra closer to Base: + * + * C,H,ZWNJ,M,B + * + * That's why we don't want to merge-clusters anything before the Base + * at this point. But if something moved from after Base to before it, + * we should merge clusters from base to them. In final-reordering, we + * only move things around before base, and merge-clusters up to base. + * These two merge-clusters from the two sides of base will interlock + * to merge things correctly. See: + * https://github.com/harfbuzz/harfbuzz/issues/2272 */ if (indic_plan->is_old_spec || end - start > 127) buffer->merge_clusters (base, end); @@ -774,17 +784,18 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, for (unsigned int i = base; i < end; i++) if (info[i].syllable() != 255) { + unsigned int min = i; unsigned int max = i; unsigned int j = start + info[i].syllable(); while (j != i) { + min = hb_min (min, j); max = hb_max (max, j); unsigned int next = start + info[j].syllable(); info[j].syllable() = 255; /* So we don't process j later again. */ j = next; } - if (i != max) - buffer->merge_clusters (i, max + 1); + buffer->merge_clusters (hb_max (base, min), max + 1); } } @@ -938,69 +949,6 @@ initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan, } } -static inline void -insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == indic_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_indic_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && buffer->successful && - last_syllable == buffer->cur().syllable() && - buffer->cur().indic_category() == OT_Repha) - buffer->next_glyph (); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void initial_reordering_indic (const hb_ot_shape_plan_t *plan, hb_font_t *font, @@ -1008,11 +956,17 @@ initial_reordering_indic (const hb_ot_shape_plan_t *plan, { if (!buffer->message (font, "start reordering indic initial")) return; + update_consonant_positions_indic (plan, font, buffer); - insert_dotted_circles_indic (plan, font, buffer); + hb_syllabic_insert_dotted_circles (font, buffer, + indic_broken_cluster, + OT_DOTTEDCIRCLE, + OT_Repha, + POS_END); foreach_syllable (buffer, start, end) initial_reordering_syllable_indic (plan, font->face, buffer, start, end); + (void) buffer->message (font, "end reordering indic initial"); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh index 41bd8bd6cc..dcb28a4e84 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic.hh @@ -29,16 +29,14 @@ #include "hb.hh" -#include "hb-ot-shape-complex.hh" +#include "hb-ot-shape-complex-syllabic.hh" /* buffer var allocations */ -#define indic_category() complex_var_u8_0() /* indic_category_t */ -#define indic_position() complex_var_u8_1() /* indic_position_t */ +#define indic_category() complex_var_u8_category() /* indic_category_t */ +#define indic_position() complex_var_u8_auxiliary() /* indic_position_t */ -#define INDIC_TABLE_ELEMENT_TYPE uint16_t - /* Cateories used in the OpenType spec: * https://docs.microsoft.com/en-us/typography/script-development/devanagari */ @@ -177,7 +175,7 @@ enum indic_matra_category_t { #define INDIC_COMBINE_CATEGORIES(S,M) \ ( \ - ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \ + static_assert_expr (S < 255 && M < 255) + \ ( S | \ ( \ ( \ @@ -194,7 +192,7 @@ enum indic_matra_category_t { ) \ ) -HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE +HB_INTERNAL uint16_t hb_indic_get_categories (hb_codepoint_t u); @@ -307,17 +305,12 @@ static const hb_codepoint_t ra_chars[] = { 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ - - 0x179Au, /* Khmer */ }; static inline bool is_ra (hb_codepoint_t u) { - for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) - if (u == ra_chars[i]) - return true; - return false; + return hb_array (ra_chars).lfind (u); } static inline void @@ -325,7 +318,7 @@ set_indic_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_category_t cat = (indic_category_t) (type & 0xFFu); indic_position_t pos = (indic_position_t) (type >> 8); @@ -370,6 +363,7 @@ set_indic_properties (hb_glyph_info_t &info) else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N; else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */ + else if (unlikely (u == 0x0B55u)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/2849 */ else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */ else if (unlikely (u == 0x09FCu)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/1613 */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh index a040318d34..c52f72f394 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh @@ -31,8 +31,32 @@ #include "hb.hh" +enum khmer_syllable_type_t { + khmer_consonant_syllable, + khmer_broken_cluster, + khmer_non_khmer_cluster, +}; + -#line 36 "hb-ot-shape-complex-khmer-machine.hh" +#line 42 "hb-ot-shape-complex-khmer-machine.hh" +#define khmer_syllable_machine_ex_C 1u +#define khmer_syllable_machine_ex_Coeng 14u +#define khmer_syllable_machine_ex_DOTTEDCIRCLE 12u +#define khmer_syllable_machine_ex_PLACEHOLDER 11u +#define khmer_syllable_machine_ex_Ra 16u +#define khmer_syllable_machine_ex_Robatic 20u +#define khmer_syllable_machine_ex_V 2u +#define khmer_syllable_machine_ex_VAbv 26u +#define khmer_syllable_machine_ex_VBlw 27u +#define khmer_syllable_machine_ex_VPre 28u +#define khmer_syllable_machine_ex_VPst 29u +#define khmer_syllable_machine_ex_Xgroup 21u +#define khmer_syllable_machine_ex_Ygroup 22u +#define khmer_syllable_machine_ex_ZWJ 6u +#define khmer_syllable_machine_ex_ZWNJ 5u + + +#line 60 "hb-ot-shape-complex-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, @@ -215,18 +239,18 @@ static const int khmer_syllable_machine_error = -1; static const int khmer_syllable_machine_en_main = 20; -#line 36 "hb-ot-shape-complex-khmer-machine.rl" +#line 43 "hb-ot-shape-complex-khmer-machine.rl" -#line 80 "hb-ot-shape-complex-khmer-machine.rl" +#line 86 "hb-ot-shape-complex-khmer-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -238,7 +262,7 @@ find_syllables_khmer (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 242 "hb-ot-shape-complex-khmer-machine.hh" +#line 266 "hb-ot-shape-complex-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -246,7 +270,7 @@ find_syllables_khmer (hb_buffer_t *buffer) act = 0; } -#line 100 "hb-ot-shape-complex-khmer-machine.rl" +#line 106 "hb-ot-shape-complex-khmer-machine.rl" p = 0; @@ -254,7 +278,7 @@ find_syllables_khmer (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 258 "hb-ot-shape-complex-khmer-machine.hh" +#line 282 "hb-ot-shape-complex-khmer-machine.hh" { int _slen; int _trans; @@ -268,7 +292,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 272 "hb-ot-shape-complex-khmer-machine.hh" +#line 296 "hb-ot-shape-complex-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -291,37 +315,37 @@ _eof_trans: {te = p+1;} break; case 8: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (non_khmer_cluster); }} +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ found_syllable (khmer_non_khmer_cluster); }} break; case 10: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p--;{ found_syllable (khmer_consonant_syllable); }} break; case 12: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p--;{ found_syllable (khmer_broken_cluster); }} break; case 11: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (non_khmer_cluster); }} +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p--;{ found_syllable (khmer_non_khmer_cluster); }} break; case 1: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + {{p = ((te))-1;}{ found_syllable (khmer_consonant_syllable); }} break; case 5: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {{p = ((te))-1;}{ found_syllable (khmer_broken_cluster); }} break; case 3: #line 1 "NONE" { switch( act ) { case 2: - {{p = ((te))-1;} found_syllable (broken_cluster); } + {{p = ((te))-1;} found_syllable (khmer_broken_cluster); } break; case 3: - {{p = ((te))-1;} found_syllable (non_khmer_cluster); } + {{p = ((te))-1;} found_syllable (khmer_non_khmer_cluster); } break; } } @@ -329,16 +353,16 @@ _eof_trans: case 4: #line 1 "NONE" {te = p+1;} -#line 75 "hb-ot-shape-complex-khmer-machine.rl" +#line 81 "hb-ot-shape-complex-khmer-machine.rl" {act = 2;} break; case 9: #line 1 "NONE" {te = p+1;} -#line 76 "hb-ot-shape-complex-khmer-machine.rl" +#line 82 "hb-ot-shape-complex-khmer-machine.rl" {act = 3;} break; -#line 342 "hb-ot-shape-complex-khmer-machine.hh" +#line 366 "hb-ot-shape-complex-khmer-machine.hh" } _again: @@ -347,7 +371,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 351 "hb-ot-shape-complex-khmer-machine.hh" +#line 375 "hb-ot-shape-complex-khmer-machine.hh" } if ( ++p != pe ) @@ -363,7 +387,7 @@ _again: } -#line 108 "hb-ot-shape-complex-khmer-machine.rl" +#line 114 "hb-ot-shape-complex-khmer-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.rl b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.rl deleted file mode 100644 index e7f14533dd..0000000000 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.rl +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH - -#include "hb.hh" - -%%{ - machine khmer_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum khmer_category_t. Not sure how to avoid duplication. -C = 1; -V = 2; -ZWNJ = 5; -ZWJ = 6; -PLACEHOLDER = 11; -DOTTEDCIRCLE = 12; -Coeng= 14; -Ra = 16; -Robatic = 20; -Xgroup = 21; -Ygroup = 22; -VAbv = 26; -VBlw = 27; -VPre = 28; -VPst = 29; - -c = (C | Ra | V); -cn = c.((ZWJ|ZWNJ)?.Robatic)?; -joiner = (ZWJ | ZWNJ); -xgroup = (joiner*.Xgroup)*; -ygroup = Ygroup*; - -# This grammar was experimentally extracted from what Uniscribe allows. - -matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?; -syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup; - - -broken_cluster = (Coeng.cn)* (Coeng | syllable_tail); -consonant_syllable = (cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster; -other = any; - -main := |* - consonant_syllable => { found_syllable (consonant_syllable); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_khmer_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ - for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables_khmer (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].khmer_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc index d6fcd7c814..7787886857 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.cc @@ -29,6 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-complex-khmer.hh" +#include "hb-ot-shape-complex-khmer-machine.hh" #include "hb-ot-layout.hh" @@ -41,7 +42,8 @@ khmer_features[] = { /* * Basic features. - * These features are applied in order, one at a time, after reordering. + * These features are applied all at once, before reordering, constrained + * to the syllable. */ {HB_TAG('p','r','e','f'), F_MANUAL_JOINERS}, {HB_TAG('b','l','w','f'), F_MANUAL_JOINERS}, @@ -140,39 +142,16 @@ override_features_khmer (hb_ot_shape_planner_t *plan) struct khmer_shape_plan_t { - bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const - { - hb_codepoint_t glyph = virama_glyph; - if (unlikely (virama_glyph == (hb_codepoint_t) -1)) - { - if (!font->get_nominal_glyph (0x17D2u, &glyph)) - glyph = 0; - /* Technically speaking, the spec says we should apply 'locl' to virama too. - * Maybe one day... */ - - /* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph - * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */ - virama_glyph = glyph; - } - - *pglyph = glyph; - return glyph != 0; - } - - mutable hb_codepoint_t virama_glyph; - hb_mask_t mask_array[KHMER_NUM_FEATURES]; }; static void * data_create_khmer (const hb_ot_shape_plan_t *plan) { - khmer_shape_plan_t *khmer_plan = (khmer_shape_plan_t *) calloc (1, sizeof (khmer_shape_plan_t)); + khmer_shape_plan_t *khmer_plan = (khmer_shape_plan_t *) hb_calloc (1, sizeof (khmer_shape_plan_t)); if (unlikely (!khmer_plan)) return nullptr; - khmer_plan->virama_glyph = (hb_codepoint_t) -1; - for (unsigned int i = 0; i < ARRAY_LENGTH (khmer_plan->mask_array); i++) khmer_plan->mask_array[i] = (khmer_features[i].flags & F_GLOBAL) ? 0 : plan->map.get_1_mask (khmer_features[i].tag); @@ -183,18 +162,9 @@ data_create_khmer (const hb_ot_shape_plan_t *plan) static void data_destroy_khmer (void *data) { - free (data); + hb_free (data); } - -enum khmer_syllable_type_t { - khmer_consonant_syllable, - khmer_broken_cluster, - khmer_non_khmer_cluster, -}; - -#include "hb-ot-shape-complex-khmer-machine.hh" - static void setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, @@ -321,76 +291,17 @@ reorder_syllable_khmer (const hb_ot_shape_plan_t *plan, } } -static inline void -insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == khmer_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_khmer_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && buffer->successful && - last_syllable == buffer->cur().syllable() && - buffer->cur().khmer_category() == OT_Repha) - buffer->next_glyph (); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void reorder_khmer (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - if (buffer->message (font, "start reordering khmer")) { - insert_dotted_circles_khmer (plan, font, buffer); + if (buffer->message (font, "start reordering khmer")) + { + hb_syllabic_insert_dotted_circles (font, buffer, + khmer_broken_cluster, + OT_DOTTEDCIRCLE, + OT_Repha); foreach_syllable (buffer, start, end) reorder_syllable_khmer (plan, font->face, buffer, start, end); diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh index 11a77bfd4b..e24d68a8b5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer.hh @@ -54,7 +54,7 @@ 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 & 0x7Fu); + khmer_category_t cat = (khmer_category_t) (type & 0xFFu); indic_position_t pos = (indic_position_t) (type >> 8); diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh deleted file mode 100644 index 9ec1f3eb7c..0000000000 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-machine-index.hh +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright © 2019,2020 David Corbett - * - * 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_SHAPE_COMPLEX_MACHINE_INDEX_HH -#define HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH - -#include "hb.hh" - - -template <typename Iter> -struct machine_index_t : - hb_iter_with_fallback_t<machine_index_t<Iter>, - typename Iter::item_t> -{ - machine_index_t (const Iter& it) : it (it) {} - machine_index_t (const machine_index_t& o) : it (o.it) {} - - static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; - - typename Iter::item_t __item__ () const { return *it; } - typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } - unsigned __len__ () const { return it.len (); } - void __next__ () { ++it; } - void __forward__ (unsigned n) { it += n; } - void __prev__ () { --it; } - void __rewind__ (unsigned n) { it -= n; } - void operator = (unsigned n) - { unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; } - void operator = (const machine_index_t& o) { *this = (*o.it).first; } - bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; } - bool operator != (const machine_index_t& o) const { return !(*this == o); } - - private: - Iter it; -}; -struct -{ - template <typename Iter, - hb_requires (hb_is_iterable (Iter))> - machine_index_t<hb_iter_type<Iter>> - operator () (Iter&& it) const - { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } -} -HB_FUNCOBJ (machine_index); - - -#endif /* HB_OT_SHAPE_COMPLEX_MACHINE_INDEX_HH */ 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 c2f4c0045c..c09497896d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh @@ -31,8 +31,43 @@ #include "hb.hh" +enum myanmar_syllable_type_t { + myanmar_consonant_syllable, + myanmar_punctuation_cluster, + myanmar_broken_cluster, + myanmar_non_myanmar_cluster, +}; + -#line 36 "hb-ot-shape-complex-myanmar-machine.hh" +#line 43 "hb-ot-shape-complex-myanmar-machine.hh" +#define myanmar_syllable_machine_ex_A 10u +#define myanmar_syllable_machine_ex_As 18u +#define myanmar_syllable_machine_ex_C 1u +#define myanmar_syllable_machine_ex_CS 19u +#define myanmar_syllable_machine_ex_D 32u +#define myanmar_syllable_machine_ex_D0 20u +#define myanmar_syllable_machine_ex_DB 3u +#define myanmar_syllable_machine_ex_GB 11u +#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_MR 22u +#define myanmar_syllable_machine_ex_MW 23u +#define myanmar_syllable_machine_ex_MY 24u +#define myanmar_syllable_machine_ex_P 31u +#define myanmar_syllable_machine_ex_PT 25u +#define myanmar_syllable_machine_ex_Ra 16u +#define myanmar_syllable_machine_ex_V 8u +#define myanmar_syllable_machine_ex_VAbv 26u +#define myanmar_syllable_machine_ex_VBlw 27u +#define myanmar_syllable_machine_ex_VPre 28u +#define myanmar_syllable_machine_ex_VPst 29u +#define myanmar_syllable_machine_ex_VS 30u +#define myanmar_syllable_machine_ex_ZWJ 6u +#define myanmar_syllable_machine_ex_ZWNJ 5u + + +#line 71 "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, @@ -293,18 +328,18 @@ static const int myanmar_syllable_machine_error = -1; static const int myanmar_syllable_machine_en_main = 0; -#line 36 "hb-ot-shape-complex-myanmar-machine.rl" +#line 44 "hb-ot-shape-complex-myanmar-machine.rl" -#line 94 "hb-ot-shape-complex-myanmar-machine.rl" +#line 101 "hb-ot-shape-complex-myanmar-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ for (unsigned int i = ts; i < te; i++) \ - info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END @@ -316,7 +351,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 320 "hb-ot-shape-complex-myanmar-machine.hh" +#line 355 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -324,7 +359,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) act = 0; } -#line 114 "hb-ot-shape-complex-myanmar-machine.rl" +#line 121 "hb-ot-shape-complex-myanmar-machine.rl" p = 0; @@ -332,7 +367,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 336 "hb-ot-shape-complex-myanmar-machine.hh" +#line 371 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -346,7 +381,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 350 "hb-ot-shape-complex-myanmar-machine.hh" +#line 385 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -365,38 +400,38 @@ _eof_trans: switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { case 6: -#line 86 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_consonant_syllable); }} break; case 4: -#line 87 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (non_myanmar_cluster); }} +#line 94 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; case 10: -#line 88 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (punctuation_cluster); }} +#line 95 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_punctuation_cluster); }} break; case 8: -#line 89 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} +#line 96 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_broken_cluster); }} break; case 3: -#line 90 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p+1;{ found_syllable (non_myanmar_cluster); }} +#line 97 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} break; case 5: -#line 86 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} +#line 93 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} break; case 7: -#line 89 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} +#line 96 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_broken_cluster); }} break; case 9: -#line 90 "hb-ot-shape-complex-myanmar-machine.rl" - {te = p;p--;{ found_syllable (non_myanmar_cluster); }} +#line 97 "hb-ot-shape-complex-myanmar-machine.rl" + {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 400 "hb-ot-shape-complex-myanmar-machine.hh" +#line 435 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -405,7 +440,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 409 "hb-ot-shape-complex-myanmar-machine.hh" +#line 444 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe ) @@ -421,7 +456,7 @@ _again: } -#line 122 "hb-ot-shape-complex-myanmar-machine.rl" +#line 129 "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 fe096ef28a..6e92a9b0ae 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.cc @@ -29,6 +29,7 @@ #ifndef HB_NO_OT_SHAPE #include "hb-ot-shape-complex-myanmar.hh" +#include "hb-ot-shape-complex-myanmar-machine.hh" /* @@ -40,7 +41,8 @@ myanmar_basic_features[] = { /* * Basic features. - * These features are applied in order, one at a time, after reordering. + * These features are applied in order, one at a time, after reordering, + * constrained to the syllable. */ HB_TAG('r','p','h','f'), HB_TAG('p','r','e','f'), @@ -97,17 +99,6 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan) map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ); } - -enum myanmar_syllable_type_t { - myanmar_consonant_syllable, - myanmar_punctuation_cluster, - myanmar_broken_cluster, - myanmar_non_myanmar_cluster, -}; - -#include "hb-ot-shape-complex-myanmar-machine.hh" - - static void setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, @@ -265,70 +256,16 @@ reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, } } -static inline void -insert_dotted_circles_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_myanmar_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void reorder_myanmar (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - if (buffer->message (font, "start reordering myanmar")) { - insert_dotted_circles_myanmar (plan, font, buffer); + if (buffer->message (font, "start reordering myanmar")) + { + hb_syllabic_insert_dotted_circles (font, buffer, + myanmar_broken_cluster, + OT_GB); foreach_syllable (buffer, start, end) reorder_syllable_myanmar (plan, font->face, buffer, start, end); diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh index 7b9821e6ba..a6d68aae57 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-myanmar.hh @@ -64,7 +64,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 & 0x7Fu; + unsigned int cat = type & 0xFFu; indic_position_t pos = (indic_position_t) (type >> 8); /* Myanmar diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc new file mode 100644 index 0000000000..5a08f878dc --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc @@ -0,0 +1,103 @@ +/* + * Copyright © 2021 Behdad Esfahbod. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb.hh" + +#ifndef HB_NO_OT_SHAPE + +#include "hb-ot-shape-complex-syllabic.hh" + + +void +hb_syllabic_insert_dotted_circles (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int broken_syllable_type, + unsigned int dottedcircle_category, + int repha_category, + int dottedcircle_position) +{ + if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) + return; + + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_syllable_type) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; + dottedcircle.complex_var_u8_category() = dottedcircle_category; + if (dottedcircle_position != -1) + dottedcircle.complex_var_u8_auxiliary() = dottedcircle_position; + dottedcircle.codepoint = dottedcircle_glyph; + + buffer->clear_output (); + + buffer->idx = 0; + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len && buffer->successful) + { + unsigned int syllable = buffer->cur().syllable(); + if (unlikely (last_syllable != syllable && (syllable & 0x0F) == broken_syllable_type)) + { + last_syllable = syllable; + + hb_glyph_info_t ginfo = dottedcircle; + ginfo.cluster = buffer->cur().cluster; + ginfo.mask = buffer->cur().mask; + ginfo.syllable() = buffer->cur().syllable(); + + /* Insert dottedcircle after possible Repha. */ + if (repha_category != -1) + { + while (buffer->idx < buffer->len && buffer->successful && + last_syllable == buffer->cur().syllable() && + buffer->cur().complex_var_u8_category() == (unsigned) repha_category) + (void) buffer->next_glyph (); + } + + (void) buffer->output_info (ginfo); + } + else + (void) buffer->next_glyph (); + } + buffer->swap_buffers (); +} + + +#endif diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh new file mode 100644 index 0000000000..b901a660d3 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh @@ -0,0 +1,42 @@ +/* + * Copyright © 2021 Behdad Esfahbod. + * + * 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_SHAPE_COMPLEX_SYLLABIC_HH +#define HB_OT_SHAPE_COMPLEX_SYLLABIC_HH + +#include "hb.hh" + +#include "hb-ot-shape-complex.hh" + + +HB_INTERNAL void +hb_syllabic_insert_dotted_circles (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int broken_syllable_type, + unsigned int dottedcircle_category, + int repha_category = -1, + int dottedcircle_position = -1); + + +#endif /* HB_OT_SHAPE_COMPLEX_SYLLABIC_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc index 347ea2e7ac..4c3068173b 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc @@ -323,20 +323,19 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, buffer->clear_output (); unsigned int count = buffer->len; - for (buffer->idx = 0; buffer->idx < count && buffer->successful;) + for (buffer->idx = 0; buffer->idx < count /* No need for: && buffer->successful */;) { hb_codepoint_t u = buffer->cur().codepoint; - if (likely (!IS_SARA_AM (u))) { - buffer->next_glyph (); + if (likely (!IS_SARA_AM (u))) + { + if (unlikely (!buffer->next_glyph ())) break; continue; } /* Is SARA AM. Decompose and reorder. */ - hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); - _hb_glyph_info_set_continuation (&nikhahit); - buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)); - if (unlikely (!buffer->successful)) - return; + (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); + _hb_glyph_info_set_continuation (&buffer->prev()); + if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break; /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ unsigned int end = buffer->out_len; 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 144e7d3a40..bb046a72ec 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh @@ -32,10 +32,71 @@ #define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH #include "hb.hh" -#include "hb-ot-shape-complex-machine-index.hh" +#include "hb-ot-shape-complex-syllabic.hh" -#line 39 "hb-ot-shape-complex-use-machine.hh" +/* buffer var allocations */ +#define use_category() complex_var_u8_category() + +#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, + use_number_joiner_terminated_cluster, + use_numeral_cluster, + use_symbol_cluster, + use_hieroglyph_cluster, + use_broken_cluster, + use_non_cluster, +}; + + +#line 58 "hb-ot-shape-complex-use-machine.hh" +#define use_syllable_machine_ex_B 1u +#define use_syllable_machine_ex_CMAbv 31u +#define use_syllable_machine_ex_CMBlw 32u +#define use_syllable_machine_ex_CS 43u +#define use_syllable_machine_ex_FAbv 24u +#define use_syllable_machine_ex_FBlw 25u +#define use_syllable_machine_ex_FMAbv 45u +#define use_syllable_machine_ex_FMBlw 46u +#define use_syllable_machine_ex_FMPst 47u +#define use_syllable_machine_ex_FPst 26u +#define use_syllable_machine_ex_G 49u +#define use_syllable_machine_ex_GB 5u +#define use_syllable_machine_ex_H 12u +#define use_syllable_machine_ex_HN 13u +#define use_syllable_machine_ex_HVM 44u +#define use_syllable_machine_ex_J 50u +#define use_syllable_machine_ex_MAbv 27u +#define use_syllable_machine_ex_MBlw 28u +#define use_syllable_machine_ex_MPre 30u +#define use_syllable_machine_ex_MPst 29u +#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 +#define use_syllable_machine_ex_SMBlw 42u +#define use_syllable_machine_ex_SUB 11u +#define use_syllable_machine_ex_Sk 48u +#define use_syllable_machine_ex_VAbv 33u +#define use_syllable_machine_ex_VBlw 34u +#define use_syllable_machine_ex_VMAbv 37u +#define use_syllable_machine_ex_VMBlw 38u +#define use_syllable_machine_ex_VMPre 23u +#define use_syllable_machine_ex_VMPst 39u +#define use_syllable_machine_ex_VPre 22u +#define use_syllable_machine_ex_VPst 35u +#define use_syllable_machine_ex_ZWNJ 14u + + +#line 100 "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, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, @@ -304,27 +365,67 @@ static const int use_syllable_machine_error = -1; static const int use_syllable_machine_en_main = 2; -#line 39 "hb-ot-shape-complex-use-machine.rl" +#line 59 "hb-ot-shape-complex-use-machine.rl" -#line 154 "hb-ot-shape-complex-use-machine.rl" +#line 176 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ HB_STMT_START { \ if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ - info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ syllable_serial++; \ if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ } HB_STMT_END + +template <typename Iter> +struct machine_index_t : + hb_iter_with_fallback_t<machine_index_t<Iter>, + typename Iter::item_t> +{ + machine_index_t (const Iter& it) : it (it) {} + machine_index_t (const machine_index_t& o) : it (o.it) {} + + static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; + static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; + + typename Iter::item_t __item__ () const { return *it; } + typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } + unsigned __len__ () const { return it.len (); } + void __next__ () { ++it; } + void __forward__ (unsigned n) { it += n; } + void __prev__ () { --it; } + void __rewind__ (unsigned n) { it -= n; } + void operator = (unsigned n) + { unsigned index = (*it).first; if (index < n) it += n - index; else if (index > n) it -= index - n; } + void operator = (const machine_index_t& o) { *this = (*o.it).first; } + bool operator == (const machine_index_t& o) const { return (*it).first == (*o.it).first; } + bool operator != (const machine_index_t& o) const { return !(*this == o); } + + private: + Iter it; +}; +struct +{ + template <typename Iter, + hb_requires (hb_is_iterable (Iter))> + machine_index_t<hb_iter_type<Iter>> + operator () (Iter&& it) const + { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } +} +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)); } +{ return !(i.use_category() == USE(O) && _hb_glyph_info_is_default_ignorable (&i)); } -static void +static inline void find_syllables_use (hb_buffer_t *buffer) { hb_glyph_info_t *info = buffer->info; @@ -335,7 +436,7 @@ find_syllables_use (hb_buffer_t *buffer) hb_second) | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) { - if (p.second.use_category() == USE_ZWNJ) + if (p.second.use_category() == USE(ZWNJ)) for (unsigned i = p.first + 1; i < buffer->len; ++i) if (not_standard_default_ignorable (info[i])) return !_hb_glyph_info_is_unicode_mark (&info[i]); @@ -351,7 +452,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 355 "hb-ot-shape-complex-use-machine.hh" +#line 456 "hb-ot-shape-complex-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -359,12 +460,12 @@ find_syllables_use (hb_buffer_t *buffer) act = 0; } -#line 198 "hb-ot-shape-complex-use-machine.rl" +#line 260 "hb-ot-shape-complex-use-machine.rl" unsigned int syllable_serial = 1; -#line 368 "hb-ot-shape-complex-use-machine.hh" +#line 469 "hb-ot-shape-complex-use-machine.hh" { int _slen; int _trans; @@ -378,7 +479,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 382 "hb-ot-shape-complex-use-machine.hh" +#line 483 "hb-ot-shape-complex-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -401,62 +502,62 @@ _eof_trans: {te = p+1;} break; case 5: -#line 141 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (independent_cluster); }} +#line 163 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (use_independent_cluster); }} break; case 9: -#line 144 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (standard_cluster); }} +#line 166 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (use_standard_cluster); }} break; case 7: -#line 149 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} +#line 171 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (use_broken_cluster); }} break; case 6: -#line 150 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (non_cluster); }} +#line 172 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (use_non_cluster); }} break; case 10: -#line 142 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (virama_terminated_cluster); }} +#line 164 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} break; case 11: -#line 143 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (sakot_terminated_cluster); }} +#line 165 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} break; case 8: -#line 144 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (standard_cluster); }} +#line 166 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_standard_cluster); }} break; case 13: -#line 145 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} +#line 167 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} break; case 12: -#line 146 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (numeral_cluster); }} +#line 168 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_numeral_cluster); }} break; case 14: -#line 147 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} +#line 169 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_symbol_cluster); }} break; case 17: -#line 148 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (hieroglyph_cluster); }} +#line 170 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} break; case 15: -#line 149 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} +#line 171 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_broken_cluster); }} break; case 16: -#line 150 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (non_cluster); }} +#line 172 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (use_non_cluster); }} break; case 1: -#line 149 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} +#line 171 "hb-ot-shape-complex-use-machine.rl" + {{p = ((te))-1;}{ found_syllable (use_broken_cluster); }} break; -#line 460 "hb-ot-shape-complex-use-machine.hh" +#line 561 "hb-ot-shape-complex-use-machine.hh" } _again: @@ -465,7 +566,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 469 "hb-ot-shape-complex-use-machine.hh" +#line 570 "hb-ot-shape-complex-use-machine.hh" } if ( ++p != pe ) @@ -481,7 +582,7 @@ _again: } -#line 203 "hb-ot-shape-complex-use-machine.rl" +#line 265 "hb-ot-shape-complex-use-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh index df3652b18a..7903a0ef89 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh @@ -6,14 +6,14 @@ * * on files with these headers: * - * # IndicSyllabicCategory-13.0.0.txt - * # Date: 2019-07-22, 19:55:00 GMT [KW, RP] - * # IndicPositionalCategory-13.0.0.txt - * # Date: 2019-07-23, 00:01:00 GMT [KW, RP] - * # ArabicShaping-13.0.0.txt - * # Date: 2020-01-31, 23:55:00 GMT [KW, RP] - * # Blocks-13.0.0.txt - * # Date: 2019-07-10, 19:06:00 GMT [KW] + * # IndicSyllabicCategory-14.0.0.txt + * # Date: 2021-05-22, 01:01:00 GMT [KW, RP] + * # IndicPositionalCategory-14.0.0.txt + * # 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] + * # Blocks-14.0.0.txt + * # Date: 2021-01-22, 23:29:00 GMT [KW] * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -31,56 +31,57 @@ * UnicodeData.txt does not have a header. */ -#include "hb.hh" +#ifndef HB_OT_SHAPE_COMPLEX_USE_TABLE_HH +#define HB_OT_SHAPE_COMPLEX_USE_TABLE_HH -#ifndef HB_NO_OT_SHAPE +#include "hb.hh" -#include "hb-ot-shape-complex-use.hh" +#include "hb-ot-shape-complex-use-machine.hh" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-macros" -#define B USE_B /* BASE */ -#define CS USE_CS /* CONS_WITH_STACKER */ -#define G USE_G /* HIEROGLYPH */ -#define GB USE_GB /* BASE_OTHER */ -#define H USE_H /* HALANT */ -#define HN USE_HN /* HALANT_NUM */ -#define HVM USE_HVM /* HALANT_OR_VOWEL_MODIFIER */ -#define J USE_J /* HIEROGLYPH_JOINER */ -#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 */ -#define Sk USE_Sk /* SAKOT */ -#define ZWNJ USE_ZWNJ /* ZWNJ */ -#define CMAbv USE_CMAbv -#define CMBlw USE_CMBlw -#define FAbv USE_FAbv -#define FBlw USE_FBlw -#define FPst USE_FPst -#define FMAbv USE_FMAbv -#define FMBlw USE_FMBlw -#define FMPst USE_FMPst -#define MAbv USE_MAbv -#define MBlw USE_MBlw -#define MPst USE_MPst -#define MPre USE_MPre -#define SMAbv USE_SMAbv -#define SMBlw USE_SMBlw -#define VAbv USE_VAbv -#define VBlw USE_VBlw -#define VPst USE_VPst -#define VPre USE_VPre -#define VMAbv USE_VMAbv -#define VMBlw USE_VMBlw -#define VMPst USE_VMPst -#define VMPre USE_VMPre +#define B USE(B) /* BASE */ +#define CS USE(CS) /* CONS_WITH_STACKER */ +#define G USE(G) /* HIEROGLYPH */ +#define GB USE(GB) /* BASE_OTHER */ +#define H USE(H) /* HALANT */ +#define HN USE(HN) /* HALANT_NUM */ +#define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */ +#define J USE(J) /* HIEROGLYPH_JOINER */ +#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 */ +#define Sk USE(Sk) /* SAKOT */ +#define ZWNJ USE(ZWNJ) /* ZWNJ */ +#define CMAbv USE(CMAbv) +#define CMBlw USE(CMBlw) +#define FAbv USE(FAbv) +#define FBlw USE(FBlw) +#define FPst USE(FPst) +#define FMAbv USE(FMAbv) +#define FMBlw USE(FMBlw) +#define FMPst USE(FMPst) +#define MAbv USE(MAbv) +#define MBlw USE(MBlw) +#define MPst USE(MPst) +#define MPre USE(MPre) +#define SMAbv USE(SMAbv) +#define SMBlw USE(SMBlw) +#define VAbv USE(VAbv) +#define VBlw USE(VBlw) +#define VPst USE(VPst) +#define VPre USE(VPre) +#define VMAbv USE(VMAbv) +#define VMBlw USE(VMBlw) +#define VMPst USE(VMPst) +#define VMPre USE(VMPre) #pragma GCC diagnostic pop -static const USE_TABLE_ELEMENT_TYPE use_table[] = { +static const uint8_t use_table[] = { #define use_offset_0x0028u 0 @@ -198,7 +199,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv, B, B, B, B, B, B, B, B, O, B, B, /* 0C10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, VAbv, VAbv, + /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, CMBlw, B, VAbv, VAbv, /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, /* 0C50 */ O, O, O, O, O, VAbv, VBlw, O, B, B, B, O, O, O, O, O, /* 0C60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, @@ -277,13 +278,13 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Tagalog */ - /* 1700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, B, - /* 1710 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, + /* 1700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1710 */ B, B, VAbv, VBlw, VBlw, VPst, O, O, O, O, O, O, O, O, O, B, /* Hanunoo */ /* 1720 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1730 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, + /* 1730 */ B, B, VAbv, VBlw, VPst, O, O, O, O, O, O, O, O, O, O, O, /* Buhid */ @@ -373,7 +374,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, - /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, + /* 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, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, @@ -629,7 +630,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, HVM, 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 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, HN, + /* 11070 */ VAbv, B, B, VAbv, VAbv, B, O, O, O, O, O, O, O, O, O, HN, /* Kaithi */ @@ -637,8 +638,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 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 4608 +#define use_offset_0x11100u 4616 /* Chakma */ @@ -676,7 +678,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 4928 +#define use_offset_0x11280u 4936 /* Multani */ @@ -704,7 +706,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 5176 +#define use_offset_0x11400u 5184 /* Newa */ @@ -727,7 +729,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 5400 +#define use_offset_0x11580u 5408 /* Siddham */ @@ -767,10 +769,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11710 */ B, B, B, B, B, B, B, B, B, B, B, O, O, MBlw, MPre, MAbv, - /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VMAbv, O, O, O, O, + /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, /* 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 5848 +#define use_offset_0x11800u 5864 /* Dogra */ @@ -780,7 +783,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 5912 +#define use_offset_0x11900u 5928 /* Dives Akuru */ @@ -792,7 +795,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 6008 +#define use_offset_0x119a0u 6024 /* Nandinagari */ @@ -820,7 +823,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 6264 +#define use_offset_0x11c00u 6280 /* Bhaiksuki */ @@ -841,7 +844,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 6448 +#define use_offset_0x11d00u 6464 /* Masaram Gondi */ @@ -861,7 +864,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 6624 +#define use_offset_0x11ee0u 6640 /* Makasar */ @@ -869,7 +872,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 6648 +#define use_offset_0x13000u 6664 /* Egyptian Hieroglyphs */ @@ -946,7 +949,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O, -#define use_offset_0x16b00u 7736 +#define use_offset_0x16b00u 7752 /* Pahawh Hmong */ @@ -956,7 +959,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 7792 +#define use_offset_0x16f00u 7808 /* Miao */ @@ -972,14 +975,14 @@ static const USE_TABLE_ELEMENT_TYPE 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 7944 +#define use_offset_0x16fe0u 7960 /* Ideographic Symbols and Punctuation */ /* 16FE0 */ O, O, O, O, B, O, O, O, -#define use_offset_0x18b00u 7952 +#define use_offset_0x18b00u 7968 /* Khitan Small Script */ @@ -1015,7 +1018,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 8424 +#define use_offset_0x1bc00u 8440 /* Duployan */ @@ -1031,7 +1034,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 8584 +#define use_offset_0x1e100u 8600 /* Nyiakeng Puachue Hmong */ @@ -1042,7 +1045,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 8664 +#define use_offset_0x1e2c0u 8680 /* Wancho */ @@ -1052,7 +1055,7 @@ static const USE_TABLE_ELEMENT_TYPE 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 8728 +#define use_offset_0x1e900u 8744 /* Adlam */ @@ -1064,9 +1067,9 @@ static const USE_TABLE_ELEMENT_TYPE 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: 8824; occupancy: 79% */ +}; /* Table items: 8840; occupancy: 79% */ -USE_TABLE_ELEMENT_TYPE +static inline uint8_t hb_use_get_category (hb_codepoint_t u) { switch (u >> 12) @@ -1110,15 +1113,15 @@ hb_use_get_category (hb_codepoint_t u) 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, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; break; case 0x11u: - if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110BFu)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; + 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, 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]; - if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x11747u)) return use_table[u - 0x11580u + use_offset_0x11580u]; if (hb_in_range<hb_codepoint_t> (u, 0x11800u, 0x1183Fu)) return use_table[u - 0x11800u + use_offset_0x11800u]; if (hb_in_range<hb_codepoint_t> (u, 0x11900u, 0x1195Fu)) return use_table[u - 0x11900u + use_offset_0x11900u]; if (hb_in_range<hb_codepoint_t> (u, 0x119A0u, 0x11A9Fu)) return use_table[u - 0x119A0u + use_offset_0x119a0u]; @@ -1154,7 +1157,7 @@ hb_use_get_category (hb_codepoint_t u) default: break; } - return USE_O; + return USE(O); } #undef B @@ -1198,5 +1201,5 @@ hb_use_get_category (hb_codepoint_t u) #undef VMPre -#endif +#endif /* HB_OT_SHAPE_COMPLEX_USE_TABLE_HH */ /* == End of generated table == */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc index 8ac569d8bf..1e4804c4a2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.cc @@ -30,14 +30,12 @@ #ifndef HB_NO_OT_SHAPE -#include "hb-ot-shape-complex-use.hh" +#include "hb-ot-shape-complex-use-machine.hh" +#include "hb-ot-shape-complex-use-table.hh" #include "hb-ot-shape-complex-arabic.hh" #include "hb-ot-shape-complex-arabic-joining-list.hh" #include "hb-ot-shape-complex-vowel-constraints.hh" -/* buffer var allocations */ -#define use_category() complex_var_u8_1() - /* * Universal Shaping Engine. @@ -49,7 +47,8 @@ use_basic_features[] = { /* * Basic features. - * These features are applied all at once, before reordering. + * These features are applied all at once, before reordering, constrained + * to the syllable. */ HB_TAG('r','k','r','f'), HB_TAG('a','b','v','f'), @@ -69,11 +68,11 @@ use_topographical_features[] = }; /* Same order as use_topographical_features. */ enum joining_form_t { - USE_ISOL, - USE_INIT, - USE_MEDI, - USE_FINA, - _USE_NONE + JOINING_FORM_ISOL, + JOINING_FORM_INIT, + JOINING_FORM_MEDI, + JOINING_FORM_FINA, + _JOINING_FORM_NONE }; static const hb_tag_t use_other_features[] = @@ -156,7 +155,7 @@ struct use_shape_plan_t static void * data_create_use (const hb_ot_shape_plan_t *plan) { - use_shape_plan_t *use_plan = (use_shape_plan_t *) calloc (1, sizeof (use_shape_plan_t)); + use_shape_plan_t *use_plan = (use_shape_plan_t *) hb_calloc (1, sizeof (use_shape_plan_t)); if (unlikely (!use_plan)) return nullptr; @@ -167,7 +166,7 @@ data_create_use (const hb_ot_shape_plan_t *plan) use_plan->arabic_plan = (arabic_shape_plan_t *) data_create_arabic (plan); if (unlikely (!use_plan->arabic_plan)) { - free (use_plan); + hb_free (use_plan); return nullptr; } } @@ -183,25 +182,9 @@ data_destroy_use (void *data) if (use_plan->arabic_plan) data_destroy_arabic (use_plan->arabic_plan); - free (data); + hb_free (data); } -enum use_syllable_type_t { - use_independent_cluster, - use_virama_terminated_cluster, - use_sakot_terminated_cluster, - use_standard_cluster, - use_number_joiner_terminated_cluster, - use_numeral_cluster, - use_symbol_cluster, - use_hieroglyph_cluster, - use_broken_cluster, - use_non_cluster, -}; - -#include "hb-ot-shape-complex-use-machine.hh" - - static void setup_masks_use (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -239,7 +222,7 @@ setup_rphf_mask (const hb_ot_shape_plan_t *plan, foreach_syllable (buffer, start, end) { - unsigned int limit = info[start].use_category() == USE_R ? 1 : hb_min (3u, end - start); + unsigned int limit = info[start].use_category() == USE(R) ? 1 : hb_min (3u, end - start); for (unsigned int i = start; i < start + limit; i++) info[i].mask |= mask; } @@ -253,7 +236,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, if (use_plan->arabic_plan) return; - static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), ""); + static_assert ((JOINING_FORM_INIT < 4 && JOINING_FORM_ISOL < 4 && JOINING_FORM_MEDI < 4 && JOINING_FORM_FINA < 4), ""); hb_mask_t masks[4], all_masks = 0; for (unsigned int i = 0; i < 4; i++) { @@ -267,7 +250,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, hb_mask_t other_masks = ~all_masks; unsigned int last_start = 0; - joining_form_t last_form = _USE_NONE; + joining_form_t last_form = _JOINING_FORM_NONE; hb_glyph_info_t *info = buffer->info; foreach_syllable (buffer, start, end) { @@ -279,7 +262,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, case use_hieroglyph_cluster: case use_non_cluster: /* These don't join. Nothing to do. */ - last_form = _USE_NONE; + last_form = _JOINING_FORM_NONE; break; case use_virama_terminated_cluster: @@ -289,18 +272,18 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, case use_numeral_cluster: case use_broken_cluster: - bool join = last_form == USE_FINA || last_form == USE_ISOL; + bool join = last_form == JOINING_FORM_FINA || last_form == JOINING_FORM_ISOL; if (join) { /* Fixup previous syllable's form. */ - last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT; + last_form = last_form == JOINING_FORM_FINA ? JOINING_FORM_MEDI : JOINING_FORM_INIT; for (unsigned int i = last_start; i < start; i++) info[i].mask = (info[i].mask & other_masks) | masks[last_form]; } /* Form for this syllable. */ - last_form = join ? USE_FINA : USE_ISOL; + last_form = join ? JOINING_FORM_FINA : JOINING_FORM_ISOL; for (unsigned int i = start; i < end; i++) info[i].mask = (info[i].mask & other_masks) | masks[last_form]; @@ -336,11 +319,11 @@ record_rphf_use (const hb_ot_shape_plan_t *plan, foreach_syllable (buffer, start, end) { - /* Mark a substituted repha as USE_R. */ + /* Mark a substituted repha as USE(R). */ for (unsigned int i = start; i < end && (info[i].mask & mask); i++) if (_hb_glyph_info_substituted (&info[i])) { - info[i].use_category() = USE_R; + info[i].use_category() = USE(R); break; } } @@ -359,7 +342,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, for (unsigned int i = start; i < end; i++) if (_hb_glyph_info_substituted (&info[i])) { - info[i].use_category() = USE_VPre; + info[i].use_category() = USE(VPre); break; } } @@ -368,7 +351,7 @@ record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED, static inline bool is_halant_use (const hb_glyph_info_t &info) { - return (info.use_category() == USE_H || info.use_category() == USE_HVM) && + return (info.use_category() == USE(H) || info.use_category() == USE(HVM)) && !_hb_glyph_info_ligated (&info); } @@ -387,24 +370,24 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) hb_glyph_info_t *info = buffer->info; -#define POST_BASE_FLAGS64 (FLAG64 (USE_FAbv) | \ - FLAG64 (USE_FBlw) | \ - FLAG64 (USE_FPst) | \ - FLAG64 (USE_MAbv) | \ - FLAG64 (USE_MBlw) | \ - FLAG64 (USE_MPst) | \ - FLAG64 (USE_MPre) | \ - FLAG64 (USE_VAbv) | \ - FLAG64 (USE_VBlw) | \ - FLAG64 (USE_VPst) | \ - FLAG64 (USE_VPre) | \ - FLAG64 (USE_VMAbv) | \ - FLAG64 (USE_VMBlw) | \ - FLAG64 (USE_VMPst) | \ - FLAG64 (USE_VMPre)) +#define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \ + FLAG64 (USE(FBlw)) | \ + FLAG64 (USE(FPst)) | \ + FLAG64 (USE(MAbv)) | \ + FLAG64 (USE(MBlw)) | \ + FLAG64 (USE(MPst)) | \ + FLAG64 (USE(MPre)) | \ + FLAG64 (USE(VAbv)) | \ + FLAG64 (USE(VBlw)) | \ + FLAG64 (USE(VPst)) | \ + FLAG64 (USE(VPre)) | \ + FLAG64 (USE(VMAbv)) | \ + FLAG64 (USE(VMBlw)) | \ + FLAG64 (USE(VMPst)) | \ + FLAG64 (USE(VMPre))) /* Move things forward. */ - if (info[start].use_category() == USE_R && end - start > 1) + if (info[start].use_category() == USE(R) && end - start > 1) { /* Got a repha. Reorder it towards the end, but before the first post-base * glyph. */ @@ -441,7 +424,7 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) * shift things in between forward. */ j = i + 1; } - else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && + else if (((flag) & (FLAG (USE(VPre)) | FLAG (USE(VMPre)))) && /* Only move the first component of a MultipleSubst. */ 0 == _hb_glyph_info_get_lig_comp (&info[i]) && j < i) @@ -454,76 +437,22 @@ reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end) } } -static inline void -insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) - return; - - /* Note: This loop is extra overhead, but should not be measurable. - * TODO Use a buffer scratch flag to remove the loop. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == use_broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - hb_glyph_info_t dottedcircle = {0}; - if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint)) - return; - dottedcircle.use_category() = hb_use_get_category (0x25CC); - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len && buffer->successful) - { - unsigned int syllable = buffer->cur().syllable(); - use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t ginfo = dottedcircle; - ginfo.cluster = buffer->cur().cluster; - ginfo.mask = buffer->cur().mask; - ginfo.syllable() = buffer->cur().syllable(); - - /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && buffer->successful && - last_syllable == buffer->cur().syllable() && - buffer->cur().use_category() == USE_R) - buffer->next_glyph (); - - buffer->output_info (ginfo); - } - else - buffer->next_glyph (); - } - buffer->swap_buffers (); -} - static void reorder_use (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - if (buffer->message (font, "start reordering USE")) { - insert_dotted_circles_use (plan, font, buffer); + if (buffer->message (font, "start reordering USE")) + { + hb_syllabic_insert_dotted_circles (font, buffer, + use_broken_cluster, + USE(B), + USE(R)); - foreach_syllable (buffer, start, end) - reorder_syllable_use (buffer, start, end); + foreach_syllable (buffer, start, end) + reorder_syllable_use (buffer, start, end); - (void) buffer->message (font, "end reordering USE"); + (void) buffer->message (font, "end reordering USE"); } HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh deleted file mode 100644 index 788fb6b6ac..0000000000 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use.hh +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_OT_SHAPE_COMPLEX_USE_HH -#define HB_OT_SHAPE_COMPLEX_USE_HH - -#include "hb.hh" - - -#include "hb-ot-shape-complex.hh" - - -#define USE_TABLE_ELEMENT_TYPE uint8_t - -/* Cateories used in the Universal Shaping Engine spec: - * https://docs.microsoft.com/en-us/typography/script-development/use - */ -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum use_category_t { - USE_O = 0, /* OTHER */ - - USE_B = 1, /* BASE */ - USE_N = 4, /* BASE_NUM */ - USE_GB = 5, /* BASE_OTHER */ - USE_SUB = 11, /* CONS_SUB */ - USE_H = 12, /* HALANT */ - - USE_HN = 13, /* HALANT_NUM */ - USE_ZWNJ = 14, /* Zero width non-joiner */ - USE_R = 18, /* REPHA */ - USE_S = 19, /* SYM */ - USE_CS = 43, /* CONS_WITH_STACKER */ - - /* https://github.com/harfbuzz/harfbuzz/issues/1102 */ - USE_HVM = 44, /* HALANT_OR_VOWEL_MODIFIER */ - - USE_Sk = 48, /* SAKOT */ - USE_G = 49, /* HIEROGLYPH */ - USE_J = 50, /* HIEROGLYPH_JOINER */ - USE_SB = 51, /* HIEROGLYPH_SEGMENT_BEGIN */ - USE_SE = 52, /* HIEROGLYPH_SEGMENT_END */ - - USE_FAbv = 24, /* CONS_FINAL_ABOVE */ - USE_FBlw = 25, /* CONS_FINAL_BELOW */ - USE_FPst = 26, /* CONS_FINAL_POST */ - USE_MAbv = 27, /* CONS_MED_ABOVE */ - USE_MBlw = 28, /* CONS_MED_BELOW */ - USE_MPst = 29, /* CONS_MED_POST */ - USE_MPre = 30, /* CONS_MED_PRE */ - USE_CMAbv = 31, /* CONS_MOD_ABOVE */ - USE_CMBlw = 32, /* CONS_MOD_BELOW */ - USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */ - USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */ - USE_VPst = 35, /* VOWEL_POST UIPC = Right */ - USE_VPre = 22, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */ - USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */ - USE_VMBlw = 38, /* VOWEL_MOD_BELOW */ - USE_VMPst = 39, /* VOWEL_MOD_POST */ - USE_VMPre = 23, /* VOWEL_MOD_PRE */ - USE_SMAbv = 41, /* SYM_MOD_ABOVE */ - USE_SMBlw = 42, /* SYM_MOD_BELOW */ - USE_FMAbv = 45, /* CONS_FINAL_MOD UIPC = Top */ - USE_FMBlw = 46, /* CONS_FINAL_MOD UIPC = Bottom */ - USE_FMPst = 47, /* CONS_FINAL_MOD UIPC = Not_Applicable */ -}; - -HB_INTERNAL USE_TABLE_ELEMENT_TYPE -hb_use_get_category (hb_codepoint_t u); - -#endif /* HB_OT_SHAPE_COMPLEX_USE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc index 1af546e4fa..045731dfb4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-13.0.0.txt - * # Date: 2020-01-22, 00:07:43 GMT + * # Scripts-14.0.0.txt + * # Date: 2021-07-10, 00:35:31 GMT */ #include "hb.hh" @@ -23,15 +23,15 @@ static void _output_dotted_circle (hb_buffer_t *buffer) { - hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu); - _hb_glyph_info_reset_continuation (&dottedcircle); + (void) buffer->output_glyph (0x25CCu); + _hb_glyph_info_reset_continuation (&buffer->prev()); } static void _output_with_dotted_circle (hb_buffer_t *buffer) { _output_dotted_circle (buffer); - buffer->next_glyph (); + (void) buffer->next_glyph (); } void @@ -51,7 +51,6 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, * * https://github.com/harfbuzz/harfbuzz/issues/1019 */ - bool processed = false; buffer->clear_output (); unsigned int count = buffer->len; switch ((unsigned) buffer->props.script) @@ -97,15 +96,14 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx + 2 < count && 0x0907u == buffer->cur (2).codepoint) { - buffer->next_glyph (); + (void) buffer->next_glyph (); matched = true; } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_BENGALI: @@ -124,10 +122,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x09E2u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_GURMUKHI: @@ -161,10 +158,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_GUJARATI: @@ -186,10 +182,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0ABEu == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_ORIYA: @@ -205,10 +200,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0B57u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TAMIL: @@ -220,10 +214,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, { matched = true; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TELUGU: @@ -244,10 +237,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0C55u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_KANNADA: @@ -263,10 +255,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x0CCCu == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_MALAYALAM: @@ -290,10 +281,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_SINHALA: @@ -326,10 +316,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_BRAHMI: @@ -348,10 +337,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x11042u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_KHUDAWADI: @@ -370,10 +358,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TIRHUTA: @@ -397,10 +384,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_MODI: @@ -418,10 +404,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, } break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; case HB_SCRIPT_TAKRI: @@ -442,21 +427,15 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, matched = 0x116B2u == buffer->cur (1).codepoint; break; } - buffer->next_glyph (); + (void) buffer->next_glyph (); if (matched) _output_with_dotted_circle (buffer); } - processed = true; break; default: break; } - if (processed) - { - if (buffer->idx < count) - buffer->next_glyph (); - buffer->swap_buffers (); - } + buffer->swap_buffers (); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh index a1a7a6a47b..8012a9ae94 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex.hh @@ -35,8 +35,8 @@ /* buffer var allocations, used by complex shapers */ -#define complex_var_u8_0() var2.u8[2] -#define complex_var_u8_1() var2.u8[3] +#define complex_var_u8_category() var2.u8[2] +#define complex_var_u8_auxiliary() var2.u8[3] #define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32 @@ -186,27 +186,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_ARABIC: /* Unicode-3.0 additions */ - case HB_SCRIPT_MONGOLIAN: case HB_SCRIPT_SYRIAC: - /* Unicode-5.0 additions */ - case HB_SCRIPT_NKO: - case HB_SCRIPT_PHAGS_PA: - - /* Unicode-6.0 additions */ - case HB_SCRIPT_MANDAIC: - - /* Unicode-7.0 additions */ - case HB_SCRIPT_MANICHAEAN: - case HB_SCRIPT_PSALTER_PAHLAVI: - - /* Unicode-9.0 additions */ - case HB_SCRIPT_ADLAM: - - /* Unicode-11.0 additions */ - case HB_SCRIPT_HANIFI_ROHINGYA: - case HB_SCRIPT_SOGDIAN: - /* For Arabic script, use the Arabic shaper even if no OT script tag was found. * This is because we do fallback shaping for Arabic script (and not others). * But note that Arabic shaping is applicable only to horizontal layout; for @@ -284,8 +265,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_myanmar; - /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ +#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) case HB_SCRIPT_MYANMAR_ZAWGYI: + /* https://github.com/harfbuzz/harfbuzz/issues/1162 */ return &_hb_ot_complex_shaper_myanmar_zawgyi; @@ -294,7 +276,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_TIBETAN: /* Unicode-3.0 additions */ - //case HB_SCRIPT_MONGOLIAN: + case HB_SCRIPT_MONGOLIAN: //case HB_SCRIPT_SINHALA: /* Unicode-3.2 additions */ @@ -315,8 +297,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-5.0 additions */ case HB_SCRIPT_BALINESE: - //case HB_SCRIPT_NKO: - //case HB_SCRIPT_PHAGS_PA: + case HB_SCRIPT_NKO: + case HB_SCRIPT_PHAGS_PA: /* Unicode-5.1 additions */ case HB_SCRIPT_CHAM: @@ -337,7 +319,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-6.0 additions */ case HB_SCRIPT_BATAK: case HB_SCRIPT_BRAHMI: - //case HB_SCRIPT_MANDAIC: + case HB_SCRIPT_MANDAIC: /* Unicode-6.1 additions */ case HB_SCRIPT_CHAKMA: @@ -351,10 +333,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_KHOJKI: case HB_SCRIPT_KHUDAWADI: case HB_SCRIPT_MAHAJANI: - //case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_MANICHAEAN: case HB_SCRIPT_MODI: case HB_SCRIPT_PAHAWH_HMONG: - //case HB_SCRIPT_PSALTER_PAHLAVI: + case HB_SCRIPT_PSALTER_PAHLAVI: case HB_SCRIPT_SIDDHAM: case HB_SCRIPT_TIRHUTA: @@ -363,7 +345,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_MULTANI: /* Unicode-9.0 additions */ - //case HB_SCRIPT_ADLAM: + case HB_SCRIPT_ADLAM: case HB_SCRIPT_BHAIKSUKI: case HB_SCRIPT_MARCHEN: case HB_SCRIPT_NEWA: @@ -376,11 +358,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-11.0 additions */ case HB_SCRIPT_DOGRA: case HB_SCRIPT_GUNJALA_GONDI: - //case HB_SCRIPT_HANIFI_ROHINGYA: + case HB_SCRIPT_HANIFI_ROHINGYA: case HB_SCRIPT_MAKASAR: case HB_SCRIPT_MEDEFAIDRIN: case HB_SCRIPT_OLD_SOGDIAN: - //case HB_SCRIPT_SOGDIAN: + case HB_SCRIPT_SOGDIAN: /* Unicode-12.0 additions */ case HB_SCRIPT_ELYMAIC: @@ -391,6 +373,15 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-13.0 additions */ case HB_SCRIPT_CHORASMIAN: case HB_SCRIPT_DIVES_AKURU: + case HB_SCRIPT_KHITAN_SMALL_SCRIPT: + case HB_SCRIPT_YEZIDI: + + /* Unicode-14.0 additions */ + case HB_SCRIPT_CYPRO_MINOAN: + case HB_SCRIPT_OLD_UYGHUR: + case HB_SCRIPT_TANGSA: + case HB_SCRIPT_TOTO: + case HB_SCRIPT_VITHKUQI: /* If the designer designed the font for the 'DFLT' script, * (or we ended up arbitrarily pick 'latn'), use the default shaper. diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc index 7d00a35ab9..eb1bc79768 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc @@ -92,7 +92,7 @@ recategorize_combining_class (hb_codepoint_t u, case HB_MODIFIED_COMBINING_CLASS_CCC15: /* tsere */ case HB_MODIFIED_COMBINING_CLASS_CCC16: /* segol */ case HB_MODIFIED_COMBINING_CLASS_CCC17: /* patah */ - case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats */ + case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats & qamats qatan */ case HB_MODIFIED_COMBINING_CLASS_CCC20: /* qubuts */ case HB_MODIFIED_COMBINING_CLASS_CCC22: /* meteg */ return HB_UNICODE_COMBINING_CLASS_BELOW; @@ -104,7 +104,7 @@ recategorize_combining_class (hb_codepoint_t u, return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT; case HB_MODIFIED_COMBINING_CLASS_CCC25: /* sin dot */ - case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam */ + case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam & holam haser for vav */ return HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT; case HB_MODIFIED_COMBINING_CLASS_CCC26: /* point varika */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc index 3eabae1b45..778b5b8bd8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc @@ -101,8 +101,9 @@ set_glyph (hb_glyph_info_t &info, hb_font_t *font) static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { + /* This is very confusing indeed. */ buffer->cur().glyph_index() = glyph; - buffer->output_glyph (unichar); /* This is very confusing indeed. */ + (void) buffer->output_glyph (unichar); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); } @@ -110,7 +111,7 @@ static inline void next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) { buffer->cur().glyph_index() = glyph; - buffer->next_glyph (); + (void) buffer->next_glyph (); } static inline void @@ -229,30 +230,35 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) { hb_codepoint_t unicode = buffer->cur().codepoint; - buffer->replace_glyphs (2, 1, &unicode); + (void) buffer->replace_glyphs (2, 1, &unicode); } else { /* Just pass on the two characters separately, let GSUB do its magic. */ set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } /* Skip any further variation selectors. */ - while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint))) + while (buffer->idx < end && + buffer->successful && + unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint))) { set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } - } else { + } + else + { set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } } - if (likely (buffer->idx < end)) { + if (likely (buffer->idx < end)) + { set_glyph (buffer->cur(), font); - buffer->next_glyph (); + (void) buffer->next_glyph (); } } @@ -348,7 +354,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, sizeof (buffer->info[0]), &buffer->cur().glyph_index(), sizeof (buffer->info[0])); - buffer->next_glyphs (done); + if (unlikely (!buffer->next_glyphs (done))) break; } while (buffer->idx < end && buffer->successful) decompose_current_character (&c, might_short_circuit); @@ -419,6 +425,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, /* Third round, recompose */ if (!all_simple && + buffer->successful && (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS || mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)) { @@ -428,8 +435,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->clear_output (); count = buffer->len; unsigned int starter = 0; - buffer->next_glyph (); - while (buffer->idx < count && buffer->successful) + (void) buffer->next_glyph (); + while (buffer->idx < count /* No need for: && buffer->successful */) { hb_codepoint_t composed, glyph; if (/* We don't try to compose a non-mark character with it's preceding starter. @@ -451,9 +458,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, font->get_nominal_glyph (composed, &glyph)) { /* Composes. */ - buffer->next_glyph (); /* Copy to out-buffer. */ - if (unlikely (!buffer->successful)) - return; + if (unlikely (!buffer->next_glyph ())) break; /* Copy to out-buffer. */ buffer->merge_out_clusters (starter, buffer->out_len); buffer->out_len--; /* Remove the second composable. */ /* Modify starter and carry on. */ @@ -466,7 +471,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, } /* Blocked, or doesn't compose. */ - buffer->next_glyph (); + if (unlikely (!buffer->next_glyph ())) break; if (info_cc (buffer->prev()) == 0) starter = buffer->out_len - 1; diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 7d90558458..0e215c24f7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -149,13 +149,17 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, * Decide who does positioning. GPOS, kerx, kern, or fallback. */ - if (0) +#ifndef HB_NO_AAT_SHAPE + bool has_gsub = 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)) + else if (hb_aat_layout_has_positioning (face) && !(has_gsub && has_gpos)) plan.apply_kerx = true; #endif - else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face)) + else if (!apply_morx && has_gpos) plan.apply_gpos = true; if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) @@ -172,6 +176,8 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif } + plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); + plan.zero_marks = script_zero_marks && !plan.apply_kerx && (!plan.apply_kern @@ -193,6 +199,12 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, script_fallback_mark_positioning; #ifndef HB_NO_AAT_SHAPE + /* If we're using morx shaping, we cancel mark position adjustment because + Apple Color Emoji assumes this will NOT be done when forming emoji sequences; + https://github.com/harfbuzz/harfbuzz/issues/2967. */ + if (plan.apply_morx) + plan.adjust_mark_positioning_when_zeroing = false; + /* Currently we always apply trak. */ plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); #endif @@ -266,11 +278,12 @@ hb_ot_shape_plan_t::position (hb_font_t *font, else if (this->apply_kerx) hb_aat_layout_position (this, font, buffer); #endif + #ifndef HB_NO_OT_KERN - else if (this->apply_kern) + if (this->apply_kern) hb_ot_layout_kern (this, font, buffer); #endif - else + else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); #ifndef HB_NO_AAT_SHAPE @@ -306,16 +319,17 @@ horizontal_features[] = }; static void -hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, - const hb_feature_t *user_features, - unsigned int num_user_features) +hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, + const hb_feature_t *user_features, + unsigned int num_user_features) { hb_ot_map_builder_t *map = &planner->map; map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); - switch (planner->props.direction) { + switch (planner->props.direction) + { case HB_DIRECTION_LTR: map->enable_feature (HB_TAG ('l','t','r','a')); map->enable_feature (HB_TAG ('l','t','r','m')); @@ -348,12 +362,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK); #endif - map->enable_feature (HB_TAG ('H','A','R','F')); + map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */ + map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ if (planner->shaper->collect_features) planner->shaper->collect_features (planner); - map->enable_feature (HB_TAG ('B','U','Z','Z')); + map->enable_feature (HB_TAG ('B','u','z','z')); /* Considered required. */ + map->enable_feature (HB_TAG ('B','U','Z','Z')); /* Considered discretionary. */ for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) map->add_feature (common_features[i]); @@ -363,6 +379,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->add_feature (horizontal_features[i]); else { + /* We only apply `vert` feature. See: + * https://github.com/harfbuzz/harfbuzz/commit/d71c0df2d17f4590d5611239577a6cb532c26528 + * https://lists.freedesktop.org/archives/harfbuzz/2013-August/003490.html */ + /* We really want to find a 'vert' feature if there's any in the font, no * matter which script/langsys it is listed (or not) under. * See various bugs referenced from: @@ -478,6 +498,14 @@ hb_set_unicode_props (hb_buffer_t *buffer) if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) { + _hb_glyph_info_set_continuation (&info[i]); + } + /* Regional_Indicators are hairy as hell... + * https://github.com/harfbuzz/harfbuzz/issues/2265 */ + else if (unlikely (i && hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F1E6u, 0x1F1FFu))) + { + if (hb_in_range<hb_codepoint_t> (info[i - 1].codepoint, 0x1F1E6u, 0x1F1FFu) && + !_hb_glyph_info_is_continuation (&info[i - 1])) _hb_glyph_info_set_continuation (&info[i]); } #ifndef HB_NO_EMOJI_SEQUENCES @@ -534,9 +562,8 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) hb_glyph_info_t info = dottedcircle; info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; - buffer->output_info (info); - while (buffer->idx < buffer->len && buffer->successful) - buffer->next_glyph (); + (void) buffer->output_info (info); + buffer->swap_buffers (); } @@ -560,6 +587,36 @@ hb_ensure_native_direction (hb_buffer_t *buffer) hb_direction_t direction = buffer->props.direction; hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script); + /* Numeric runs in natively-RTL scripts are actually native-LTR, so we reset + * the horiz_dir if the run contains at least one decimal-number char, and no + * letter chars (ideally we should be checking for chars with strong + * directionality but hb-unicode currently lacks bidi categories). + * + * This allows digit sequences in Arabic etc to be shaped in "native" + * direction, so that features like ligatures will work as intended. + * + * https://github.com/harfbuzz/harfbuzz/issues/501 + */ + if (unlikely (horiz_dir == HB_DIRECTION_RTL && direction == HB_DIRECTION_LTR)) + { + bool found_number = false, found_letter = false; + const auto* info = buffer->info; + const auto count = buffer->len; + for (unsigned i = 0; i < count; i++) + { + auto gc = _hb_glyph_info_get_general_category (&info[i]); + if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + found_number = true; + else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) + { + found_letter = true; + break; + } + } + if (found_number && !found_letter) + horiz_dir = HB_DIRECTION_LTR; + } + /* TODO vertical: * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType * Ogham fonts are supposed to be implemented BTT or not. Need to research that @@ -1113,8 +1170,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) _hb_buffer_allocate_unicode_vars (c->buffer); - c->buffer->clear_output (); - hb_ot_shape_initialize_masks (c); hb_set_unicode_props (c->buffer); hb_insert_dotted_circle (c->buffer, c->font); @@ -1124,7 +1179,8 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ensure_native_direction (c->buffer); if (c->plan->shaper->preprocess_text && - c->buffer->message(c->font, "start preprocess-text")) { + c->buffer->message(c->font, "start preprocess-text")) + { c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); (void) c->buffer->message(c->font, "end preprocess-text"); } @@ -1166,7 +1222,7 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, * @lookup_indexes: (out): The #hb_set_t set of lookups returned * * Computes the complete set of GSUB or GPOS lookups that are applicable - * under a given @shape_plan. + * under a given @shape_plan. * * Since: 0.9.7 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.h b/thirdparty/harfbuzz/src/hb-ot-shape.h index 7b1bcc0637..afdff72833 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.h +++ b/thirdparty/harfbuzz/src/hb-ot-shape.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.hh b/thirdparty/harfbuzz/src/hb-ot-shape.hh index acc98772a9..e8c81015c7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape.hh @@ -112,6 +112,7 @@ struct hb_ot_shape_plan_t #else static constexpr bool apply_kern = false; #endif + bool apply_fallback_kern : 1; #ifndef HB_NO_AAT_SHAPE bool apply_kerx : 1; bool apply_morx : 1; diff --git a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh index 6aa4fa4492..41d1734b39 100644 --- a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh @@ -297,7 +297,7 @@ struct STAT unsigned int axis_index; if (!get_design_axes ().lfind (tag, &axis_index)) return false; - hb_array_t<const OffsetTo<AxisValue>> axis_values = get_axis_value_offsets (); + hb_array_t<const Offset16To<AxisValue>> axis_values = get_axis_value_offsets (); for (unsigned int i = 0; i < axis_values.length; i++) { const AxisValue& axis_value = this+axis_values[i]; @@ -359,7 +359,7 @@ struct STAT hb_array_t<const StatAxisRecord> const get_design_axes () const { return (this+designAxesOffset).as_array (designAxisCount); } - hb_array_t<const OffsetTo<AxisValue>> const get_axis_value_offsets () const + hb_array_t<const Offset16To<AxisValue>> const get_axis_value_offsets () const { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); } @@ -373,7 +373,7 @@ struct STAT * in the 'fvar' table. In all fonts, must * be greater than zero if axisValueCount * is greater than zero. */ - LNNOffsetTo<UnsizedArrayOf<StatAxisRecord>> + NNOffset32To<UnsizedArrayOf<StatAxisRecord>> designAxesOffset; /* Offset in bytes from the beginning of * the STAT table to the start of the design @@ -381,7 +381,7 @@ struct STAT * set to zero; if designAxisCount is greater * than zero, must be greater than zero. */ HBUINT16 axisValueCount; /* The number of axis value tables. */ - LNNOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue>>> + NNOffset32To<UnsizedArrayOf<Offset16To<AxisValue>>> offsetToAxisValueOffsets; /* Offset in bytes from the beginning of * the STAT table to the start of the design diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index f1c391cf0e..fc9bffc23f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * <meta name="updated_at" content="2020-11-17 08:21 AM" /> - * File-Date: 2020-09-29 + * <meta name="updated_at" content="2021-09-02 09:40 PM" /> + * File-Date: 2021-08-06 */ #ifndef HB_OT_TAG_TABLE_HH @@ -93,6 +93,7 @@ static const LangTag ot_languages[] = { {"auz", HB_TAG('A','R','A',' ')}, /* Uzbeki Arabic -> Arabic */ {"av", HB_TAG('A','V','R',' ')}, /* Avaric -> Avar */ {"avl", HB_TAG('A','R','A',' ')}, /* Eastern Egyptian Bedawi Arabic -> Arabic */ +/*{"avn", HB_TAG('A','V','N',' ')},*/ /* Avatime */ /*{"awa", HB_TAG('A','W','A',' ')},*/ /* Awadhi */ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */ {"ayc", HB_TAG('A','Y','M',' ')}, /* Southern Aymara -> Aymara */ @@ -169,6 +170,7 @@ static const LangTag ot_languages[] = { {"bko", HB_TAG('B','M','L',' ')}, /* Kwa' -> Bamileke */ {"bla", HB_TAG('B','K','F',' ')}, /* Siksika -> Blackfoot */ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe -> Balante */ + {"blg", HB_TAG('I','B','A',' ')}, /* Balau (retired code) -> Iban */ {"bli", HB_TAG_NONE }, /* Bolia != Baluchi */ {"blk", HB_TAG('B','L','K',' ')}, /* Pa’o Karen */ {"blk", HB_TAG('K','R','N',' ')}, /* Pa'o Karen -> Karen */ @@ -344,6 +346,7 @@ static const LangTag ot_languages[] = { {"cth", HB_TAG('Q','I','N',' ')}, /* Thaiphum Chin -> Chin */ {"ctl", HB_TAG('C','C','H','N')}, /* Tlacoatzintepec Chinantec -> Chinantec */ {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol -> Bikol */ +/*{"ctt", HB_TAG('C','T','T',' ')},*/ /* Wayanad Chetti */ {"ctu", HB_TAG('M','Y','N',' ')}, /* Chol -> Mayan */ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavonic */ {"cuc", HB_TAG('C','C','H','N')}, /* Usila Chinantec -> Chinantec */ @@ -358,6 +361,7 @@ static const LangTag ot_languages[] = { {"czo", HB_TAG('Z','H','S',' ')}, /* Min Zhong Chinese -> Chinese, Simplified */ {"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin -> Chin */ {"da", HB_TAG('D','A','N',' ')}, /* Danish */ +/*{"dag", HB_TAG('D','A','G',' ')},*/ /* Dagbani */ {"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin -> Chin */ {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) (retired code) */ /*{"dar", HB_TAG('D','A','R',' ')},*/ /* Dargwa */ @@ -535,23 +539,27 @@ static const LangTag ot_languages[] = { {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */ {"haa", HB_TAG('A','T','H',' ')}, /* Han -> Athapaskan */ {"hae", HB_TAG('O','R','O',' ')}, /* Eastern Oromo -> Oromo */ - {"hai", HB_TAG_NONE }, /* Haida [macrolanguage] != Haitian (Haitian Creole) */ + {"hai", HB_TAG('H','A','I','0')}, /* Haida [macrolanguage] */ {"hak", HB_TAG('Z','H','S',' ')}, /* Hakka Chinese -> Chinese, Simplified */ {"hal", HB_TAG_NONE }, /* Halang != Halam (Falam Chin) */ {"har", HB_TAG('H','R','I',' ')}, /* Harari */ /*{"haw", HB_TAG('H','A','W',' ')},*/ /* Hawaiian */ + {"hax", HB_TAG('H','A','I','0')}, /* Southern Haida -> Haida */ /*{"hay", HB_TAG('H','A','Y',' ')},*/ /* Haya */ /*{"haz", HB_TAG('H','A','Z',' ')},*/ /* Hazaragi */ {"hbn", HB_TAG_NONE }, /* Heiban != Hammer-Banna */ {"hca", HB_TAG('C','P','P',' ')}, /* Andaman Creole Hindi -> Creoles */ + {"hdn", HB_TAG('H','A','I','0')}, /* Northern Haida -> Haida */ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ {"hea", HB_TAG('H','M','N',' ')}, /* Northern Qiandong Miao -> Hmong */ +/*{"hei", HB_TAG('H','E','I',' ')},*/ /* Heiltsuk */ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ /*{"hil", HB_TAG('H','I','L',' ')},*/ /* Hiligaynon */ {"hji", HB_TAG('M','L','Y',' ')}, /* Haji -> Malay */ {"hlt", HB_TAG('Q','I','N',' ')}, /* Matu Chin -> Chin */ {"hma", HB_TAG('H','M','N',' ')}, /* Southern Mashan Hmong -> Hmong */ {"hmc", HB_TAG('H','M','N',' ')}, /* Central Huishui Hmong -> Hmong */ + {"hmd", HB_TAG('H','M','D',' ')}, /* Large Flowery Miao -> A-Hmao */ {"hmd", HB_TAG('H','M','N',' ')}, /* Large Flowery Miao -> Hmong */ {"hme", HB_TAG('H','M','N',' ')}, /* Eastern Huishui Hmong -> Hmong */ {"hmg", HB_TAG('H','M','N',' ')}, /* Southwestern Guiyang Hmong -> Hmong */ @@ -567,6 +575,7 @@ static const LangTag ot_languages[] = { {"hms", HB_TAG('H','M','N',' ')}, /* Southern Qiandong Miao -> Hmong */ {"hmw", HB_TAG('H','M','N',' ')}, /* Western Mashan Hmong -> Hmong */ {"hmy", HB_TAG('H','M','N',' ')}, /* Southern Guiyang Hmong -> Hmong */ + {"hmz", HB_TAG('H','M','Z',' ')}, /* Hmong Shua -> Hmong Shuat */ {"hmz", HB_TAG('H','M','N',' ')}, /* Hmong Shua -> Hmong */ /*{"hnd", HB_TAG('H','N','D',' ')},*/ /* Southern Hindko -> Hindko */ {"hne", HB_TAG('C','H','H',' ')}, /* Chhattisgarhi -> Chattisgarhi */ @@ -623,6 +632,7 @@ static const LangTag ot_languages[] = { {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */ {"io", HB_TAG('I','D','O',' ')}, /* Ido */ {"iri", HB_TAG_NONE }, /* Rigwe != Irish */ +/*{"iru", HB_TAG('I','R','U',' ')},*/ /* Irula */ {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */ {"ism", HB_TAG_NONE }, /* Masimasi != Inari Sami */ {"it", HB_TAG('I','T','A',' ')}, /* Italian */ @@ -658,6 +668,7 @@ static const LangTag ot_languages[] = { {"kac", HB_TAG_NONE }, /* Kachin != Kachchi */ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */ +/*{"kaw", HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */ {"kby", HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */ {"kca", HB_TAG('K','H','K',' ')}, /* Khanty -> Khanty-Kazim */ @@ -777,6 +788,7 @@ static const LangTag ot_languages[] = { {"kvu", HB_TAG('K','R','N',' ')}, /* Yinbaw Karen -> Karen */ {"kvy", HB_TAG('K','R','N',' ')}, /* Yintale Karen -> Karen */ {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */ +/*{"kwk", HB_TAG('K','W','K',' ')},*/ /* Kwakiutl -> Kwakʼwala */ {"kww", HB_TAG('C','P','P',' ')}, /* Kwinti -> Creoles */ {"kwy", HB_TAG('K','O','N','0')}, /* San Salvador Kongo -> Kongo */ {"kxc", HB_TAG('K','M','S',' ')}, /* Konso -> Komso */ @@ -804,6 +816,7 @@ static const LangTag ot_languages[] = { {"lcf", HB_TAG('M','L','Y',' ')}, /* Lubu -> Malay */ {"ldi", HB_TAG('K','O','N','0')}, /* Laari -> Kongo */ {"ldk", HB_TAG_NONE }, /* Leelau != Ladakhi */ +/*{"lef", HB_TAG('L','E','F',' ')},*/ /* Lelemi */ /*{"lez", HB_TAG('L','E','Z',' ')},*/ /* Lezghian -> Lezgi */ {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */ {"li", HB_TAG('L','I','M',' ')}, /* Limburgish */ @@ -830,10 +843,12 @@ static const LangTag ot_languages[] = { {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ /*{"lom", HB_TAG('L','O','M',' ')},*/ /* Loma (Liberia) */ {"lou", HB_TAG('C','P','P',' ')}, /* Louisiana Creole -> Creoles */ +/*{"lpo", HB_TAG('L','P','O',' ')},*/ /* Lipo */ /*{"lrc", HB_TAG('L','R','C',' ')},*/ /* Northern Luri -> Luri */ {"lri", HB_TAG('L','U','H',' ')}, /* Marachi -> Luyia */ {"lrm", HB_TAG('L','U','H',' ')}, /* Marama -> Luyia */ {"lrt", HB_TAG('C','P','P',' ')}, /* Larantuka Malay -> Creoles */ + {"lsb", HB_TAG_NONE }, /* Burundian Sign Language != Lower Sorbian */ {"lsm", HB_TAG('L','U','H',' ')}, /* Saamia -> Luyia */ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */ {"ltg", HB_TAG('L','V','I',' ')}, /* Latgalian -> Latvian */ @@ -990,7 +1005,7 @@ static const LangTag ot_languages[] = { /*{"nga", HB_TAG('N','G','A',' ')},*/ /* Ngbaka */ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ {"ngm", HB_TAG('C','P','P',' ')}, /* Ngatik Men's Creole -> Creoles */ - {"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni -> Sutu */ + {"ngo", HB_TAG('S','X','T',' ')}, /* Ngoni (retired code) -> Sutu */ {"ngr", HB_TAG_NONE }, /* Engdewu != Nagari */ {"ngu", HB_TAG('N','A','H',' ')}, /* Guerrero Nahuatl -> Nahuatl */ {"nhc", HB_TAG('N','A','H',' ')}, /* Tabasco Nahuatl -> Nahuatl */ @@ -1228,6 +1243,7 @@ static const LangTag ot_languages[] = { {"rbl", HB_TAG('B','I','K',' ')}, /* Miraya Bikol -> Bikol */ {"rcf", HB_TAG('C','P','P',' ')}, /* Réunion Creole French -> Creoles */ /*{"rej", HB_TAG('R','E','J',' ')},*/ /* Rejang */ +/*{"rhg", HB_TAG('R','H','G',' ')},*/ /* Rohingya */ /*{"ria", HB_TAG('R','I','A',' ')},*/ /* Riang (India) */ {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */ {"rif", HB_TAG('B','B','R',' ')}, /* Tarifit -> Berber */ @@ -1283,6 +1299,7 @@ static const LangTag ot_languages[] = { {"sek", HB_TAG('A','T','H',' ')}, /* Sekani -> Athapaskan */ /*{"sel", HB_TAG('S','E','L',' ')},*/ /* Selkup */ {"sez", HB_TAG('Q','I','N',' ')}, /* Senthang Chin -> Chin */ + {"sfm", HB_TAG('S','F','M',' ')}, /* Small Flowery Miao */ {"sfm", HB_TAG('H','M','N',' ')}, /* Small Flowery Miao -> Hmong */ {"sg", HB_TAG('S','G','O',' ')}, /* Sango */ /*{"sga", HB_TAG('S','G','A',' ')},*/ /* Old Irish (to 900) */ @@ -1410,6 +1427,7 @@ static const LangTag ot_languages[] = { {"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */ {"tkm", HB_TAG_NONE }, /* Takelma != Turkmen */ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ +/*{"tli", HB_TAG('T','L','I',' ')},*/ /* Tlingit */ {"tmg", HB_TAG('C','P','P',' ')}, /* Ternateño -> Creoles */ {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek [macrolanguage] */ {"tmh", HB_TAG('B','B','R',' ')}, /* Tamashek [macrolanguage] -> Berber */ @@ -1496,6 +1514,7 @@ static const LangTag ot_languages[] = { {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ {"wbr", HB_TAG('R','A','J',' ')}, /* Wagdi -> Rajasthani */ +/*{"wci", HB_TAG('W','C','I',' ')},*/ /* Waci Gbe */ {"wea", HB_TAG('K','R','N',' ')}, /* Wewaw -> Karen */ {"wes", HB_TAG('C','P','P',' ')}, /* Cameroon Pidgin -> Creoles */ {"weu", HB_TAG('Q','I','N',' ')}, /* Rawngtu Chin -> Chin */ @@ -1520,6 +1539,8 @@ static const LangTag ot_languages[] = { {"xmm", HB_TAG('C','P','P',' ')}, /* Manado Malay -> Creoles */ {"xmv", HB_TAG('M','L','G',' ')}, /* Antankarana Malagasy -> Malagasy */ {"xmw", HB_TAG('M','L','G',' ')}, /* Tsimihety Malagasy -> Malagasy */ + {"xnj", HB_TAG('S','X','T',' ')}, /* Ngoni (Tanzania) -> Sutu */ + {"xnq", HB_TAG('S','X','T',' ')}, /* Ngoni (Mozambique) -> Sutu */ {"xnr", HB_TAG('D','G','R',' ')}, /* Kangri -> Dogri (macrolanguage) */ /*{"xog", HB_TAG('X','O','G',' ')},*/ /* Soga */ {"xpe", HB_TAG('X','P','E',' ')}, /* Liberia Kpelle -> Kpelle (Liberia) */ @@ -1528,6 +1549,8 @@ static const LangTag ot_languages[] = { {"xsl", HB_TAG('S','L','A',' ')}, /* South Slavey -> Slavey */ {"xsl", HB_TAG('A','T','H',' ')}, /* South Slavey -> Athapaskan */ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) -> Silte Gurage */ +/*{"xub", HB_TAG('X','U','B',' ')},*/ /* Betta Kurumba -> Bette Kuruma */ +/*{"xuj", HB_TAG('X','U','J',' ')},*/ /* Jennu Kurumba -> Jennu Kuruma */ {"xup", HB_TAG('A','T','H',' ')}, /* Upper Umpqua -> Athapaskan */ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat -> Todo */ {"yaj", HB_TAG('B','A','D','0')}, /* Banda-Yangere -> Banda */ @@ -1538,13 +1561,16 @@ static const LangTag ot_languages[] = { {"ybb", HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */ {"ybd", HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ {"ydd", HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ +/*{"ygp", HB_TAG('Y','G','P',' ')},*/ /* Gepo */ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ {"yih", HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ {"yim", HB_TAG_NONE }, /* Yimchungru Naga != Yi Modern */ +/*{"yna", HB_TAG('Y','N','A',' ')},*/ /* Aluo */ {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */ {"yos", HB_TAG('Q','I','N',' ')}, /* Yos (retired code) -> Chin */ {"yua", HB_TAG('M','Y','N',' ')}, /* Yucateco -> Mayan */ {"yue", HB_TAG('Z','H','H',' ')}, /* Yue Chinese -> Chinese, Traditional, Hong Kong SAR */ +/*{"ywq", HB_TAG('Y','W','Q',' ')},*/ /* Wuding-Luquan Yi */ {"za", HB_TAG('Z','H','A',' ')}, /* Zhuang [macrolanguage] */ {"zch", HB_TAG('Z','H','A',' ')}, /* Central Hongshuihe Zhuang -> Zhuang */ {"zdj", HB_TAG('C','M','R',' ')}, /* Ngazidja Comorian -> Comorian */ @@ -2808,6 +2834,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("hnd", -1); /* Southern Hindko */ case HB_TAG('H','Y','E',' '): /* Armenian */ return hb_language_from_string ("hyw", -1); /* Western Armenian */ + case HB_TAG('I','B','A',' '): /* Iban */ + return hb_language_from_string ("iba", -1); /* Iban */ case HB_TAG('I','J','O',' '): /* Ijo */ return hb_language_from_string ("ijo", -1); /* Ijo [family] */ case HB_TAG('I','N','U',' '): /* Inuktitut */ @@ -2892,6 +2920,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag) return hb_language_from_string ("sq", -1); /* Albanian [macrolanguage] */ case HB_TAG('S','R','B',' '): /* Serbian */ return hb_language_from_string ("sr", -1); /* Serbian */ + case HB_TAG('S','X','T',' '): /* Sutu */ + return hb_language_from_string ("xnj", -1); /* Ngoni (Tanzania) */ case HB_TAG('S','Y','R',' '): /* Syriac */ return hb_language_from_string ("syr", -1); /* Syriac [macrolanguage] */ case HB_TAG('S','Y','R','E'): /* Syriac, Estrangela script-variant (equivalent to ISO 15924 'Syre') */ diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc index 19bd3639d3..1837063af8 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag.cc +++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc @@ -164,6 +164,15 @@ hb_ot_all_tags_from_script (hb_script_t script, *count = i; } +/** + * hb_ot_tag_to_script: + * @tag: a script tag + * + * Converts a script tag to an #hb_script_t. + * + * Return value: The #hb_script_t corresponding to @tag. + * + **/ hb_script_t hb_ot_tag_to_script (hb_tag_t tag) { @@ -351,13 +360,13 @@ parse_private_use_subtag (const char *private_use_subtag, * hb_ot_tags_from_script_and_language: * @script: an #hb_script_t to convert. * @language: an #hb_language_t to convert. - * @script_count: (allow-none): maximum number of script tags to retrieve (IN) + * @script_count: (inout) (optional): maximum number of script tags to retrieve (IN) * and actual number of script tags retrieved (OUT) - * @script_tags: (out) (allow-none): array of size at least @script_count to store the + * @script_tags: (out) (optional): array of size at least @script_count to store the * script tag results - * @language_count: (allow-none): maximum number of language tags to retrieve + * @language_count: (inout) (optional): maximum number of language tags to retrieve * (IN) and actual number of language tags retrieved (OUT) - * @language_tags: (out) (allow-none): array of size at least @language_count to store + * @language_tags: (out) (optional): array of size at least @language_count to store * the language tag results * * Converts an #hb_script_t and an #hb_language_t to script and language tags. @@ -424,10 +433,12 @@ hb_ot_tags_from_script_and_language (hb_script_t script, /** * hb_ot_tag_to_language: + * @tag: an language tag * + * Converts a language tag to an #hb_language_t. * - * - * Return value: (transfer none): + * Return value: (transfer none) (nullable): + * The #hb_language_t corresponding to @tag. * * Since: 0.9.2 **/ @@ -478,9 +489,9 @@ hb_ot_tag_to_language (hb_tag_t tag) * hb_ot_tags_to_script_and_language: * @script_tag: a script tag * @language_tag: a language tag - * @script: (allow-none): the #hb_script_t corresponding to @script_tag (OUT). - * @language: (allow-none): the #hb_language_t corresponding to @script_tag and - * @language_tag (OUT). + * @script: (out) (optional): the #hb_script_t corresponding to @script_tag. + * @language: (out) (optional): the #hb_language_t corresponding to @script_tag and + * @language_tag. * * Converts a script tag and a language tag to an #hb_script_t and an * #hb_language_t. @@ -511,7 +522,7 @@ hb_ot_tags_to_script_and_language (hb_tag_t script_tag, unsigned char *buf; const char *lang_str = hb_language_to_string (*language); size_t len = strlen (lang_str); - buf = (unsigned char *) malloc (len + 16); + buf = (unsigned char *) hb_malloc (len + 16); if (unlikely (!buf)) { *language = nullptr; @@ -533,7 +544,7 @@ hb_ot_tags_to_script_and_language (hb_tag_t script_tag, for (shift = 28; shift >= 0; shift -= 4) buf[len++] = TOHEX (script_tag >> shift); *language = hb_language_from_string ((char *) buf, len); - free (buf); + hb_free (buf); } } } diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh index 29219adb0a..65f26c1d22 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @@ -58,7 +58,7 @@ struct AxisValueMap DEFINE_SIZE_STATIC (4); }; -struct SegmentMaps : ArrayOf<AxisValueMap> +struct SegmentMaps : Array16Of<AxisValueMap> { int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh index f9e933fb2b..05f289db26 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh @@ -142,11 +142,13 @@ struct AxisRecord max = hb_max (default_, maxValue / 65536.f); } - protected: + public: Tag axisTag; /* Tag identifying the design variation for the axis. */ + protected: HBFixed minValue; /* The minimum coordinate value for the axis. */ HBFixed defaultValue; /* The default coordinate value for the axis. */ HBFixed maxValue; /* The maximum coordinate value for the axis. */ + public: HBUINT16 flags; /* Axis flags. */ NameID axisNameID; /* The name ID for entries in the 'name' table that * provide a display name for this axis. */ @@ -214,7 +216,6 @@ struct fvar return axes.lfind (tag, axis_index) && (axes[*axis_index].get_axis_deprecated (info), true); } #endif - bool find_axis_info (hb_tag_t tag, hb_ot_var_axis_info_t *info) const { @@ -289,7 +290,7 @@ struct fvar ; } - protected: + public: hb_array_t<const AxisRecord> get_axes () const { return hb_array (&(this+firstAxis), axisCount); } @@ -303,7 +304,7 @@ struct fvar protected: FixedVersion<>version; /* Version of the fvar table * initially set to 0x00010000u */ - OffsetTo<AxisRecord> + Offset16To<AxisRecord> firstAxis; /* Offset in bytes from the beginning of the table * to the start of the AxisRecord array. */ HBUINT16 reserved; /* This field is permanently reserved. Set to 2. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index 4d4e6dcae4..49b5532d40 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -374,7 +374,7 @@ struct GlyphVariationData * low 12 bits are the number of tuple variation tables * for this glyph. The number of tuple variation tables * can be any number between 1 and 4095. */ - OffsetTo<HBUINT8> + Offset16To<HBUINT8> data; /* Offset from the start of the GlyphVariationData table * to the serialized data. */ /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */ @@ -419,7 +419,9 @@ struct gvar out->glyphCount = num_glyphs; unsigned int subset_data_size = 0; - for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) + for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1; + gid < num_glyphs; + gid++) { hb_codepoint_t old_gid; if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue; @@ -449,7 +451,9 @@ struct gvar out->dataZ = subset_data - (char *) out; unsigned int glyph_offset = 0; - for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++) + for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1; + gid < num_glyphs; + gid++) { hb_codepoint_t old_gid; hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid) @@ -652,8 +656,8 @@ no_more_gaps: /* apply specified / inferred deltas to points */ for (unsigned int i = 0; i < points.length; i++) { - points[i].x += roundf (deltas[i].x); - points[i].y += roundf (deltas[i].y); + points[i].x += deltas[i].x; + points[i].y += deltas[i].y; } } while (iterator.move_to_next ()); @@ -676,7 +680,7 @@ no_more_gaps: * can be referenced within glyph variation data tables for * multiple glyphs, as opposed to other tuple records stored * directly within a glyph variation data table. */ - LNNOffsetTo<UnsizedArrayOf<F2DOT14>> + NNOffset32To<UnsizedArrayOf<F2DOT14>> sharedTuples; /* Offset from the start of this table to the shared tuple records. * Array of tuple records shared across all glyph variation data tables. */ HBUINT16 glyphCount; /* The number of glyphs in this font. This must match the number of @@ -684,7 +688,7 @@ no_more_gaps: HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows. * If bit 0 is clear, the offsets are uint16; if bit 0 is set, the * offsets are uint32. */ - LOffsetTo<GlyphVariationData> + Offset32To<GlyphVariationData> dataZ; /* Offset from the start of this table to the array of * GlyphVariationData tables. */ UnsizedArrayOf<HBUINT8> diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index fdcc88d674..72217e7f29 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -49,12 +49,12 @@ struct DeltaSetIndexMap { unsigned int width = plan.get_width (); unsigned int inner_bit_count = plan.get_inner_bit_count (); - const hb_array_t<const unsigned int> output_map = plan.get_output_map (); + 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); + if (unlikely (!c->extend_min (this))) return_trace (false); format = ((width-1)<<4)|(inner_bit_count-1); mapCount = output_map.length; @@ -76,7 +76,7 @@ struct DeltaSetIndexMap return_trace (true); } - unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */ + 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. */ @@ -217,7 +217,7 @@ struct index_map_subset_plan_t hb_codepoint_t old_gid; if (plan->old_gid_for_new_gid (gid, &old_gid)) { - unsigned int v = input_map->map (old_gid); + uint32_t v = input_map->map (old_gid); unsigned int outer = v >> 16; output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); } @@ -234,14 +234,14 @@ struct index_map_subset_plan_t { return (map_count? (DeltaSetIndexMap::min_size + get_width () * map_count): 0); } bool is_identity () const { return get_output_map ().length == 0; } - hb_array_t<const unsigned int> get_output_map () const { return output_map.as_array (); } + hb_array_t<const uint32_t> get_output_map () const { return output_map.as_array (); } protected: unsigned int map_count; hb_vector_t<unsigned int> max_inners; unsigned int outer_bit_count; unsigned int inner_bit_count; - hb_vector_t<unsigned int> output_map; + hb_vector_t<uint32_t> output_map; }; struct hvarvvar_subset_plan_t @@ -272,7 +272,7 @@ struct hvarvvar_subset_plan_t index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan); if (index_maps[0] == &Null (DeltaSetIndexMap)) { - retain_adv_map = plan->retain_gids; + retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; outer_map.add (0); for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) { @@ -367,15 +367,15 @@ struct HVARVVAR TRACE_SERIALIZE (this); if (im_plans[index_map_subset_plan_t::ADV_INDEX].is_identity ()) advMap = 0; - else if (unlikely (!advMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX]))) + else if (unlikely (!advMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX]))) return_trace (false); if (im_plans[index_map_subset_plan_t::LSB_INDEX].is_identity ()) lsbMap = 0; - else if (unlikely (!lsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX]))) + else if (unlikely (!lsbMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX]))) return_trace (false); if (im_plans[index_map_subset_plan_t::RSB_INDEX].is_identity ()) rsbMap = 0; - else if (unlikely (!rsbMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX]))) + else if (unlikely (!rsbMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX]))) return_trace (false); return_trace (true); @@ -398,8 +398,10 @@ struct HVARVVAR out->version.major = 1; out->version.minor = 0; - if (unlikely (!out->varStore.serialize (c->serializer, out) - .serialize (c->serializer, hvar_plan.var_store, hvar_plan.inner_maps.as_array ()))) + if (unlikely (!out->varStore + .serialize_serialize (c->serializer, + hvar_plan.var_store, + hvar_plan.inner_maps.as_array ()))) return_trace (false); return_trace (out->T::serialize_index_maps (c->serializer, @@ -408,7 +410,7 @@ struct HVARVVAR float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const { - unsigned int varidx = (this+advMap).map (glyph); + uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, font->coords, font->num_coords); } @@ -416,7 +418,7 @@ struct HVARVVAR const int *coords, unsigned int coord_count) const { if (!has_side_bearing_deltas ()) return 0.f; - unsigned int varidx = (this+lsbMap).map (glyph); + uint32_t varidx = (this+lsbMap).map (glyph); return (this+varStore).get_delta (varidx, coords, coord_count); } @@ -425,13 +427,13 @@ struct HVARVVAR protected: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ - LOffsetTo<VariationStore> + Offset32To<VariationStore> varStore; /* Offset to item variation store table. */ - LOffsetTo<DeltaSetIndexMap> + Offset32To<DeltaSetIndexMap> advMap; /* Offset to advance var-idx mapping. */ - LOffsetTo<DeltaSetIndexMap> + Offset32To<DeltaSetIndexMap> lsbMap; /* Offset to lsb/tsb var-idx mapping. */ - LOffsetTo<DeltaSetIndexMap> + Offset32To<DeltaSetIndexMap> rsbMap; /* Offset to rsb/bsb var-idx mapping. */ public: @@ -466,7 +468,7 @@ struct VVAR : HVARVVAR { return_trace (false); if (!im_plans[index_map_subset_plan_t::VORG_INDEX].get_map_count ()) vorgMap = 0; - else if (unlikely (!vorgMap.serialize (c, this).serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX]))) + else if (unlikely (!vorgMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX]))) return_trace (false); return_trace (true); @@ -475,7 +477,7 @@ struct VVAR : HVARVVAR { bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); } protected: - LOffsetTo<DeltaSetIndexMap> + Offset32To<DeltaSetIndexMap> vorgMap; /* Offset to vertical-origin var-idx mapping. */ public: diff --git a/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh index 1b7fad9cec..208db46741 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh @@ -103,7 +103,7 @@ protected: HBUINT16 valueRecordSize;/* The size in bytes of each value record — * must be greater than zero. */ HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ - OffsetTo<VariationStore> + Offset16To<VariationStore> varStore; /* Offset to item variation store table. */ UnsizedArrayOf<HBUINT8> valuesZ; /* Array of value records. The records must be diff --git a/thirdparty/harfbuzz/src/hb-ot-var.cc b/thirdparty/harfbuzz/src/hb-ot-var.cc index 1fe57383c0..6b42b45cd9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var.cc +++ b/thirdparty/harfbuzz/src/hb-ot-var.cc @@ -56,7 +56,7 @@ * * Tests whether a face includes any OpenType variation data in the `fvar` table. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 1.4.2 **/ @@ -87,7 +87,7 @@ hb_ot_var_get_axis_count (hb_face_t *face) * hb_ot_var_get_axes: * @face: #hb_face_t to work upon * @start_offset: offset of the first lookup to retrieve - * @axes_count: (inout) (allow-none): Input = the maximum number of variation axes to return; + * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return; * Output = the actual number of variation axes returned (may be zero) * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found * @@ -133,7 +133,7 @@ hb_ot_var_find_axis (hb_face_t *face, * hb_ot_var_get_axis_infos: * @face: #hb_face_t to work upon * @start_offset: offset of the first lookup to retrieve - * @axes_count: (inout) (allow-none): Input = the maximum number of variation axes to return; + * @axes_count: (inout) (optional): Input = the maximum number of variation axes to return; * Output = the actual number of variation axes returned (may be zero) * @axes_array: (out caller-allocates) (array length=axes_count): The array of variation axes found * @@ -162,7 +162,7 @@ hb_ot_var_get_axis_infos (hb_face_t *face, * Fetches the variation-axis information corresponding to the specified axis tag * in the specified face. * - * Return value: true if data found, false otherwise + * Return value: %true if data found, %false otherwise * * Since: 2.2.0 **/ @@ -237,7 +237,7 @@ hb_ot_var_named_instance_get_postscript_name_id (hb_face_t *face, * hb_ot_var_named_instance_get_design_coords: * @face: The #hb_face_t to work on * @instance_index: The index of the named instance to query - * @coords_length: (inout) (allow-none): Input = the maximum number of coordinates to return; + * @coords_length: (inout) (optional): Input = the maximum number of coordinates to return; * Output = the actual number of coordinates returned (may be zero) * @coords: (out) (array length=coords_length): The array of coordinates found for the query * diff --git a/thirdparty/harfbuzz/src/hb-ot-var.h b/thirdparty/harfbuzz/src/hb-ot-var.h index ef2ca0a716..ce201d3b4f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var.h +++ b/thirdparty/harfbuzz/src/hb-ot-var.h @@ -24,7 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_H_IN +#if !defined(HB_OT_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb-ot.h> instead." #endif @@ -36,34 +36,38 @@ HB_BEGIN_DECLS /** - * hb_tag_t: - * @HB_OT_TAG_VAR_AXIS_ITALIC: Registered tag for the roman/italic axis + * HB_OT_TAG_VAR_AXIS_ITALIC: + * + * Registered tag for the roman/italic axis. */ #define HB_OT_TAG_VAR_AXIS_ITALIC HB_TAG('i','t','a','l') /** - * hb_tag_t: - * @HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE: Registered tag for the optical-size axis + * HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE: * + * Registered tag for the optical-size axis. * <note>Note: The optical-size axis supersedes the OpenType `size` feature.</note> */ #define HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE HB_TAG('o','p','s','z') /** - * hb_tag_t: - * @HB_OT_TAG_VAR_AXIS_SLANT: Registered tag for the slant axis + * HB_OT_TAG_VAR_AXIS_SLANT: + * + * Registered tag for the slant axis */ #define HB_OT_TAG_VAR_AXIS_SLANT HB_TAG('s','l','n','t') /** - * hb_tag_t: - * @HB_OT_TAG_VAR_AXIS_WIDTH: Registered tag for the width axis + * HB_OT_TAG_VAR_AXIS_WIDTH: + * + * Registered tag for the width axis. */ #define HB_OT_TAG_VAR_AXIS_WIDTH HB_TAG('w','d','t','h') /** - * hb_tag_t: - * @HB_OT_TAG_VAR_AXIS_WEIGHT: Registered tag for the weight axis + * HB_OT_TAG_VAR_AXIS_WEIGHT: + * + * Registered tag for the weight axis. */ #define HB_OT_TAG_VAR_AXIS_WEIGHT HB_TAG('w','g','h','t') @@ -88,11 +92,14 @@ hb_ot_var_get_axis_count (hb_face_t *face); * hb_ot_var_axis_flags_t: * @HB_OT_VAR_AXIS_FLAG_HIDDEN: The axis should not be exposed directly in user interfaces. * + * Flags for #hb_ot_var_axis_info_t. + * * Since: 2.2.0 */ typedef enum { /*< flags >*/ HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u, + /*< private >*/ _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/ } hb_ot_var_axis_flags_t; diff --git a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh index c6803200f9..efa7737d6f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-vorg-table.hh @@ -125,7 +125,7 @@ struct VORG FixedVersion<>version; /* Version of VORG table. Set to 0x00010000u. */ FWORD defaultVertOriginY; /* The default vertical origin. */ - SortedArrayOf<VertOriginMetric> + SortedArray16Of<VertOriginMetric> vertYOrigins; /* The array of vertical origins. */ public: diff --git a/thirdparty/harfbuzz/src/hb-pool.hh b/thirdparty/harfbuzz/src/hb-pool.hh index dcf0faf2a9..dcf8f6627d 100644 --- a/thirdparty/harfbuzz/src/hb-pool.hh +++ b/thirdparty/harfbuzz/src/hb-pool.hh @@ -41,7 +41,7 @@ struct hb_pool_t { next = nullptr; - for (chunk_t *_ : chunks) ::free (_); + for (chunk_t *_ : chunks) hb_free (_); chunks.fini (); } @@ -51,7 +51,7 @@ struct hb_pool_t if (unlikely (!next)) { if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr; - chunk_t *chunk = (chunk_t *) calloc (1, sizeof (chunk_t)); + chunk_t *chunk = (chunk_t *) hb_calloc (1, sizeof (chunk_t)); if (unlikely (!chunk)) return nullptr; chunks.push (chunk); next = chunk->thread (); @@ -65,7 +65,7 @@ struct hb_pool_t return obj; } - void free (T* obj) + void release (T* obj) { * (T**) obj = next; next = obj; diff --git a/thirdparty/harfbuzz/src/hb-priority-queue.hh b/thirdparty/harfbuzz/src/hb-priority-queue.hh new file mode 100644 index 0000000000..7d799ae906 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-priority-queue.hh @@ -0,0 +1,151 @@ +/* + * Copyright © 2020 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#ifndef HB_PRIORITY_QUEUE_HH +#define HB_PRIORITY_QUEUE_HH + +#include "hb.hh" +#include "hb-vector.hh" + +/* + * hb_priority_queue_t + * + * Priority queue implemented as a binary heap. Supports extract minimum + * and insert operations. + */ +struct hb_priority_queue_t +{ + HB_DELETE_COPY_ASSIGN (hb_priority_queue_t); + hb_priority_queue_t () { init (); } + ~hb_priority_queue_t () { fini (); } + + private: + typedef hb_pair_t<int64_t, unsigned> item_t; + hb_vector_t<item_t> heap; + + public: + void init () { heap.init (); } + + void fini () { heap.fini (); } + + void reset () { heap.resize (0); } + + bool in_error () const { return heap.in_error (); } + + void insert (int64_t priority, unsigned value) + { + heap.push (item_t (priority, value)); + bubble_up (heap.length - 1); + } + + item_t pop_minimum () + { + item_t result = heap[0]; + + heap[0] = heap[heap.length - 1]; + heap.shrink (heap.length - 1); + bubble_down (0); + + return result; + } + + const item_t& minimum () + { + return heap[0]; + } + + bool is_empty () const { return heap.length == 0; } + explicit operator bool () const { return !is_empty (); } + unsigned int get_population () const { return heap.length; } + + /* Sink interface. */ + hb_priority_queue_t& operator << (item_t item) + { insert (item.first, item.second); return *this; } + + private: + + static constexpr unsigned parent (unsigned index) + { + return (index - 1) / 2; + } + + static constexpr unsigned left_child (unsigned index) + { + return 2 * index + 1; + } + + static constexpr unsigned right_child (unsigned index) + { + return 2 * index + 2; + } + + void bubble_down (unsigned index) + { + unsigned left = left_child (index); + unsigned right = right_child (index); + + bool has_left = left < heap.length; + if (!has_left) + // If there's no left, then there's also no right. + return; + + bool has_right = right < heap.length; + if (heap[index].first <= heap[left].first + && (!has_right || heap[index].first <= heap[right].first)) + return; + + if (!has_right || heap[left].first < heap[right].first) + { + swap (index, left); + bubble_down (left); + return; + } + + swap (index, right); + bubble_down (right); + } + + void bubble_up (unsigned index) + { + if (index == 0) return; + + unsigned parent_index = parent (index); + if (heap[parent_index].first <= heap[index].first) + return; + + swap (index, parent_index); + bubble_up (parent_index); + } + + void swap (unsigned a, unsigned b) + { + item_t temp = heap[a]; + heap[a] = heap[b]; + heap[b] = temp; + } +}; + +#endif /* HB_PRIORITY_QUEUE_HH */ diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh new file mode 100644 index 0000000000..b02128b5c4 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -0,0 +1,769 @@ +/* + * Copyright © 2020 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#ifndef HB_REPACKER_HH +#define HB_REPACKER_HH + +#include "hb-open-type.hh" +#include "hb-map.hh" +#include "hb-priority-queue.hh" +#include "hb-serialize.hh" +#include "hb-vector.hh" + + +struct graph_t +{ + struct vertex_t + { + vertex_t () : + distance (0), + incoming_edges (0), + start (0), + end (0), + priority(0) {} + + void fini () { obj.fini (); } + + hb_serialize_context_t::object_t obj; + int64_t distance; + unsigned incoming_edges; + unsigned start; + unsigned end; + unsigned priority; + + bool is_shared () const + { + return incoming_edges > 1; + } + + bool is_leaf () const + { + return !obj.links.length; + } + + void raise_priority () + { + priority++; + } + + int64_t modified_distance (unsigned order) const + { + // TODO(garretrieger): once priority is high enough, should try + // setting distance = 0 which will force to sort immediately after + // it's parent where possible. + + int64_t modified_distance = + hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFF); + return (modified_distance << 24) | (0x00FFFFFF & 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))); + } + }; + + 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; + } + }; + + /* + * A topological sorting of an object graph. Ordered + * in reverse serialization order (first object in the + * serialization is at the end of the list). This matches + * the 'packed' object stack used internally in the + * serializer + */ + graph_t (const hb_vector_t<hb_serialize_context_t::object_t *>& objects) + : edge_count_invalid (true), + distance_invalid (true), + positions_invalid (true), + successful (true) + { + bool removed_nil = false; + for (unsigned i = 0; i < objects.length; i++) + { + // TODO(grieger): check all links point to valid objects. + + // If this graph came from a serialization buffer object 0 is the + // nil object. We don't need it for our purposes here so drop it. + if (i == 0 && !objects[i]) + { + removed_nil = true; + continue; + } + + vertex_t* v = vertices_.push (); + 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--; + } + } + + ~graph_t () + { + vertices_.fini_deep (); + clone_buffers_.fini_deep (); + } + + bool in_error () const + { + return !successful || vertices_.in_error () || clone_buffers_.in_error (); + } + + const vertex_t& root () const + { + return vertices_[root_idx ()]; + } + + unsigned root_idx () const + { + // Object graphs are in reverse order, the first object is at the end + // of the vector. Since the graph is topologically sorted it's safe to + // assume the first object has no incoming edges. + return vertices_.length - 1; + } + + const hb_serialize_context_t::object_t& object(unsigned i) const + { + return vertices_[i].obj; + } + + /* + * serialize graph into the provided serialization buffer. + */ + void serialize (hb_serialize_context_t* c) const + { + c->start_serialize<void> (); + for (unsigned i = 0; i < vertices_.length; i++) { + c->push (); + + size_t size = vertices_[i].obj.tail - vertices_[i].obj.head; + char* start = c->allocate_size <char> (size); + if (!start) return; + + memcpy (start, vertices_[i].obj.head, size); + + for (const auto& link : vertices_[i].obj.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->end_serialize (); + } + + /* + * Generates a new topological sorting of graph using Kahn's + * algorithm: https://en.wikipedia.org/wiki/Topological_sorting#Algorithms + */ + void sort_kahn () + { + positions_invalid = true; + + if (vertices_.length <= 1) { + // Graph of 1 or less doesn't need sorting. + return; + } + + hb_vector_t<unsigned> queue; + hb_vector_t<vertex_t> sorted_graph; + 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 (); + + queue.push (root_idx ()); + int new_id = vertices_.length - 1; + + while (!queue.in_error () && queue.length) + { + unsigned next_id = queue[0]; + queue.remove (0); + + vertex_t& next = vertices_[next_id]; + sorted_graph.push (next); + id_map[next_id] = new_id--; + + for (const auto& link : next.obj.links) { + removed_edges[link.objidx]++; + if (!(vertices_[link.objidx].incoming_edges - removed_edges[link.objidx])) + queue.push (link.objidx); + } + } + + 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); + + sorted_graph.as_array ().reverse (); + + vertices_.fini_deep (); + vertices_ = sorted_graph; + sorted_graph.fini_deep (); + } + + /* + * Generates a new topological sorting of graph ordered by the shortest + * distance to each node. + */ + void sort_shortest_distance () + { + positions_invalid = true; + + if (vertices_.length <= 1) { + // Graph of 1 or less doesn't need sorting. + return; + } + + update_distances (); + + hb_priority_queue_t queue; + hb_vector_t<vertex_t> sorted_graph; + 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 (); + + queue.insert (root ().modified_distance (0), root_idx ()); + int new_id = root_idx (); + unsigned order = 1; + while (!queue.in_error () && !queue.is_empty ()) + { + unsigned next_id = queue.pop_minimum().second; + + vertex_t& next = vertices_[next_id]; + sorted_graph.push (next); + id_map[next_id] = new_id--; + + for (const auto& link : next.obj.links) { + 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 + // distance they'll be added to the topological order in the order that they are + // referenced from the parent object. + queue.insert (vertices_[link.objidx].modified_distance (order++), + link.objidx); + } + } + + 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); + + sorted_graph.as_array ().reverse (); + + vertices_.fini_deep (); + 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. + */ + void duplicate (unsigned parent_idx, unsigned child_idx) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d", + parent_idx, child_idx); + + positions_invalid = true; + + 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; + } + + clone->obj.head = buffer->head; + clone->obj.tail = buffer->tail; + clone->distance = child.distance; + + for (const auto& l : child.obj.links) + clone->obj.links.push (l); + + check_success (!clone->obj.links.in_error ()); + + auto& parent = vertices_[parent_idx]; + unsigned clone_idx = vertices_.length - 2; + for (unsigned i = 0; i < parent.obj.links.length; i++) + { + auto& l = parent.obj.links[i]; + if (l.objidx == child_idx) + { + l.objidx = clone_idx; + clone->incoming_edges++; + child.incoming_edges--; + } + } + + // 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_[vertices_.length - 1] = root; + } + + /* + * Raises the sorting priority of all children. + */ + void raise_childrens_priority (unsigned parent_idx) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d", + parent_idx); + // This operation doesn't change ordering until a sort is run, so no need + // 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 (); + } + + /* + * Will any offsets overflow on graph when it's serialized? + */ + bool will_overflow (hb_vector_t<overflow_record_t>* overflows = nullptr) + { + if (overflows) overflows->resize (0); + update_positions (); + + for (int parent_idx = vertices_.length - 1; parent_idx >= 0; parent_idx--) + { + for (const auto& link : vertices_[parent_idx].obj.links) + { + int64_t offset = compute_offset (parent_idx, link); + if (is_valid_offset (offset, link)) + continue; + + if (!overflows) return true; + + overflow_record_t r; + r.parent = parent_idx; + r.link = &link; + overflows->push (r); + } + } + + if (!overflows) return false; + return overflows->length; + } + + void print_overflows (const hb_vector_t<overflow_record_t>& overflows) + { + if (!DEBUG_ENABLED(SUBSET_REPACK)) return; + + update_incoming_edge_count (); + 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)", + o.parent, + o.link->objidx, + child.incoming_edges, + child.obj.links.length); + } + } + + void err_other_error () { this->successful = false; } + + private: + + 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 () + { + if (!edge_count_invalid) return; + + for (unsigned i = 0; i < vertices_.length; i++) + vertices_[i].incoming_edges = 0; + + for (const vertex_t& v : vertices_) + { + for (auto& l : v.obj.links) + { + vertices_[l.objidx].incoming_edges++; + } + } + + edge_count_invalid = false; + } + + /* + * compute the serialized start and end positions for each vertex. + */ + void update_positions () + { + if (!positions_invalid) return; + + unsigned current_pos = 0; + for (int i = root_idx (); i >= 0; i--) + { + auto& v = vertices_[i]; + v.start = current_pos; + current_pos += v.obj.tail - v.obj.head; + v.end = current_pos; + } + + positions_invalid = false; + } + + /* + * Finds the distance to each object in the graph + * from the initial node. + */ + void update_distances () + { + if (!distance_invalid) return; + + // Uses Dijkstra's algorithm to find all of the shortest distances. + // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm + // + // Implementation Note: + // Since our priority queue doesn't support fast priority decreases + // we instead just add new entries into the queue when a priority changes. + // Redundant ones are filtered out later on by the visited set. + // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf + // for practical performance this is faster then using a more advanced queue + // (such as a fibonaacci queue) with a fast decrease priority. + for (unsigned i = 0; i < vertices_.length; i++) + { + if (i == vertices_.length - 1) + vertices_[i].distance = 0; + else + vertices_[i].distance = hb_int_max (int64_t); + } + + hb_priority_queue_t queue; + queue.insert (0, vertices_.length - 1); + + hb_set_t visited; + + while (!queue.in_error () && !queue.is_empty ()) + { + unsigned next_idx = queue.pop_minimum ().second; + if (visited.has (next_idx)) continue; + const auto& next = vertices_[next_idx]; + int64_t next_distance = vertices_[next_idx].distance; + visited.add (next_idx); + + for (const auto& link : next.obj.links) + { + if (visited.has (link.objidx)) continue; + + const auto& child = vertices_[link.objidx].obj; + int64_t child_weight = child.tail - child.head + + ((int64_t) 1 << (link.width * 8)); + int64_t child_distance = next_distance + child_weight; + + if (child_distance < vertices_[link.objidx].distance) + { + vertices_[link.objidx].distance = child_distance; + queue.insert (child_distance, link.objidx); + } + } + } + + check_success (!queue.in_error ()); + if (!check_success (queue.is_empty ())) + { + DEBUG_MSG (SUBSET_REPACK, nullptr, "Graph is not fully connected."); + return; + } + + distance_invalid = false; + } + + int64_t compute_offset ( + unsigned parent_idx, + const hb_serialize_context_t::object_t::link_t& link) const + { + const auto& parent = vertices_[parent_idx]; + const auto& child = vertices_[link.objidx]; + int64_t offset = 0; + switch ((hb_serialize_context_t::whence_t) link.whence) { + case hb_serialize_context_t::whence_t::Head: + offset = child.start - parent.start; break; + case hb_serialize_context_t::whence_t::Tail: + offset = child.start - parent.end; break; + case hb_serialize_context_t::whence_t::Absolute: + offset = child.start; break; + } + + assert (offset >= link.bias); + offset -= link.bias; + return offset; + } + + bool is_valid_offset (int64_t offset, + const hb_serialize_context_t::object_t::link_t& link) const + { + if (link.is_signed) + { + if (link.width == 4) + return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31); + else + return offset >= -(1 << 15) && offset < (1 << 15); + } + else + { + if (link.width == 4) + return offset >= 0 && offset < ((int64_t) 1 << 32); + else if (link.width == 3) + return offset >= 0 && offset < ((int32_t) 1 << 24); + else + return offset >= 0 && offset < (1 << 16); + } + } + + /* + * 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 + { + for (unsigned i = 0; i < sorted_graph->length; i++) + { + for (unsigned j = 0; j < (*sorted_graph)[i].obj.links.length; j++) + { + auto& link = (*sorted_graph)[i].obj.links[j]; + link.objidx = id_map[link.objidx]; + } + } + } + + template <typename O> void + serialize_link_of_type (const hb_serialize_context_t::object_t::link_t& link, + char* head, + hb_serialize_context_t* c) const + { + OT::Offset<O>* offset = reinterpret_cast<OT::Offset<O>*> (head + link.position); + *offset = 0; + c->add_link (*offset, + // serializer has an extra nil object at the start of the + // object array. So all id's are +1 of what our id's are. + link.objidx + 1, + (hb_serialize_context_t::whence_t) link.whence, + link.bias); + } + + void serialize_link (const hb_serialize_context_t::object_t::link_t& link, + char* head, + hb_serialize_context_t* c) const + { + switch (link.width) + { + case 4: + if (link.is_signed) + { + serialize_link_of_type<OT::HBINT32> (link, head, c); + } else { + serialize_link_of_type<OT::HBUINT32> (link, head, c); + } + return; + case 2: + if (link.is_signed) + { + serialize_link_of_type<OT::HBINT16> (link, head, c); + } else { + serialize_link_of_type<OT::HBUINT16> (link, head, c); + } + return; + case 3: + serialize_link_of_type<OT::HBUINT24> (link, head, c); + return; + default: + // Unexpected link width. + assert (0); + } + } + + 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 distance_invalid; + bool positions_invalid; + bool successful; +}; + + +/* + * Attempts to modify the topological sorting of the provided object graph to + * eliminate offset overflows in the links between objects of the graph. If a + * non-overflowing ordering is found the updated graph is serialized it into the + * provided serialization context. + * + * 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. + */ +inline void +hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed, + hb_serialize_context_t* c) { + // 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; + } + + 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); + 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--) + { + const graph_t::overflow_record_t& r = overflows[i]; + const auto& child = sorted_graph.vertices_[r.link->objidx]; + if (child.is_shared ()) + { + // 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. + 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; + } + + if (sorted_graph.in_error ()) + { + c->err (HB_SERIALIZE_ERROR_OTHER); + return; + } + sorted_graph.serialize (c); +} + + +#endif /* HB_REPACKER_HH */ diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 024b4d1c99..56c46015a6 100644 --- a/thirdparty/harfbuzz/src/hb-sanitize.hh +++ b/thirdparty/harfbuzz/src/hb-sanitize.hh @@ -73,7 +73,7 @@ * === The sanitize() contract === * * The sanitize() method of each object type shall return true if it's safe to - * call other methods of the object, and false otherwise. + * call other methods of the object, and %false otherwise. * * Note that what sanitize() checks for might align with what the specification * describes as valid table data, but does not have to be. In particular, we @@ -105,7 +105,7 @@ #define HB_SANITIZE_MAX_EDITS 32 #endif #ifndef HB_SANITIZE_MAX_OPS_FACTOR -#define HB_SANITIZE_MAX_OPS_FACTOR 8 +#define HB_SANITIZE_MAX_OPS_FACTOR 64 #endif #ifndef HB_SANITIZE_MAX_OPS_MIN #define HB_SANITIZE_MAX_OPS_MIN 16384 @@ -113,8 +113,8 @@ #ifndef HB_SANITIZE_MAX_OPS_MAX #define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF #endif -#ifndef HB_SANITIZE_MAX_SUTABLES -#define HB_SANITIZE_MAX_SUTABLES 0x4000 +#ifndef HB_SANITIZE_MAX_SUBTABLES +#define HB_SANITIZE_MAX_SUBTABLES 0x4000 #endif struct hb_sanitize_context_t : @@ -139,7 +139,7 @@ struct hb_sanitize_context_t : bool visit_subtables (unsigned count) { max_subtables += count; - return max_subtables < HB_SANITIZE_MAX_SUTABLES; + return max_subtables < HB_SANITIZE_MAX_SUBTABLES; } private: @@ -233,7 +233,7 @@ struct hb_sanitize_context_t : (this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len && - this->max_ops-- > 0); + (this->max_ops -= len) > 0); DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, "check_range [%p..%p]" diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index 4566153a59..7212d9872a 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -41,6 +41,16 @@ * Serialize */ +enum hb_serialize_error_t { + HB_SERIALIZE_ERROR_NONE = 0x00000000u, + HB_SERIALIZE_ERROR_OTHER = 0x00000001u, + HB_SERIALIZE_ERROR_OFFSET_OVERFLOW = 0x00000002u, + HB_SERIALIZE_ERROR_OUT_OF_ROOM = 0x00000004u, + HB_SERIALIZE_ERROR_INT_OVERFLOW = 0x00000008u, + HB_SERIALIZE_ERROR_ARRAY_OVERFLOW = 0x00000010u +}; +HB_MARK_AS_FLAG_T (hb_serialize_error_t); + struct hb_serialize_context_t { typedef unsigned objidx_t; @@ -51,6 +61,8 @@ struct hb_serialize_context_t Absolute /* Absolute: from the start of the serialize buffer. */ }; + + struct object_t { void fini () { links.fini (); } @@ -70,7 +82,7 @@ struct hb_serialize_context_t struct link_t { - bool is_wide: 1; + unsigned width: 3; bool is_signed: 1; unsigned whence: 2; unsigned position: 28; @@ -90,10 +102,11 @@ struct hb_serialize_context_t char *tail; object_t *current; // Just for sanity check unsigned num_links; + hb_serialize_error_t errors; }; snapshot_t snapshot () - { return snapshot_t { head, tail, current, current->links.length }; } + { return snapshot_t { head, tail, current, current->links.length, errors }; } hb_serialize_context_t (void *start_, unsigned int size) : start ((char *) start_), @@ -117,30 +130,60 @@ struct hb_serialize_context_t object_pool.fini (); } - bool in_error () const { return !this->successful; } + bool in_error () const { return bool (errors); } + + bool successful () const { return !bool (errors); } + + HB_NODISCARD bool ran_out_of_room () const { return errors & HB_SERIALIZE_ERROR_OUT_OF_ROOM; } + HB_NODISCARD bool offset_overflow () const { return errors & HB_SERIALIZE_ERROR_OFFSET_OVERFLOW; } + HB_NODISCARD bool only_offset_overflow () const { return errors == HB_SERIALIZE_ERROR_OFFSET_OVERFLOW; } + HB_NODISCARD bool only_overflow () const + { + return errors == HB_SERIALIZE_ERROR_OFFSET_OVERFLOW + || errors == HB_SERIALIZE_ERROR_INT_OVERFLOW + || errors == HB_SERIALIZE_ERROR_ARRAY_OVERFLOW; + } + + void reset (void *start_, unsigned int size) + { + start = (char*) start_; + end = start + size; + reset (); + current = nullptr; + } void reset () { - this->successful = true; - this->ran_out_of_room = false; + this->errors = HB_SERIALIZE_ERROR_NONE; this->head = this->start; this->tail = this->end; this->debug_depth = 0; fini (); this->packed.push (nullptr); + this->packed_map.init (); } - bool check_success (bool success) - { return this->successful && (success || (err_other_error (), false)); } + bool check_success (bool success, + hb_serialize_error_t err_type = HB_SERIALIZE_ERROR_OTHER) + { + return successful () + && (success || err (err_type)); + } template <typename T1, typename T2> - bool check_equal (T1 &&v1, T2 &&v2) - { return check_success ((long long) v1 == (long long) v2); } + bool check_equal (T1 &&v1, T2 &&v2, hb_serialize_error_t err_type) + { + if ((long long) v1 != (long long) v2) + { + return err (err_type); + } + return true; + } template <typename T1, typename T2> - bool check_assign (T1 &v1, T2 &&v2) - { return check_equal (v1 = v2, v2); } + bool check_assign (T1 &v1, T2 &&v2, hb_serialize_error_t err_type) + { return check_equal (v1 = v2, v2, err_type); } template <typename T> bool propagate_error (T &&obj) { return check_success (!hb_deref (obj).in_error ()); } @@ -167,12 +210,18 @@ struct hb_serialize_context_t "end [%p..%p] serialized %u bytes; %s", this->start, this->end, (unsigned) (this->head - this->start), - this->successful ? "successful" : "UNSUCCESSFUL"); + successful () ? "successful" : "UNSUCCESSFUL"); propagate_error (packed, packed_map); if (unlikely (!current)) return; - if (unlikely (in_error())) return; + if (unlikely (in_error())) + { + // Offset overflows that occur before link resolution cannot be handled + // by repacking, so set a more general error. + if (offset_overflow ()) err (HB_SERIALIZE_ERROR_OTHER); + return; + } assert (!current->next); @@ -212,7 +261,7 @@ struct hb_serialize_context_t current = current->next; revert (obj->head, obj->tail); obj->fini (); - object_pool.free (obj); + object_pool.release (obj); } /* Set share to false when an object is unlikely sharable with others @@ -256,10 +305,11 @@ struct hb_serialize_context_t packed.push (obj); - if (unlikely (packed.in_error ())) { - // obj wasn't successfully added to packed, so clean it up otherwise it's - // links will be leaked. - propagate_error (packed); + if (unlikely (!propagate_error (packed))) + { + /* Obj wasn't successfully added to packed, so clean it up otherwise its + * links will be leaked. When we use constructor/destructors properly, we + * can remove these. */ obj->fini (); return 0; } @@ -274,9 +324,11 @@ struct hb_serialize_context_t void revert (snapshot_t snap) { - if (unlikely (in_error ())) return; + // 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); + errors = snap.errors; revert (snap.head, snap.tail); } @@ -311,7 +363,6 @@ struct hb_serialize_context_t whence_t whence = Head, unsigned bias = 0) { - static_assert (sizeof (T) == 2 || sizeof (T) == 4, ""); if (unlikely (in_error ())) return; if (!objidx) @@ -321,8 +372,10 @@ struct hb_serialize_context_t assert (current->head <= (const char *) &ofs); auto& link = *current->links.push (); + if (current->links.in_error ()) + err (HB_SERIALIZE_ERROR_OTHER); - link.is_wide = sizeof (T) == 4; + link.width = sizeof (T); link.is_signed = hb_is_signed (hb_unwrap_type (T)); link.whence = (unsigned) whence; link.position = (const char *) &ofs - current->head; @@ -350,7 +403,7 @@ struct hb_serialize_context_t for (const object_t::link_t &link : parent->links) { const object_t* child = packed[link.objidx]; - if (unlikely (!child)) { err_other_error(); return; } + if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; } unsigned offset = 0; switch ((whence_t) link.whence) { case Head: offset = child->head - parent->head; break; @@ -362,15 +415,19 @@ struct hb_serialize_context_t offset -= link.bias; if (link.is_signed) { - if (link.is_wide) + assert (link.width == 2 || link.width == 4); + if (link.width == 4) assign_offset<int32_t> (parent, link, offset); else assign_offset<int16_t> (parent, link, offset); } else { - if (link.is_wide) + assert (link.width == 2 || link.width == 3 || link.width == 4); + if (link.width == 4) assign_offset<uint32_t> (parent, link, offset); + else if (link.width == 3) + assign_offset<uint32_t, 3> (parent, link, offset); else assign_offset<uint16_t> (parent, link, offset); } @@ -397,22 +454,22 @@ struct hb_serialize_context_t Type *start_embed (const Type &obj) const { return start_embed (hb_addressof (obj)); } - /* Following two functions exist to allow setting breakpoint on. */ - void err_ran_out_of_room () { this->ran_out_of_room = true; } - void err_other_error () { this->successful = false; } + bool err (hb_serialize_error_t err_type) + { + return !bool ((errors = (errors | err_type))); + } template <typename Type> - Type *allocate_size (unsigned int size) + Type *allocate_size (size_t size) { - if (unlikely (!this->successful)) return nullptr; + if (unlikely (in_error ())) return nullptr; - if (this->tail - this->head < ptrdiff_t (size)) + if (unlikely (size > INT_MAX || this->tail - this->head < ptrdiff_t (size))) { - err_ran_out_of_room (); - this->successful = false; + err (HB_SERIALIZE_ERROR_OUT_OF_ROOM); return nullptr; } - memset (this->head, 0, size); + hb_memset (this->head, 0, size); char *ret = this->head; this->head += size; return reinterpret_cast<Type *> (ret); @@ -467,18 +524,19 @@ struct hb_serialize_context_t hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } template <typename Type> - Type *extend_size (Type *obj, unsigned int size) + Type *extend_size (Type *obj, size_t size) { if (unlikely (in_error ())) return nullptr; assert (this->start <= (char *) obj); assert ((char *) obj <= this->head); - assert ((char *) obj + size >= this->head); - if (unlikely (!this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr; + assert ((size_t) (this->head - (char *) obj) <= size); + if (unlikely (((char *) obj + size < (char *) obj) || + !this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr; return reinterpret_cast<Type *> (obj); } template <typename Type> - Type *extend_size (Type &obj, unsigned int size) + Type *extend_size (Type &obj, size_t size) { return extend_size (hb_addressof (obj), size); } template <typename Type> @@ -496,12 +554,16 @@ struct hb_serialize_context_t /* Output routines. */ hb_bytes_t copy_bytes () const { - assert (this->successful); + assert (successful ()); /* Copy both items from head side and tail side... */ unsigned int len = (this->head - this->start) + (this->end - this->tail); - char *p = (char *) malloc (len); + // If len is zero don't hb_malloc as the memory won't get properly + // cleaned up later. + if (!len) return hb_bytes_t (); + + char *p = (char *) hb_malloc (len); if (unlikely (!p)) return hb_bytes_t (); memcpy (p, this->start, this->head - this->start); @@ -516,23 +578,25 @@ struct hb_serialize_context_t hb_bytes_t b = copy_bytes (); return hb_blob_create (b.arrayZ, b.length, HB_MEMORY_MODE_WRITABLE, - (char *) b.arrayZ, free); + (char *) b.arrayZ, hb_free); } + const hb_vector_t<object_t *>& object_graph() const + { return packed; } + private: - template <typename T> + template <typename T, unsigned Size = sizeof (T)> void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset) { - auto &off = * ((BEInt<T, sizeof (T)> *) (parent->head + link.position)); + auto &off = * ((BEInt<T, Size> *) (parent->head + link.position)); assert (0 == off); - check_assign (off, offset); + check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW); } public: /* TODO Make private. */ char *start, *head, *tail, *end; unsigned int debug_depth; - bool successful; - bool ran_out_of_room; + hb_serialize_error_t errors; private: @@ -549,5 +613,4 @@ struct hb_serialize_context_t hb_hashmap_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 b97526f775..1ef1ba5fb2 100644 --- a/thirdparty/harfbuzz/src/hb-set-digest.hh +++ b/thirdparty/harfbuzz/src/hb-set-digest.hh @@ -87,6 +87,8 @@ struct hb_set_digest_lowest_bits_t } } template <typename T> + void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); } + template <typename T> bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { for (unsigned int i = 0; i < count; i++) @@ -96,6 +98,8 @@ struct hb_set_digest_lowest_bits_t } return true; } + template <typename T> + bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } bool may_have (hb_codepoint_t g) const { return !!(mask & mask_for (g)); } @@ -135,12 +139,16 @@ struct hb_set_digest_combiner_t tail.add_array (array, count, stride); } template <typename T> + void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); } + template <typename T> bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { head.add_sorted_array (array, count, stride); tail.add_sorted_array (array, count, stride); return true; } + template <typename T> + bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } bool may_have (hb_codepoint_t g) const { diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc index 3b4059ad32..204dbb5645 100644 --- a/thirdparty/harfbuzz/src/hb-set.cc +++ b/thirdparty/harfbuzz/src/hb-set.cc @@ -109,7 +109,7 @@ hb_set_destroy (hb_set_t *set) set->fini_shallow (); - free (set); + hb_free (set); } /** @@ -117,7 +117,7 @@ hb_set_destroy (hb_set_t *set) * @set: A set * @key: The user-data key to set * @data: A pointer to the user data to set - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified set. @@ -162,14 +162,32 @@ hb_set_get_user_data (hb_set_t *set, * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, false otherwise + * Return value: %true if allocation succeeded, %false otherwise * * Since: 0.9.2 **/ hb_bool_t hb_set_allocation_successful (const hb_set_t *set) { - return set->successful; + return !set->in_error (); +} + +/** + * hb_set_copy: + * @set: A set + * + * Allocate a copy of @set. + * + * Return value: Newly-allocated set. + * + * Since: 2.8.2 + **/ +hb_set_t * +hb_set_copy (const hb_set_t *set) +{ + hb_set_t *copy = hb_set_create (); + copy->set (*set); + return copy; } /** @@ -183,6 +201,7 @@ hb_set_allocation_successful (const hb_set_t *set) void hb_set_clear (hb_set_t *set) { + /* Immutible-safe. */ set->clear (); } @@ -209,7 +228,7 @@ hb_set_is_empty (const hb_set_t *set) * * Tests whether @codepoint belongs to @set. * - * Return value: %true if @codepoint is in @set, false otherwise + * Return value: %true if @codepoint is in @set, %false otherwise * * Since: 0.9.2 **/ @@ -233,6 +252,7 @@ void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint) { + /* Immutible-safe. */ set->add (codepoint); } @@ -252,6 +272,7 @@ hb_set_add_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last) { + /* Immutible-safe. */ set->add_range (first, last); } @@ -268,6 +289,7 @@ void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint) { + /* Immutible-safe. */ set->del (codepoint); } @@ -280,6 +302,9 @@ hb_set_del (hb_set_t *set, * Removes all of the elements from @first to @last * (inclusive) from @set. * + * If @last is #HB_SET_VALUE_INVALID, then all values + * greater than or equal to @first are removed. + * * Since: 0.9.7 **/ void @@ -287,6 +312,7 @@ hb_set_del_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last) { + /* Immutible-safe. */ set->del_range (first, last); } @@ -298,7 +324,7 @@ hb_set_del_range (hb_set_t *set, * Tests whether @set and @other are equal (contain the same * elements). * - * Return value: %TRUE if the two sets are equal, %FALSE otherwise. + * Return value: %true if the two sets are equal, %false otherwise. * * Since: 0.9.7 **/ @@ -306,7 +332,7 @@ hb_bool_t hb_set_is_equal (const hb_set_t *set, const hb_set_t *other) { - return set->is_equal (other); + return set->is_equal (*other); } /** @@ -316,7 +342,7 @@ hb_set_is_equal (const hb_set_t *set, * * Tests whether @set is a subset of @larger_set. * - * Return value: %TRUE if the @set is a subset of (or equal to) @larger_set, %FALSE otherwise. + * Return value: %true if the @set is a subset of (or equal to) @larger_set, %false otherwise. * * Since: 1.8.1 **/ @@ -324,7 +350,7 @@ hb_bool_t hb_set_is_subset (const hb_set_t *set, const hb_set_t *larger_set) { - return set->is_subset (larger_set); + return set->is_subset (*larger_set); } /** @@ -340,7 +366,8 @@ void hb_set_set (hb_set_t *set, const hb_set_t *other) { - set->set (other); + /* Immutible-safe. */ + set->set (*other); } /** @@ -356,7 +383,8 @@ void hb_set_union (hb_set_t *set, const hb_set_t *other) { - set->union_ (other); + /* Immutible-safe. */ + set->union_ (*other); } /** @@ -372,7 +400,8 @@ void hb_set_intersect (hb_set_t *set, const hb_set_t *other) { - set->intersect (other); + /* Immutible-safe. */ + set->intersect (*other); } /** @@ -388,7 +417,8 @@ void hb_set_subtract (hb_set_t *set, const hb_set_t *other) { - set->subtract (other); + /* Immutible-safe. */ + set->subtract (*other); } /** @@ -405,25 +435,24 @@ void hb_set_symmetric_difference (hb_set_t *set, const hb_set_t *other) { - set->symmetric_difference (other); + /* Immutible-safe. */ + set->symmetric_difference (*other); } -#ifndef HB_DISABLE_DEPRECATED /** * hb_set_invert: * @set: A set * * Inverts the contents of @set. * - * Since: 0.9.10 - * - * Deprecated: 1.6.1 + * Since: 3.0.0 **/ void -hb_set_invert (hb_set_t *set HB_UNUSED) +hb_set_invert (hb_set_t *set) { + /* Immutible-safe. */ + set->invert (); } -#endif /** * hb_set_get_population: @@ -447,7 +476,7 @@ hb_set_get_population (const hb_set_t *set) * * Finds the smallest element in the set. * - * Return value: minimum of @set, or %HB_SET_VALUE_INVALID if @set is empty. + * Return value: minimum of @set, or #HB_SET_VALUE_INVALID if @set is empty. * * Since: 0.9.7 **/ @@ -463,7 +492,7 @@ hb_set_get_min (const hb_set_t *set) * * Finds the largest element in the set. * - * Return value: maximum of @set, or %HB_SET_VALUE_INVALID if @set is empty. + * Return value: maximum of @set, or #HB_SET_VALUE_INVALID if @set is empty. * * Since: 0.9.7 **/ @@ -481,9 +510,9 @@ hb_set_get_max (const hb_set_t *set) * * Fetches the next element in @set that is greater than current value of @codepoint. * - * Set @codepoint to %HB_SET_VALUE_INVALID to get started. + * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a next value, false otherwise + * Return value: %true if there was a next value, %false otherwise * * Since: 0.9.2 **/ @@ -502,9 +531,9 @@ hb_set_next (const hb_set_t *set, * * Fetches the previous element in @set that is lower than current value of @codepoint. * - * Set @codepoint to %HB_SET_VALUE_INVALID to get started. + * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a previous value, false otherwise + * Return value: %true if there was a previous value, %false otherwise * * Since: 1.8.0 **/ @@ -525,9 +554,9 @@ hb_set_previous (const hb_set_t *set, * Fetches the next consecutive range of elements in @set that * are greater than current value of @last. * - * Set @last to %HB_SET_VALUE_INVALID to get started. + * Set @last to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a next range, false otherwise + * Return value: %true if there was a next range, %false otherwise * * Since: 0.9.7 **/ @@ -549,9 +578,9 @@ hb_set_next_range (const hb_set_t *set, * Fetches the previous consecutive range of elements in @set that * are greater than current value of @last. * - * Set @first to %HB_SET_VALUE_INVALID to get started. + * Set @first to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a previous range, false otherwise + * Return value: %true if there was a previous range, %false otherwise * * Since: 1.8.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-set.h b/thirdparty/harfbuzz/src/hb-set.h index cafc36dbad..423225bf96 100644 --- a/thirdparty/harfbuzz/src/hb-set.h +++ b/thirdparty/harfbuzz/src/hb-set.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,7 +36,11 @@ HB_BEGIN_DECLS -/* +/** + * HB_SET_VALUE_INVALID: + * + * Unset #hb_set_t value. + * * Since: 0.9.21 */ #define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1) @@ -81,12 +85,18 @@ hb_set_get_user_data (hb_set_t *set, HB_EXTERN hb_bool_t hb_set_allocation_successful (const hb_set_t *set); +HB_EXTERN hb_set_t * +hb_set_copy (const hb_set_t *set); + HB_EXTERN void hb_set_clear (hb_set_t *set); HB_EXTERN hb_bool_t hb_set_is_empty (const hb_set_t *set); +HB_EXTERN void +hb_set_invert (hb_set_t *set); + HB_EXTERN hb_bool_t hb_set_has (const hb_set_t *set, hb_codepoint_t codepoint); diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index b6e2086a2e..437e234361 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -1,5 +1,6 @@ /* * Copyright © 2012,2017 Google, Inc. + * Copyright © 2021 Behdad Esfahbod * * This is part of HarfBuzz, a text shaping library. * @@ -28,418 +29,67 @@ #define HB_SET_HH #include "hb.hh" -#include "hb-machinery.hh" +#include "hb-bit-set-invertible.hh" -/* - * hb_set_t - */ - -/* TODO Keep a free-list so we can free pages that are completely zeroed. At that - * point maybe also use a sentinel value for "all-1" pages? */ - -struct hb_set_t +template <typename impl_t> +struct hb_sparseset_t { - HB_DELETE_COPY_ASSIGN (hb_set_t); - hb_set_t () { init (); } - ~hb_set_t () { fini (); } - - struct page_map_t - { - int cmp (const page_map_t &o) const { return (int) o.major - (int) major; } - - uint32_t major; - uint32_t index; - }; - - struct page_t - { - void init0 () { v.clear (); } - void init1 () { v.clear (0xFF); } - - unsigned int len () const - { return ARRAY_LENGTH_CONST (v); } - - bool is_empty () const - { - for (unsigned int i = 0; i < len (); i++) - if (v[i]) - return false; - return true; - } - - void add (hb_codepoint_t g) { elt (g) |= mask (g); } - void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } - bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } - - void add_range (hb_codepoint_t a, hb_codepoint_t b) - { - elt_t *la = &elt (a); - elt_t *lb = &elt (b); - if (la == lb) - *la |= (mask (b) << 1) - mask(a); - else - { - *la |= ~(mask (a) - 1); - la++; - - memset (la, 0xff, (char *) lb - (char *) la); - - *lb |= ((mask (b) << 1) - 1); - } - } - - void del_range (hb_codepoint_t a, hb_codepoint_t b) - { - elt_t *la = &elt (a); - elt_t *lb = &elt (b); - if (la == lb) - *la &= ~((mask (b) << 1) - mask(a)); - else - { - *la &= mask (a) - 1; - la++; - - memset (la, 0, (char *) lb - (char *) la); - - *lb &= ~((mask (b) << 1) - 1); - } - } - - bool is_equal (const page_t *other) const - { - return 0 == hb_memcmp (&v, &other->v, sizeof (v)); - } - - unsigned int get_population () const - { - unsigned int pop = 0; - for (unsigned int i = 0; i < len (); i++) - pop += hb_popcount (v[i]); - return pop; - } - - bool next (hb_codepoint_t *codepoint) const - { - unsigned int m = (*codepoint + 1) & MASK; - if (!m) - { - *codepoint = INVALID; - return false; - } - unsigned int i = m / ELT_BITS; - unsigned int j = m & ELT_MASK; - - const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); - for (const elt_t *p = &vv; i < len (); p = &v[++i]) - if (*p) - { - *codepoint = i * ELT_BITS + elt_get_min (*p); - return true; - } - - *codepoint = INVALID; - return false; - } - bool previous (hb_codepoint_t *codepoint) const - { - unsigned int m = (*codepoint - 1) & MASK; - if (m == MASK) - { - *codepoint = INVALID; - return false; - } - unsigned int i = m / ELT_BITS; - unsigned int j = m & ELT_MASK; - - /* Fancy mask to avoid shifting by elt_t bitsize, which is undefined. */ - const elt_t mask = j < 8 * sizeof (elt_t) - 1 ? - ((elt_t (1) << (j + 1)) - 1) : - (elt_t) -1; - const elt_t vv = v[i] & mask; - const elt_t *p = &vv; - while (true) - { - if (*p) - { - *codepoint = i * ELT_BITS + elt_get_max (*p); - return true; - } - if ((int) i <= 0) break; - p = &v[--i]; - } - - *codepoint = INVALID; - return false; - } - hb_codepoint_t get_min () const - { - for (unsigned int i = 0; i < len (); i++) - if (v[i]) - return i * ELT_BITS + elt_get_min (v[i]); - return INVALID; - } - hb_codepoint_t get_max () const - { - for (int i = len () - 1; i >= 0; i--) - if (v[i]) - return i * ELT_BITS + elt_get_max (v[i]); - return 0; - } - - typedef unsigned long long elt_t; - static constexpr unsigned PAGE_BITS = 512; - static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, ""); - - static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); } - static unsigned int elt_get_max (const elt_t &elt) { return hb_bit_storage (elt) - 1; } - - typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t; - - static constexpr unsigned ELT_BITS = sizeof (elt_t) * 8; - static constexpr unsigned ELT_MASK = ELT_BITS - 1; - static constexpr unsigned BITS = sizeof (vector_t) * 8; - static constexpr unsigned MASK = BITS - 1; - static_assert ((unsigned) PAGE_BITS == (unsigned) BITS, ""); + hb_object_header_t header; + impl_t s; - elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; } - elt_t const &elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; } - elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & ELT_MASK); } + hb_sparseset_t () { init (); } + ~hb_sparseset_t () { fini (); } - vector_t v; - }; - static_assert (page_t::PAGE_BITS == sizeof (page_t) * 8, ""); + 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_object_header_t header; - bool successful; /* Allocations successful */ - mutable unsigned int population; - hb_sorted_vector_t<page_map_t> page_map; - hb_vector_t<page_t> pages; - - void init_shallow () - { - successful = true; - population = 0; - page_map.init (); - pages.init (); - } + void init_shallow () { s.init (); } void init () { hb_object_init (this); init_shallow (); } - void fini_shallow () - { - population = 0; - page_map.fini (); - pages.fini (); - } + void fini_shallow () { s.fini (); } void fini () { hb_object_fini (this); fini_shallow (); } - bool in_error () const { return !successful; } + explicit operator bool () const { return !is_empty (); } - bool resize (unsigned int count) - { - if (unlikely (!successful)) return false; - if (!pages.resize (count) || !page_map.resize (count)) - { - pages.resize (page_map.length); - successful = false; - return false; - } - return true; - } - - void reset () - { - if (unlikely (hb_object_is_immutable (this))) - return; - clear (); - successful = true; - } - - void clear () - { - if (unlikely (hb_object_is_immutable (this))) - return; - population = 0; - page_map.resize (0); - pages.resize (0); - } - bool is_empty () const - { - unsigned int count = pages.length; - for (unsigned int i = 0; i < count; i++) - if (!pages[i].is_empty ()) - return false; - return true; - } + void err () { s.err (); } + bool in_error () const { return s.in_error (); } - void dirty () { population = UINT_MAX; } + void reset () { s.reset (); } + void clear () { s.clear (); } + void invert () { s.invert (); } + bool is_empty () const { return s.is_empty (); } - void add (hb_codepoint_t g) - { - if (unlikely (!successful)) return; - if (unlikely (g == INVALID)) return; - dirty (); - page_t *page = page_for_insert (g); if (unlikely (!page)) return; - page->add (g); - } - bool add_range (hb_codepoint_t a, hb_codepoint_t b) - { - if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ - if (unlikely (a > b || a == INVALID || b == INVALID)) return false; - dirty (); - unsigned int ma = get_major (a); - unsigned int mb = get_major (b); - if (ma == mb) - { - page_t *page = page_for_insert (a); if (unlikely (!page)) return false; - page->add_range (a, b); - } - else - { - page_t *page = page_for_insert (a); if (unlikely (!page)) return false; - page->add_range (a, major_start (ma + 1) - 1); - - for (unsigned int m = ma + 1; m < mb; m++) - { - page = page_for_insert (major_start (m)); if (unlikely (!page)) return false; - page->init1 (); - } - - page = page_for_insert (b); if (unlikely (!page)) return false; - page->add_range (major_start (mb), b); - } - return true; - } + void add (hb_codepoint_t g) { s.add (g); } + bool add_range (hb_codepoint_t a, hb_codepoint_t b) { return s.add_range (a, b); } template <typename T> void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - if (unlikely (!successful)) return; - if (!count) return; - dirty (); - hb_codepoint_t g = *array; - while (count) - { - unsigned int m = get_major (g); - page_t *page = page_for_insert (g); if (unlikely (!page)) return; - unsigned int start = major_start (m); - unsigned int end = major_start (m + 1); - do - { - page->add (g); - - array = &StructAtOffsetUnaligned<T> (array, stride); - count--; - } - while (count && (g = *array, start <= g && g < end)); - } - } + { s.add_array (array, count, stride); } + template <typename T> + void add_array (const hb_array_t<const T>& arr) { add_array (&arr, arr.len ()); } /* Might return false if array looks unsorted. * Used for faster rejection of corrupt data. */ template <typename T> bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) - { - if (unlikely (!successful)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ - if (!count) return true; - dirty (); - hb_codepoint_t g = *array; - hb_codepoint_t last_g = g; - while (count) - { - unsigned int m = get_major (g); - page_t *page = page_for_insert (g); if (unlikely (!page)) return false; - unsigned int end = major_start (m + 1); - do - { - /* If we try harder we can change the following comparison to <=; - * Not sure if it's worth it. */ - if (g < last_g) return false; - last_g = g; - page->add (g); - - array = (const T *) ((const char *) array + stride); - count--; - } - while (count && (g = *array, g < end)); - } - return true; - } - - void del (hb_codepoint_t g) - { - /* TODO perform op even if !successful. */ - if (unlikely (!successful)) return; - page_t *page = page_for (g); - if (!page) - return; - dirty (); - page->del (g); - } - - private: - void del_pages (int ds, int de) - { - if (ds <= de) - { - unsigned int write_index = 0; - for (unsigned int i = 0; i < page_map.length; i++) - { - int m = (int) page_map[i].major; - if (m < ds || de < m) - page_map[write_index++] = page_map[i]; - } - compact (write_index); - resize (write_index); - } - } + { return s.add_sorted_array (array, count, stride); } + template <typename T> + bool add_sorted_array (const hb_sorted_array_t<const T>& arr) { return add_sorted_array (&arr, arr.len ()); } - public: - void del_range (hb_codepoint_t a, hb_codepoint_t b) - { - /* TODO perform op even if !successful. */ - if (unlikely (!successful)) return; - if (unlikely (a > b || a == INVALID || b == INVALID)) return; - dirty (); - unsigned int ma = get_major (a); - unsigned int mb = get_major (b); - /* Delete pages from ds through de if ds <= de. */ - int ds = (a == major_start (ma))? (int) ma: (int) (ma + 1); - int de = (b + 1 == major_start (mb + 1))? (int) mb: ((int) mb - 1); - if (ds > de || (int) ma < ds) - { - page_t *page = page_for (a); - if (page) - { - if (ma == mb) - page->del_range (a, b); - else - page->del_range (a, major_start (ma + 1) - 1); - } - } - if (de < (int) mb && ma != mb) - { - page_t *page = page_for (b); - if (page) - page->del_range (major_start (mb), b); - } - del_pages (ds, de); - } + void del (hb_codepoint_t g) { s.del (g); } + void del_range (hb_codepoint_t a, hb_codepoint_t b) { s.del_range (a, b); } - bool get (hb_codepoint_t g) const - { - const page_t *page = page_for (g); - if (!page) - return false; - return page->get (g); - } + bool get (hb_codepoint_t g) const { return s.get (g); } /* Has interface. */ static constexpr bool SENTINEL = false; @@ -450,435 +100,49 @@ struct hb_set_t bool operator () (hb_codepoint_t k) const { return has (k); } /* Sink interface. */ - hb_set_t& operator << (hb_codepoint_t v) + hb_sparseset_t& operator << (hb_codepoint_t v) { add (v); return *this; } - hb_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) + hb_sparseset_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range) { add_range (range.first, range.second); return *this; } bool intersects (hb_codepoint_t first, hb_codepoint_t last) const - { - hb_codepoint_t c = first - 1; - return next (&c) && c <= last; - } - void set (const hb_set_t *other) - { - if (unlikely (!successful)) return; - unsigned int count = other->pages.length; - if (!resize (count)) - return; - population = other->population; - memcpy ((void *) pages, (const void *) other->pages, count * pages.item_size); - memcpy ((void *) page_map, (const void *) other->page_map, count * page_map.item_size); - } - - bool is_equal (const hb_set_t *other) const - { - if (get_population () != other->get_population ()) - return false; - - unsigned int na = pages.length; - unsigned int nb = other->pages.length; - - unsigned int a = 0, b = 0; - for (; a < na && b < nb; ) - { - if (page_at (a).is_empty ()) { a++; continue; } - if (other->page_at (b).is_empty ()) { b++; continue; } - if (page_map[a].major != other->page_map[b].major || - !page_at (a).is_equal (&other->page_at (b))) - return false; - a++; - b++; - } - for (; a < na; a++) - if (!page_at (a).is_empty ()) { return false; } - for (; b < nb; b++) - if (!other->page_at (b).is_empty ()) { return false; } + { return s.intersects (first, last); } - return true; - } + void set (const hb_sparseset_t &other) { s.set (other.s); } - bool is_subset (const hb_set_t *larger_set) const - { - if (get_population () > larger_set->get_population ()) - return false; + bool is_equal (const hb_sparseset_t &other) const { return s.is_equal (other.s); } - /* TODO Optimize to use pages. */ - hb_codepoint_t c = INVALID; - while (next (&c)) - if (!larger_set->has (c)) - return false; + bool is_subset (const hb_sparseset_t &larger_set) const { return s.is_subset (larger_set.s); } - return true; - } - - void compact (unsigned int length) - { - hb_vector_t<uint32_t> old_index_to_page_map_index; - old_index_to_page_map_index.resize(pages.length); - for (uint32_t i = 0; i < old_index_to_page_map_index.length; i++) - old_index_to_page_map_index[i] = 0xFFFFFFFF; + void union_ (const hb_sparseset_t &other) { s.union_ (other.s); } + void intersect (const hb_sparseset_t &other) { s.intersect (other.s); } + void subtract (const hb_sparseset_t &other) { s.subtract (other.s); } + void symmetric_difference (const hb_sparseset_t &other) { s.symmetric_difference (other.s); } - for (uint32_t i = 0; i < length; i++) - old_index_to_page_map_index[page_map[i].index] = i; - - compact_pages (old_index_to_page_map_index); - } - - void compact_pages (const hb_vector_t<uint32_t>& old_index_to_page_map_index) - { - unsigned int write_index = 0; - for (unsigned int i = 0; i < pages.length; i++) - { - if (old_index_to_page_map_index[i] == 0xFFFFFFFF) continue; - - if (write_index < i) - pages[write_index] = pages[i]; - - page_map[old_index_to_page_map_index[i]].index = write_index; - write_index++; - } - } - - template <typename Op> - void process (const Op& op, const hb_set_t *other) - { - if (unlikely (!successful)) return; - - dirty (); - - unsigned int na = pages.length; - unsigned int nb = other->pages.length; - unsigned int next_page = na; - - unsigned int count = 0, newCount = 0; - unsigned int a = 0, b = 0; - unsigned int write_index = 0; - for (; a < na && b < nb; ) - { - if (page_map[a].major == other->page_map[b].major) - { - if (!Op::passthru_left) - { - // Move page_map entries that we're keeping from the left side set - // to the front of the page_map vector. This isn't necessary if - // passthru_left is set since no left side pages will be removed - // in that case. - if (write_index < a) - page_map[write_index] = page_map[a]; - write_index++; - } - - count++; - a++; - b++; - } - else if (page_map[a].major < other->page_map[b].major) - { - if (Op::passthru_left) - count++; - a++; - } - else - { - if (Op::passthru_right) - count++; - b++; - } - } - if (Op::passthru_left) - count += na - a; - if (Op::passthru_right) - count += nb - b; - - if (!Op::passthru_left) - { - na = write_index; - next_page = write_index; - compact (write_index); - } - - if (!resize (count)) - return; - - newCount = count; - - /* Process in-place backward. */ - a = na; - b = nb; - for (; a && b; ) - { - if (page_map[a - 1].major == other->page_map[b - 1].major) - { - a--; - b--; - count--; - page_map[count] = page_map[a]; - page_at (count).v = op (page_at (a).v, other->page_at (b).v); - } - else if (page_map[a - 1].major > other->page_map[b - 1].major) - { - a--; - if (Op::passthru_left) - { - count--; - page_map[count] = page_map[a]; - } - } - else - { - b--; - if (Op::passthru_right) - { - count--; - page_map[count].major = other->page_map[b].major; - page_map[count].index = next_page++; - page_at (count).v = other->page_at (b).v; - } - } - } - if (Op::passthru_left) - while (a) - { - a--; - count--; - page_map[count] = page_map [a]; - } - if (Op::passthru_right) - while (b) - { - b--; - count--; - page_map[count].major = other->page_map[b].major; - page_map[count].index = next_page++; - page_at (count).v = other->page_at (b).v; - } - assert (!count); - if (pages.length > newCount) - resize (newCount); - } - - void union_ (const hb_set_t *other) - { - process (hb_bitwise_or, other); - } - void intersect (const hb_set_t *other) - { - process (hb_bitwise_and, other); - } - void subtract (const hb_set_t *other) - { - process (hb_bitwise_sub, other); - } - void symmetric_difference (const hb_set_t *other) - { - process (hb_bitwise_xor, other); - } - bool next (hb_codepoint_t *codepoint) const - { - if (unlikely (*codepoint == INVALID)) { - *codepoint = get_min (); - return *codepoint != INVALID; - } - - page_map_t map = {get_major (*codepoint), 0}; - unsigned int i; - page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST); - if (i < page_map.length && page_map[i].major == map.major) - { - if (pages[page_map[i].index].next (codepoint)) - { - *codepoint += page_map[i].major * page_t::PAGE_BITS; - return true; - } - i++; - } - for (; i < page_map.length; i++) - { - hb_codepoint_t m = pages[page_map[i].index].get_min (); - if (m != INVALID) - { - *codepoint = page_map[i].major * page_t::PAGE_BITS + m; - return true; - } - } - *codepoint = INVALID; - return false; - } - bool previous (hb_codepoint_t *codepoint) const - { - if (unlikely (*codepoint == INVALID)) { - *codepoint = get_max (); - return *codepoint != INVALID; - } - - page_map_t map = {get_major (*codepoint), 0}; - unsigned int i; - page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST); - if (i < page_map.length && page_map[i].major == map.major) - { - if (pages[page_map[i].index].previous (codepoint)) - { - *codepoint += page_map[i].major * page_t::PAGE_BITS; - return true; - } - } - i--; - for (; (int) i >= 0; i--) - { - hb_codepoint_t m = pages[page_map[i].index].get_max (); - if (m != INVALID) - { - *codepoint = page_map[i].major * page_t::PAGE_BITS + m; - return true; - } - } - *codepoint = INVALID; - return false; - } + bool next (hb_codepoint_t *codepoint) const { return s.next (codepoint); } + bool previous (hb_codepoint_t *codepoint) const { return s.previous (codepoint); } bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const - { - hb_codepoint_t i; - - i = *last; - if (!next (&i)) - { - *last = *first = INVALID; - return false; - } - - /* TODO Speed up. */ - *last = *first = i; - while (next (&i) && i == *last + 1) - (*last)++; - - return true; - } + { return s.next_range (first, last); } bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const - { - hb_codepoint_t i; - - i = *first; - if (!previous (&i)) - { - *last = *first = INVALID; - return false; - } - - /* TODO Speed up. */ - *last = *first = i; - while (previous (&i) && i == *first - 1) - (*first)--; - - return true; - } - - unsigned int get_population () const - { - if (population != UINT_MAX) - return population; + { return s.previous_range (first, last); } - unsigned int pop = 0; - unsigned int count = pages.length; - for (unsigned int i = 0; i < count; i++) - pop += pages[i].get_population (); + unsigned int get_population () const { return s.get_population (); } + hb_codepoint_t get_min () const { return s.get_min (); } + hb_codepoint_t get_max () const { return s.get_max (); } - population = pop; - return pop; - } - hb_codepoint_t get_min () const - { - unsigned int count = pages.length; - for (unsigned int i = 0; i < count; i++) - if (!page_at (i).is_empty ()) - return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min (); - return INVALID; - } - hb_codepoint_t get_max () const - { - unsigned int count = pages.length; - for (int i = count - 1; i >= 0; i++) - if (!page_at (i).is_empty ()) - return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max (); - return INVALID; - } - - static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; + static constexpr hb_codepoint_t INVALID = impl_t::INVALID; /* * Iterator implementation. */ - struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> - { - static constexpr bool is_sorted_iterator = true; - iter_t (const hb_set_t &s_ = Null (hb_set_t), - bool init = true) : s (&s_), v (INVALID), l(0) - { - if (init) - { - l = s->get_population () + 1; - __next__ (); - } - } - - typedef hb_codepoint_t __item_t__; - hb_codepoint_t __item__ () const { return v; } - bool __more__ () const { return v != INVALID; } - void __next__ () { s->next (&v); if (l) l--; } - void __prev__ () { s->previous (&v); } - unsigned __len__ () const { return l; } - iter_t end () const { return iter_t (*s, false); } - bool operator != (const iter_t& o) const - { return s != o.s || v != o.v; } - - protected: - const hb_set_t *s; - hb_codepoint_t v; - unsigned l; - }; - iter_t iter () const { return iter_t (*this); } + using iter_t = typename impl_t::iter_t; + iter_t iter () const { return iter_t (this->s); } operator iter_t () const { return iter (); } +}; - protected: - - page_t *page_for_insert (hb_codepoint_t g) - { - page_map_t map = {get_major (g), pages.length}; - unsigned int i; - if (!page_map.bfind (map, &i, HB_BFIND_NOT_FOUND_STORE_CLOSEST)) - { - if (!resize (pages.length + 1)) - return nullptr; +struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> {}; - pages[map.index].init0 (); - memmove (page_map + i + 1, - page_map + i, - (page_map.length - 1 - i) * page_map.item_size); - page_map[i] = map; - } - return &pages[page_map[i].index]; - } - page_t *page_for (hb_codepoint_t g) - { - page_map_t key = {get_major (g)}; - const page_map_t *found = page_map.bsearch (key); - if (found) - return &pages[found->index]; - return nullptr; - } - const page_t *page_for (hb_codepoint_t g) const - { - page_map_t key = {get_major (g)}; - const page_map_t *found = page_map.bsearch (key); - if (found) - return &pages[found->index]; - return nullptr; - } - page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } - const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } - unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; } - hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; } -}; +static_assert (hb_set_t::INVALID == HB_SET_VALUE_INVALID, ""); #endif /* HB_SET_HH */ diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc index 65a5fc4512..66332165c3 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc @@ -66,7 +66,7 @@ hb_shape_plan_key_t::init (bool copy, const char * const *shaper_list) { hb_feature_t *features = nullptr; - if (copy && num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) + if (copy && num_user_features && !(features = (hb_feature_t *) hb_calloc (num_user_features, sizeof (hb_feature_t)))) goto bail; this->props = *props; @@ -130,7 +130,7 @@ hb_shape_plan_key_t::init (bool copy, #undef HB_SHAPER_PLAN bail: - ::free (features); + ::hb_free (features); return false; } @@ -264,9 +264,9 @@ hb_shape_plan_create2 (hb_face_t *face, #ifndef HB_NO_OT_SHAPE bail3: #endif - shape_plan->key.free (); + shape_plan->key.fini (); bail2: - free (shape_plan); + hb_free (shape_plan); bail: return hb_shape_plan_get_empty (); } @@ -320,8 +320,8 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) #ifndef HB_NO_OT_SHAPE shape_plan->ot.fini (); #endif - shape_plan->key.free (); - free (shape_plan); + shape_plan->key.fini (); + hb_free (shape_plan); } /** @@ -329,12 +329,12 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * @shape_plan: A shaping plan * @key: The user-data key to set * @data: A pointer to the user data - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the given shaping plan. * - * Return value: + * Return value: %true if success, %false otherwise. * * Since: 0.9.7 **/ @@ -404,7 +404,7 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan, buffer->assert_unicode (); - if (unlikely (hb_object_is_inert (shape_plan))) + if (unlikely (!hb_object_is_valid (shape_plan))) return false; assert (shape_plan->face_unsafe == font->face); @@ -439,7 +439,7 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan, * Executes the given shaping plan on the specified buffer, using * the given @font and @features. * - * Return value: + * Return value: %true if success, %false otherwise. * * Since: 0.9.7 **/ @@ -529,7 +529,7 @@ hb_shape_plan_create_cached2 (hb_face_t *face, retry: hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans; - bool dont_cache = hb_object_is_inert (face); + bool dont_cache = !hb_object_is_valid (face); if (likely (!dont_cache)) { @@ -560,7 +560,7 @@ retry: if (unlikely (dont_cache)) return shape_plan; - hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t)); + hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) hb_calloc (1, sizeof (hb_face_t::plan_node_t)); if (unlikely (!node)) return shape_plan; @@ -570,7 +570,7 @@ retry: if (unlikely (!face->shape_plans.cmpexch (cached_plan_nodes, node))) { hb_shape_plan_destroy (shape_plan); - free (node); + hb_free (node); goto retry; } DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "inserted into cache"); diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.h b/thirdparty/harfbuzz/src/hb-shape-plan.h index 336524ee2f..fc7c041899 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.h +++ b/thirdparty/harfbuzz/src/hb-shape-plan.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.hh b/thirdparty/harfbuzz/src/hb-shape-plan.hh index 6da7edb2f8..8cb4ddb927 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.hh +++ b/thirdparty/harfbuzz/src/hb-shape-plan.hh @@ -55,7 +55,7 @@ struct hb_shape_plan_key_t unsigned int num_coords, const char * const *shaper_list); - HB_INTERNAL void free () { ::free ((void *) user_features); } + HB_INTERNAL void fini () { hb_free ((void *) user_features); } HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other); diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc index a3debce397..c1f619c81c 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -48,9 +48,7 @@ **/ -#if HB_USE_ATEXIT -static void free_static_shaper_list (); -#endif +static inline void free_static_shaper_list (); static const char *nil_shaper_list[] = {nullptr}; @@ -59,7 +57,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, { static const char ** create () { - const char **shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *)); + const char **shaper_list = (const char **) hb_calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *)); if (unlikely (!shaper_list)) return nullptr; @@ -69,25 +67,21 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, shaper_list[i] = shapers[i].name; shaper_list[i] = nullptr; -#if HB_USE_ATEXIT - atexit (free_static_shaper_list); -#endif + hb_atexit (free_static_shaper_list); return shaper_list; } static void destroy (const char **l) - { free (l); } + { hb_free (l); } static const char ** get_null () { return nil_shaper_list; } } static_shaper_list; -#if HB_USE_ATEXIT -static +static inline void free_static_shaper_list () { static_shaper_list.free_instance (); } -#endif /** @@ -111,10 +105,10 @@ hb_shape_list_shapers () * hb_shape_full: * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape - * @features: (array length=num_features) (allow-none): an array of user + * @features: (array length=num_features) (nullable): an array of user * specified #hb_feature_t or %NULL * @num_features: the length of @features array - * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated + * @shaper_list: (array zero-terminated=1) (nullable): a %NULL-terminated * array of shapers to use or %NULL * * See hb_shape() for details. If @shaper_list is not %NULL, the specified @@ -146,7 +140,7 @@ hb_shape_full (hb_font_t *font, * hb_shape: * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape - * @features: (array length=num_features) (allow-none): an array of user + * @features: (array length=num_features) (nullable): an array of user * specified #hb_feature_t or %NULL * @num_features: the length of @features array * diff --git a/thirdparty/harfbuzz/src/hb-shape.h b/thirdparty/harfbuzz/src/hb-shape.h index 39507ff744..922f8c011e 100644 --- a/thirdparty/harfbuzz/src/hb-shape.h +++ b/thirdparty/harfbuzz/src/hb-shape.h @@ -26,7 +26,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif diff --git a/thirdparty/harfbuzz/src/hb-shaper.cc b/thirdparty/harfbuzz/src/hb-shaper.cc index 0ea68ad1f5..a11ed83afd 100644 --- a/thirdparty/harfbuzz/src/hb-shaper.cc +++ b/thirdparty/harfbuzz/src/hb-shaper.cc @@ -38,9 +38,7 @@ static const hb_shaper_entry_t all_shapers[] = { static_assert (0 != ARRAY_LENGTH_CONST (all_shapers), "No shaper enabled."); #endif -#if HB_USE_ATEXIT -static void free_static_shapers (); -#endif +static inline void free_static_shapers (); static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_t, hb_shapers_lazy_loader_t> @@ -51,7 +49,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_ if (!env || !*env) return nullptr; - hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) calloc (1, sizeof (all_shapers)); + hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) hb_calloc (1, sizeof (all_shapers)); if (unlikely (!shapers)) return nullptr; @@ -83,23 +81,19 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_ p = end + 1; } -#if HB_USE_ATEXIT - atexit (free_static_shapers); -#endif + hb_atexit (free_static_shapers); return shapers; } - static void destroy (const hb_shaper_entry_t *p) { free ((void *) p); } + static void destroy (const hb_shaper_entry_t *p) { hb_free ((void *) p); } static const hb_shaper_entry_t *get_null () { return all_shapers; } } static_shapers; -#if HB_USE_ATEXIT -static +static inline void free_static_shapers () { static_shapers.free_instance (); } -#endif const hb_shaper_entry_t * _hb_shapers_get () diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc index f5b7fa50a0..ec4b241470 100644 --- a/thirdparty/harfbuzz/src/hb-static.cc +++ b/thirdparty/harfbuzz/src/hb-static.cc @@ -43,6 +43,7 @@ uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof /*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {}; DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; +DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) = {0xFF,0xFF,0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; diff --git a/thirdparty/harfbuzz/src/hb-style.cc b/thirdparty/harfbuzz/src/hb-style.cc index 86b9f7da5f..dfb1017c88 100644 --- a/thirdparty/harfbuzz/src/hb-style.cc +++ b/thirdparty/harfbuzz/src/hb-style.cc @@ -25,7 +25,6 @@ #include "hb.hh" #ifndef HB_NO_STYLE -#ifdef HB_EXPERIMENTAL_API #include "hb-ot-var-avar-table.hh" #include "hb-ot-var-fvar-table.hh" @@ -36,55 +35,46 @@ #include "hb-ot-face.hh" /** - * hb_style_tag_t: - * @HB_STYLE_TAG_ITALIC: Used to vary between non-italic and italic. - * A value of 0 can be interpreted as "Roman" (non-italic); a value of 1 can - * be interpreted as (fully) italic. - * @HB_STYLE_TAG_OPTICAL_SIZE: Used to vary design to suit different text sizes. - * Non-zero. Values can be interpreted as text size, in points. - * @HB_STYLE_TAG_SLANT: Used to vary between upright and slanted text. Values - * must be greater than -90 and less than +90. Values can be interpreted as - * the angle, in counter-clockwise degrees, of oblique slant from whatever the - * designer considers to be upright for that font design. - * @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider. - * Non-zero. Values can be interpreted as a percentage of whatever the font - * designer considers “normal width” for that font design. - * @HB_STYLE_TAG_WEIGHT: Used to vary stroke thicknesses or other design details - * to give variation from lighter to blacker. Values can be interpreted in direct - * comparison to values for usWeightClass in the OS/2 table, - * or the CSS font-weight property. + * SECTION:hb-style + * @title: hb-style + * @short_description: Font Styles + * @include: hb.h * - * Defined by https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg - * - * Since: EXPERIMENTAL + * Functions for fetching style information from fonts. **/ -typedef enum { - HB_STYLE_TAG_ITALIC = HB_TAG ('i','t','a','l'), - HB_STYLE_TAG_OPTICAL_SIZE = HB_TAG ('o','p','s','z'), - HB_STYLE_TAG_SLANT = HB_TAG ('s','l','n','t'), - HB_STYLE_TAG_WIDTH = HB_TAG ('w','d','t','h'), - HB_STYLE_TAG_WEIGHT = HB_TAG ('w','g','h','t'), - _HB_STYLE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ -} hb_style_tag_t; +static inline float +_hb_angle_to_ratio (float a) +{ + return tanf (a * float (M_PI / 180.)); +} +#if 0 +static inline float +_hb_ratio_to_angle (float r) +{ + return atanf (r) * float (180. / M_PI); +} +#endif /** * hb_style_get_value: * @font: a #hb_font_t object. * @style_tag: a style tag. * - * Searches variation axes of a hb_font_t object for a specific axis first, + * Searches variation axes of a #hb_font_t object for a specific axis first, * if not set, then tries to get default style values from different * tables of the font. * * Returns: Corresponding axis or default value to a style tag. * - * Since: EXPERIMENTAL + * Since: 3.0.0 **/ float -hb_style_get_value (hb_font_t *font, hb_tag_t tag) +hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag) { - hb_style_tag_t style_tag = (hb_style_tag_t) tag; + if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO)) + return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE)); + hb_face_t *face = font->face; #ifndef HB_NO_VAR @@ -111,12 +101,14 @@ hb_style_get_value (hb_font_t *font, hb_tag_t tag) return face->table.OS2->is_italic () || face->table.head->is_italic () ? 1 : 0; case HB_STYLE_TAG_OPTICAL_SIZE: { - unsigned int lower, upper; + unsigned int lower, design, upper; return face->table.OS2->v5 ().get_optical_size (&lower, &upper) ? (float) (lower + upper) / 2.f + : hb_ot_layout_get_size_params (face, &design, nullptr, nullptr, nullptr, nullptr) + ? design / 10.f : 12.f; } - case HB_STYLE_TAG_SLANT: + case HB_STYLE_TAG_SLANT_ANGLE: return face->table.post->table->italicAngle.to_float (); case HB_STYLE_TAG_WIDTH: return face->table.OS2->has_data () @@ -132,4 +124,3 @@ hb_style_get_value (hb_font_t *font, hb_tag_t tag) } #endif -#endif diff --git a/thirdparty/harfbuzz/src/hb-style.h b/thirdparty/harfbuzz/src/hb-style.h index 1209c79e94..30a6f2b878 100644 --- a/thirdparty/harfbuzz/src/hb-style.h +++ b/thirdparty/harfbuzz/src/hb-style.h @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -33,10 +33,46 @@ HB_BEGIN_DECLS -#ifdef HB_EXPERIMENTAL_API +/** + * hb_style_tag_t: + * @HB_STYLE_TAG_ITALIC: Used to vary between non-italic and italic. + * A value of 0 can be interpreted as "Roman" (non-italic); a value of 1 can + * be interpreted as (fully) italic. + * @HB_STYLE_TAG_OPTICAL_SIZE: Used to vary design to suit different text sizes. + * Non-zero. Values can be interpreted as text size, in points. + * @HB_STYLE_TAG_SLANT_ANGLE: Used to vary between upright and slanted text. Values + * must be greater than -90 and less than +90. Values can be interpreted as + * the angle, in counter-clockwise degrees, of oblique slant from whatever the + * designer considers to be upright for that font design. + * @HB_STYLE_TAG_SLANT_RATIO: same as @HB_STYLE_TAG_SLANT_ANGLE expression as ratio. + * @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider. + * Non-zero. Values can be interpreted as a percentage of whatever the font + * designer considers “normal width” for that font design. + * @HB_STYLE_TAG_WEIGHT: Used to vary stroke thicknesses or other design details + * to give variation from lighter to blacker. Values can be interpreted in direct + * comparison to values for usWeightClass in the OS/2 table, + * or the CSS font-weight property. + * + * Defined by [OpenType Design-Variation Axis Tag Registry](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg). + * + * Since: 3.0.0 + **/ +typedef enum +{ + HB_STYLE_TAG_ITALIC = HB_TAG ('i','t','a','l'), + HB_STYLE_TAG_OPTICAL_SIZE = HB_TAG ('o','p','s','z'), + HB_STYLE_TAG_SLANT_ANGLE = HB_TAG ('s','l','n','t'), + HB_STYLE_TAG_SLANT_RATIO = HB_TAG ('S','l','n','t'), + HB_STYLE_TAG_WIDTH = HB_TAG ('w','d','t','h'), + HB_STYLE_TAG_WEIGHT = HB_TAG ('w','g','h','t'), + + /*< private >*/ + _HB_STYLE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/ +} hb_style_tag_t; + + HB_EXTERN float -hb_style_get_value (hb_font_t *font, hb_tag_t style_tag); -#endif +hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag); HB_END_DECLS diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.cc b/thirdparty/harfbuzz/src/hb-subset-cff-common.cc index 04e1db24ac..711b2236d6 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.cc @@ -38,13 +38,12 @@ using namespace CFF; -/** - * hb_plan_subset_cff_fdselect - * Determine an optimal FDSelect format according to a provided plan. + +/* Determine an optimal FDSelect format according to a provided plan. * * Return value: FDSelect format, size, and ranges for the most compact subset FDSelect * along with a font index remapping table - **/ + */ bool hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan, @@ -169,10 +168,7 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c, return_trace (true); } -/** - * hb_serialize_cff_fdselect - * Serialize a subset FDSelect format planned above. - **/ +/* Serialize a subset FDSelect format planned above. */ bool hb_serialize_cff_fdselect (hb_serialize_context_t *c, const unsigned int num_glyphs, diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh index 422b20b8d0..7fd96ca86d 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh @@ -259,7 +259,10 @@ struct subr_flattener_t return false; cs_interpreter_t<ENV, OPSET, flatten_param_t> interp; interp.env.init (str, acc, fd); - flatten_param_t param = { flat_charstrings[i], plan->drop_hints }; + flatten_param_t param = { + flat_charstrings[i], + (bool) (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + }; if (unlikely (!interp.interpret (param))) return false; } @@ -636,7 +639,7 @@ struct subr_subsetter_t param.init (&parsed_charstrings[i], &parsed_global_subrs, &parsed_local_subrs[fd], closures.global_closure, closures.local_closures[fd], - plan->drop_hints); + plan->flags & HB_SUBSET_FLAGS_NO_HINTING); if (unlikely (!interp.interpret (param))) return false; @@ -645,7 +648,7 @@ struct subr_subsetter_t SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]); } - if (plan->drop_hints) + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) { /* mark hint ops and arguments for drop */ for (unsigned int i = 0; i < plan->num_output_glyphs (); i++) @@ -660,7 +663,7 @@ struct subr_subsetter_t param.init (&parsed_charstrings[i], &parsed_global_subrs, &parsed_local_subrs[fd], closures.global_closure, closures.local_closures[fd], - plan->drop_hints); + plan->flags & HB_SUBSET_FLAGS_NO_HINTING); drop_hints_param_t drop; if (drop_hints_in_str (parsed_charstrings[i], param, drop)) @@ -685,7 +688,7 @@ struct subr_subsetter_t param.init (&parsed_charstrings[i], &parsed_global_subrs, &parsed_local_subrs[fd], closures.global_closure, closures.local_closures[fd], - plan->drop_hints); + plan->flags & HB_SUBSET_FLAGS_NO_HINTING); collect_subr_refs_in_str (parsed_charstrings[i], param); } } diff --git a/thirdparty/harfbuzz/src/hb-subset-cff1.cc b/thirdparty/harfbuzz/src/hb-subset-cff1.cc index df322f8451..b4e24122c9 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff1.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff1.cc @@ -402,7 +402,7 @@ struct cff_subset_plan { void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan) { const Encoding *encoding = acc.encoding; - unsigned int size0, size1, supp_size; + unsigned int size0, size1; hb_codepoint_t code, last_code = CFF_UNDEF_CODE; hb_vector_t<hb_codepoint_t> supp_codes; @@ -412,7 +412,6 @@ struct cff_subset_plan { return; } - supp_size = 0; supp_codes.init (); subset_enc_num_codes = plan->num_output_glyphs () - 1; @@ -448,7 +447,6 @@ struct cff_subset_plan { code_pair_t pair = { supp_codes[i], sid }; subset_enc_supp_codes.push (pair); } - supp_size += SuppEncoding::static_size * supp_codes.length; } } supp_codes.fini (); @@ -545,8 +543,8 @@ struct cff_subset_plan { num_glyphs = plan->num_output_glyphs (); orig_fdcount = acc.fdCount; - drop_hints = plan->drop_hints; - desubroutinize = plan->desubroutinize; + drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; + desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE; /* check whether the subset renumbers any glyph IDs */ gid_renum = false; @@ -919,12 +917,6 @@ _hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc, return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ()); } -/** - * hb_subset_cff1: - * Subsets the CFF table according to a provided plan. - * - * Return value: subsetted cff table. - **/ bool hb_subset_cff1 (hb_subset_context_t *c) { diff --git a/thirdparty/harfbuzz/src/hb-subset-cff2.cc b/thirdparty/harfbuzz/src/hb-subset-cff2.cc index 17ee040deb..896ae64016 100644 --- a/thirdparty/harfbuzz/src/hb-subset-cff2.cc +++ b/thirdparty/harfbuzz/src/hb-subset-cff2.cc @@ -262,8 +262,8 @@ struct cff2_subset_plan { { orig_fdcount = acc.fdArray->count; - drop_hints = plan->drop_hints; - desubroutinize = plan->desubroutinize; + drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING; + desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE; if (desubroutinize) { @@ -470,10 +470,6 @@ _hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc, return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs ()); } -/** - * hb_subset_cff2: - * Subsets the CFF2 table according to a provided subset context. - **/ bool hb_subset_cff2 (hb_subset_context_t *c) { diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc index fe9be3ce02..4885280996 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.cc +++ b/thirdparty/harfbuzz/src/hb-subset-input.cc @@ -30,35 +30,37 @@ /** * hb_subset_input_create_or_fail: * - * Return value: New subset input. + * Creates a new subset input object. + * + * Return value: (transfer full): New subset input, or %NULL if failed. Destroy + * with hb_subset_input_destroy(). * * Since: 1.8.0 **/ hb_subset_input_t * -hb_subset_input_create_or_fail () +hb_subset_input_create_or_fail (void) { hb_subset_input_t *input = hb_object_create<hb_subset_input_t>(); if (unlikely (!input)) return nullptr; - input->unicodes = hb_set_create (); - input->glyphs = hb_set_create (); - input->name_ids = hb_set_create (); - hb_set_add_range (input->name_ids, 0, 6); - input->name_languages = hb_set_create (); - hb_set_add (input->name_languages, 0x0409); - input->drop_tables = hb_set_create (); - input->drop_hints = false; - input->desubroutinize = false; - input->retain_gids = false; - input->name_legacy = false; + for (auto& set : input->sets_iter ()) + set = hb_set_create (); + + if (input->in_error ()) + { + hb_subset_input_destroy (input); + return nullptr; + } + + input->flags = HB_SUBSET_FLAGS_DEFAULT; + + hb_set_add_range (input->sets.name_ids, 0, 6); + hb_set_add (input->sets.name_languages, 0x0409); hb_tag_t default_drop_tables[] = { // Layout disabled by default - HB_TAG ('G', 'S', 'U', 'B'), - HB_TAG ('G', 'P', 'O', 'S'), - HB_TAG ('G', 'D', 'E', 'F'), HB_TAG ('m', 'o', 'r', 'x'), HB_TAG ('m', 'o', 'r', 't'), HB_TAG ('k', 'e', 'r', 'x'), @@ -81,149 +83,281 @@ hb_subset_input_create_or_fail () HB_TAG ('S', 'i', 'l', 'f'), HB_TAG ('S', 'i', 'l', 'l'), }; + input->sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables)); + + hb_tag_t default_no_subset_tables[] = { + HB_TAG ('a', 'v', 'a', 'r'), + HB_TAG ('f', 'v', 'a', 'r'), + HB_TAG ('g', 'a', 's', 'p'), + HB_TAG ('c', 'v', 't', ' '), + HB_TAG ('f', 'p', 'g', 'm'), + HB_TAG ('p', 'r', 'e', 'p'), + HB_TAG ('V', 'D', 'M', 'X'), + HB_TAG ('D', 'S', 'I', 'G'), + HB_TAG ('M', 'V', 'A', 'R'), + HB_TAG ('c', 'v', 'a', 'r'), + HB_TAG ('S', 'T', 'A', 'T'), + }; + input->sets.no_subset_tables->add_array (default_no_subset_tables, + ARRAY_LENGTH (default_no_subset_tables)); + + //copied from _layout_features_groups in fonttools + hb_tag_t default_layout_features[] = { + // default shaper + // common + HB_TAG ('r', 'v', 'r', 'n'), + HB_TAG ('c', 'c', 'm', 'p'), + HB_TAG ('l', 'i', 'g', 'a'), + HB_TAG ('l', 'o', 'c', 'l'), + HB_TAG ('m', 'a', 'r', 'k'), + HB_TAG ('m', 'k', 'm', 'k'), + HB_TAG ('r', 'l', 'i', 'g'), - input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables)); + //fractions + HB_TAG ('f', 'r', 'a', 'c'), + HB_TAG ('n', 'u', 'm', 'r'), + HB_TAG ('d', 'n', 'o', 'm'), + //horizontal + HB_TAG ('c', 'a', 'l', 't'), + HB_TAG ('c', 'l', 'i', 'g'), + HB_TAG ('c', 'u', 'r', 's'), + HB_TAG ('k', 'e', 'r', 'n'), + HB_TAG ('r', 'c', 'l', 't'), + + //vertical + HB_TAG ('v', 'a', 'l', 't'), + HB_TAG ('v', 'e', 'r', 't'), + HB_TAG ('v', 'k', 'r', 'n'), + HB_TAG ('v', 'p', 'a', 'l'), + HB_TAG ('v', 'r', 't', '2'), + + //ltr + HB_TAG ('l', 't', 'r', 'a'), + HB_TAG ('l', 't', 'r', 'm'), + + //rtl + HB_TAG ('r', 't', 'l', 'a'), + HB_TAG ('r', 't', 'l', 'm'), + + //Complex shapers + //arabic + HB_TAG ('i', 'n', 'i', 't'), + HB_TAG ('m', 'e', 'd', 'i'), + HB_TAG ('f', 'i', 'n', 'a'), + HB_TAG ('i', 's', 'o', 'l'), + HB_TAG ('m', 'e', 'd', '2'), + HB_TAG ('f', 'i', 'n', '2'), + HB_TAG ('f', 'i', 'n', '3'), + HB_TAG ('c', 's', 'w', 'h'), + HB_TAG ('m', 's', 'e', 't'), + HB_TAG ('s', 't', 'c', 'h'), + + //hangul + HB_TAG ('l', 'j', 'm', 'o'), + HB_TAG ('v', 'j', 'm', 'o'), + HB_TAG ('t', 'j', 'm', 'o'), + + //tibetan + HB_TAG ('a', 'b', 'v', 's'), + HB_TAG ('b', 'l', 'w', 's'), + HB_TAG ('a', 'b', 'v', 'm'), + HB_TAG ('b', 'l', 'w', 'm'), + + //indic + HB_TAG ('n', 'u', 'k', 't'), + HB_TAG ('a', 'k', 'h', 'n'), + HB_TAG ('r', 'p', 'h', 'f'), + HB_TAG ('r', 'k', 'r', 'f'), + HB_TAG ('p', 'r', 'e', 'f'), + HB_TAG ('b', 'l', 'w', 'f'), + HB_TAG ('h', 'a', 'l', 'f'), + HB_TAG ('a', 'b', 'v', 'f'), + HB_TAG ('p', 's', 't', 'f'), + HB_TAG ('c', 'f', 'a', 'r'), + HB_TAG ('v', 'a', 't', 'u'), + HB_TAG ('c', 'j', 'c', 't'), + HB_TAG ('i', 'n', 'i', 't'), + HB_TAG ('p', 'r', 'e', 's'), + HB_TAG ('a', 'b', 'v', 's'), + HB_TAG ('b', 'l', 'w', 's'), + HB_TAG ('p', 's', 't', 's'), + HB_TAG ('h', 'a', 'l', 'n'), + HB_TAG ('d', 'i', 's', 't'), + HB_TAG ('a', 'b', 'v', 'm'), + HB_TAG ('b', 'l', 'w', 'm'), + }; + + input->sets.layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features)); + + if (input->in_error ()) + { + hb_subset_input_destroy (input); + return nullptr; + } return input; } /** * hb_subset_input_reference: (skip) - * @subset_input: a subset_input. + * @input: a #hb_subset_input_t object. * + * Increases the reference count on @input. * - * - * Return value: + * Return value: @input. * * Since: 1.8.0 **/ hb_subset_input_t * -hb_subset_input_reference (hb_subset_input_t *subset_input) +hb_subset_input_reference (hb_subset_input_t *input) { - return hb_object_reference (subset_input); + return hb_object_reference (input); } /** * hb_subset_input_destroy: - * @subset_input: a subset_input. + * @input: a #hb_subset_input_t object. + * + * Decreases the reference count on @input, and if it reaches zero, destroys + * @input, freeing all memory. * * Since: 1.8.0 **/ void -hb_subset_input_destroy (hb_subset_input_t *subset_input) +hb_subset_input_destroy (hb_subset_input_t *input) { - if (!hb_object_destroy (subset_input)) return; + if (!hb_object_destroy (input)) return; - hb_set_destroy (subset_input->unicodes); - hb_set_destroy (subset_input->glyphs); - hb_set_destroy (subset_input->name_ids); - hb_set_destroy (subset_input->name_languages); - hb_set_destroy (subset_input->drop_tables); + for (hb_set_t* set : input->sets_iter ()) + hb_set_destroy (set); - free (subset_input); + hb_free (input); } /** * hb_subset_input_unicode_set: - * @subset_input: a subset_input. + * @input: a #hb_subset_input_t object. + * + * Gets the set of Unicode code points to retain, the caller should modify the + * set as needed. + * + * Return value: (transfer none): pointer to the #hb_set_t of Unicode code + * points. * * Since: 1.8.0 **/ HB_EXTERN hb_set_t * -hb_subset_input_unicode_set (hb_subset_input_t *subset_input) +hb_subset_input_unicode_set (hb_subset_input_t *input) { - return subset_input->unicodes; + return input->sets.unicodes; } /** * hb_subset_input_glyph_set: - * @subset_input: a subset_input. + * @input: a #hb_subset_input_t object. + * + * Gets the set of glyph IDs to retain, the caller should modify the set as + * needed. + * + * Return value: (transfer none): pointer to the #hb_set_t of glyph IDs. * * Since: 1.8.0 **/ HB_EXTERN hb_set_t * -hb_subset_input_glyph_set (hb_subset_input_t *subset_input) -{ - return subset_input->glyphs; -} - -HB_EXTERN hb_set_t * -hb_subset_input_nameid_set (hb_subset_input_t *subset_input) -{ - return subset_input->name_ids; -} - -HB_EXTERN hb_set_t * -hb_subset_input_namelangid_set (hb_subset_input_t *subset_input) +hb_subset_input_glyph_set (hb_subset_input_t *input) { - return subset_input->name_languages; + return input->sets.glyphs; } +/** + * hb_subset_input_set: + * @input: a #hb_subset_input_t object. + * @set_type: a #hb_subset_sets_t set type. + * + * Gets the set of the specified type. + * + * Return value: (transfer none): pointer to the #hb_set_t of the specified type. + * + * Since: 2.9.1 + **/ HB_EXTERN hb_set_t * -hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input) -{ - return subset_input->drop_tables; -} - -HB_EXTERN void -hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, - hb_bool_t drop_hints) +hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type) { - subset_input->drop_hints = drop_hints; + return input->sets_iter () [set_type]; } -HB_EXTERN hb_bool_t -hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input) -{ - return subset_input->drop_hints; -} - -HB_EXTERN void -hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input, - hb_bool_t desubroutinize) -{ - subset_input->desubroutinize = desubroutinize; -} - -HB_EXTERN hb_bool_t -hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input) +/** + * hb_subset_input_get_flags: + * @input: a #hb_subset_input_t object. + * + * Gets all of the subsetting flags in the input object. + * + * Return value: the subsetting flags bit field. + * + * Since: 2.9.0 + **/ +HB_EXTERN hb_subset_flags_t +hb_subset_input_get_flags (hb_subset_input_t *input) { - return subset_input->desubroutinize; + return (hb_subset_flags_t) input->flags; } /** - * hb_subset_input_set_retain_gids: - * @subset_input: a subset_input. - * @retain_gids: If true the subsetter will not renumber glyph ids. - * Since: 2.4.0 + * hb_subset_input_set_flags: + * @input: a #hb_subset_input_t object. + * @value: bit field of flags + * + * Sets all of the flags in the input object to the values specified by the bit + * field. + * + * Since: 2.9.0 **/ HB_EXTERN void -hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input, - hb_bool_t retain_gids) +hb_subset_input_set_flags (hb_subset_input_t *input, + unsigned value) { - subset_input->retain_gids = retain_gids; + input->flags = (hb_subset_flags_t) value; } /** - * hb_subset_input_get_retain_gids: - * Returns: value of retain_gids. - * Since: 2.4.0 + * hb_subset_input_set_user_data: (skip) + * @input: a #hb_subset_input_t object. + * @key: The user-data key to set + * @data: A pointer to the user data + * @destroy: (nullable): A callback to call when @data is not needed anymore + * @replace: Whether to replace an existing data with the same key + * + * Attaches a user-data key/data pair to the given subset input object. + * + * Return value: %true if success, %false otherwise + * + * Since: 2.9.0 **/ -HB_EXTERN hb_bool_t -hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input) +hb_bool_t +hb_subset_input_set_user_data (hb_subset_input_t *input, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace) { - return subset_input->retain_gids; + return hb_object_set_user_data (input, key, data, destroy, replace); } -HB_EXTERN void -hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input, - hb_bool_t name_legacy) -{ - subset_input->name_legacy = name_legacy; -} - -HB_EXTERN hb_bool_t -hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input) +/** + * hb_subset_input_get_user_data: (skip) + * @input: a #hb_subset_input_t object. + * @key: The user-data key to query + * + * Fetches the user data associated with the specified key, + * attached to the specified subset input object. + * + * Return value: (transfer none): A pointer to the user data + * + * Since: 2.9.0 + **/ +void * +hb_subset_input_get_user_data (const hb_subset_input_t *input, + hb_user_data_key_t *key) { - return subset_input->name_legacy; + return hb_object_get_user_data (input, key); } diff --git a/thirdparty/harfbuzz/src/hb-subset-input.hh b/thirdparty/harfbuzz/src/hb-subset-input.hh index 0aeb96695b..a3e28b0562 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.hh +++ b/thirdparty/harfbuzz/src/hb-subset-input.hh @@ -31,30 +31,51 @@ #include "hb.hh" #include "hb-subset.h" +#include "hb-map.hh" +#include "hb-set.hh" #include "hb-font.hh" +HB_MARK_AS_FLAG_T (hb_subset_flags_t); + struct hb_subset_input_t { hb_object_header_t header; - hb_set_t *unicodes; - hb_set_t *glyphs; - hb_set_t *name_ids; - hb_set_t *name_languages; - hb_set_t *drop_tables; - - bool drop_hints; - bool desubroutinize; - bool retain_gids; - bool name_legacy; - /* TODO - * - * features - * lookups - * name_ids - * ... - */ + 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*)]; + }; + + unsigned flags; + + inline unsigned num_sets () const + { + return sizeof (set_ptrs) / sizeof (hb_set_t*); + } + + inline hb_array_t<hb_set_t*> sets_iter () + { + return hb_array_t<hb_set_t*> (set_ptrs, num_sets ()); + } + + bool in_error () const + { + for (unsigned i = 0; i < num_sets (); i++) + { + if (unlikely (set_ptrs[i]->in_error ())) + return true; + } + return false; + } }; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 24beada3e8..677df35fad 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -35,10 +35,12 @@ #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-colrv1-closure.hh" #include "hb-ot-var-fvar-table.hh" #include "hb-ot-stat-table.hh" +typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline void _add_cff_seac_components (const OT::cff1::accelerator_t &cff, @@ -54,7 +56,23 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff, } #endif -#ifndef HB_NO_SUBSET_LAYOUT +static void +_remap_palette_indexes (const hb_set_t *palette_indexes, + hb_map_t *mapping /* OUT */) +{ + unsigned new_idx = 0; + for (unsigned palette_index : palette_indexes->iter ()) + { + if (palette_index == 0xFFFF) + { + mapping->set (palette_index, palette_index); + continue; + } + mapping->set (palette_index, new_idx); + new_idx++; + } +} + static void _remap_indexes (const hb_set_t *indexes, hb_map_t *mapping /* OUT */) @@ -66,60 +84,100 @@ _remap_indexes (const hb_set_t *indexes, } -static inline void -_gsub_closure_glyphs_lookups_features (hb_face_t *face, - hb_set_t *gids_to_retain, - hb_map_t *gsub_lookups, - hb_map_t *gsub_features) +#ifndef HB_NO_SUBSET_LAYOUT +typedef void (*layout_collect_func_t) (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *scripts, const hb_tag_t *languages, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */); + + +template <typename T> +static void _collect_layout_indices (hb_face_t *face, + const T& table, + const hb_set_t *layout_features_to_retain, + layout_collect_func_t layout_collect_func, + hb_set_t *indices /* OUT */) { - hb_set_t lookup_indices; - hb_ot_layout_collect_lookups (face, - HB_OT_TAG_GSUB, - nullptr, - nullptr, - nullptr, - &lookup_indices); - hb_ot_layout_lookups_substitute_closure (face, - &lookup_indices, - gids_to_retain); - hb_blob_ptr_t<OT::GSUB> gsub = hb_sanitize_context_t ().reference_table<OT::GSUB> (face); - gsub->closure_lookups (face, - gids_to_retain, - &lookup_indices); - _remap_indexes (&lookup_indices, gsub_lookups); + hb_vector_t<hb_tag_t> features; + if (!features.alloc (table.get_feature_count () + 1)) + return; - //closure features - hb_set_t feature_indices; - gsub->closure_features (gsub_lookups, &feature_indices); - _remap_indexes (&feature_indices, gsub_features); - gsub.destroy (); + 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 (!features) + return; + + // 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) + { + // Looking for all features, trigger the faster collection method. + layout_collect_func (face, + T::tableTag, + nullptr, + nullptr, + nullptr, + indices); + return; + } + + layout_collect_func (face, + T::tableTag, + nullptr, + nullptr, + features.arrayZ, + indices); } +template <typename T> static inline void -_gpos_closure_lookups_features (hb_face_t *face, - const hb_set_t *gids_to_retain, - hb_map_t *gpos_lookups, - hb_map_t *gpos_features) +_closure_glyphs_lookups_features (hb_face_t *face, + hb_set_t *gids_to_retain, + const hb_set_t *layout_features_to_retain, + hb_map_t *lookups, + hb_map_t *features, + script_langsys_map *langsys_map) { + hb_blob_ptr_t<T> table = hb_sanitize_context_t ().reference_table<T> (face); + hb_tag_t table_tag = table->tableTag; hb_set_t lookup_indices; - hb_ot_layout_collect_lookups (face, - HB_OT_TAG_GPOS, - nullptr, - nullptr, - nullptr, - &lookup_indices); - hb_blob_ptr_t<OT::GPOS> gpos = hb_sanitize_context_t ().reference_table<OT::GPOS> (face); - gpos->closure_lookups (face, - gids_to_retain, + _collect_layout_indices<T> (face, + *table, + layout_features_to_retain, + hb_ot_layout_collect_lookups, + &lookup_indices); + + if (table_tag == HB_OT_TAG_GSUB) + hb_ot_layout_lookups_substitute_closure (face, + &lookup_indices, + gids_to_retain); + table->closure_lookups (face, + gids_to_retain, &lookup_indices); - _remap_indexes (&lookup_indices, gpos_lookups); + _remap_indexes (&lookup_indices, lookups); - //closure features + // Collect and prune features hb_set_t feature_indices; - gpos->closure_features (gpos_lookups, &feature_indices); - _remap_indexes (&feature_indices, gpos_features); - gpos.destroy (); + _collect_layout_indices<T> (face, + *table, + layout_features_to_retain, + hb_ot_layout_collect_features, + &feature_indices); + + table->prune_features (lookups, &feature_indices); + hb_map_t duplicate_feature_map; + table->find_duplicate_features (lookups, &feature_indices, &duplicate_feature_map); + + feature_indices.clear (); + table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices); + _remap_indexes (&feature_indices, features); + + table.destroy (); } + #endif #ifndef HB_NO_VAR @@ -153,9 +211,9 @@ static inline void #endif static inline void -_cmap_closure (hb_face_t *face, - const hb_set_t *unicodes, - hb_set_t *glyphset) +_cmap_closure (hb_face_t *face, + const hb_set_t *unicodes, + hb_set_t *glyphset) { OT::cmap::accelerator_t cmap; cmap.init (face); @@ -176,20 +234,74 @@ _remove_invalid_gids (hb_set_t *glyphs, } static void +_populate_unicodes_to_retain (const hb_set_t *unicodes, + const hb_set_t *glyphs, + hb_subset_plan_t *plan) +{ + OT::cmap::accelerator_t cmap; + cmap.init (plan->source); + + constexpr static const int size_threshold = 4096; + + if (glyphs->is_empty () && unicodes->get_population () < size_threshold) + { + /* This is the fast path if it's anticipated that size of unicodes + * is << than the number of codepoints in the font. */ + for (hb_codepoint_t cp : *unicodes) + { + hb_codepoint_t gid; + if (!cmap.get_nominal_glyph (cp, &gid)) + { + DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); + continue; + } + + plan->codepoint_to_glyph->set (cp, gid); + } + } + else + { + hb_map_t unicode_glyphid_map; + cmap.collect_mapping (hb_set_get_empty (), &unicode_glyphid_map); + + for (hb_pair_t<hb_codepoint_t, hb_codepoint_t> cp_gid : + + unicode_glyphid_map.iter ()) + { + if (!unicodes->has (cp_gid.first) && !glyphs->has (cp_gid.second)) + continue; + + plan->codepoint_to_glyph->set (cp_gid.first, cp_gid.second); + } + + /* Add gids which where requested, but not mapped in cmap */ + // TODO(garretrieger): + // Once https://github.com/harfbuzz/harfbuzz/issues/3169 + // is implemented, this can be done with union and del_range + for (hb_codepoint_t gid : glyphs->iter ()) + { + if (gid >= plan->source->get_num_glyphs ()) + break; + plan->_glyphset_gsub->add (gid); + } + } + + + plan->codepoint_to_glyph->keys () | hb_sink (plan->unicodes); + + plan->codepoint_to_glyph->values () | hb_sink (plan->_glyphset_gsub); + + cmap.fini (); +} + +static void _populate_gids_to_retain (hb_subset_plan_t* plan, - const hb_set_t *unicodes, - const hb_set_t *input_glyphs_to_retain, bool close_over_gsub, bool close_over_gpos, bool close_over_gdef) { - OT::cmap::accelerator_t cmap; OT::glyf::accelerator_t glyf; #ifndef HB_NO_SUBSET_CFF OT::cff1::accelerator_t cff; #endif OT::COLR::accelerator_t colr; - cmap.init (plan->source); glyf.init (plan->source); #ifndef HB_NO_SUBSET_CFF cff.init (plan->source); @@ -197,69 +309,88 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, colr.init (plan->source); plan->_glyphset_gsub->add (0); // Not-def - hb_set_union (plan->_glyphset_gsub, input_glyphs_to_retain); - - hb_codepoint_t cp = HB_SET_VALUE_INVALID; - while (unicodes->next (&cp)) - { - hb_codepoint_t gid; - if (!cmap.get_nominal_glyph (cp, &gid)) - { - DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp); - continue; - } - plan->unicodes->add (cp); - plan->codepoint_to_glyph->set (cp, gid); - plan->_glyphset_gsub->add (gid); - } _cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub); #ifndef HB_NO_SUBSET_LAYOUT if (close_over_gsub) // closure all glyphs/lookups/features needed for GSUB substitutions. - _gsub_closure_glyphs_lookups_features (plan->source, plan->_glyphset_gsub, plan->gsub_lookups, plan->gsub_features); + _closure_glyphs_lookups_features<OT::GSUB> ( + plan->source, + plan->_glyphset_gsub, + plan->layout_features, + plan->gsub_lookups, + plan->gsub_features, + plan->gsub_langsys); if (close_over_gpos) - _gpos_closure_lookups_features (plan->source, plan->_glyphset_gsub, plan->gpos_lookups, plan->gpos_features); + _closure_glyphs_lookups_features<OT::GPOS> ( + plan->source, + plan->_glyphset_gsub, + plan->layout_features, + plan->gpos_lookups, + plan->gpos_features, + plan->gpos_langsys); #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_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 ()); + // Populate a full set of glyphs to retain by adding all referenced // composite glyphs. - hb_codepoint_t gid = HB_SET_VALUE_INVALID; - while (plan->_glyphset_gsub->next (&gid)) + for (hb_codepoint_t gid : cur_glyphset->iter ()) { glyf.add_gid_and_children (gid, plan->_glyphset); #ifndef HB_NO_SUBSET_CFF if (cff.is_valid ()) _add_cff_seac_components (cff, gid, plan->_glyphset); #endif - if (colr.is_valid ()) - colr.closure_glyphs (gid, plan->_glyphset); } _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ()); + #ifndef HB_NO_VAR if (close_over_gdef) - _collect_layout_variation_indices (plan->source, plan->_glyphset, plan->gpos_lookups, plan->layout_variation_indices, plan->layout_variation_idx_map); + _collect_layout_variation_indices (plan->source, + plan->_glyphset_gsub, + plan->gpos_lookups, + plan->layout_variation_indices, + plan->layout_variation_idx_map); #endif #ifndef HB_NO_SUBSET_CFF cff.fini (); #endif glyf.fini (); - cmap.fini (); } static void _create_old_gid_to_new_gid_map (const hb_face_t *face, - bool retain_gids, - const hb_set_t *all_gids_to_retain, - hb_map_t *glyph_map, /* OUT */ - hb_map_t *reverse_glyph_map, /* OUT */ - unsigned int *num_glyphs /* OUT */) + bool retain_gids, + const hb_set_t *all_gids_to_retain, + hb_map_t *glyph_map, /* OUT */ + hb_map_t *reverse_glyph_map, /* OUT */ + unsigned int *num_glyphs /* OUT */) { if (!retain_gids) { @@ -302,33 +433,36 @@ _nameid_closure (hb_face_t *face, /** * hb_subset_plan_create: + * @face: font face to create the plan for. + * @input: a #hb_subset_input_t input. + * * Computes a plan for subsetting the supplied face according * to a provided input. The plan describes * which tables and glyphs should be retained. * - * Return value: New subset plan. + * Return value: (transfer full): New subset plan. Destroy with + * hb_subset_plan_destroy(). * * Since: 1.7.5 **/ hb_subset_plan_t * -hb_subset_plan_create (hb_face_t *face, - hb_subset_input_t *input) +hb_subset_plan_create (hb_face_t *face, + const hb_subset_input_t *input) { hb_subset_plan_t *plan; if (unlikely (!(plan = hb_object_create<hb_subset_plan_t> ()))) return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t)); plan->successful = true; - plan->drop_hints = input->drop_hints; - plan->desubroutinize = input->desubroutinize; - plan->retain_gids = input->retain_gids; - plan->name_legacy = input->name_legacy; + plan->flags = input->flags; plan->unicodes = hb_set_create (); - plan->name_ids = hb_set_reference (input->name_ids); + plan->name_ids = hb_set_copy (input->sets.name_ids); _nameid_closure (face, plan->name_ids); - plan->name_languages = hb_set_reference (input->name_languages); - plan->glyphs_requested = hb_set_reference (input->glyphs); - plan->drop_tables = hb_set_reference (input->drop_tables); + plan->name_languages = hb_set_copy (input->sets.name_languages); + plan->layout_features = hb_set_copy (input->sets.layout_features); + plan->glyphs_requested = hb_set_copy (input->sets.glyphs); + plan->drop_tables = hb_set_copy (input->sets.drop_tables); + plan->no_subset_tables = hb_set_copy (input->sets.no_subset_tables); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); @@ -339,20 +473,32 @@ hb_subset_plan_create (hb_face_t *face, plan->reverse_glyph_map = hb_map_create (); plan->gsub_lookups = hb_map_create (); plan->gpos_lookups = hb_map_create (); + + if (plan->check_success (plan->gsub_langsys = hb_object_create<script_langsys_map> ())) + plan->gsub_langsys->init_shallow (); + if (plan->check_success (plan->gpos_langsys = hb_object_create<script_langsys_map> ())) + plan->gpos_langsys->init_shallow (); + plan->gsub_features = hb_map_create (); plan->gpos_features = hb_map_create (); + plan->colrv1_layers = hb_map_create (); + plan->colr_palettes = hb_map_create (); plan->layout_variation_indices = hb_set_create (); plan->layout_variation_idx_map = hb_map_create (); + if (plan->in_error ()) { + return plan; + } + + _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan); + _populate_gids_to_retain (plan, - input->unicodes, - input->glyphs, - !input->drop_tables->has (HB_OT_TAG_GSUB), - !input->drop_tables->has (HB_OT_TAG_GPOS), - !input->drop_tables->has (HB_OT_TAG_GDEF)); + !input->sets.drop_tables->has (HB_OT_TAG_GSUB), + !input->sets.drop_tables->has (HB_OT_TAG_GPOS), + !input->sets.drop_tables->has (HB_OT_TAG_GDEF)); _create_old_gid_to_new_gid_map (face, - input->retain_gids, + input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS, plan->_glyphset, plan->glyph_map, plan->reverse_glyph_map, @@ -363,6 +509,10 @@ hb_subset_plan_create (hb_face_t *face, /** * hb_subset_plan_destroy: + * @plan: a #hb_subset_plan_t + * + * Decreases the reference count on @plan, and if it reaches zero, destroys + * @plan, freeing all memory. * * Since: 1.7.5 **/ @@ -374,8 +524,10 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_set_destroy (plan->unicodes); hb_set_destroy (plan->name_ids); hb_set_destroy (plan->name_languages); + hb_set_destroy (plan->layout_features); hb_set_destroy (plan->glyphs_requested); hb_set_destroy (plan->drop_tables); + hb_set_destroy (plan->no_subset_tables); hb_face_destroy (plan->source); hb_face_destroy (plan->dest); hb_map_destroy (plan->codepoint_to_glyph); @@ -387,9 +539,30 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_map_destroy (plan->gpos_lookups); hb_map_destroy (plan->gsub_features); hb_map_destroy (plan->gpos_features); + hb_map_destroy (plan->colrv1_layers); + hb_map_destroy (plan->colr_palettes); hb_set_destroy (plan->layout_variation_indices); hb_map_destroy (plan->layout_variation_idx_map); + if (plan->gsub_langsys) + { + for (auto _ : plan->gsub_langsys->iter ()) + hb_set_destroy (_.second); + + hb_object_destroy (plan->gsub_langsys); + plan->gsub_langsys->fini_shallow (); + hb_free (plan->gsub_langsys); + } + + if (plan->gpos_langsys) + { + for (auto _ : plan->gpos_langsys->iter ()) + hb_set_destroy (_.second); + + hb_object_destroy (plan->gpos_langsys); + plan->gpos_langsys->fini_shallow (); + hb_free (plan->gpos_langsys); + } - free (plan); + hb_free (plan); } diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index e9f603dd1d..92a4e27ccc 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -39,11 +39,8 @@ struct hb_subset_plan_t { hb_object_header_t header; - bool successful : 1; - bool drop_hints : 1; - bool desubroutinize : 1; - bool retain_gids : 1; - bool name_legacy : 1; + bool successful; + unsigned flags; // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; @@ -54,9 +51,15 @@ struct hb_subset_plan_t // name_languages we would like to retain hb_set_t *name_languages; + //layout features which will be preserved + hb_set_t *layout_features; + //glyph ids requested to retain hb_set_t *glyphs_requested; + // Tables which should not be processed, just pass them through. + hb_set_t *no_subset_tables; + // Tables which should be dropped. hb_set_t *drop_tables; @@ -79,10 +82,18 @@ struct hb_subset_plan_t hb_map_t *gsub_lookups; hb_map_t *gpos_lookups; - //active features we'd like to retain + //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; + + //active features after removing redundant langsys and prune_features hb_map_t *gsub_features; hb_map_t *gpos_features; + //active layers/palettes we'd like to retain + hb_map_t *colrv1_layers; + hb_map_t *colr_palettes; + //The set of layout item variation store delta set indices to be retained hb_set_t *layout_variation_indices; //Old -> New layout item variation store delta set index mapping @@ -172,12 +183,15 @@ struct hb_subset_plan_t add_table (hb_tag_t tag, hb_blob_t *contents) { - hb_blob_t *source_blob = source->reference_table (tag); - DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", - HB_UNTAG(tag), - hb_blob_get_length (contents), - hb_blob_get_length (source_blob)); - hb_blob_destroy (source_blob); + if (HB_DEBUG_SUBSET) + { + hb_blob_t *source_blob = source->reference_table (tag); + DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", + HB_UNTAG(tag), + hb_blob_get_length (contents), + hb_blob_get_length (source_blob)); + hb_blob_destroy (source_blob); + } return hb_face_builder_add_table (dest, tag, contents); } }; @@ -186,7 +200,7 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; HB_INTERNAL hb_subset_plan_t * hb_subset_plan_create (hb_face_t *face, - hb_subset_input_t *input); + const hb_subset_input_t *input); HB_INTERNAL void hb_subset_plan_destroy (hb_subset_plan_t *plan); diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 8b77ecd45a..34f92e0d81 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -39,8 +39,10 @@ #include "hb-ot-maxp-table.hh" #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-cpal-table.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" +#include "hb-ot-post-table-v2subset.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" @@ -50,7 +52,28 @@ #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-var-gvar-table.hh" #include "hb-ot-var-hvar-table.hh" +#include "hb-repacker.hh" +/** + * SECTION:hb-subset + * @title: hb-subset + * @short_description: Subsets font files. + * @include: hb-subset.h + * + * Subsetting reduces the codepoint coverage of font files and removes all data + * that is no longer needed. A subset input describes the desired subset. The input is + * provided along with a font to the subsetting operation. Output is a new font file + * containing only the data specified in the input. + * + * Currently most outline and bitmap tables are supported: glyf, CFF, CFF2, sbix, + * COLR, and CBDT/CBLC. This also includes fonts with variable outlines via OpenType + * variations. Notably EBDT/EBLC and SVG are not supported. Layout subsetting is supported + * only for OpenType Layout tables (GSUB, GPOS, GDEF). Notably subsetting of graphite or AAT tables + * is not yet supported. + * + * Fonts with graphite or AAT tables may still be subsetted but will likely need to use the + * retain glyph ids option and configure the subset to pass through the layout tables untouched. + */ static unsigned _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len) @@ -64,69 +87,133 @@ _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len) return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs)); } +/* + * Repack the serialization buffer if any offset overflows exist. + */ +static hb_blob_t* +_repack (hb_tag_t tag, const hb_serialize_context_t& c) +{ + if (tag != HB_OT_TAG_GPOS + && tag != HB_OT_TAG_GSUB) + { + // Check for overflow in a non-handled table. + return c.successful () ? c.copy_blob () : nullptr; + } + + 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); + + if (unlikely (repacked.in_error ())) + // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset + // portion. + return nullptr; + + return repacked.copy_blob (); +} + +template<typename TableType> +static +bool +_try_subset (const TableType *table, + hb_vector_t<char>* buf, + unsigned buf_size, + hb_subset_context_t* c /* OUT */) +{ + c->serializer->start_serialize<TableType> (); + if (c->serializer->in_error ()) return false; + + bool needed = table->subset (c); + if (!c->serializer->ran_out_of_room ()) + { + c->serializer->end_serialize (); + return needed; + } + + buf_size += (buf_size >> 1) + 32; + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", + HB_UNTAG (c->table_tag), buf_size); + + if (unlikely (!buf->alloc (buf_size))) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", + HB_UNTAG (c->table_tag), buf_size); + return needed; + } + + c->serializer->reset (buf->arrayZ, buf_size); + return _try_subset (table, buf, buf_size, c); +} + template<typename TableType> static bool _subset (hb_subset_plan_t *plan) { - bool result = false; hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source); const TableType *table = source_blob->as<TableType> (); hb_tag_t tag = TableType::tableTag; - if (source_blob->data) + if (!source_blob->data) + { + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); + hb_blob_destroy (source_blob); + return false; + } + + hb_vector_t<char> buf; + /* TODO Not all tables are glyph-related. 'name' table size for example should not be + * affected by number of glyphs. Accommodate that. */ + unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); + if (unlikely (!buf.alloc (buf_size))) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); + hb_blob_destroy (source_blob); + return false; + } + + bool needed = false; + hb_serialize_context_t serializer (buf.arrayZ, buf_size); { - hb_vector_t<char> buf; - /* TODO Not all tables are glyph-related. 'name' table size for example should not be - * affected by number of glyphs. Accommodate that. */ - unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); - if (unlikely (!buf.alloc (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - hb_blob_destroy (source_blob); - return false; - } - retry: - hb_serialize_context_t serializer ((void *) buf, buf_size); - serializer.start_serialize<TableType> (); hb_subset_context_t c (source_blob, plan, &serializer, tag); - bool needed = table->subset (&c); - if (serializer.ran_out_of_room) - { - buf_size += (buf_size >> 1) + 32; - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size); - if (unlikely (!buf.alloc (buf_size))) - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size); - hb_blob_destroy (source_blob); - return false; - } - goto retry; - } - serializer.end_serialize (); + needed = _try_subset (table, &buf, buf_size, &c); + } + hb_blob_destroy (source_blob); - result = !serializer.in_error (); + if (serializer.in_error () && !serializer.only_offset_overflow ()) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag)); + return false; + } - if (result) - { - if (needed) - { - hb_blob_t *dest_blob = serializer.copy_blob (); - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); - result = c.plan->add_table (tag, dest_blob); - hb_blob_destroy (dest_blob); - } - else - { - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); - } - } + if (!needed) + { + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); + return true; } - else - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - hb_blob_destroy (source_blob); - DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!"); + bool result = false; + hb_blob_t *dest_blob = _repack (tag, serializer); + if (dest_blob) + { + DEBUG_MSG (SUBSET, nullptr, + "OT::%c%c%c%c final subset table size: %u bytes.", + HB_UNTAG (tag), dest_blob->length); + result = plan->add_table (tag, dest_blob); + hb_blob_destroy (dest_blob); + } + + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s", + HB_UNTAG (tag), result ? "success" : "FAILED!"); return result; } @@ -159,7 +246,7 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */ case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */ - return plan->drop_hints; + return plan->flags & HB_SUBSET_FLAGS_NO_HINTING; #ifdef HB_NO_SUBSET_LAYOUT // Drop Layout Tables if requested. @@ -179,8 +266,21 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) } static bool +_passthrough (hb_subset_plan_t *plan, hb_tag_t tag) +{ + hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); + bool result = plan->add_table (tag, source_table); + hb_blob_destroy (source_table); + return result; +} + +static bool _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) { + if (plan->no_subset_tables->has (tag)) { + return _passthrough (plan, tag); + } + DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag)); switch (tag) { @@ -202,6 +302,7 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) case HB_OT_TAG_OS2 : return _subset<const OT::OS2 > (plan); case HB_OT_TAG_post: return _subset<const OT::post> (plan); case HB_OT_TAG_COLR: return _subset<const OT::COLR> (plan); + 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 */ @@ -221,28 +322,34 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag) #endif default: - hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); - bool result = plan->add_table (tag, source_table); - hb_blob_destroy (source_table); - return result; + if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) + return _passthrough (plan, tag); + + // Drop table + return true; } } /** - * hb_subset: + * hb_subset_or_fail: * @source: font face data to be subset. * @input: input to use for the subsetting. * - * Subsets a font according to provided input. + * Subsets a font according to provided input. Returns nullptr + * if the subset operation fails. + * + * Since: 2.9.0 **/ hb_face_t * -hb_subset (hb_face_t *source, hb_subset_input_t *input) +hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input) { if (unlikely (!input || !source)) return hb_face_get_empty (); hb_subset_plan_t *plan = hb_subset_plan_create (source, input); - if (unlikely (plan->in_error ())) - return hb_face_get_empty (); + if (unlikely (plan->in_error ())) { + hb_subset_plan_destroy (plan); + return nullptr; + } hb_set_t tags_set; bool success = true; @@ -262,7 +369,7 @@ hb_subset (hb_face_t *source, hb_subset_input_t *input) } end: - hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty (); + hb_face_t *result = success ? hb_face_reference (plan->dest) : nullptr; hb_subset_plan_destroy (plan); return result; diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index ddf4409734..1c65a4da1c 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -31,66 +31,119 @@ HB_BEGIN_DECLS -/* - * hb_subset_input_t +/** + * hb_subset_input_t: * * Things that change based on the input. Characters to keep, etc. */ typedef struct hb_subset_input_t hb_subset_input_t; +/** + * hb_subset_flags_t: + * @HB_SUBSET_FLAGS_DEFAULT: all flags at their default value of false. + * @HB_SUBSET_FLAGS_NO_HINTING: If set hinting instructions will be dropped in + * the produced subset. Otherwise hinting instructions will be retained. + * @HB_SUBSET_FLAGS_RETAIN_GIDS: If set glyph indices will not be modified in + * the produced subset. If glyphs are dropped their indices will be retained + * as an empty glyph. + * @HB_SUBSET_FLAGS_DESUBROUTINIZE: If set and subsetting a CFF font the + * subsetter will attempt to remove subroutines from the CFF glyphs. + * @HB_SUBSET_FLAGS_NAME_LEGACY: If set non-unicode name records will be + * retained in the subset. + * @HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG: If set the subsetter will set the + * OVERLAP_SIMPLE flag on each simple glyph. + * @HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED: If set the subsetter will not + * drop unrecognized tables and instead pass them through untouched. + * @HB_SUBSET_FLAGS_NOTDEF_OUTLINE: If set the notdef glyph outline will be + * retained in the final subset. + * @HB_SUBSET_FLAGS_GLYPH_NAMES: If set the PS glyph names will be retained + * in the final subset. + * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in + * OS/2 will not be recalculated. + * + * List of boolean properties that can be configured on the subset input. + * + * Since: 2.9.0 + **/ +typedef enum { /*< flags >*/ + HB_SUBSET_FLAGS_DEFAULT = 0x00000000u, + HB_SUBSET_FLAGS_NO_HINTING = 0x00000001u, + HB_SUBSET_FLAGS_RETAIN_GIDS = 0x00000002u, + HB_SUBSET_FLAGS_DESUBROUTINIZE = 0x00000004u, + HB_SUBSET_FLAGS_NAME_LEGACY = 0x00000008u, + HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG = 0x00000010u, + HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED = 0x00000020u, + HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 0x00000040u, + HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u, + HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, +} hb_subset_flags_t; + +/** + * hb_subset_sets_t: + * @HB_SUBSET_SETS_GLYPH_INDEX: the set of glyph indexes to retain in the subset. + * @HB_SUBSET_SETS_UNICODE: the set of unicode codepoints to retain in the subset. + * @HB_SUBSET_SETS_NO_SUBSET_TABLE_TAG: the set of table tags which specifies tables that should not be + * subsetted. + * @HB_SUBSET_SETS_DROP_TABLE_TAG: the set of table tags which specifies tables which will be dropped + * in the subset. + * @HB_SUBSET_SETS_NAME_ID: the set of name ids that will be retained. + * @HB_SUBSET_SETS_NAME_LANG_ID: the set of name lang ids that will be retained. + * @HB_SUBSET_SETS_LAYOUT_FEATURE_TAG: the set of layout feature tags that will be retained + * in the subset. + * + * List of sets that can be configured on the subset input. + * + * Since: 2.9.1 + **/ +typedef enum { + HB_SUBSET_SETS_GLYPH_INDEX = 0, + HB_SUBSET_SETS_UNICODE, + HB_SUBSET_SETS_NO_SUBSET_TABLE_TAG, + HB_SUBSET_SETS_DROP_TABLE_TAG, + HB_SUBSET_SETS_NAME_ID, + HB_SUBSET_SETS_NAME_LANG_ID, + HB_SUBSET_SETS_LAYOUT_FEATURE_TAG, +} hb_subset_sets_t; + HB_EXTERN hb_subset_input_t * hb_subset_input_create_or_fail (void); HB_EXTERN hb_subset_input_t * -hb_subset_input_reference (hb_subset_input_t *subset_input); +hb_subset_input_reference (hb_subset_input_t *input); HB_EXTERN void -hb_subset_input_destroy (hb_subset_input_t *subset_input); +hb_subset_input_destroy (hb_subset_input_t *input); -HB_EXTERN hb_set_t * -hb_subset_input_unicode_set (hb_subset_input_t *subset_input); +HB_EXTERN hb_bool_t +hb_subset_input_set_user_data (hb_subset_input_t *input, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); -HB_EXTERN hb_set_t * -hb_subset_input_glyph_set (hb_subset_input_t *subset_input); +HB_EXTERN void * +hb_subset_input_get_user_data (const hb_subset_input_t *input, + hb_user_data_key_t *key); HB_EXTERN hb_set_t * -hb_subset_input_nameid_set (hb_subset_input_t *subset_input); +hb_subset_input_unicode_set (hb_subset_input_t *input); HB_EXTERN hb_set_t * -hb_subset_input_namelangid_set (hb_subset_input_t *subset_input); +hb_subset_input_glyph_set (hb_subset_input_t *input); HB_EXTERN hb_set_t * -hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input); +hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type); -HB_EXTERN void -hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, - hb_bool_t drop_hints); -HB_EXTERN hb_bool_t -hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input); +HB_EXTERN hb_subset_flags_t +hb_subset_input_get_flags (hb_subset_input_t *input); HB_EXTERN void -hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input, - hb_bool_t desubroutinize); -HB_EXTERN hb_bool_t -hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input); - -HB_EXTERN void -hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input, - hb_bool_t retain_gids); -HB_EXTERN hb_bool_t -hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input); +hb_subset_input_set_flags (hb_subset_input_t *input, + unsigned value); -HB_EXTERN void -hb_subset_input_set_name_legacy (hb_subset_input_t *subset_input, - hb_bool_t name_legacy); -HB_EXTERN hb_bool_t -hb_subset_input_get_name_legacy (hb_subset_input_t *subset_input); - -/* hb_subset () */ HB_EXTERN hb_face_t * -hb_subset (hb_face_t *source, hb_subset_input_t *input); - +hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input); HB_END_DECLS diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh index 88623db338..1a4c89c17f 100644 --- a/thirdparty/harfbuzz/src/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh @@ -4,7 +4,7 @@ * * ./gen-ucd-table.py ucd.nounihan.grouped.xml * - * on file with this description: Unicode 13.0.0 + * on file with this description: Unicode 14.0.0 */ #ifndef HB_UCD_TABLE_HH @@ -13,7 +13,7 @@ #include "hb.hh" static const hb_script_t -_hb_ucd_sc_map[157] = +_hb_ucd_sc_map[162] = { HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, HB_SCRIPT_ARABIC, @@ -93,7 +93,9 @@ _hb_ucd_sc_map[157] = HB_SCRIPT_NANDINAGARI, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG, HB_SCRIPT_WANCHO, HB_SCRIPT_CHORASMIAN, HB_SCRIPT_DIVES_AKURU, HB_SCRIPT_KHITAN_SMALL_SCRIPT, - HB_SCRIPT_YEZIDI, + HB_SCRIPT_YEZIDI, HB_SCRIPT_CYPRO_MINOAN, + HB_SCRIPT_OLD_UYGHUR, HB_SCRIPT_TANGSA, + HB_SCRIPT_TOTO, HB_SCRIPT_VITHKUQI, }; static const uint16_t _hb_ucd_dm1_p0_map[825] = @@ -1065,144 +1067,144 @@ _hb_ucd_dm2_u64_map[388] = #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[32480] = +_hb_ucd_u8[33120] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 28, - 29, 26, 30, 31, 32, 33, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 34, 35, 35, 35, 35, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 26, 57, 58, 59, 59, 59, 59, 59, 26, 26, 60, 59, 59, 59, 59, 59, - 59, 59, 26, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 26, 62, 59, 63, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 64, 26, 26, 65, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 66, 67, 59, 59, 59, 59, 68, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 69, 70, 71, 72, 73, 74, 59, 59, - 75, 76, 59, 59, 77, 59, 78, 79, 80, 81, 73, 82, 83, 84, 59, 59, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 28, 26, 29, 30, 31, 32, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 33, 34, 34, 34, 34, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 26, 56, 57, 58, 58, 58, 58, 59, 26, 26, 60, 58, 58, 58, 58, 58, + 58, 58, 26, 61, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 26, 62, 58, 63, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 64, 26, 26, 65, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 66, 67, 68, 58, 58, 58, 58, 69, 58, + 58, 58, 58, 58, 58, 58, 58, 70, 71, 72, 73, 74, 75, 76, 58, 77, + 78, 79, 58, 80, 81, 58, 82, 83, 84, 85, 75, 86, 87, 88, 58, 58, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 85, 26, 26, 26, 26, 26, 26, 26, 86, 87, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 88, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 89, 59, 59, 59, 59, 59, 59, 26, 90, 59, 59, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 91, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 92, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 94, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 89, 26, 26, 26, 26, 26, 26, 26, 90, 91, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 92, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 93, 58, 58, 58, 58, 58, 58, 26, 94, 58, 58, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 95, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 96, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 97, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 25, 25, 25, 21, @@ -1255,7 +1257,7 @@ _hb_ucd_u8[32480] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 7, 7, 7, 7, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 25, 25, 25, 21, 21, 23, 21, 21, 26, 26, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 1, 2, 21, 21, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 1, 21, 21, 21, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 21, 21, 7, 7, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -1275,10 +1277,9 @@ _hb_ucd_u8[32480] = 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 2, 2, 21, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 7, 7, 7, 7, 7, 7, 7, 7, 24, 7, 7, 7, 7, 7, 7, 2, + 1, 1, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12, 12, 12, 12, 12, 12, 12, 12, 1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 7, 10, 10, @@ -1320,14 +1321,14 @@ _hb_ucd_u8[32480] = 15, 15, 15, 26, 26, 26, 26, 26, 26, 23, 26, 2, 2, 2, 2, 2, 12, 10, 10, 10, 12, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 7, 12, 12, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 12, 7, 12, 12, 12, 10, 10, 10, 10, 2, 12, 12, 12, 2, 12, 12, 12, 12, 2, 2, - 2, 2, 2, 2, 2, 12, 12, 2, 7, 7, 7, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 12, 12, 2, 7, 7, 7, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 15, 15, 15, 15, 15, 15, 15, 26, 7, 12, 10, 10, 21, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 2, 2, 12, 7, 10, 12, 10, 10, 10, 10, 10, 2, 12, 10, 10, 2, 10, 10, 12, 12, 2, 2, - 2, 2, 2, 2, 2, 10, 10, 2, 2, 2, 2, 2, 2, 2, 7, 2, + 2, 2, 2, 2, 2, 10, 10, 2, 2, 2, 2, 2, 2, 7, 7, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 7, 10, 10, @@ -1344,6 +1345,7 @@ _hb_ucd_u8[32480] = 7, 12, 7, 7, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 23, 7, 7, 7, 7, 7, 7, 6, 12, 12, 12, 12, 12, 12, 12, 12, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 2, 7, 2, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 2, 2, @@ -1387,17 +1389,17 @@ _hb_ucd_u8[32480] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 22, 18, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 21, 21, 21, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, - 7, 7, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 7, 7, 12, 12, 12, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 7, 7, 12, 12, 12, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, + 7, 7, 12, 12, 10, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 2, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, 10, 10, 10, 10, 10, 10, 10, 10, 12, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 6, 21, 21, 21, 23, 7, 12, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, - 21, 21, 21, 21, 21, 21, 17, 21, 21, 21, 21, 12, 12, 12, 1, 2, + 21, 21, 21, 21, 21, 21, 17, 21, 21, 21, 21, 12, 12, 12, 1, 12, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -1419,12 +1421,12 @@ _hb_ucd_u8[32480] = 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 12, 21, 21, 21, 21, 21, 21, 21, 6, 21, 21, 21, 21, 21, 21, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, - 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10, - 10, 10, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, + 10, 10, 12, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 21, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, + 12, 12, 12, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 21, 21, 2, 12, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 12, 12, 12, 12, 10, 10, 12, 12, 10, 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 12, 10, 10, 10, 12, 10, 12, @@ -1443,7 +1445,6 @@ _hb_ucd_u8[32480] = 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 9, 5, 9, 5, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, 5, 2, 2, 9, 9, 9, 9, 9, 9, 2, 2, @@ -1466,8 +1467,10 @@ _hb_ucd_u8[32480] = 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 25, 25, 25, 22, 18, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 9, 26, 26, 26, 26, 9, 26, 26, 5, 9, 9, 9, 5, 5, 9, 9, 9, 5, 26, 9, 26, 26, 25, 9, 9, 9, 9, 9, 26, 26, 26, 26, 26, 26, 9, 26, 9, 26, 9, 26, 9, 9, 9, 9, 26, 5, @@ -1509,8 +1512,6 @@ _hb_ucd_u8[32480] = 25, 25, 25, 25, 25, 26, 26, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 9, 5, 9, 9, 9, 5, 5, 9, 5, 9, 5, 9, 5, 9, 9, 9, 9, 5, 9, 5, 5, 9, 5, 5, 5, 5, 5, 5, 6, 6, 9, 9, 9, 5, 9, 5, 5, 26, 26, 26, 26, 26, 26, 9, 5, 9, 5, 12, @@ -1525,7 +1526,7 @@ _hb_ucd_u8[32480] = 20, 19, 22, 18, 22, 18, 22, 18, 22, 18, 21, 21, 21, 21, 21, 6, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 17, 17, 21, 21, 21, 21, 17, 21, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 26, 26, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 26, 26, 21, 21, 21, 22, 18, 22, 18, 22, 18, 22, 18, 17, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1558,8 +1559,9 @@ _hb_ucd_u8[32480] = 9, 5, 9, 5, 5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 9, 9, 9, 9, 5, 9, 9, 9, 9, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5, - 2, 2, 9, 5, 9, 9, 9, 9, 5, 9, 5, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 9, 5, 7, 6, 6, 5, 7, 7, 7, 7, 7, + 9, 5, 9, 5, 9, 9, 9, 9, 5, 9, 5, 2, 2, 2, 2, 2, + 9, 5, 2, 5, 2, 5, 9, 5, 9, 5, 2, 2, 2, 2, 2, 2, + 2, 2, 6, 6, 6, 9, 5, 7, 6, 6, 5, 7, 7, 7, 7, 7, 7, 7, 12, 7, 7, 7, 12, 7, 7, 7, 7, 12, 7, 7, 7, 7, 7, 7, 7, 10, 10, 12, 12, 10, 26, 26, 26, 26, 12, 2, 2, 2, 15, 15, 15, 15, 15, 15, 26, 26, 23, 26, 2, 2, 2, 2, 2, 2, @@ -1601,16 +1603,18 @@ _hb_ucd_u8[32480] = 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 2, 7, 2, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 24, 24, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 18, 22, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 23, 26, 2, 2, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 26, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 23, 26, 26, 26, 21, 21, 21, 21, 21, 21, 21, 22, 18, 21, 2, 2, 2, 2, 2, 2, 21, 17, 17, 16, 16, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 21, 21, 22, 18, 21, 21, 21, 21, 16, 16, 16, 21, 21, 21, 2, 21, 21, 21, 21, 17, 22, 18, 22, 18, 22, 18, 21, 21, 21, 25, 17, 25, 25, 25, 2, 21, 23, 21, 21, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 1, 2, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 25, 18, 25, 22, @@ -1641,7 +1645,14 @@ _hb_ucd_u8[32480] = 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 2, 9, 9, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, + 6, 6, 6, 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 2, 2, 7, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 2, 2, 2, 7, 2, 2, 7, 7, 7, 7, 7, 7, 7, 2, 21, 15, 15, 15, 15, 15, 15, 15, 15, @@ -1675,14 +1686,15 @@ _hb_ucd_u8[32480] = 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 7, 2, 2, 2, 2, 2, 2, 2, 2, 12, 15, 15, 15, 15, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, + 7, 7, 12, 12, 12, 12, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 10, 12, 10, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 21, 21, 2, 2, 15, 15, 15, 15, 15, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, + 12, 7, 7, 12, 12, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 10, 10, 10, 12, 12, 12, 12, 10, 10, 12, 12, 21, 21, 1, 21, 21, - 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, + 21, 21, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 12, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, 12, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -1719,7 +1731,7 @@ _hb_ucd_u8[32480] = 12, 21, 21, 21, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 10, 12, 10, 10, - 12, 12, 12, 12, 12, 12, 10, 12, 7, 2, 2, 2, 2, 2, 2, 2, + 12, 12, 12, 12, 12, 12, 10, 12, 7, 21, 2, 2, 2, 2, 2, 2, 10, 10, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 21, 21, 21, 26, 12, 12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 21, 2, 2, 2, 2, @@ -1756,6 +1768,7 @@ _hb_ucd_u8[32480] = 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 7, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 26, 26, 26, 26, @@ -1771,16 +1784,18 @@ _hb_ucd_u8[32480] = 12, 12, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 21, 6, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 6, 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 2, 6, 6, 2, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 26, 12, 12, 21, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, + 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 10, 10, 12, 12, 12, 26, 26, 26, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, 12, 12, 12, 12, 26, 26, 12, 12, 12, 12, 12, 12, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 12, 12, 12, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 26, 26, 12, 12, 12, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5, 5, @@ -1818,15 +1833,18 @@ _hb_ucd_u8[32480] = 26, 26, 26, 26, 26, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 26, 26, 21, 21, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, 2, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 6, 6, 6, 6, 6, 6, 6, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 7, 26, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 23, + 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 7, 2, 7, 7, 2, 7, 7, 7, 7, 7, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 12, 12, 12, 12, 12, 12, 12, 6, 2, 2, 2, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 15, 15, 15, 23, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1847,12 +1865,12 @@ _hb_ucd_u8[32480] = 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, + 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 26, 26, 26, - 26, 26, 26, 26, 26, 2, 2, 2, 26, 26, 26, 2, 2, 2, 2, 2, + 26, 26, 26, 26, 26, 2, 2, 2, 26, 26, 26, 26, 26, 2, 2, 2, 26, 26, 26, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1891,9 +1909,9 @@ _hb_ucd_u8[32480] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 51, 0, 52, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 0, 0, 57, 58, 0, - 59, 60, 61, 62, 63, 64, 65, 0, 66, 67, 0, 68, 69, 70, 71, 0, - 60, 0, 72, 73, 74, 75, 0, 0, 69, 0, 76, 77, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 55, 0, 0, 0, 0, 56, 0, 0, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 0, 67, 68, 0, 69, 70, 71, 72, 0, + 61, 0, 73, 74, 75, 76, 0, 0, 70, 0, 77, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1903,7 +1921,7 @@ _hb_ucd_u8[32480] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 79, 80, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1913,13 +1931,13 @@ _hb_ucd_u8[32480] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 82, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 83, 84, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 85, 0, 79, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 87, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 80, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, 18, 19, 20, 0, 0, 0, @@ -1928,86 +1946,87 @@ _hb_ucd_u8[32480] = 28, 29, 0, 0, 0, 0, 30, 0, 0, 0, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 35, 36, 0, 0, 26, 37, 38, 39, 0, 0, 0, 0, 0, 40, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 1, - 42, 43, 44, 45, 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, 48, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, 0, 0, - 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 46, 0, 47, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 50, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 47, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 42, 43, 1, + 44, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, + 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 49, 52, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 49, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 56, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 58, 59, 0, 0, 0, 0, - 0, 0, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 60, 61, 0, 0, 0, 0, + 0, 0, 62, 63, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, - 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 68, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 71, 72, 0, 0, 0, 0, 0, 0, 0, 0, - 73, 0, 66, 74, 0, 0, 0, 0, 0, 0, 75, 76, 72, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 67, 0, 0, 0, - 0, 77, 78, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, - 80, 0, 79, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 82, - 83, 84, 85, 86, 0, 0, 0, 0, 0, 0, 0, 0, 87, 88, 89, 1, - 1, 1, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, - 94, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 71, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 71,100,101, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 86, 0,102, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, - 1, 1, 86, 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0,104, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 73, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,106,107,108, 0, 0, 0, - 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 47, 0, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, + 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 71, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 74, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 68, 77, 0, 0, 0, 0, 0, 0, 78, 79, 80, 81, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 70, 0, 0, 0, + 0, 82, 83, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, + 85, 0, 84, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 87, + 88, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 92, 93, 94, 1, + 1, 1, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 98, + 99,100,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 74, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 74,105,106, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 91, 0,107, 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, + 1, 1, 91, 0, 0, 0, 0, 0, 0,108, 0, 0, 0, 0,109, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 0, 76, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111,112,113, 0, 0, 0, + 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 49, 0, 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,115,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26,112, 0,113, 0, 0, 0, 0, 0,114, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 115, 0, 0, 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117,118, 72, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, - 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, - 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, - 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,120, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,121, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,122, 0, 0, 0, 0, 0, 0, 0, 0, 0,123, 0, 47, 0, 0, - 26,124,124, 0, 0, 0, 0, 0, 0, 0, 0, 0,125, 0, 0, 49, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97,127, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,105, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 97, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,132, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,134, 0, 0, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 136,137,138,139,140,141, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143, 0, 0, 0, - 0, 0, 0, 0,133, 1, 1,144,145,112, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,146, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,147, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26,117, 0,118, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 120, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,121, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122,123, 75, 0, + 0, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0, 0, 0, + 0, 0, 76,102, 0, 0, 0, 0, 0, 0, 0,125, 0, 0, 0, 0, + 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, + 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,126, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 0, 49, 0, 0, + 26,130,130, 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 0, 0, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,132, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102,133, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,134, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,135,110, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0,102, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,137, 0, 0, 0, + 0, 0, 0, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,138, 0, 0, 0, 0, 0, 0, 0,139, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,140, 0, 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 142,143,144,145,146,147, 0, 0, 0,148, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,149, 0, 0, 0, + 0, 0, 0, 0,139, 1, 1,150,151,117, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, + 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,152, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230, 230,230,230,230,230,230,230,230,230,232,220,220,220,220,232,216, 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, @@ -2028,7 +2047,8 @@ _hb_ucd_u8[32480] = 220,230,220,230,220,230,230, 0, 0, 0, 0, 0,230,230,220,230, 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0, 0,230,230, 0,230, 230,230,230,230,230,230,230,230, 0,230,230,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220, 0, 0, 0, 0, 0, 0, 0,220, + 230,230, 0, 0, 0,220,220,220, 0, 0, 0, 0,230,220,220,220, + 230,230,230,230, 0, 0,230,230,230,230,230,220,220,220,220,220, 230,230,230,230,230,230, 0,220,230,230,220,230,230,220,230,230, 230,220,220,220, 27, 28, 29,230,230,230,220,230,230,220,220,230, 230,230,230,230, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, @@ -2042,32 +2062,34 @@ _hb_ucd_u8[32480] = 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0, 0, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230, 0, 0, 0, 0, - 9, 0, 0, 0, 0, 0, 0, 0, 0,230, 0, 0, 0,228, 0, 0, - 0, 0, 0, 0, 0,222,230,220, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,230,220, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 0,230,230,230,230,230, 0, 0,220,230,230,230,230, - 230,220,220,220,220,220,220,230,230,220, 0,220, 0, 0, 0,230, - 220,230,230,230,230,230,230,230, 0, 0, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,230,230,230, 0, - 1,220,220,220,220,220,230,230,220,220,220,220,230, 0, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, - 230, 0, 0, 0,230,230, 0, 0, 0, 0, 0, 0,230,230,220,230, - 230,230,230,230,230,230,220,230,230,234,214,220,202,230,230,230, - 230,230,230,230,230,230,230,230,230,230,232,228,228,220, 0,230, - 233,220,230,220,230,230, 1, 1,230,230,230,230, 1, 1, 1,230, - 230, 0, 0, 0, 0,230, 0, 0, 0, 1, 1,230,220,230, 1, 1, - 220,220,220,220,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230,230,230,230,230, - 230,230, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0,220, - 220,220, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 7, - 0, 0, 0, 0,230, 0,230,230,220, 0, 0,230,230, 0, 0, 0, - 0, 0,230,230, 0,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26, 0,230,230,230,230,230,230,230,220,220,220,220,220, - 220,220,230,230,230,230,230, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,220, 0,230,230, 1,220, 0, 0, 0, 0, 9, 0, 0, 0, 0, - 0,230,220, 0, 0, 0, 0,230,230, 0, 0, 0, 0, 0, 0, 0, - 0, 0,220,220,230,230,230,220,230,220,220,220, 0, 9, 7, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0,230, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0,222,230,220, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,220, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,230,230,230,230, + 230, 0, 0,220,230,230,230,230,230,220,220,220,220,220,220,230, + 230,220, 0,220,220,230,230,220,220,230,230,230,230,230,220,230, + 230,230,230, 0, 0, 0, 0,230,220,230,230,230,230,230,230,230, + 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 0,230,230,230, 0, 1,220,220,220,220,220,230,230, + 220,220,220,220,230, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0,220, 0, 0, 0, 0, 0, 0,230, 0, 0, 0,230,230, 0, 0, + 0, 0, 0, 0,230,230,220,230,230,230,230,230,230,230,220,230, + 230,234,214,220,202,230,230,230,230,230,230,230,230,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 230,230,230,230, 1, 1, 1,230,230, 0, 0, 0, 0,230, 0, 0, + 0, 1, 1,230,220,230, 1, 1,220,220,220,220,230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 230,230,230,230,230,230,230,230,230,230, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0,220,220,220, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,230, 0,230,230, + 220, 0, 0,230,230, 0, 0, 0, 0, 0,230,230, 0,230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0,230,230,230,230, + 230,230,230,220,220,220,220,220,220,220,230,230,230,230,230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,220, 0,230,230, 1,220, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0,230,220, 0, 0, 0, 0,230, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0,220,220,230,230,230,220, + 230,220,220,220, 0, 0,230,220,230,220, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0,230,230,230,230,230, 0, 0, 0, 0, 0, 9, 0, @@ -2135,7 +2157,7 @@ _hb_ucd_u8[32480] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 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, 26, 34, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, @@ -2155,114 +2177,114 @@ _hb_ucd_u8[32480] = 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 27, 28, 28, 29, 30, 31, 32, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 35, 35, 35, 35, 35, 59, 59, 60, 35, - 35, 35, 35, 35, 35, 35, 61, 62, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 63, 64, 35, 65, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 67, 66, 68, 69, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 70, 71, 35, 35, - 35, 35, 72, 35, 35, 35, 35, 35, 35, 35, 35, 35, 73, 74, 75, 76, - 77, 78, 35, 35, 79, 80, 35, 35, 81, 35, 82, 83, 84, 85, 17, 86, - 87, 88, 35, 35, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 27, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 34, 34, 34, 34, 58, 59, 59, 60, 34, + 34, 34, 34, 34, 34, 34, 61, 62, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 63, 64, 34, 65, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 67, 66, 68, 69, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 70, 71, 72, 34, 34, + 34, 34, 73, 34, 34, 34, 34, 34, 34, 34, 34, 74, 75, 76, 77, 78, + 79, 80, 34, 81, 82, 83, 34, 84, 85, 34, 86, 87, 88, 89, 17, 90, + 91, 92, 34, 34, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 89, 25, 25, 25, 25, 25, 25, 25, 90, - 91, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 92, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 93, 35, 35, 35, 35, 35, 35, - 25, 94, 35, 35, 25, 25, 25, 25, 25, 25, 25, 25, 25, 95, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 25, 25, 25, 25, 25, 25, 93, 25, 25, 25, 25, 25, 25, 25, 94, + 95, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 96, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 97, 34, 34, 34, 34, 34, 34, + 25, 98, 34, 34, 25, 25, 25, 25, 25, 25, 25, 25, 25, 99, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2289,7 +2311,7 @@ _hb_ucd_u8[32480] = 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 2, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -2307,10 +2329,8 @@ _hb_ucd_u8[32480] = 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, @@ -2359,9 +2379,9 @@ _hb_ucd_u8[32480] = 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, + 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 2, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, + 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, @@ -2369,7 +2389,7 @@ _hb_ucd_u8[32480] = 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 2, 2, - 2, 2, 2, 2, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, + 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 20, 20, @@ -2389,7 +2409,8 @@ _hb_ucd_u8[32480] = 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 24, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, @@ -2424,8 +2445,8 @@ _hb_ucd_u8[32480] = 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 2, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 2, 2, @@ -2435,7 +2456,7 @@ _hb_ucd_u8[32480] = 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, @@ -2458,11 +2479,11 @@ _hb_ucd_u8[32480] = 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 2, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 2, 2, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, @@ -2480,8 +2501,7 @@ _hb_ucd_u8[32480] = 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, + 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, @@ -2492,7 +2512,9 @@ _hb_ucd_u8[32480] = 0, 0, 0, 0, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, @@ -2502,16 +2524,15 @@ _hb_ucd_u8[32480] = 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 2, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 30, 30, 30, 30, 30, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, @@ -2533,8 +2554,7 @@ _hb_ucd_u8[32480] = 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, - 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, @@ -2544,8 +2564,9 @@ _hb_ucd_u8[32480] = 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, + 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19, + 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2587,14 +2608,16 @@ _hb_ucd_u8[32480] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 14, 14, 14, 14, 14, 14, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 3, 3, 3, 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, @@ -2642,11 +2665,17 @@ _hb_ucd_u8[32480] = 106,106,106,106,106,106,106,106,106,106,106,106,106,106, 2, 2, 2, 2, 2, 2, 2, 2,104,104,104,104,104,104,104,104,104,104, 104,104,104,104,104,104,104,104,104,104, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,104,110,110,110,110,110,110,110,110,110,110, + 2, 2, 2, 2, 2,104,161,161,161,161,161,161,161,161,161,161, + 161, 2,161,161,161,161,161,161,161, 2,161,161, 2,161,161,161, + 161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161,161, + 161,161,161,161,161,161,161,161, 2,161,161,161,161,161,161,161, + 2,161,161, 2, 2, 2,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110, 2, 2, 2, 2, 2, 2, 2, 2, 2,110,110,110,110,110,110, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,110,110,110,110,110,110,110,110, 2, 2, - 2, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, + 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 2, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 2, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, @@ -2692,14 +2721,15 @@ _hb_ucd_u8[32480] = 130,130,130,130,130,130,144,144,144,144,144,144,144,144,144,144, 144,144,144,144,144,144,144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2, 2, 2,144,144,144,144,144,144,144,144,144,144, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2,156,156,156,156,156,156,156,156,156,156, + 2, 2, 2, 2, 2, 2,156,156,156,156,156,156,156,156,156,156, 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,147,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147, 2, 2, 2, 2, 2, 2, 2, 2,148,148,148,148,148,148,148,148,148,148, 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, + 2, 2, 2, 2, 2, 2,158,158,158,158,158,158,158,158,158,158, + 158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, 153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, @@ -2707,9 +2737,9 @@ _hb_ucd_u8[32480] = 2, 2, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, 2, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101,101,101,101,101,101,101,101,101, 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101,101,101,101,101,101,101,101,101, @@ -2752,12 +2782,12 @@ _hb_ucd_u8[32480] = 2, 2, 2, 2, 2, 2,114,114,114,114,114,114,114,114,114,114, 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, - 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 2, - 2, 2, 2, 2, 2, 2,102,102,102,102,102,102,102,102,102,102, + 102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, 126, 2, 2,126,126,126,126,126,126,126,126,126,126,126,126,126, - 126,126, 2, 2, 2, 2,142,142,142,142,142,142,142,142,142,142, + 126,126, 2, 2, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, + 2, 2, 2, 2, 2, 2,142,142,142,142,142,142,142,142,142,142, 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, 142,142, 2, 2, 2, 2,125,125,125,125,125,125,125,125,125,125, 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, @@ -2805,6 +2835,8 @@ _hb_ucd_u8[32480] = 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2,157,157,157,157,157,157,157,157,157,157, + 157,157,157,157,157,157,157,157,157, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 2, @@ -2814,7 +2846,10 @@ _hb_ucd_u8[32480] = 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, 115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, 115,115,115,115,115, 2,115,115,115,115,115,115,115,115,115,115, - 2, 2, 2, 2,115,115,103,103,103,103,103,103,103,103,103,103, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, + 159,159,159,159,159, 2,159,159,159,159,159,159,159,159,159,159, + 2, 2, 2, 2, 2, 2,103,103,103,103,103,103,103,103,103,103, 103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, 103,103,103,103, 2, 2,103,103,103,103,103,103, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,119,119,119,119,119,119,119,119,119,119, @@ -2827,16 +2862,17 @@ _hb_ucd_u8[32480] = 146, 2, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 0, 0,155, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,136,136,136,136,136,136,136,136,136,136, 136,136,136,136,136,136,136,136,136,136,136,136,136,136, 2, 2, 2, 2, 2, 2, 2, 2,155,155,155,155,155,155,155,155,155,155, 155,155,155,155,155,155,155,155,155,155,155,155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,136,136,136,136,136,136,136,136,136, 2, - 2, 2, 2, 2, 2, 2, 17, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, + 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 2, 2, 2, 2, 2, 2, 2, 2,139,139,139,139,139,139,139,139,139,139, 139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, @@ -2845,14 +2881,16 @@ _hb_ucd_u8[32480] = 105, 2, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, 105,105,105, 2, 2, 2,105,105,105,105,105,105,105,105,105, 2, 2, 2, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 2, 2,105,105,105,105, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, + 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 2, 2, 2, 2, 2, 2, 9, 9, 9, 9, 9, 9, 2, 2, 2, 2, + 1, 1, 1, 1, 0, 0, 9, 9, 9, 9, 9, 9, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2868,24 +2906,28 @@ _hb_ucd_u8[32480] = 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, 131,131, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131,131,131,131,131,131,131,131,131, - 131,131,131,131,131,131, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, + 131,131,131,131,131,131, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, 151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, 151,151,151, 2, 2, 2,151,151,151,151,151,151,151,151,151,151, 151,151,151,151, 2, 2,151,151,151,151,151,151,151,151,151,151, - 2, 2, 2, 2,151,151,152,152,152,152,152,152,152,152,152,152, + 2, 2, 2, 2,151,151,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, + 160,160,160,160,160, 2,152,152,152,152,152,152,152,152,152,152, 152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, - 2, 2, 2, 2, 2,152,113,113,113,113,113,113,113,113,113,113, + 2, 2, 2, 2, 2,152, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, + 30, 30, 2, 30, 30, 2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 2,113,113,113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, 113,113,113,113,113,113,113,113,113,113,113,113,113, 2, 2, 2, 2, 2, 2, 2, 2, 2,132,132,132,132,132,132,132,132,132,132, 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, 132,132, 2, 2, 2, 2,132,132,132,132,132,132,132,132,132,132, 2, 2, 2, 2,132,132, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, @@ -2895,14 +2937,14 @@ _hb_ucd_u8[32480] = 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, - 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, + 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, + 0, 0, 0, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, @@ -3099,7 +3141,7 @@ _hb_ucd_u8[32480] = 0, 0, 0, 0, 0, 0, 72, 73, 74, 75, 76, 77, 78, 79, 80, 0, }; static const uint16_t -_hb_ucd_u16[11328] = +_hb_ucd_u16[11584] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -3109,14 +3151,14 @@ _hb_ucd_u16[11328] = 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 72, 72, 72, 48, 73, 74, 75, 76, 32, - 77, 48, 48, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 84, 85, 92, 93, 94, 95, 96, 97, 98, 85, 99, 100, 101, 89, 102, - 103, 84, 85, 104, 105, 106, 89, 107, 108, 109, 110, 111, 112, 113, 95, 114, - 115, 116, 85, 117, 118, 119, 89, 120, 121, 116, 85, 122, 123, 124, 89, 125, - 126, 116, 48, 127, 128, 129, 89, 130, 131, 132, 48, 133, 134, 135, 95, 136, - 137, 48, 48, 138, 139, 140, 72, 72, 141, 48, 142, 143, 144, 145, 72, 72, - 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 72, 72, + 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32, + 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, + 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, + 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, + 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, + 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, + 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, 168, 48, 48, 170, 171, 172, 48, 48, @@ -3124,51 +3166,49 @@ _hb_ucd_u16[11328] = 178, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, - 184, 185, 48, 186, 48, 187, 184, 188, 48, 48, 48, 189, 190, 191, 192, 193, + 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 72, 72, 72, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 240, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, - 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 72, 263, 264, 216, - 265, 266, 267, 268, 269, 270, 271, 271, 272, 273, 274, 209, 275, 276, 209, 277, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 279, 209, 280, 209, 209, 209, 209, 281, 209, 282, 278, 283, 209, 284, 285, 209, - 209, 209, 286, 72, 287, 72, 270, 270, 270, 288, 209, 209, 209, 209, 289, 270, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 290, 291, 209, 209, 292, - 209, 209, 209, 209, 209, 209, 293, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 270, 296, 209, 209, 297, 278, 298, 278, + 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, + 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 209, 281, 209, 209, 209, 209, 282, 209, 283, 279, 284, 209, 285, 286, 209, + 209, 209, 287, 140, 288, 140, 271, 271, 271, 289, 209, 209, 209, 209, 290, 271, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 291, 292, 209, 209, 293, + 209, 209, 209, 209, 209, 209, 294, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 278, 278, 278, 278, 278, 278, 278, 278, 299, 300, 278, 278, 278, 301, 278, 302, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 209, 209, 209, 278, 303, 209, 209, 304, 209, 305, 209, 209, 209, 209, 209, 209, - 9, 9, 306, 11, 11, 307, 308, 309, 13, 13, 13, 13, 13, 13, 310, 311, - 11, 11, 312, 48, 48, 48, 313, 314, 48, 315, 316, 316, 316, 316, 32, 32, - 317, 318, 319, 320, 321, 322, 72, 72, 209, 323, 209, 209, 209, 209, 209, 324, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 325, 72, 326, - 327, 328, 329, 330, 137, 48, 48, 48, 48, 331, 178, 48, 48, 48, 48, 332, - 333, 48, 48, 137, 48, 48, 48, 48, 200, 334, 48, 48, 209, 209, 324, 48, - 209, 335, 336, 209, 337, 338, 209, 209, 336, 209, 209, 338, 209, 209, 209, 209, + 279, 279, 279, 279, 279, 279, 279, 279, 300, 301, 279, 279, 279, 302, 279, 303, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 209, 209, 209, 279, 304, 209, 209, 305, 209, 306, 209, 209, 209, 209, 209, 209, + 9, 9, 9, 11, 11, 11, 307, 308, 13, 13, 13, 13, 13, 13, 309, 310, + 11, 11, 311, 48, 48, 48, 312, 313, 48, 314, 315, 315, 315, 315, 32, 32, + 316, 317, 318, 319, 320, 321, 140, 140, 209, 322, 209, 209, 209, 209, 209, 323, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 324, 140, 325, + 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331, + 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48, + 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 209, 209, 209, 209, + 48, 338, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, - 48, 339, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 287, 48, 48, 229, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 286, 48, 48, 229, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 340, 48, 341, 72, 13, 13, 342, 343, 13, 344, 48, 48, 48, 48, 345, 346, - 31, 347, 348, 349, 13, 13, 13, 350, 351, 352, 353, 354, 355, 72, 72, 356, + 339, 48, 340, 140, 13, 13, 341, 342, 13, 343, 48, 48, 48, 48, 344, 345, + 31, 346, 347, 348, 13, 13, 13, 349, 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, - 64, 48, 365, 48, 366, 367, 48, 151, 77, 48, 48, 368, 369, 370, 371, 372, + 64, 48, 365, 48, 366, 367, 48, 151, 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, - 383, 384, 316, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, + 383, 384, 315, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 388, 48, 389, 48, 48, 206, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, @@ -3177,120 +3217,130 @@ _hb_ucd_u16[11328] = 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 72, 72, + 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 400, 72, 48, 48, 48, 48, 401, 48, 48, 74, 72, 72, 402, - 32, 403, 32, 404, 405, 406, 407, 73, 48, 48, 48, 48, 48, 48, 48, 408, - 409, 2, 3, 4, 5, 410, 411, 412, 48, 413, 48, 200, 414, 415, 416, 417, - 418, 48, 172, 419, 204, 204, 72, 72, 48, 48, 48, 48, 48, 48, 48, 71, - 420, 270, 270, 421, 271, 271, 271, 422, 423, 424, 425, 72, 72, 209, 209, 426, - 72, 72, 72, 72, 72, 72, 72, 72, 48, 151, 48, 48, 48, 101, 427, 428, - 48, 48, 429, 48, 430, 48, 48, 431, 48, 432, 48, 48, 433, 434, 72, 72, - 9, 9, 435, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 436, 11, 437, - 48, 48, 74, 48, 48, 48, 438, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, + 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, + 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, + 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, + 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, + 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, + 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 315, 48, 199, 74, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 439, 48, 48, 440, 48, 441, 48, 442, 48, 200, 443, 72, 72, 72, 48, 444, - 48, 445, 48, 446, 72, 72, 72, 72, 48, 48, 48, 447, 270, 448, 270, 270, - 449, 450, 48, 451, 452, 453, 48, 454, 48, 455, 72, 72, 456, 48, 457, 458, - 48, 48, 48, 459, 48, 460, 48, 461, 48, 462, 463, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 196, 72, 72, 72, 9, 9, 9, 464, 11, 11, 11, 465, - 48, 48, 466, 192, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 270, 467, 48, 48, 468, 469, 72, 72, 72, 72, - 48, 455, 470, 48, 62, 471, 72, 72, 72, 72, 72, 48, 472, 72, 48, 315, - 473, 48, 48, 474, 475, 448, 476, 477, 222, 48, 48, 478, 479, 48, 196, 192, - 480, 48, 481, 482, 483, 48, 48, 484, 222, 48, 48, 485, 486, 487, 488, 489, - 48, 98, 490, 491, 72, 72, 72, 72, 492, 493, 494, 48, 48, 495, 496, 192, - 497, 84, 85, 498, 499, 500, 501, 502, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 503, 504, 505, 469, 72, 48, 48, 48, 506, 507, 192, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 508, 509, 510, 511, 72, 72, - 48, 48, 48, 512, 513, 192, 514, 72, 48, 48, 515, 516, 192, 72, 72, 72, - 48, 173, 517, 518, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 490, 519, 72, 72, 72, 72, 72, 72, 9, 9, 11, 11, 148, 520, - 521, 522, 48, 523, 524, 192, 72, 72, 72, 72, 525, 48, 48, 526, 527, 72, - 528, 48, 48, 529, 530, 531, 48, 48, 532, 533, 534, 72, 48, 48, 48, 196, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 85, 48, 508, 535, 536, 148, 175, 537, 48, 538, 539, 540, 72, 72, 72, 72, - 541, 48, 48, 542, 543, 192, 544, 48, 545, 546, 192, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 547, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 101, 270, 548, 549, 550, + 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, + 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, + 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, + 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 476, 48, 48, 477, 478, 140, 140, 140, 140, + 48, 464, 479, 48, 62, 480, 140, 48, 481, 140, 140, 48, 482, 140, 48, 314, + 483, 48, 48, 484, 485, 457, 486, 487, 222, 48, 48, 488, 489, 48, 196, 192, + 490, 48, 491, 492, 493, 48, 48, 494, 222, 48, 48, 495, 496, 497, 498, 499, + 48, 97, 500, 501, 140, 140, 140, 140, 502, 503, 504, 48, 48, 505, 506, 192, + 507, 83, 84, 508, 509, 510, 511, 512, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 513, 514, 515, 478, 140, 48, 48, 48, 516, 517, 192, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 518, 519, 520, 521, 140, 140, + 48, 48, 48, 522, 523, 192, 524, 140, 48, 48, 525, 526, 192, 140, 140, 140, + 48, 173, 527, 528, 314, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 500, 529, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 530, + 531, 532, 48, 533, 534, 192, 140, 140, 140, 140, 535, 48, 48, 536, 537, 140, + 538, 48, 48, 539, 540, 541, 48, 48, 542, 543, 544, 48, 48, 48, 48, 196, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 84, 48, 518, 545, 546, 148, 175, 547, 48, 548, 549, 550, 140, 140, 140, 140, + 551, 48, 48, 552, 553, 192, 554, 48, 555, 556, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 557, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 100, 271, 558, 559, 560, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 72, 72, 72, 72, 72, 72, - 271, 271, 271, 271, 271, 271, 551, 552, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 388, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 200, 553, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 315, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 196, 48, 200, 370, 72, 72, 72, 72, 72, 72, 48, 204, 554, - 48, 48, 48, 555, 556, 557, 558, 559, 48, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 9, 9, 11, 11, 270, 560, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 561, 562, 563, 563, 564, 565, 72, 72, 72, 72, 566, 567, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 207, 140, 140, 140, 140, 140, 140, + 272, 272, 272, 272, 272, 272, 561, 562, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 563, + 48, 48, 200, 564, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 314, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 565, + 48, 48, 48, 566, 567, 568, 569, 570, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 571, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 572, 573, 574, 574, 575, 576, 140, 140, 140, 140, 577, 578, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 74, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 72, 72, - 196, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 440, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 199, 140, 140, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 579, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 200, 72, 72, 72, 568, 569, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 580, 140, 140, 580, 581, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 206, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 48, 48, 71, 151, 196, 570, 571, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 325, - 209, 209, 572, 209, 209, 209, 573, 574, 575, 209, 576, 209, 209, 209, 577, 72, - 209, 209, 209, 209, 578, 72, 72, 72, 72, 72, 72, 72, 72, 72, 270, 579, - 209, 209, 209, 209, 209, 286, 270, 452, 72, 72, 72, 72, 72, 72, 72, 72, - 9, 580, 11, 581, 582, 583, 242, 9, 584, 585, 586, 587, 588, 9, 580, 11, - 589, 590, 11, 591, 592, 593, 594, 9, 595, 11, 9, 580, 11, 581, 582, 11, - 242, 9, 584, 594, 9, 595, 11, 9, 580, 11, 596, 9, 597, 598, 599, 600, - 11, 601, 9, 602, 603, 604, 605, 11, 606, 9, 607, 11, 608, 609, 609, 609, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 582, 583, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 32, 32, 584, 32, 585, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 324, + 209, 209, 586, 209, 209, 209, 587, 588, 589, 209, 590, 209, 209, 209, 288, 140, + 209, 209, 209, 209, 591, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 592, + 209, 209, 209, 209, 209, 287, 271, 461, 140, 140, 140, 140, 140, 140, 140, 140, + 9, 593, 11, 594, 595, 596, 241, 9, 597, 598, 599, 600, 601, 9, 593, 11, + 602, 603, 11, 604, 605, 606, 607, 9, 608, 11, 9, 593, 11, 594, 595, 11, + 241, 9, 597, 607, 9, 608, 11, 9, 593, 11, 609, 9, 610, 611, 612, 613, + 11, 614, 9, 615, 616, 617, 618, 11, 619, 9, 620, 11, 621, 622, 622, 622, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 32, 32, 32, 623, 32, 32, 624, 625, 626, 627, 45, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 628, 629, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 630, 631, 632, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 48, 48, 151, 633, 634, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 635, 140, 48, 48, 636, 637, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 638, 200, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 639, 585, 140, 140, + 9, 9, 597, 11, 640, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 498, 271, 271, 641, 642, 140, 140, 140, 140, + 498, 271, 643, 644, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 645, 48, 646, 647, 648, 649, 650, 651, 652, 206, 653, 206, 140, 140, 140, 654, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 655, 655, 655, 209, 324, + 656, 209, 209, 209, 209, 209, 209, 209, 209, 209, 657, 140, 140, 140, 658, 209, + 659, 209, 209, 325, 660, 661, 324, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 662, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 663, 426, 426, + 209, 209, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 660, 325, 427, + 325, 209, 209, 209, 664, 176, 209, 209, 664, 209, 657, 661, 140, 140, 140, 140, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, - 32, 32, 32, 610, 32, 32, 611, 612, 613, 614, 45, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 615, 616, 617, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 151, 618, 619, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 48, 620, 621, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 622, 623, 72, 72, - 9, 9, 584, 11, 624, 370, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 488, 270, 270, 625, 626, 72, 72, 72, 72, - 488, 270, 627, 628, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 629, 48, 630, 631, 632, 633, 634, 635, 636, 206, 637, 206, 72, 72, 72, 638, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 209, 209, 326, 209, 209, 209, 209, 209, 209, 324, 335, 639, 639, 639, 209, 325, - 640, 209, 209, 209, 209, 209, 209, 209, 209, 209, 641, 72, 72, 72, 642, 209, - 643, 209, 209, 326, 577, 644, 325, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 645, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 646, 424, 424, - 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 209, 209, 209, 577, 326, 72, - 326, 209, 209, 209, 646, 176, 209, 209, 646, 209, 641, 644, 72, 72, 72, 72, - 209, 209, 209, 209, 209, 209, 209, 647, 209, 209, 209, 209, 648, 209, 209, 209, - 209, 209, 209, 209, 209, 324, 641, 649, 286, 209, 577, 286, 643, 286, 72, 72, - 209, 209, 209, 209, 209, 209, 209, 209, 209, 650, 209, 209, 287, 72, 72, 192, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 72, 72, + 209, 209, 209, 209, 209, 323, 657, 665, 287, 209, 426, 288, 324, 176, 664, 287, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 666, 209, 209, 288, 140, 140, 192, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 205, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 196, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 469, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 101, 72, - 48, 204, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 71, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 651, 72, 652, 652, 652, 652, 652, 652, 72, 72, 72, 72, 72, 72, 72, 72, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 72, + 48, 48, 48, 48, 71, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 667, 140, 668, 668, 668, 668, 668, 668, 140, 140, 140, 140, 140, 140, 140, 140, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 653, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 669, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 654, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 670, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, @@ -3299,191 +3349,199 @@ _hb_ucd_u16[11328] = 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, - 39, 39, 40, 41, 42, 43, 44, 45, 45, 45, 27, 46, 47, 48, 49, 27, - 50, 50, 50, 50, 50, 51, 52, 50, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 111, 112, 113, 114, 111, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 124, 125, 124, 126, 45, 45, 127, 128, 129, 130, 131, 132, 45, 45, - 133, 133, 133, 133, 134, 133, 135, 136, 133, 134, 133, 137, 137, 138, 45, 45, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, 140, 141, 140, 140, 142, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 144, 144, 144, 144, 145, 146, 144, 144, 145, 144, 144, 147, 148, 149, 144, 144, - 144, 148, 144, 144, 144, 150, 144, 151, 144, 152, 153, 153, 153, 153, 153, 154, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 156, 157, 158, 158, 158, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 169, 169, 169, 169, 170, 171, 171, - 172, 173, 174, 174, 174, 174, 174, 175, 174, 174, 176, 155, 155, 155, 155, 177, - 178, 179, 180, 180, 181, 182, 183, 184, 185, 185, 186, 185, 187, 188, 169, 169, - 189, 190, 191, 191, 191, 192, 191, 193, 194, 194, 195, 8, 196, 45, 45, 45, - 197, 197, 197, 197, 198, 197, 197, 199, 200, 200, 200, 200, 201, 201, 201, 202, - 203, 203, 203, 204, 205, 206, 206, 206, 207, 140, 140, 208, 209, 210, 211, 212, - 4, 4, 213, 4, 4, 214, 215, 216, 4, 4, 4, 217, 8, 8, 8, 218, + 39, 39, 40, 41, 42, 43, 44, 27, 45, 46, 27, 27, 27, 27, 47, 27, + 48, 48, 48, 48, 48, 49, 50, 48, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125, + 132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143, + 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170, + 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176, + 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168, + 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 8, 195, 125, 125, 125, + 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201, + 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211, + 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 11, 219, 11, 11, 219, 220, 11, 221, 11, 11, 11, 222, 222, 223, 11, 224, - 225, 0, 0, 0, 0, 0, 226, 227, 228, 229, 0, 0, 45, 8, 8, 196, + 11, 217, 11, 11, 217, 218, 11, 219, 11, 11, 11, 220, 220, 221, 11, 222, + 223, 0, 0, 0, 0, 0, 224, 225, 226, 227, 0, 0, 228, 8, 8, 229, 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 234, 45, 235, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 234, 125, 235, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, 0, 0, - 239, 239, 240, 239, 239, 240, 4, 4, 241, 241, 241, 241, 241, 241, 241, 242, - 140, 140, 141, 243, 243, 243, 244, 245, 144, 246, 247, 247, 247, 247, 14, 14, - 0, 0, 0, 0, 0, 248, 45, 45, 249, 250, 249, 249, 249, 249, 249, 251, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 252, 45, 253, - 254, 0, 255, 256, 257, 258, 258, 258, 258, 259, 260, 261, 261, 261, 261, 262, - 263, 264, 264, 265, 143, 143, 143, 143, 266, 0, 264, 264, 0, 0, 267, 261, - 143, 266, 0, 0, 0, 0, 143, 268, 0, 0, 0, 0, 0, 261, 261, 269, - 261, 261, 261, 261, 261, 270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 0, 0, 0, 0, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 271, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 273, 272, 272, 272, 274, 275, 275, 275, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, - 276, 276, 277, 45, 14, 14, 14, 14, 14, 14, 278, 278, 278, 278, 278, 279, - 0, 0, 280, 4, 4, 4, 4, 4, 281, 4, 4, 4, 282, 45, 45, 283, - 284, 284, 285, 286, 287, 287, 287, 288, 289, 289, 289, 289, 290, 291, 50, 50, - 292, 292, 293, 294, 294, 295, 143, 296, 297, 297, 297, 297, 298, 299, 139, 300, - 301, 301, 301, 302, 303, 304, 139, 139, 305, 305, 305, 305, 306, 307, 308, 309, - 310, 311, 247, 4, 4, 312, 313, 153, 153, 153, 153, 153, 308, 308, 314, 315, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 316, 143, 317, 143, 143, 318, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 319, 249, 249, 249, 249, 249, 249, 320, 45, 45, - 321, 322, 21, 323, 324, 27, 27, 27, 27, 27, 27, 27, 325, 48, 27, 27, + 239, 239, 239, 239, 239, 239, 4, 4, 240, 240, 240, 240, 240, 240, 240, 241, + 139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246, 14, 14, + 0, 0, 0, 0, 0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125, 252, + 253, 0, 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 260, 260, 261, + 262, 263, 263, 264, 142, 142, 142, 142, 265, 0, 263, 263, 0, 0, 266, 260, + 142, 265, 0, 0, 0, 0, 142, 267, 0, 0, 0, 0, 0, 260, 260, 268, + 260, 260, 260, 260, 260, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 0, 0, 0, 0, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 271, 270, 270, 270, 272, 273, 273, 273, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 275, 125, 14, 14, 14, 14, 14, 14, 276, 276, 276, 276, 276, 277, + 0, 0, 278, 4, 4, 4, 4, 4, 279, 4, 4, 4, 280, 281, 125, 282, + 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 48, 48, + 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299, + 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308, + 309, 310, 246, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 315, 142, 316, 142, 142, 317, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125, + 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 325, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 326, 45, 27, 27, 27, 27, 327, 27, 27, 47, 45, 45, 328, - 8, 286, 329, 0, 0, 330, 331, 46, 27, 27, 27, 27, 27, 27, 27, 332, - 333, 0, 1, 2, 1, 2, 334, 260, 261, 335, 143, 266, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 344, 45, 45, 341, 341, 341, 341, 341, 341, 341, 345, - 346, 0, 0, 347, 11, 11, 11, 11, 348, 349, 350, 45, 45, 0, 0, 351, - 45, 45, 45, 45, 45, 45, 45, 45, 352, 353, 354, 354, 354, 355, 356, 253, - 357, 357, 358, 359, 360, 361, 361, 362, 363, 364, 365, 365, 366, 367, 45, 45, - 368, 368, 368, 368, 368, 369, 369, 369, 370, 371, 372, 373, 373, 374, 373, 375, - 376, 376, 377, 378, 378, 378, 379, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, - 380, 380, 380, 381, 380, 382, 383, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 384, 385, 385, 386, 387, 388, 389, 389, 390, 391, 392, 45, 45, 45, 393, 394, - 395, 396, 397, 398, 45, 45, 45, 45, 399, 399, 400, 401, 400, 402, 400, 400, - 403, 404, 405, 406, 407, 407, 408, 408, 409, 409, 45, 45, 410, 410, 411, 412, - 413, 413, 413, 414, 415, 416, 417, 418, 419, 420, 421, 45, 45, 45, 45, 45, - 422, 422, 422, 422, 423, 45, 45, 45, 424, 424, 424, 425, 424, 424, 424, 426, - 427, 427, 428, 429, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 27, 430, 431, 431, 432, 433, 45, 45, 45, 45, - 434, 434, 435, 436, 436, 437, 45, 45, 45, 45, 45, 438, 439, 45, 440, 441, - 442, 442, 442, 442, 443, 444, 442, 445, 446, 446, 446, 446, 447, 448, 449, 450, - 451, 451, 451, 452, 453, 454, 454, 455, 456, 456, 456, 456, 456, 456, 457, 458, - 459, 460, 459, 461, 45, 45, 45, 45, 462, 463, 464, 465, 465, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 45, 45, 45, 45, 45, 45, 45, 45, - 476, 476, 476, 476, 476, 477, 478, 45, 479, 479, 479, 479, 480, 481, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 482, 482, 482, 483, 482, 484, 45, 45, - 485, 485, 485, 485, 486, 487, 488, 45, 489, 489, 489, 490, 491, 45, 45, 45, - 492, 493, 494, 492, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 495, 495, 495, 496, 45, 45, 45, 45, 45, 45, 497, 497, 497, 497, 497, 498, - 499, 500, 501, 502, 503, 504, 45, 45, 45, 45, 505, 506, 506, 505, 507, 45, - 508, 508, 508, 508, 509, 510, 510, 510, 510, 510, 511, 45, 512, 512, 512, 513, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 514, 515, 515, 516, 517, 515, 518, 519, 519, 520, 521, 522, 45, 45, 45, 45, - 523, 524, 524, 525, 526, 527, 528, 529, 530, 531, 532, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 533, 534, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 535, 536, 536, 536, 537, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 538, 538, 538, 538, 538, 538, 539, 45, 45, 45, 45, 45, 45, - 538, 538, 538, 538, 538, 538, 540, 541, 538, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 538, 542, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, - 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, - 543, 543, 544, 545, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 27, 27, 27, 326, 27, 27, 27, 27, 27, 327, 27, 27, 328, 125, 125, 27, + 8, 285, 329, 0, 0, 330, 331, 332, 27, 27, 27, 27, 27, 27, 27, 333, + 334, 0, 1, 2, 1, 2, 335, 259, 260, 336, 142, 265, 337, 338, 339, 340, + 341, 342, 343, 344, 345, 345, 125, 125, 342, 342, 342, 342, 342, 342, 342, 346, + 347, 0, 0, 348, 11, 11, 11, 11, 349, 350, 351, 125, 125, 0, 0, 352, + 125, 125, 125, 125, 125, 125, 125, 125, 353, 354, 355, 355, 355, 356, 357, 252, + 358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125, + 369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376, + 377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 386, 385, 387, 388, 125, 389, 4, 4, 390, 125, 125, 125, 125, + 391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401, + 402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407, + 410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419, + 420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125, + 429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433, + 434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 27, 45, 437, 437, 438, 439, 125, 125, 125, 125, + 440, 440, 441, 442, 442, 443, 125, 444, 445, 125, 125, 446, 447, 125, 448, 449, + 450, 450, 450, 450, 451, 452, 450, 453, 454, 454, 454, 454, 455, 456, 457, 458, + 459, 459, 459, 460, 461, 462, 462, 463, 464, 464, 464, 464, 464, 464, 465, 466, + 467, 468, 467, 469, 125, 125, 125, 125, 470, 471, 472, 473, 473, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 125, 125, 125, 125, 125, 125, 125, 125, + 484, 484, 484, 484, 484, 485, 486, 125, 487, 487, 487, 487, 488, 489, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 490, 490, 490, 491, 490, 492, 125, 125, + 493, 493, 493, 493, 494, 495, 496, 125, 497, 497, 497, 498, 498, 125, 125, 125, + 499, 500, 501, 499, 502, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 503, 503, 503, 504, 125, 125, 125, 125, 125, 125, 505, 505, 505, 505, 505, 506, + 507, 508, 509, 510, 511, 512, 125, 125, 125, 125, 513, 514, 514, 513, 515, 125, + 516, 516, 516, 516, 517, 518, 518, 518, 518, 518, 519, 154, 520, 520, 520, 521, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 522, 523, 523, 524, 525, 523, 526, 527, 527, 528, 529, 530, 125, 125, 125, 125, + 531, 532, 532, 533, 534, 535, 536, 537, 538, 539, 540, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 541, 542, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544, 544, 544, 545, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, - 546, 546, 546, 546, 547, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, - 278, 278, 278, 548, 549, 550, 551, 45, 45, 45, 45, 45, 45, 552, 553, 554, - 555, 555, 555, 555, 556, 557, 558, 559, 555, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 560, 560, 560, 560, 560, 561, 45, 45, 45, 45, 45, 45, - 562, 562, 562, 562, 563, 562, 562, 562, 564, 562, 45, 45, 45, 45, 565, 566, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 568, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, - 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, 570, 45, 45, - 571, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 572, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 573, 45, 45, 45, 574, 575, 576, 576, 576, 576, 576, 576, 576, 576, 576, - 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 577, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 578, 578, 578, 578, 578, 578, 579, 580, 581, 582, 267, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 583, - 0, 0, 584, 0, 0, 0, 585, 586, 587, 0, 588, 0, 0, 0, 589, 45, - 11, 11, 11, 11, 590, 45, 45, 45, 45, 45, 45, 45, 45, 45, 0, 267, - 0, 0, 0, 0, 0, 234, 0, 589, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 226, 0, 0, 0, 591, 592, 593, 594, 0, 0, 0, - 595, 596, 0, 597, 598, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 600, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 0, - 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 602, 602, 602, 603, 604, 605, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 606, 607, 608, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 609, 609, 610, 611, 612, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 613, 613, 613, 614, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 615, 616, 617, 45, 45, - 618, 618, 618, 618, 619, 620, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 333, 0, 0, 0, 621, 45, 45, 45, 45, - 333, 0, 0, 622, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 623, 27, 624, 625, 626, 627, 628, 629, 630, 631, 632, 631, 45, 45, 45, 325, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 253, 0, 0, 0, 0, 0, 0, 267, 228, 333, 333, 333, 0, 583, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 622, 45, 45, 45, 633, 0, - 634, 0, 0, 253, 589, 635, 583, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636, 349, 349, - 0, 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 589, 253, 45, - 253, 0, 0, 0, 636, 286, 0, 0, 636, 0, 622, 635, 45, 45, 45, 45, - 0, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 0, 638, 0, 0, 0, - 0, 0, 0, 0, 0, 267, 622, 639, 234, 0, 589, 234, 248, 234, 45, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 235, 45, 45, 286, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 319, 45, 45, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 640, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 319, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 566, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 641, 45, - 249, 319, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 249, 249, 249, 642, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 643, 45, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 45, + 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 546, 546, 546, 546, 546, 546, 546, 546, 547, 125, 125, 125, 125, 125, 125, + 546, 546, 546, 546, 546, 546, 548, 549, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 546, 546, 546, 550, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 551, 551, 551, 551, 551, 551, 552, + 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + 553, 553, 554, 555, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 556, 556, 557, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 558, 559, 560, 561, 562, 562, 562, 562, 563, 564, 565, 566, 567, + 568, 568, 568, 568, 569, 570, 571, 572, 568, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 573, 573, 573, 573, 573, 574, 125, 125, 125, 125, 125, 125, + 575, 575, 575, 575, 576, 575, 575, 575, 577, 575, 125, 125, 125, 125, 578, 579, + 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, + 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, + 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, + 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 581, + 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, + 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 583, 125, 125, + 584, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 585, + 586, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 587, 125, 125, 588, 589, 590, 590, 590, 590, 590, 590, 590, 590, 590, + 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 591, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 592, 592, 592, 592, 592, 592, 593, 594, 595, 596, 266, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 8, 8, 597, 8, 598, 0, 0, 0, 0, 0, 0, 0, 266, 125, 125, 125, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, + 0, 0, 600, 0, 0, 0, 601, 602, 603, 0, 604, 0, 0, 0, 235, 125, + 11, 11, 11, 11, 605, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 266, + 0, 0, 0, 0, 0, 234, 0, 606, 125, 125, 125, 125, 125, 125, 125, 125, + 0, 0, 0, 0, 0, 224, 0, 0, 0, 607, 608, 609, 610, 0, 0, 0, + 611, 612, 0, 613, 614, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 617, 0, 0, 0, + 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 618, 618, 618, 619, 620, 621, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 4, 622, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 623, 624, 625, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 626, 626, 627, 628, 629, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 630, 631, 125, 632, 632, 632, 633, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 634, 635, + 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 638, 125, 125, + 639, 639, 639, 639, 640, 641, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 334, 0, 0, 0, 642, 125, 125, 125, 125, + 334, 0, 0, 247, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 643, 27, 644, 645, 646, 647, 648, 649, 650, 651, 652, 651, 125, 125, 125, 653, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 0, 0, 252, 0, 0, 0, 0, 0, 0, 266, 226, 334, 334, 334, 0, 599, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 125, 125, 125, 654, 0, + 655, 0, 0, 252, 606, 656, 599, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 657, 350, 350, + 0, 0, 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, 0, 606, 252, 228, + 252, 0, 0, 0, 658, 285, 0, 0, 658, 0, 247, 656, 125, 125, 125, 125, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 266, 247, 659, 234, 0, 350, 235, 599, 285, 658, 234, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 235, 125, 125, 285, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 125, 125, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 660, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 579, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 661, 125, + 248, 318, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 662, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 663, 125, 0, 0, 0, 0, 0, 0, 125, 125, 125, 125, 125, 125, 125, 125, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3836,7 +3894,7 @@ _hb_ucd_gc (unsigned u) static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[15060+(((_hb_ucd_u8[13636+(((_hb_ucd_u8[12656+(u>>3>>4)])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:0; + return u<125259u?_hb_ucd_u8[15332+(((_hb_ucd_u8[13892+(((_hb_ucd_u8[12912+(u>>3>>4)])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -3846,59 +3904,59 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[16372+(((_hb_ucd_b4(16244+_hb_ucd_u8,u>>2>>6))<<6)+((u>>2)&63u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[16692+(((_hb_ucd_b4(16564+_hb_ucd_u8,u>>2>>6))<<6)+((u>>2)&63u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[19126+(((_hb_ucd_u16[3040+(((_hb_ucd_u8[17332+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:2; + return u<918000u?_hb_ucd_u8[19446+(((_hb_ucd_u16[3168+(((_hb_ucd_u8[17652+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6144+(((_hb_ucd_u8[29430+(u>>6)])<<6)+((u)&63u))]:0; + return u<195102u?_hb_ucd_u16[6400+(((_hb_ucd_u8[30070+(u>>6)])<<6)+((u)&63u))]:0; } #elif !defined(HB_NO_UCD_UNASSIGNED) static const uint8_t -_hb_ucd_u8[17508] = +_hb_ucd_u8[17936] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 9, 10, 11, 7, 7, 7, 7, 12, 13, 14, 14, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 21, 23, 21, 21, 21, 21, 24, 7, 7, - 25, 26, 21, 21, 21, 21, 27, 28, 21, 21, 29, 30, 31, 32, 33, 34, + 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 22, 22, 22, 22, 24, 7, 7, + 25, 26, 22, 22, 22, 27, 28, 29, 22, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 35, 7, 36, 37, 7, 38, 7, 7, 7, 39, 21, 40, - 7, 7, 41, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 42, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 43, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 44, + 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 22, 42, + 7, 7, 43, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 44, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 46, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43, @@ -3908,42 +3966,44 @@ _hb_ucd_u8[17508] = 84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, - 92, 34, 34, 34, 34, 34, 34, 34, 34, 93, 34, 34, 94, 95, 96, 97, - 98, 99,100,101,102,103,104,105, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,106, + 91, 34, 34, 34, 34, 34, 34, 34, 34, 92, 34, 34, 93, 94, 95, 96, + 97, 98, 99,100,101,102,103,104, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,105, + 106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, - 108,108, 34, 34,109,110,111,112, 34, 34,113,114,115,116,117,118, - 119,120,121,122,123,124,125,126,127,128,129,123, 34, 34,130,123, - 131,132,133,134,135,136,137,138,139,140,141,123,142,143,144,145, - 146,147,148,149,150,151,152,123,153,154,123,155,156,157,158,123, - 159,160,161,162,163,164,123,123,165,166,167,168,123,169,123,170, - 34, 34, 34, 34, 34, 34, 34,171,172, 34,173,123,123,123,123,123, - 123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, - 34, 34, 34, 34, 34, 34, 34, 34,174,123,123,123,123,123,123,123, - 123,123,123,123,123,123,123,123, 34, 34, 34, 34,175,123,123,123, - 34, 34, 34, 34,176,177,178,179,123,123,123,123,180,181,182,183, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,184, - 34, 34, 34, 34, 34, 34, 34, 34, 34,185,186,123,123,123,123,123, - 34, 34,187, 34, 34,188,123,123,123,123,123,123,123,123,123,123, - 123,123,123,123,123,123,123,123,189,190,123,123,123,123,123,123, - 69,191,192,193,194,195,196,123,197,198,199,200,201,202,203,204, - 69, 69, 69, 69,205,206,123,123,123,123,123,123,123,123,123,123, - 207,123,208,123,123,209,123,123,123,123,123,123,123,123,123,123, - 34,210,211,123,123,123,123,123,212,213,214,123,215,216,123,123, - 217,218,219,220,221,123, 69,222, 69, 69, 69, 69, 69,223,224,225, - 226,227,228,229,230,231, 69,232,123,123,123,123,123,123,123,123, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,233, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,234, 34, - 235, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,236, 34, 34, - 34, 34, 34, 34, 34, 34, 34,237,123,123,123,123,123,123,123,123, - 34, 34, 34, 34,238,123,123,123,123,123,123,123,123,123,123,123, - 34, 34, 34, 34, 34, 34,239,123,123,123,123,123,123,123,123,123, - 240,123,241,242,123,123,123,123,123,123,123,123,123,123,123,123, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,243, - 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,244, + 107,107, 34, 34,108,109,110,111, 34, 34,112,113,114,115,116,117, + 118,119,120,121,122,123,124,125,126,127,128,129, 34, 34,130,131, + 132,133,134,135,136,137,138,139,140,141,142,122,143,144,145,146, + 147,148,149,150,151,152,153,122,154,155,122,156,157,158,159,122, + 160,161,162,163,164,165,122,122,166,167,168,169,122,170,122,171, + 34, 34, 34, 34, 34, 34, 34,172,173, 34,174,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,175, + 34, 34, 34, 34, 34, 34, 34, 34,176,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122, 34, 34, 34, 34,177,122,122,122, + 34, 34, 34, 34,178,179,180,181,122,122,122,122,182,183,184,185, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,186, + 34, 34, 34, 34, 34, 34, 34, 34, 34,187,188,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,189, + 34, 34,190, 34, 34,191,122,122,122,122,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122,192,193,122,122,122,122,122,122, + 122,122,122,122,122,122,122,122,122,122,122,122,122,122,194,195, + 69,196,197,198,199,200,201,122,202,203,204,205,206,207,208,209, + 69, 69, 69, 69,210,211,122,122,122,122,122,122,122,122,212,122, + 213,122,214,122,122,215,122,122,122,122,122,122,122,122,122,216, + 34,217,218,122,122,122,122,122,219,220,221,122,222,223,122,122, + 224,225,226,227,228,122, 69,229, 69, 69, 69, 69, 69,230,231,232, + 233,234, 69, 69,235,236, 69,237,122,122,122,122,122,122,122,122, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,238, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,239, 34, + 240, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,241, 34, 34, + 34, 34, 34, 34, 34, 34, 34,242,122,122,122,122,122,122,122,122, + 34, 34, 34, 34,243,122,122,122,122,122,122,122,122,122,122,122, + 34, 34, 34, 34, 34, 34,244,122,122,122,122,122,122,122,122,122, + 245,122,246,247,122,122,122,122,122,122,122,122,122,122,122,122, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,248, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,249, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -3980,298 +4040,306 @@ _hb_ucd_u8[17508] = 43, 43, 40, 21, 2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43, 43, 43, 75, 43, 75, 43, 43, 44, 2, 2, 2, 2, 2, 2, 2, 64, 36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 44, 44, 44, 44, 44, 57, 43, 43, 43, 43, 43, 43, - 43, 82, 43, 43, 43, 43, 43, 43, 43, 83, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 83, 71, 84, 85, 43, 43, 43, 83, 84, 85, 84, - 70, 43, 43, 43, 36, 36, 36, 36, 36, 43, 2, 7, 7, 7, 7, 7, - 86, 36, 36, 36, 36, 36, 36, 36, 70, 84, 62, 36, 36, 36, 61, 62, - 61, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, - 61, 61, 44, 36, 36, 44, 71, 84, 85, 43, 80, 87, 88, 87, 85, 61, - 44, 44, 44, 87, 44, 44, 36, 62, 36, 43, 44, 7, 7, 7, 7, 7, - 36, 20, 27, 27, 27, 56, 63, 80, 57, 83, 62, 36, 36, 61, 44, 62, - 61, 36, 62, 61, 36, 44, 80, 84, 85, 80, 44, 57, 80, 57, 43, 44, - 57, 44, 44, 44, 62, 36, 61, 61, 44, 44, 44, 7, 7, 7, 7, 7, - 43, 36, 70, 64, 44, 44, 44, 44, 57, 83, 62, 36, 36, 36, 36, 62, - 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, 36, 36, 44, 71, 84, - 85, 43, 43, 57, 83, 87, 85, 44, 61, 44, 44, 44, 44, 44, 44, 44, - 66, 44, 44, 44, 62, 43, 43, 43, 57, 84, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 44, 71, 85, 85, 43, 80, 87, 88, 87, 85, 44, - 44, 44, 57, 83, 44, 44, 36, 62, 78, 27, 27, 27, 44, 44, 44, 44, - 44, 71, 62, 36, 36, 61, 44, 36, 61, 36, 36, 44, 62, 61, 61, 36, - 44, 62, 61, 44, 36, 61, 44, 36, 36, 36, 36, 36, 36, 44, 44, 84, - 83, 88, 44, 84, 88, 84, 85, 44, 61, 44, 44, 87, 44, 44, 44, 44, - 27, 89, 67, 67, 56, 90, 44, 44, 83, 84, 71, 36, 36, 36, 61, 36, - 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 44, 62, 43, - 83, 84, 88, 43, 80, 43, 43, 44, 44, 44, 57, 80, 36, 61, 44, 44, - 44, 44, 44, 91, 27, 27, 27, 89, 70, 84, 72, 36, 36, 36, 61, 36, - 36, 36, 62, 36, 36, 44, 71, 85, 84, 84, 88, 83, 88, 84, 43, 44, - 44, 44, 87, 88, 44, 44, 44, 61, 62, 61, 44, 44, 44, 44, 44, 44, - 43, 84, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 70, 71, 84, - 85, 43, 80, 84, 88, 84, 85, 77, 44, 44, 36, 92, 27, 27, 27, 93, - 27, 27, 27, 27, 89, 36, 36, 36, 57, 84, 62, 36, 36, 36, 36, 36, - 36, 36, 36, 61, 44, 36, 36, 36, 36, 62, 36, 36, 36, 36, 62, 44, - 36, 36, 36, 61, 44, 80, 44, 87, 84, 43, 80, 80, 84, 84, 84, 84, - 44, 84, 64, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, 36, - 70, 36, 43, 43, 43, 80, 44, 94, 36, 36, 36, 75, 43, 43, 43, 60, - 7, 7, 7, 7, 7, 2, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, + 36, 36, 36, 36, 82, 36, 36, 61, 65, 44, 44, 44, 43, 43, 43, 43, + 36, 36, 36, 36, 83, 43, 43, 43, 43, 84, 43, 43, 43, 43, 43, 43, + 43, 85, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 85, 71, 86, + 87, 43, 43, 43, 85, 86, 87, 86, 70, 43, 43, 43, 36, 36, 36, 36, + 36, 43, 2, 7, 7, 7, 7, 7, 88, 36, 36, 36, 36, 36, 36, 36, + 70, 86, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 86, + 87, 43, 80, 89, 90, 89, 87, 61, 44, 44, 44, 89, 44, 44, 36, 62, + 36, 43, 44, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 56, 63, 80, + 57, 85, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 86, + 87, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61, + 44, 44, 44, 7, 7, 7, 7, 7, 43, 36, 70, 64, 44, 44, 44, 44, + 57, 85, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, + 61, 36, 62, 36, 36, 44, 71, 86, 87, 43, 43, 57, 85, 89, 87, 44, + 61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43, + 57, 86, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 87, + 87, 43, 80, 89, 90, 89, 87, 44, 44, 44, 57, 85, 44, 44, 36, 62, + 78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36, + 61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36, + 36, 36, 36, 36, 36, 44, 44, 86, 85, 90, 44, 86, 90, 86, 87, 44, + 61, 44, 44, 89, 44, 44, 44, 44, 27, 91, 67, 67, 56, 92, 44, 44, + 85, 86, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 44, 71, 43, 85, 86, 90, 43, 80, 43, 43, 44, + 44, 44, 57, 80, 36, 61, 62, 44, 44, 44, 44, 93, 27, 27, 27, 91, + 70, 86, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 87, + 86, 86, 90, 85, 90, 86, 43, 44, 44, 44, 89, 90, 44, 44, 62, 61, + 62, 61, 44, 44, 44, 44, 44, 44, 43, 86, 36, 36, 36, 36, 61, 36, + 36, 36, 36, 36, 36, 70, 71, 86, 87, 43, 80, 86, 90, 86, 87, 77, + 44, 44, 36, 94, 27, 27, 27, 95, 27, 27, 27, 27, 91, 36, 36, 36, + 57, 86, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36, + 36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 89, + 86, 43, 80, 80, 86, 86, 86, 86, 44, 86, 64, 44, 44, 44, 44, 44, + 62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 96, + 36, 36, 36, 75, 43, 43, 43, 60, 7, 7, 7, 7, 7, 2, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 62, 61, 61, 36, 36, 61, 36, 36, 36, 36, 62, 62, 36, 36, 36, 36, 70, 36, 43, 43, 43, 43, 71, 44, 36, 36, 61, 81, 43, 43, 43, 44, 7, 7, 7, 7, 7, 44, 36, 36, - 77, 67, 2, 2, 2, 2, 2, 2, 2, 95, 95, 67, 43, 67, 67, 67, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 84, + 77, 67, 2, 2, 2, 2, 2, 2, 2, 97, 97, 67, 43, 67, 67, 67, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 50, 50, 50, 4, 4, 86, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, - 57, 43, 43, 43, 43, 43, 43, 83, 43, 43, 60, 43, 36, 36, 70, 43, + 57, 43, 43, 43, 43, 43, 43, 85, 43, 43, 60, 43, 36, 36, 70, 43, 43, 43, 43, 43, 57, 43, 43, 43, 43, 43, 43, 43, 43, 43, 80, 67, - 67, 67, 67, 76, 67, 67, 90, 67, 2, 2, 95, 67, 21, 64, 44, 44, - 36, 36, 36, 36, 36, 92, 85, 43, 83, 43, 43, 43, 85, 83, 85, 71, - 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 84, 43, 36, 36, 43, - 71, 84, 96, 92, 84, 84, 84, 36, 70, 43, 71, 36, 36, 36, 36, 36, - 36, 83, 85, 83, 84, 84, 85, 92, 7, 7, 7, 7, 7, 84, 85, 67, + 67, 67, 67, 76, 67, 67, 92, 67, 2, 2, 97, 67, 21, 64, 44, 44, + 36, 36, 36, 36, 36, 94, 87, 43, 85, 43, 43, 43, 87, 85, 87, 71, + 7, 7, 7, 7, 7, 2, 2, 2, 36, 36, 36, 86, 43, 36, 36, 43, + 71, 86, 98, 94, 86, 86, 86, 36, 70, 43, 71, 36, 36, 36, 36, 36, + 36, 85, 87, 85, 86, 86, 87, 94, 7, 7, 7, 7, 7, 86, 87, 67, 11, 11, 11, 48, 44, 44, 48, 44, 16, 16, 16, 16, 16, 53, 45, 16, 36, 36, 36, 36, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 61, 36, 36, 44, 36, 36, 36, 61, 61, 36, 36, 44, 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 57, 43, - 2, 2, 2, 2, 97, 27, 27, 27, 27, 27, 27, 27, 27, 27, 98, 44, + 2, 2, 2, 2, 99, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, 67, 67, 67, 67, 67, 44, 44, 44, 11, 11, 11, 44, 16, 16, 16, 44, - 99, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, - 100, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,101,102, 44, - 36, 36, 36, 36, 36, 63, 2,103,104, 36, 36, 36, 61, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 61, 36, 36, 43, 80, 44, 44, 44, 44, 44, - 36, 43, 60, 64, 44, 44, 44, 44, 36, 43, 44, 44, 44, 44, 44, 44, - 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 85, 43, 43, 43, 84, - 84, 84, 84, 83, 85, 43, 43, 43, 43, 43, 2, 86, 2, 66, 70, 44, + 101, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 72, + 102, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,103,104, 44, + 36, 36, 36, 36, 36, 63, 2,105,106, 36, 36, 36, 61, 44, 44, 44, + 36, 43, 85, 44, 44, 44, 44, 62, 36, 43,107, 64, 44, 44, 44, 44, + 36, 43, 44, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36, + 61, 43, 44, 44, 44, 44, 44, 44, 36, 36, 43, 87, 43, 43, 43, 86, + 86, 86, 86, 85, 87, 43, 43, 43, 43, 43, 2, 88, 2, 66, 70, 44, 7, 7, 7, 7, 7, 44, 44, 44, 27, 27, 27, 27, 27, 44, 44, 44, - 2, 2, 2,105, 2, 59, 43, 68, 36,106, 36, 36, 36, 36, 36, 36, + 2, 2, 2,108, 2, 59, 43, 84, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 44, 44, 36, 36, 70, 71, 36, 36, 36, 36, 36, 36, 36, 36, 70, 61, 44, 44, 36, 36, 36, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 61, 43, 83, 84, 85, 83, 84, 44, 44, - 84, 83, 84, 84, 85, 43, 44, 44, 90, 44, 2, 7, 7, 7, 7, 7, + 36, 36, 36, 36, 36, 36, 36, 61, 43, 85, 86, 87, 85, 86, 44, 44, + 86, 85, 86, 86, 87, 43, 44, 44, 92, 44, 2, 7, 7, 7, 7, 7, 36, 36, 36, 36, 36, 36, 36, 44, 36, 36, 61, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 44, 44, 36, 36, 36, 36, 36, 44, 44, 44, - 7, 7, 7, 7, 7, 98, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 36, 36, 36, 70, 83, 85, 44, 2, 36, 36, 92, 83, 43, 43, 43, 80, - 83, 83, 85, 43, 43, 43, 83, 84, 84, 85, 43, 43, 43, 43, 80, 57, - 2, 2, 2, 86, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,107, - 80, 44, 44, 44, 44, 44, 44, 44, 43, 43, 96, 36, 36, 36, 36, 36, - 36, 36, 83, 43, 43, 83, 83, 84, 84, 83, 96, 36, 36, 36, 44, 44, - 95, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 90, 44, - 43, 96, 36, 36, 36, 36, 36, 36, 92, 43, 43, 84, 43, 85, 43, 36, - 36, 36, 36, 83, 43, 84, 85, 85, 43, 84, 44, 44, 44, 44, 2, 2, - 36, 36, 84, 84, 84, 84, 43, 43, 43, 43, 84, 43, 44, 91, 2, 2, + 7, 7, 7, 7, 7,100, 44, 67, 67, 67, 67, 67, 67, 67, 67, 67, + 36, 36, 36, 70, 85, 87, 44, 2, 36, 36, 94, 85, 43, 43, 43, 80, + 85, 85, 87, 43, 43, 43, 85, 86, 86, 87, 43, 43, 43, 43, 80, 57, + 2, 2, 2, 88, 2, 2, 2, 44, 43, 43, 43, 43, 43, 43, 43,109, + 43, 43, 43, 43, 43, 43, 43, 80, 43, 43, 98, 36, 36, 36, 36, 36, + 36, 36, 85, 43, 43, 85, 85, 86, 86, 85, 98, 36, 36, 36, 61, 44, + 97, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 21, 64, + 43, 98, 36, 36, 36, 36, 36, 36, 94, 43, 43, 86, 43, 87, 43, 36, + 36, 36, 36, 85, 43, 86, 87, 87, 43, 86, 44, 44, 44, 44, 2, 2, + 36, 36, 86, 86, 86, 86, 43, 43, 43, 43, 86, 43, 44, 93, 2, 2, 7, 7, 7, 7, 7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40, 2, - 16, 16, 16, 16,108, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, + 16, 16, 16, 16,110, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11, 2, 2, 2, 2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43, - 83, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 92, 43, 61, 44, 44, + 85, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 94, 43, 61, 44, 44, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16, - 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,109, 40, 40, - 43, 43, 43, 43, 43, 57, 43, 43, 32, 32, 32, 16, 16, 16, 16, 32, - 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 44, 11, 11, 11, 44, - 16, 16, 16, 16, 48, 48, 48, 48, 16, 16, 16, 16, 16, 16, 16, 44, - 16, 16, 16, 16,110,110,110,110, 16, 16,108, 16, 11, 11,111,112, - 41, 16,108, 16, 11, 11,111, 41, 16, 16, 44, 16, 11, 11,113, 41, - 16, 16, 16, 16, 11, 11,114, 41, 44, 16,108, 16, 11, 11,111,115, - 116,116,116,116,116,117, 65, 65,118,118,118, 2,119,120,119,120, - 2, 2, 2, 2,121, 65, 65,122, 2, 2, 2, 2,123,124, 2,125, - 126, 2,127,128, 2, 2, 2, 2, 2, 9,126, 2, 2, 2, 2,129, - 65, 65, 68, 65, 65, 65, 65, 65,130, 44, 27, 27, 27, 8,127,131, - 27, 27, 27, 27, 27, 8,127,102, 40, 40, 40, 40, 40, 40, 81, 44, - 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,132, 51, - 107, 51,107, 43, 43, 43, 43, 43, 67,133, 67,134, 67, 34, 11, 16, - 11, 32,134, 67, 49, 11, 11, 67, 67, 67,133,133,133, 11, 11,135, - 11, 11, 35, 36, 39, 67, 16, 11, 8, 8, 49, 16, 16, 26, 67,136, - 27, 27, 27, 27, 27, 27, 27, 27,103,103,103,103,103,103,103,103, - 103,137,138,103,139, 67, 44, 44, 8, 8,140, 67, 67, 8, 67, 67, - 140, 26, 67,140, 67, 67, 67,140, 67, 67, 67, 67, 67, 67, 67, 8, - 67,140,140, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 67, 67, 67, 67, 4, 4, 67, 67, - 8, 67, 67, 67,141,142, 67, 67, 67, 67, 67, 67, 67, 67,140, 67, - 67, 67, 67, 67, 67, 26, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 90, 44, 44, 44, 44, 67, 67, 67, 67, 67, 90, 44, 44, - 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, - 67, 67, 67, 26, 67, 67, 67, 67, 26, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 8, 8, 8, 8, 67, 67, 67, 67, 67, 67, 67, 26, - 67, 67, 67, 67, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, - 27, 27, 67, 67, 67, 67, 67, 67, 8, 8,127,143, 8, 8, 8, 8, - 8, 8, 8, 4, 4, 4, 4, 4, 8,127,144,144,144,144,144,144, - 144,144,144,144,143, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, - 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,140, 26, 8, 8,140, 67, - 67, 67, 44, 67, 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, - 11, 11, 11, 11, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16,108, - 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, - 32, 32,136, 67, 67,134, 34,145, 43, 32, 44, 44, 91, 2, 97, 2, - 16, 16, 16,146, 44, 44,146, 44, 36, 36, 36, 36, 44, 44, 44, 52, - 64, 44, 44, 44, 44, 44, 44, 57, 36, 36, 36, 61, 44, 44, 44, 44, - 36, 36, 36, 61, 36, 36, 36, 61, 2,119,119, 2,123,124,119, 2, - 2, 2, 2, 6, 2,105,119, 2,119, 4, 4, 4, 4, 2, 2, 86, - 2, 2, 2, 2, 2,118, 2, 2,105,147, 2, 2, 2, 2, 2, 2, - 67, 64, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 55, 67, 67, - 67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 44, 44, 1, 2,148,149, 4, 4, 4, 4, - 4, 67, 4, 4, 4, 4,150,151,152,103,103,103,103, 43, 43, 84, - 153, 40, 40, 67,103,154, 63, 67, 36, 36, 36, 61, 57,155,156, 69, - 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, - 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90, - 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, - 157, 27, 27, 27, 27, 27, 27, 27, 36, 36,106, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36,158, 2, 7, 7, 7, 7, 7, 36, 44, 44, - 32, 32, 32, 32, 32, 32, 32, 70, 51,159, 43, 43, 43, 43, 43, 86, - 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,103,103,103,103,103, - 43, 2, 2, 2, 44, 44, 44, 44, 41, 41, 41,156, 40, 40, 40, 40, - 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, - 45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,160, 34, 35, - 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, - 11, 11, 32, 32, 32, 32, 32, 32, 44, 32, 11, 11, 34,108, 44, 44, - 44, 44, 48, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, - 36, 92, 85, 83, 67, 67, 80, 44, 27, 27, 27, 67,161, 44, 44, 44, - 36, 36, 2, 2, 44, 44, 44, 44, 84, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 84, 84, 84, 84, 84, 84, 84, 84, 43, 44, 44, 44, 44, 2, + 16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,111, 40, 40, + 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, + 16, 16, 16, 44, 11, 11, 11, 44, 16, 16, 16, 16, 48, 48, 48, 48, + 16, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, 16,112,112,112,112, + 16, 16,110, 16, 11, 11,113,114, 41, 16,110, 16, 11, 11,113, 41, + 16, 16, 44, 16, 11, 11,115, 41, 16, 16, 16, 16, 11, 11,116, 41, + 44, 16,110, 16, 11, 11,113,117,118,118,118,118,118,119, 65, 65, + 120,120,120, 2,121,122,121,122, 2, 2, 2, 2,123, 65, 65,124, + 2, 2, 2, 2,125,126, 2,127,128, 2,129,130, 2, 2, 2, 2, + 2, 9,128, 2, 2, 2, 2,131, 65, 65,132, 65, 65, 65, 65, 65, + 133, 44, 27, 27, 27, 8,129,134, 27, 27, 27, 27, 27, 8,129,104, + 40, 40, 40, 40, 40, 40, 81, 44, 20, 20, 20, 20, 20, 20, 20, 20, + 135, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43,136, 51, + 109, 51,109, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44, + 67,137, 67,138, 67, 34, 11, 16, 11, 32,138, 67, 49, 11, 11, 67, + 67, 67,137,137,137, 11, 11,139, 11, 11, 35, 36, 39, 67, 16, 11, + 8, 8, 49, 16, 16, 26, 67,140, 27, 27, 27, 27, 27, 27, 27, 27, + 105,105,105,105,105,105,105,105,105,141,142,105,143, 67, 44, 44, + 8, 8,144, 67, 67, 8, 67, 67,144, 26, 67,144, 67, 67, 67,144, + 67, 67, 67, 67, 67, 67, 67, 8, 67,144,144, 67, 67, 67, 67, 67, + 67, 67, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 67, 67, 67, 67, 4, 4, 67, 67, 8, 67, 67, 67,145,146, 67, 67, + 67, 67, 67, 67, 67, 67,144, 67, 67, 67, 67, 67, 67, 26, 8, 8, + 8, 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, + 8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 92, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67, + 67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67, + 26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 8, 8, 8, 8, + 67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67, 4, 4, 4, 4, + 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, + 8, 8,129,147, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, + 8,129,148,148,148,148,148,148,148,148,148,148,147, 8, 8, 8, + 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, + 8, 8,144, 26, 8, 8,144, 67, 67, 67, 44, 67, 67, 67, 67, 67, + 67, 67, 67, 55, 67, 67, 67, 67, 32, 11, 32, 34, 34, 34, 34, 11, + 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,140, 67, 67,138, 34,149, + 43, 32, 44, 44, 93, 2, 99, 2, 16, 16, 16,150, 44, 44,150, 44, + 36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57, + 36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61, + 2,121,121, 2,125,126,121, 2, 2, 2, 2, 6, 2,108,121, 2, + 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, + 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, + 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, + 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, + 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, + 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, + 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, + 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, + 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, + 7, 7, 7, 7, 7, 36, 44, 44, 32, 32, 32, 32, 32, 32, 32, 70, + 51,165, 43, 43, 43, 43, 43, 88, 32, 32, 32, 32, 32, 32, 40, 43, + 36, 36, 36,105,105,105,105,105, 43, 2, 2, 2, 44, 44, 44, 44, + 41, 41, 41,162, 40, 40, 40, 40, 41, 32, 32, 32, 32, 32, 32, 32, + 16, 32, 32, 32, 32, 32, 32, 32, 45, 16, 16, 16, 34, 34, 34, 32, + 32, 32, 32, 32, 42,166, 34, 35, 32, 32, 16, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 11, 11, 32, 11, 11, 32, 32, 32, 32, 32, 32, + 32, 32, 11, 11, 34,110, 44, 44, 32,150,150, 32, 32, 44, 44, 44, + 44, 40,167, 35, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36, + 36, 94, 87, 85, 67, 67, 80, 44, 27, 27, 27, 67,168, 44, 44, 44, + 36, 36, 2, 2, 44, 44, 44, 44, 86, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 86, 86, 86, 86, 86, 86, 86, 86, 43, 44, 44, 44, 44, 2, 43, 36, 36, 36, 2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 70, 43, 43, 43, 43, 43, 84, 44, 44, 44, 44, 44, 91, - 36, 70, 84, 43, 43, 84, 43, 84,162, 2, 2, 2, 2, 2, 2, 52, + 36, 36, 36, 70, 43, 43, 43, 43, 43, 86, 44, 44, 44, 44, 44, 93, + 36, 70, 86, 43, 43, 86, 43, 86,107, 2, 2, 2, 2, 2, 2, 52, 7, 7, 7, 7, 7, 44, 44, 2, 36, 36, 70, 69, 36, 36, 36, 36, - 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 83, - 85, 83, 85, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 83, 44, - 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 92, 83, 36, + 7, 7, 7, 7, 7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 85, + 87, 85, 87, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 85, 44, + 7, 7, 7, 7, 7, 44, 2, 2, 69, 36, 36, 77, 67, 94, 85, 36, 71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 62,106, 2, 36, 36, 36, 36, 36, 92, 43, 84, - 2,106,163, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, - 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,112, 40, 40, - 16, 16, 16, 16,109, 41, 44, 44, 36, 92, 85, 84, 83,162, 85, 44, + 44, 44, 44, 44, 44, 62, 83, 2, 36, 36, 36, 36, 36, 94, 43, 86, + 2, 83,169, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61, + 62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,114, 40, 40, + 16, 16, 16, 16,111, 41, 44, 44, 36, 94, 87, 86, 85,107, 87, 44, 36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36, - 164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,165, - 16, 16, 16,108, 44, 44, 44, 44, 44,146, 16, 16, 44, 44, 62, 71, - 36, 36, 36, 36,166, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, + 170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,171, + 16, 16, 16,110, 44, 44, 44, 44, 44,150, 16, 16, 44, 44, 62, 71, + 36, 36, 36, 36,172, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61, 36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, - 41, 44, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,144, 44, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36,161, 44, 2, 2, 2,167,128, 44, 44, 44, - 6,168,169,144,144,144,144,144,144,144,128,167,128, 2,125,170, - 2, 64, 2, 2,150,144,144,128, 2,171, 8,172, 66, 2, 44, 44, - 36, 36, 36, 36, 36, 36, 61, 79, 91, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,127,128, 4, 2, 36, 36, 36, 36, 36, + 41,117, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36,148, 44, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 44, 44, 44, 55, 36, 36, 36, 36, 36, 36,168, 67, + 2, 2, 2,152,130, 44, 44, 44, 6,173,174,148,148,148,148,148, + 148,148,130,152,130, 2,127,175, 2, 64, 2, 2,156,148,148,130, + 2,176, 8,177, 66, 2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 61, 79, 93, 2, 3, 2, 4, 5, 6, 2, + 16, 16, 16, 16, 16, 17, 18,129,130, 4, 2, 36, 36, 36, 36, 36, 69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44, - 20,173, 56,174, 26, 8,140, 90, 44, 44, 44, 44, 79, 65, 67, 44, + 20,178, 56,135, 26, 8,144, 92, 44, 44, 44, 44, 79, 65, 67, 44, 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62, - 2, 64, 44,175, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, - 103,103,139, 27, 89, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 90, - 67, 67, 67, 67, 67, 67, 90, 44, 90, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 50, 44,176, 27, 27, 27, 27, 27, 27, 27, + 2, 64, 44,179, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67, + 105,105,143, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 92, + 67, 67, 67, 67, 67, 67, 92, 44, 92, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 67, 50, 44,180, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 44, 44, 27, 27, 44, 44, 44, 44, 62, 36, - 149, 36, 36, 36, 36,177, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 91, 36, 36, 44, 44, 36, 36, 36, 36, - 178,103,103, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, + 155, 36, 36, 36, 36,181, 44, 44, 36, 36, 36, 43, 43, 80, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 93, 36, 36, 44, 44, 36, 36, 36, 36, + 182,105,105, 44, 44, 44, 44, 44, 11, 11, 11, 11, 16, 16, 16, 16, 11, 11, 44, 44, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 44, 44, - 36, 36, 44, 44, 44, 44, 44, 91, 36, 36, 36, 44, 61, 36, 36, 36, - 36, 36, 36, 62, 61, 44, 61, 62, 36, 36, 36, 91, 27, 27, 27, 27, - 36, 36, 36, 77,157, 27, 27, 27, 44, 44, 44,175, 27, 27, 27, 27, - 36, 61, 36, 44, 44,175, 27, 27, 36, 36, 36, 27, 27, 27, 44, 91, - 36, 36, 36, 36, 36, 44, 44, 91, 36, 36, 36, 36, 44, 44, 27, 36, - 44, 27, 27, 27, 27, 27, 27, 27, 70, 43, 57, 80, 44, 44, 43, 43, - 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36, 44, 43, 80, 44, 57, - 27, 27, 27, 27, 98, 44, 44, 44, 2, 2, 2, 2, 64, 44, 44, 44, - 36, 36, 36, 36, 36, 36,179, 30, 36, 36, 36, 36, 36, 36,179, 27, - 36, 36, 36, 36, 78, 36, 36, 36, 36, 36, 70, 80, 44,175, 27, 27, - 2, 2, 2, 64, 44, 44, 44, 44, 36, 36, 36, 44, 91, 2, 2, 2, - 36, 36, 36, 44, 27, 27, 27, 27, 36, 61, 44, 44, 27, 27, 27, 27, - 36, 44, 44, 44, 91, 2, 64, 44, 44, 44, 44, 44,175, 27, 27, 27, - 11, 47, 44, 44, 44, 44, 44, 44, 16,108, 44, 44, 44, 27, 27, 27, - 36, 36, 43, 43, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27, 98, - 36, 36, 36, 36, 36, 57,180, 44, 36, 44, 44, 44, 44, 44, 44, 44, - 27, 27, 27, 93, 44, 44, 44, 44,176, 27, 30, 2, 2, 44, 44, 44, - 36, 36,179, 27, 27, 27, 44, 44, 85, 96, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 44, 93, + 11, 11, 11, 11, 11, 47, 11, 11, 11, 47, 11,150, 16, 16, 16, 16, + 16,150, 16, 16, 16, 16, 16, 16, 16,150, 16, 16, 16,150,110, 44, + 40, 40, 40, 52, 40, 40, 40, 40, 81, 40, 40, 40, 40, 81, 44, 44, + 36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62, + 36, 36, 36, 93, 27, 27, 27, 27, 36, 36, 36, 77,163, 27, 27, 27, + 44, 44, 44,179, 27, 27, 27, 27, 36, 61, 36, 44, 44,179, 27, 27, + 36, 36, 36, 27, 27, 27, 44, 93, 36, 36, 36, 36, 36, 44, 44, 93, + 36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27, + 70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36, + 36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27,100, 44, 44, 44, + 2, 2, 2, 2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,183, 30, + 36, 36, 36, 36, 36, 36,183, 27, 36, 36, 36, 36, 78, 36, 36, 36, + 36, 36, 70, 80, 44,179, 27, 27, 2, 2, 2, 64, 44, 44, 44, 44, + 36, 36, 36, 44, 93, 2, 2, 2, 36, 36, 36, 44, 27, 27, 27, 27, + 36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 93, 2, 64, 44, + 44, 44, 44, 44,179, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44, + 16,110, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44, + 27, 27, 27, 27, 27, 27, 27,100, 36, 36, 36, 36, 36, 57,184, 44, + 36, 44, 44, 44, 44, 44, 44, 44, 27, 27, 27, 95, 44, 44, 44, 44, + 180, 27, 30, 2, 2, 44, 44, 44, 36, 43, 43, 2, 2, 44, 44, 44, + 36, 36,183, 27, 27, 27, 44, 44, 87, 98, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 43, 60, 2, 2, 2, 44, - 27, 27, 27, 7, 7, 7, 7, 7, 44, 44, 44, 44, 44, 44, 44, 57, - 84, 85, 43, 83, 85, 60,181, 2, 2, 44, 44, 44, 44, 44, 79, 44, - 43, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, 85, 43, - 43, 43, 80, 7, 7, 7, 7, 7, 2, 2, 92, 96, 44, 44, 44, 44, - 36, 70, 2, 61, 44, 44, 44, 44, 36, 92, 84, 43, 43, 43, 43, 83, - 96, 36, 63, 2, 59, 43, 60, 85, 7, 7, 7, 7, 7, 63, 63, 2, - 175, 27, 27, 27, 27, 27, 27, 27, 27, 27, 98, 44, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 84, 85, 43, 84, 83, 43, 2, 2, 2, 80, + 27, 27, 27, 7, 7, 7, 7, 7, 71, 70, 71, 44, 44, 44, 44, 57, + 86, 87, 43, 85, 87, 60,185, 2, 2, 80, 44, 44, 44, 44, 79, 44, + 43, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, 87, 43, + 43, 43, 80, 7, 7, 7, 7, 7, 2, 2, 94, 98, 44, 44, 44, 44, + 36, 70, 2, 61, 44, 44, 44, 44, 36, 94, 86, 43, 43, 43, 43, 85, + 98, 36, 63, 2, 59, 43, 60, 87, 7, 7, 7, 7, 7, 63, 63, 2, + 179, 27, 27, 27, 27, 27, 27, 27, 27, 27,100, 44, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 86, 87, 43, 86, 85, 43, 2, 2, 2, 80, 36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70, - 84, 85, 43, 43, 43, 80, 44, 44, 43, 84, 62, 36, 36, 36, 61, 62, - 61, 36, 62, 36, 36, 57, 71, 84, 83, 84, 88, 87, 88, 87, 84, 44, - 61, 44, 44, 87, 44, 44, 62, 36, 36, 84, 44, 43, 43, 43, 80, 44, - 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 92, 84, 43, 43, 43, 43, - 84, 43, 83, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 91, 71, - 84, 85, 43, 43, 83, 83, 84, 85, 83, 43, 36, 72, 44, 44, 44, 44, - 36, 36, 36, 36, 36, 36, 36, 92, 84, 43, 43, 44, 84, 84, 43, 85, + 86, 87, 43, 43, 43, 80, 44, 44, 43, 86, 62, 36, 36, 36, 61, 62, + 61, 36, 62, 36, 36, 57, 71, 86, 85, 86, 90, 89, 90, 89, 86, 44, + 61, 44, 44, 89, 44, 44, 62, 36, 36, 86, 44, 43, 43, 43, 80, 44, + 43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 94, 86, 43, 43, 43, 43, + 86, 43, 85, 71, 36, 63, 2, 2, 7, 7, 7, 7, 7, 2, 93, 71, + 86, 87, 43, 43, 85, 85, 86, 87, 85, 43, 36, 72, 44, 44, 44, 44, + 36, 36, 36, 36, 36, 36, 36, 94, 86, 43, 43, 44, 86, 86, 43, 87, 60, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 44, - 84, 85, 43, 43, 43, 83, 85, 85, 60, 2, 61, 44, 44, 44, 44, 44, - 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 85, 84, - 43, 43, 43, 85, 61, 44, 44, 44, 84, 43, 43, 85, 43, 43, 44, 44, - 7, 7, 7, 7, 7, 27, 2, 95, 43, 43, 43, 43, 85, 60, 44, 44, - 27, 98, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, - 36, 36, 62, 61, 36, 36, 36, 36, 84, 84, 84, 87, 88, 57, 83, 71, - 96, 85, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, - 92, 84, 43, 43, 44, 43, 84, 84, 71, 72, 88, 44, 44, 44, 44, 44, - 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 83, 70, 43, 60, - 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 83, 85, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 83, 43, 2, 72, 2, - 2, 64, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 85, + 86, 87, 43, 43, 43, 85, 87, 87, 60, 2, 61, 44, 44, 44, 44, 44, + 2, 2, 2, 2, 2, 2, 64, 44, 36, 36, 36, 36, 36, 70, 87, 86, + 43, 43, 43, 87, 63, 44, 44, 44, 86, 43, 43, 87, 43, 43, 44, 44, + 7, 7, 7, 7, 7, 27, 2, 97, 43, 43, 43, 43, 87, 60, 44, 44, + 27,100, 44, 44, 44, 44, 44, 62, 36, 36, 36, 61, 62, 44, 36, 36, + 36, 36, 62, 61, 36, 36, 36, 36, 86, 86, 86, 89, 90, 57, 85, 71, + 98, 87, 2, 64, 44, 44, 44, 44, 36, 36, 36, 36, 44, 36, 36, 36, + 94, 86, 43, 43, 44, 43, 86, 86, 71, 72, 90, 44, 44, 44, 44, 44, + 70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 85, 70, 43, 60, + 2, 2, 2, 59, 44, 44, 44, 44, 70, 43, 43, 85, 87, 43, 36, 36, + 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 85, 43, 2, 72, 2, + 2, 64, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 87, 63, 2, 2, 44, 44, 44, 44, 44, 2, 36, 36, 36, 36, 36, 36, 36, - 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 87, 43, 43, 43, - 83, 43, 85, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, + 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 89, 43, 43, 43, + 85, 43, 87, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36, 70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44, - 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 84, 84, 88, - 43, 87, 85, 85, 61, 44, 44, 44, 36, 70, 83,162, 64, 44, 44, 44, - 27, 27, 89, 67, 67, 67, 56, 20,161, 67, 67, 67, 67, 67, 67, 67, - 67, 44, 44, 44, 44, 44, 44, 91,103,103,103,103,103,103,103,177, - 2, 2, 64, 44, 44, 44, 44, 44, 65, 65, 65, 65, 68, 44, 44, 44, - 43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60, 2, 2, 67, 67, - 40, 40, 95, 44, 44, 44, 44, 44, 7, 7, 7, 7, 7,175, 27, 27, - 27, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 44, 44, 62, 36, - 27, 27, 27, 30, 2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57, - 92, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40, - 40, 86, 80, 44, 44, 44, 44, 44, 84, 44, 44, 44, 44, 44, 44, 44, + 36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 86, 86, 90, + 43, 89, 87, 87, 61, 44, 44, 44, 36, 70, 85,107, 64, 44, 44, 44, + 27, 27, 91, 67, 67, 67, 56, 20,168, 67, 67, 67, 67, 67, 67, 67, + 67, 44, 44, 44, 44, 44, 44, 93,105,105,105,105,105,105,105,181, + 2, 2, 64, 44, 44, 44, 44, 44, 63, 64, 44, 44, 44, 44, 44, 44, + 65, 65, 65, 65,132, 44, 44, 44, 43, 43, 60, 44, 44, 44, 44, 44, + 43, 43, 43, 60, 2, 2, 67, 67, 40, 40, 97, 44, 44, 44, 44, 44, + 7, 7, 7, 7, 7,179, 27, 27, 27, 62, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 44, 44, 62, 36, 27, 27, 27, 30, 2, 64, 44, 44, + 36, 36, 36, 36, 36, 61, 44, 57, 94, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 44, 44, 44, 57, + 43, 74, 40, 40, 40, 40, 40, 40, 40, 88, 80, 44, 44, 44, 44, 44, + 86, 44, 44, 44, 44, 44, 44, 44, 40, 40, 52, 40, 40, 40, 52, 81, 36, 61, 44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60, 65, 65, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 90, 55, 67, 67, 67, 67, 67,182, 85, 43, 67,182, 84, - 84,183, 65, 65, 65, 82, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, - 67, 67, 67, 67, 67, 43, 43, 67, 67, 67, 67, 67, 90, 44, 44, 44, - 67, 43, 76, 44, 44, 44, 44, 44, 27, 27, 44, 44, 44, 44, 44, 44, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 16, 16,108, 16, 16, 16, 16, 16, - 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 11, - 44, 47, 48, 47, 48, 11, 47, 11, 11, 11, 11, 16, 16,146,146, 16, - 16, 16,146, 16, 16, 16, 16, 16, 16, 16, 11, 48, 11, 47, 48, 11, - 11, 11, 47, 11, 11, 11, 47, 16, 16, 16, 16, 16, 11, 48, 11, 47, - 11, 11, 47, 47, 44, 11, 11, 11, 47, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 16, 16, 16, 44, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, - 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, - 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, - 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, - 16, 33, 16, 16, 16, 32, 44, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 43, 43, 43, 76, 67, 50, 43, 43, 43, 43, 43, 43, 43, 43, 76, 67, - 67, 67, 50, 67, 67, 67, 67, 67, 67, 67, 76, 21, 2, 2, 44, 44, - 44, 44, 44, 44, 44, 57, 43, 43, 43, 43, 43, 80, 43, 43, 43, 43, - 43, 43, 43, 43, 80, 57, 43, 43, 43, 57, 80, 43, 43, 80, 44, 44, - 43, 43, 43, 74, 40, 40, 40, 44, 7, 7, 7, 7, 7, 44, 44, 77, - 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 94, - 36, 36, 61,175, 27, 27, 27, 27, 43, 43, 43, 80, 44, 44, 44, 44, - 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,157, 27, - 184, 27, 98, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,157, + 43, 43, 43, 43, 43, 43, 43, 44, 43, 43, 43, 80, 44, 44, 44, 44, + 67, 67, 67, 92, 55, 67, 67, 67, 67, 67,186, 87, 43, 67,186, 86, + 86,187, 65, 65, 65, 84, 43, 43, 43, 76, 50, 43, 43, 43, 67, 67, + 67, 67, 67, 67, 67, 43, 43, 67, 67, 43, 76, 44, 44, 44, 44, 44, + 27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 16, 16,110, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11, + 11, 11, 11, 16, 16,150,150, 16, 16, 16,150, 16, 16, 16, 16, 16, + 16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16, + 16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11, + 47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11, + 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, + 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, + 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, + 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 43, 43, 43, 76, 67, 50, 43, 43, + 43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67, + 67, 67, 76, 21, 2, 2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43, + 16, 16, 16, 16, 16, 39, 16, 16, 16, 16, 16, 16, 16, 16, 16,110, + 43, 43, 43, 80, 43, 43, 43, 43, 43, 43, 43, 43, 80, 57, 43, 43, + 43, 57, 80, 43, 43, 80, 44, 44, 43, 43, 43, 74, 40, 40, 40, 44, + 7, 7, 7, 7, 7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 36, 80, + 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 44, 44, 96, + 36, 36, 36, 61, 36, 36, 62, 61, 36, 36, 61,179, 27, 27, 27, 27, + 16, 16, 43, 43, 43, 74, 44, 44, 27, 27, 27, 27, 27, 27,163, 27, + 188, 27,100, 44, 44, 44, 44, 44, 27, 27, 27, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 44, 36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36, 36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 89, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 90, 44, 44, 44, 44, 44, 44, - 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, - 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 90, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 90, 44, 67, 90, 44, 44, - 67, 90, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44, - 65, 65, 65, 65, 65, 65, 65, 65,165,165,165,165,165,165,165, 44, - 165,165,165,165,165,165,165, 0, 0, 0, 29, 21, 21, 21, 23, 21, + 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, + 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, + 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 55, 67, + 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 44, 67, 67, 92, 44, + 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44, + 65, 65, 65, 65, 65, 65, 65, 65,171,171,171,171,171,171,171, 44, + 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, @@ -4280,2075 +4348,629 @@ _hb_ucd_u8[17508] = 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, - 1, 2, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, - 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 1, 12, 12, 10, - 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, - 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, - 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 17, 21, 7, 6, 11, 12, - 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, - 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, - 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, - 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, - 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, - 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, - 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 23, 26, 10, 21, 6, 10, - 4, 4, 3, 3, 7, 25, 21, 22, 17, 16, 16, 22, 16, 16, 25, 17, - 25, 2, 25, 24, 23, 2, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, - 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, - 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, - 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 41, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, - 9, 0, 10, 11, 0, 0, 12, 13, 14, 15, 16, 0, 0, 0, 0, 17, - 18, 19, 20, 0, 0, 0, 21, 22, 0, 23, 24, 0, 0, 23, 25, 26, - 0, 23, 25, 0, 0, 23, 25, 0, 0, 23, 25, 0, 0, 0, 25, 0, - 0, 0, 27, 0, 0, 23, 25, 0, 0, 28, 25, 0, 0, 0, 29, 0, - 0, 30, 31, 0, 0, 32, 33, 0, 34, 35, 0, 36, 37, 0, 38, 0, - 0, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 42, 42, 0, 0, 0, 0, 43, 0, - 0, 0, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 46, 0, 0, 47, 0, 48, 49, 0, 0, 50, 51, 52, 0, 53, 0, 54, - 0, 55, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 0, 58, 59, - 0, 0, 0, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 0, 0, 0, 64, - 0, 65, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 67, 68, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, - 70, 71, 0, 0, 0, 0, 51, 72, 0, 73, 74, 0, 0, 75, 76, 0, - 0, 0, 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, 0, 0, 0, 25, - 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 83, 0, 0, 0, 0, - 84, 85, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, - 0, 0, 70, 63, 0, 90, 0, 0, 91, 92, 0, 75, 0, 0, 93, 0, - 0, 94, 0, 0, 0, 0, 0, 95, 0, 96, 25, 97, 0, 0, 0, 0, - 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 63,100, 0, - 0, 63, 0, 0, 0,101, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 0, 0, 0, 0,103,104, 0, 0, 0, 0, 76, - 0, 42,105, 0,106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 63, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,108, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,109, 0,110, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,111, - 0, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113,114,115, 0, 0, - 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 117,118, 0, 0, 0, 0, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,120, 0, 0, 0,121, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 31, 0, - 0, 0, 32, 33, 34, 35, 1, 36, 0, 0, 0, 0, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, 0, 0, 0, 0, - 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 43, 36, 44, 45, - 21, 45, 46, 0, 0, 0, 0, 0, 0, 0, 19, 1, 21, 0, 0, 47, - 0, 0, 0, 0, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 52, 1, 1, 1, - 53, 21, 43, 54, 55, 21, 35, 1, 0, 0, 0, 0, 0, 0, 0, 56, - 0, 0, 0, 57, 58, 59, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 57, 0, 61, 0, 0, - 0, 0, 0, 0, 0, 0, 62, 63, 0, 0, 64, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 70, 71, 0, - 0, 0, 0, 0, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 0, 0, - 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 80, 0, + 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, + 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, + 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, + 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, + 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, + 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, + 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, + 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, + 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, + 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, + 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, + 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, + 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, + 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, + 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, + 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, + 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 34, 0, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, + 0, 0, 39, 40, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 6, 7, 8, 0, 9, 0, 10, 11, 0, 0, 12, 13, + 14, 15, 16, 0, 0, 0, 0, 17, 18, 19, 20, 0, 21, 0, 22, 23, + 0, 24, 25, 0, 0, 24, 26, 27, 0, 24, 26, 0, 0, 24, 26, 0, + 0, 24, 26, 0, 0, 0, 26, 0, 0, 24, 28, 0, 0, 24, 26, 0, + 0, 29, 26, 0, 0, 0, 30, 0, 0, 31, 32, 0, 0, 33, 34, 0, + 35, 36, 0, 37, 38, 0, 39, 0, 0, 40, 0, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 46, 0, 0, + 0, 47, 0, 0, 0, 0, 0, 0, 48, 0, 0, 49, 0, 50, 51, 0, + 0, 52, 53, 54, 0, 55, 0, 56, 0, 57, 0, 0, 0, 0, 58, 59, + 0, 0, 0, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 62, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, + 0, 0, 0, 65, 0, 0, 0, 66, 0, 67, 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 71, + 0, 0, 0, 0, 0, 0, 0, 0, 72, 73, 0, 0, 0, 0, 53, 74, + 0, 75, 76, 0, 0, 77, 78, 0, 0, 0, 0, 0, 0, 79, 80, 81, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 82, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 0, 86, 0, 0, 0, 0, 87, 88, 0, 0, 0, 0, 0, 89, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, + 0, 0, 92, 0, 93, 0, 0, 0, 0, 0, 72, 94, 0, 95, 0, 0, + 96, 97, 0, 77, 0, 0, 98, 0, 0, 99, 0, 0, 0, 0, 0,100, + 0,101, 26,102, 0, 0, 0, 0, 0, 0,103, 0, 0, 0,104, 0, + 0, 0, 0, 0, 0, 65,105, 0, 0, 65, 0, 0, 0,106, 0, 0, + 0,107, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, + 0,108,109, 0, 0, 0, 0, 78, 0, 44,110, 0,111, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, + 0, 0,112, 0,113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,114, + 0,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, 0,117, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,118,119,120, 0, 0, 0, 0,121, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,122,123, 0, 0, 0, 0, 0, 0, + 0,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,124, 0,125, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,126, 0, + 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, + 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 0, 0, 0, 0, + 19, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 1, + 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, + 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 39, + 14, 39, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, + 0, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 0, 0, + 0, 0, 19, 1, 21, 0, 0, 47, 0, 0, 0, 0, 0, 38, 48, 1, + 1, 49, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, + 0, 0, 0, 0, 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, + 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 0, 0, 0, 0, 55, + 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 56, 0, 60, 0, 0, + 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 69, 70, 0, + 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 0, 0, 0, 0, 0, 0, + 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, - 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 64, 0, 0, 81, - 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, - 0, 0, 0, 0, 0, 19, 84, 0, 63, 0, 0, 0, 0, 49, 1, 85, - 0, 0, 0, 0, 1, 54, 15, 86, 84, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 56, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, - 0, 88, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, - 0, 0, 0, 0, 89, 9, 12, 4, 90, 8, 91, 47, 0, 59, 50, 0, - 21, 1, 21, 92, 93, 1, 1, 1, 1, 1, 1, 1, 1, 94, 95, 96, - 0, 0, 0, 0, 97, 1, 98, 59, 81, 99,100, 4, 59, 0, 0, 0, - 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,101,102, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,103, 0, 0, 0, 0, 19, 0, 1, 1, 50, - 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, - 1, 1, 1, 1, 50, 0, 0, 0, 0, 0, 52, 69, 0, 0, 0, 0, - 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, - 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104,105, 59, 38, - 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, - 0, 0, 0, 0, 0, 0, 0,106, 1, 14, 4, 12, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 38, 89, 0, - 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,108, 62, - 0,109, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 59, 0, 0, 0, 0, 0,110, 14, 54, 84, 0, 0, 0, - 0, 0, 0, 0, 0, 0,111, 0, 89, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 62, 63, 0, 0, 63, 0, 88, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,111, 0, 0, 0, 0,112, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 79, 56, 0, 38, 1, 59, 1, 59, 0, 0, - 64, 88, 0, 0, 0, 0, 0, 60,113, 0, 0, 0, 0, 0, 0, 0, - 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,113, 0, 0, - 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, - 79, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 57, 0, 88,114, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 8, 91, 0, 0, - 0, 0, 0, 0, 1, 89, 0, 0, 0, 0, 0, 0,115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,116, 0,117,118,119,120, 0, 52, 4, - 121, 49, 23, 0, 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, - 38, 59, 0, 0, 0, 0, 0, 0, 1, 89, 1, 1, 1, 1, 39, 1, - 48,104, 89, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 4,121, 0, 0, 0, 1,122, 0, 0, 0, 0, 0, - 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, - 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, - 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, - 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, - 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, - 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, - 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, - 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, - 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, - 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, - 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, - 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, - 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, - 0, 0, 0,220,230,230, 0,220,230,220,220,220, 27, 28, 29,230, - 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, - 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, - 0, 0, 9, 0,103,103, 9, 0,107,107,107,107,118,118, 9, 0, - 122,122,122,122,220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, - 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0, - 130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, - 0, 9, 9, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, - 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220, 0, 0, 9, 9, - 0, 0, 7, 0,230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0, - 230,234,214,220,202,230,230,230,230,230,232,228,228,220, 0,230, - 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, - 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, - 230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230, - 230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 9, 9, 0, 0, 6, 6, 0, 0, - 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216, - 216,216,216, 0,220,220,220, 0,230,230, 7, 0, 16, 17, 17, 17, - 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, - 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 19, 84, 0, + 62, 0, 0, 0, 0, 49, 1, 85, 0, 0, 0, 0, 1, 52, 15, 86, + 36, 10, 21, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, + 0, 0, 88, 0, 0, 0, 0, 0, 0, 89, 0, 0, 88, 0, 0, 0, + 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 87, 9, 12, 4, + 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, + 1, 1, 1, 1, 1, 94, 95, 96, 0, 0, 0, 0, 97, 1, 98, 58, + 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 61, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, 0, + 0, 0, 0, 19, 0, 1, 1, 50, 0, 0, 0, 0, 0, 0, 0, 38, + 0, 0, 0, 0, 50, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 0, 1, 1, 1, 1, 50, 0, 0, 0, + 0, 0,104, 68, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, + 0, 0, 0, 0, 78, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0,107, + 1, 14, 4, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, + 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 87, 0, + 0, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,109, 61, + 0,110, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 19, 58, 0, 0, 0, 0, 0,111, 14, 52, 84, 0, 0, 0, + 112, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 61, + 0, 0, 0, 0, 0, 0,113, 0, 87, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0, + 63, 89, 0, 0, 0, 0, 0, 59,115, 0, 0, 0, 0, 0, 0, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,115, 0, 0, + 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, + 78, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 8, 91, 0, 0, + 0, 0, 0, 0, 1, 87, 0, 0, 0, 0, 0, 0,116, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4, + 122, 49, 23, 0, 0, 0, 0, 0, 0, 0, 38, 50, 0, 0, 0, 0, + 38, 58, 0, 0, 0, 0, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, + 48,105, 87, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4,122, 0, 0, + 0, 1,123, 0, 0, 0, 0, 0, 0, 0, 0, 0,230,230,230,230, + 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, + 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, + 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, + 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, + 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, + 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, + 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, + 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, + 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, + 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, + 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, + 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, + 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, + 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, + 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, + 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, + 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, + 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, + 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, + 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, + 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, + 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, + 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, + 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, + 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, + 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, + 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, + 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, + 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, + 220,220,220, 0,230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, + 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, + 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, - 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, - 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, - 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, - 0, 0, 0, 33, 34, 35, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 1, 2, 39, 40, - 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, - 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, - 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, - 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, - 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, - 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, - 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, - 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, - 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, - 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, - 0, 0, 0, 0, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, - 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, - 10, 11, 12, 12, 12, 12, 13, 14, 14, 14, 14, 15, 16, 17, 18, 19, - 20, 14, 21, 14, 22, 14, 14, 14, 14, 23, 24, 24, 25, 26, 14, 14, - 14, 14, 27, 28, 14, 14, 29, 30, 31, 32, 33, 34, 7, 7, 7, 7, + 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, + 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, + 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, + 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, + 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, + 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, + 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, + 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, + 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, + 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, + 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, + 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, + 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, + 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, + 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 35, 7, 36, 37, 7, 38, 7, 7, 7, 39, 14, 40, 7, 7, 41, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 42, 0, 0, 1, - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, - 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, - 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, + 7, 7, 43, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 44, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, + 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, + 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 80, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 82, 83, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, + 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 70, 70, 98, 99,100,101,102,102,103,104,105,106,107,108,109,110, - 111,112, 97,113,114,115,116,117,118, 97,119,119,120, 97,121,122, - 123,124,125,126,127,128,129,130,131, 97,132,133,134,135,136,137, - 138,139,140,141,142, 97,143,144, 97,145,146,147,148, 97,149,150, - 151,152,153,154, 97, 97,155,156,157,158, 97,159, 97,160,161,161, - 161,161,161,161,161,162,163,161,164, 97, 97, 97, 97, 97,165,165, - 165,165,165,165,165,165,166, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97,167,167,167,167,168, 97, 97, 97,169,169, - 169,169,170,171,172,173, 97, 97, 97, 97,174,175,176,177,178,178, - 178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, - 178,178,178,178,178,178,178,178,178,178,178,178,178,179,178,178, - 178,178,178,178,180,180,180,181,182, 97, 97, 97, 97, 97,183,184, - 185,186,186,187, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97,188,189, 97, 97, 97, 97, 97, 97, 59,190, - 191,192,193,194,195, 97,196,197,198, 59, 59,199, 59,200,201,201, - 201,201,201,202, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,203, 97, - 204, 97, 97,205, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,206,207, - 208, 97, 97, 97, 97, 97,209,210,211, 97,212,213, 97, 97,214,215, - 59,216,217, 97, 59, 59, 59, 59, 59, 59, 59,218,219,220,221,222, - 223,224,225,226, 59,227, 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,228, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,229, 70,230, 70, + 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,102,103,104,105, + 106,107,108,109,110,111, 96,112,113,114,115,116,117,118,119,119, + 120,121,122,123,124,125,126,127,128,129,130,131,132, 96,133,134, + 135,136,137,138,139,140,141,142,143, 96,144,145, 96,146,147,148, + 149, 96,150,151,152,153,154,155, 96, 96,156,157,158,159, 96,160, + 96,161,162,162,162,162,162,162,162,163,164,162,165, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96,166,167,167,167,167,167,167,167,167,168, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,169,169,169,169,170, 96, + 96, 96,171,171,171,171,172,173,174,175, 96, 96, 96, 96,176,177, + 178,179,180,180,180,180,180,180,180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, + 180,181,180,180,180,180,180,180,182,182,182,183,184, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96,185,186,187,188,189,189,190, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,191,192, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 193,194, 59,195,196,197,198,199,200, 96,201,202,203, 59, 59,204, + 59,205,206,206,206,206,206,207, 96, 96, 96, 96, 96, 96, 96, 96, + 208, 96,209, 96,210, 96, 96,211, 96, 96, 96, 96, 96, 96, 96, 96, + 96,212,213,214,215, 96, 96, 96, 96, 96,216,217,218, 96,219,220, + 96, 96,221,222, 59,223,224, 96, 59, 59, 59, 59, 59, 59, 59,225, + 226,227,228,229, 59, 59,230,231, 59,232, 96, 96, 96, 96, 96, 96, + 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,233, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,231, 70, 70, 70, 70, - 70, 70, 70, 70, 70,232, 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, - 70, 70,233, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 70, 70, - 70, 70, 70, 70,234, 97, 97, 97, 97, 97, 97, 97, 97, 97,235, 97, - 236,237, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, - 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, - 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, - 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, - 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 2, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, - 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, - 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, - 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, - 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, - 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, - 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, - 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, - 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, - 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, - 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, - 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, - 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, - 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, - 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, - 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, - 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, - 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, - 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, - 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, - 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, - 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, - 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, - 2, 2, 2, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, - 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 2, 2, 2, 23, 23, - 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, - 2, 2, 2, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 2, 16, 16, - 16, 16, 2, 2, 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, - 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, - 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, - 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, - 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, - 18, 18, 18, 2, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, - 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, - 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, - 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, - 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, - 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 45, 45, 45, 45, - 45, 45, 45, 2, 2, 2, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, - 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, - 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, - 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, - 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, - 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 2, - 2, 2, 2, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 2, 2, 2, 2, 62, 62, 62, 62, 62, 2, 2, 2, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2, - 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 1, 1, - 2, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, - 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, - 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, 55, 55, - 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, - 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, - 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, - 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 2, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, - 17, 17, 17, 17, 17, 0, 13, 13, 13, 13, 13, 2, 2, 2, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, - 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, 2, 2, 79, 79, - 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, - 0, 19, 19, 19, 19, 19, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 0, 0, - 2, 2, 2, 2, 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, - 2, 2, 2, 2, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, - 2, 2, 2, 2, 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, - 68, 68, 68, 68, 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, - 2, 92, 92, 92, 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, - 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, - 0, 0, 2, 2, 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, - 2, 2, 2, 2, 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, - 2, 12, 12, 12, 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, - 19, 19, 19, 19, 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, - 2, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, - 14, 14, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, - 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, - 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, 0, 0, 3, 3, - 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, - 12, 12, 12, 12, 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, - 0, 0, 0, 0, 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, - 49, 2, 49, 49, 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, - 49, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, - 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 2, 2, 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118, - 118,118,118,118,118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, - 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, - 51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135, - 135,135,135,135,135,135,135,135,135,135, 2, 2, 2, 2,106,106, - 106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104, - 104,104, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,104,110,110, - 110,110,110,110,110,110,110,110,110,110,110,110,110, 2,110,110, - 110,110,110,110, 2, 2, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 2, 81,120,120, - 120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116, - 116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, 2,116,128,128, - 128,128,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, - 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, 97, 97, 2, 2, - 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 2, - 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 2, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, - 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, 88, 88,117,117, - 117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112, - 112,112,112,112,112, 2, 2, 2, 2,112,112,112,112,112, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, - 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 2, 2, 2, 2, 2,122,122,122,122,122,122,122,122,122,122, - 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, 2, 2, 2,122, - 122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89, 2, - 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,130,130,130,130, - 130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130,144,144, - 144,144,144,144,144,144,144,144, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 2,156,156,156,156,156,156,156,156,156,156, - 2,156,156,156, 2, 2,156,156, 2, 2, 2, 2, 2, 2,147,147, - 147,147,147,147,147,147,148,148,148,148,148,148,148,148,148,148, - 2, 2, 2, 2, 2, 2,153,153,153,153,153,153,153,153,153,153, - 153,153, 2, 2, 2, 2,149,149,149,149,149,149,149,149,149,149, - 149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, - 2, 2, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101, - 101,101,101,101,101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, - 2, 2, 2, 2, 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 2, 96, 96,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111, 2,100,100,100,100,100,100,100,100, 2, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108, - 108,108,108,108,108,108,108,108, 2,108,108,108,108,108,108,108, - 108,108,108,108,108, 2,129,129,129,129,129,129,129, 2,129, 2, - 129,129,129,129, 2,129,129,129,129,129,129,129,129,129,129,129, - 129,129,129,129, 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109, - 109,109,109,109,109,109,109,109,109, 2, 2, 2, 2, 2,109,109, - 2, 2, 2, 2, 2, 2,107,107,107,107, 2,107,107,107,107,107, - 107,107,107, 2, 2,107,107, 2, 2,107,107,107,107,107,107,107, - 107,107,107,107,107,107,107, 2,107,107,107,107,107,107,107, 2, - 107,107, 2,107,107,107,107,107, 2, 1,107,107,107,107,107, 2, - 2,107,107,107, 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, - 2, 2, 2,107,107,107,107,107,107,107, 2, 2,107,107,107,107, - 107,107,107, 2, 2, 2,137,137,137,137,137,137,137,137,137,137, - 137,137, 2,137,137,137,137,137, 2, 2, 2, 2, 2, 2,124,124, - 124,124,124,124,124,124,124,124, 2, 2, 2, 2, 2, 2,123,123, - 123,123,123,123,123,123,123,123,123,123,123,123, 2, 2,114,114, - 114,114,114,114,114,114,114,114,114,114,114, 2, 2, 2,114,114, - 2, 2, 2, 2, 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102, - 102,102,102,102,102,102,102, 2, 2, 2, 2, 2, 2, 2,102,102, - 2, 2, 2, 2, 2, 2,126,126,126,126,126,126,126,126,126,126, - 126, 2, 2,126,126,126,126,126,126,126, 2, 2, 2, 2,142,142, - 142,142,142,142,142,142,142,142,142,142, 2, 2, 2, 2,125,125, - 125,125,125,125,125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2,125,154,154,154,154,154,154,154, 2, 2,154, - 2, 2,154,154,154,154,154,154,154,154, 2,154,154, 2,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154, 2,154,154, 2, - 2,154,154,154,154,154,154,154, 2, 2, 2, 2, 2, 2,150,150, - 150,150,150,150,150,150, 2, 2,150,150,150,150,150,150,150,150, - 150,150,150, 2, 2, 2,141,141,141,141,141,141,141,141,140,140, - 140,140,140,140,140,140,140,140,140, 2, 2, 2, 2, 2,121,121, - 121,121,121,121,121,121,121, 2, 2, 2, 2, 2, 2, 2,133,133, - 133,133,133,133,133,133,133, 2,133,133,133,133,133,133,133,133, - 133,133,133,133,133, 2,133,133,133,133,133,133, 2, 2,133,133, - 133,133,133, 2, 2, 2,134,134,134,134,134,134,134,134, 2, 2, - 134,134,134,134,134,134, 2,134,134,134,134,134,134,134,134,134, - 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, - 2,138,138,138,138,138,138,138,138,138,138,138,138,138, 2, 2, - 138, 2,138,138, 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143, - 143,143,143,143, 2,143,143, 2,143,143,143,143,143,143,143,143, - 143,143,143,143,143,143,143,143,143,143,143,143,143, 2,143,143, - 2,143,143,143,143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, - 2, 2, 2, 2, 2, 2,145,145,145,145,145,145,145,145,145, 2, - 2, 2, 2, 2, 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, - 63, 63, 63, 63, 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, - 63, 63, 2, 2, 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 2, 80, 2, 2, 2, 2, 2, 2, 2,127,127, - 127,127,127,127,127,127,127,127,127,127,127,127,127, 2, 79, 2, - 2, 2, 2, 2, 2, 2,115,115,115,115,115,115,115,115,115,115, - 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,103,103, - 103,103,103,103,103,103,103,103,103,103,103,103, 2, 2,119,119, - 119,119,119,119,119,119,119,119,119,119,119,119, 2, 2,119,119, - 2,119,119,119,119,119, 2, 2, 2, 2, 2,119,119,119,146,146, - 146,146,146,146,146,146,146,146,146, 2, 2, 2, 2, 2, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99, 2, 2, - 2, 2, 2, 2, 2, 99,136,139, 0, 0,155, 2, 2, 2,136,136, - 136,136,136,136,136,136,155,155,155,155,155,155,155,155,155,155, - 155,155,155,155, 2, 2,136, 2, 2, 2, 2, 2, 2, 2, 17, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139, - 139,139, 2, 2, 2, 2,105,105,105,105,105,105,105,105,105,105, - 105, 2, 2, 2, 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, - 2, 2, 2, 2, 2, 2,105,105, 2, 2,105,105,105,105, 0, 0, - 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, - 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0,131,131,131,131,131,131,131,131,131,131, - 131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131,131,131, 2,131, - 131,131,131,131,131,131, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, - 2, 56, 56, 2, 56, 56, 56, 56, 56, 2, 2, 2, 2, 2,151,151, - 151,151,151,151,151,151,151,151,151,151,151, 2, 2, 2,151,151, - 151,151,151,151, 2, 2,151,151, 2, 2, 2, 2,151,151,152,152, - 152,152,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,113,113, - 113,113,113,113,113,113,113,113,113,113,113, 2, 2,113,113,113, - 113,113,113,113,113, 2,132,132,132,132,132,132,132,132,132,132, - 132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2,132,132, 3, 3, - 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, - 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, - 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, 2, 2, 13, 2, - 2, 2, 2, 2, 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, - 2, 2, 2, 2, 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, - 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, - 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, - 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, - 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, - 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, - 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0, - 107, 0, 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, - 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124, - 125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,128,129,130,131,132,133,134,135,136,137,138,139, - 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, - 156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, - 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171, - 172, 0, 0, 0,173,174,175,176,177,178,179,180,181,182,183,184, - 185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200, - 201,202,203,204,205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 3, 4, -}; -static const uint16_t -_hb_ucd_u16[9080] = -{ - 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, - 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, - 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, - 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, - 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, - 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, - 48, 67, 68, 69, 48, 70, 71, 72, 72, 72, 48, 73, 74, 75, 76, 32, - 77, 48, 48, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 84, 85, 92, 93, 94, 95, 96, 97, 98, 85, 99, 100, 101, 89, 102, - 103, 84, 85, 104, 105, 106, 89, 107, 108, 109, 110, 111, 112, 113, 95, 114, - 115, 116, 85, 117, 118, 119, 89, 120, 121, 116, 85, 122, 123, 124, 89, 125, - 126, 116, 48, 127, 128, 129, 89, 130, 131, 132, 48, 133, 134, 135, 95, 136, - 137, 48, 48, 138, 139, 140, 72, 72, 141, 48, 142, 143, 144, 145, 72, 72, - 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 72, 72, - 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, - 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, - 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, - 184, 185, 48, 186, 48, 187, 184, 188, 48, 48, 48, 189, 190, 191, 192, 193, - 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, - 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, - 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 72, 72, 72, - 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, - 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, - 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 240, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 241, 13, 13, 13, 13, 13, 13, - 242, 243, 242, 242, 243, 244, 242, 245, 246, 246, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 262, 72, 263, 264, 216, - 265, 266, 267, 268, 269, 270, 271, 271, 272, 273, 274, 209, 275, 276, 209, 277, - 278, 278, 278, 278, 278, 278, 278, 278, 279, 209, 280, 209, 209, 209, 209, 281, - 209, 282, 278, 283, 209, 284, 285, 209, 209, 209, 286, 72, 287, 72, 270, 270, - 270, 288, 209, 209, 209, 209, 289, 270, 209, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 209, 290, 291, 209, 209, 292, 209, 209, 209, 209, 209, 209, 293, 209, - 209, 209, 209, 209, 209, 209, 294, 295, 270, 296, 209, 209, 297, 278, 298, 278, - 299, 300, 278, 278, 278, 301, 278, 302, 209, 209, 209, 278, 303, 209, 209, 304, - 209, 305, 209, 209, 209, 209, 209, 209, 9, 9, 306, 11, 11, 307, 308, 309, - 13, 13, 13, 13, 13, 13, 310, 311, 11, 11, 312, 48, 48, 48, 313, 314, - 48, 315, 316, 316, 316, 316, 32, 32, 317, 318, 319, 320, 321, 322, 72, 72, - 209, 323, 209, 209, 209, 209, 209, 324, 209, 209, 209, 209, 209, 325, 72, 326, - 327, 328, 329, 330, 137, 48, 48, 48, 48, 331, 178, 48, 48, 48, 48, 332, - 333, 48, 48, 137, 48, 48, 48, 48, 200, 334, 48, 48, 209, 209, 324, 48, - 209, 335, 336, 209, 337, 338, 209, 209, 336, 209, 209, 338, 209, 209, 209, 209, - 48, 48, 48, 48, 209, 209, 209, 209, 48, 48, 48, 48, 48, 48, 48, 151, - 48, 339, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 286, 48, 48, 229, - 340, 48, 341, 72, 13, 13, 342, 343, 13, 344, 48, 48, 48, 48, 345, 346, - 31, 347, 348, 349, 13, 13, 13, 350, 351, 352, 353, 354, 355, 72, 72, 356, - 357, 48, 358, 359, 48, 48, 48, 360, 361, 48, 48, 362, 363, 192, 32, 364, - 64, 48, 365, 48, 366, 367, 48, 151, 77, 48, 48, 368, 369, 370, 371, 372, - 48, 48, 373, 374, 375, 376, 48, 377, 48, 48, 48, 378, 379, 380, 381, 382, - 383, 384, 316, 11, 11, 385, 386, 11, 11, 11, 11, 11, 48, 48, 387, 192, - 48, 48, 388, 48, 389, 48, 48, 206, 390, 390, 390, 390, 390, 390, 390, 390, - 391, 391, 391, 391, 391, 391, 391, 391, 48, 48, 48, 48, 48, 48, 204, 48, - 48, 48, 48, 48, 48, 207, 72, 72, 392, 393, 394, 395, 396, 48, 48, 48, - 48, 48, 48, 397, 398, 399, 48, 48, 48, 48, 48, 400, 72, 48, 48, 48, - 48, 401, 48, 48, 74, 72, 72, 402, 32, 403, 32, 404, 405, 406, 407, 73, - 48, 48, 48, 48, 48, 48, 48, 408, 409, 2, 3, 4, 5, 410, 411, 412, - 48, 413, 48, 200, 414, 415, 416, 417, 418, 48, 172, 419, 204, 204, 72, 72, - 48, 48, 48, 48, 48, 48, 48, 71, 420, 270, 270, 421, 271, 271, 271, 422, - 423, 424, 425, 72, 72, 209, 209, 426, 72, 72, 72, 72, 72, 72, 72, 72, - 48, 151, 48, 48, 48, 101, 427, 428, 48, 48, 429, 48, 430, 48, 48, 431, - 48, 432, 48, 48, 433, 434, 72, 72, 9, 9, 435, 11, 11, 48, 48, 48, - 48, 204, 192, 9, 9, 436, 11, 437, 48, 48, 74, 48, 48, 48, 438, 72, - 48, 48, 48, 315, 48, 199, 74, 72, 439, 48, 48, 440, 48, 441, 48, 442, - 48, 200, 443, 72, 72, 72, 48, 444, 48, 445, 48, 446, 72, 72, 72, 72, - 48, 48, 48, 447, 270, 448, 270, 270, 449, 450, 48, 451, 452, 453, 48, 454, - 48, 455, 72, 72, 456, 48, 457, 458, 48, 48, 48, 459, 48, 460, 48, 461, - 48, 462, 463, 72, 72, 72, 72, 72, 48, 48, 48, 48, 196, 72, 72, 72, - 9, 9, 9, 464, 11, 11, 11, 465, 48, 48, 466, 192, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 270, 467, 48, 48, 468, 469, 72, 72, 72, 72, - 48, 455, 470, 48, 62, 471, 72, 72, 72, 72, 72, 48, 472, 72, 48, 315, - 473, 48, 48, 474, 475, 448, 476, 477, 222, 48, 48, 478, 479, 48, 196, 192, - 480, 48, 481, 482, 483, 48, 48, 484, 222, 48, 48, 485, 486, 487, 488, 489, - 48, 98, 490, 491, 72, 72, 72, 72, 492, 493, 494, 48, 48, 495, 496, 192, - 497, 84, 85, 498, 499, 500, 501, 502, 48, 48, 48, 503, 504, 505, 469, 72, - 48, 48, 48, 506, 507, 192, 72, 72, 48, 48, 508, 509, 510, 511, 72, 72, - 48, 48, 48, 512, 513, 192, 514, 72, 48, 48, 515, 516, 192, 72, 72, 72, - 48, 173, 517, 518, 72, 72, 72, 72, 48, 48, 490, 519, 72, 72, 72, 72, - 72, 72, 9, 9, 11, 11, 148, 520, 521, 522, 48, 523, 524, 192, 72, 72, - 72, 72, 525, 48, 48, 526, 527, 72, 528, 48, 48, 529, 530, 531, 48, 48, - 532, 533, 534, 72, 48, 48, 48, 196, 85, 48, 508, 535, 536, 148, 175, 537, - 48, 538, 539, 540, 72, 72, 72, 72, 541, 48, 48, 542, 543, 192, 544, 48, - 545, 546, 192, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 48, 547, - 72, 72, 72, 101, 270, 548, 549, 550, 48, 207, 72, 72, 72, 72, 72, 72, - 271, 271, 271, 271, 271, 271, 551, 552, 48, 48, 48, 48, 388, 72, 72, 72, - 48, 48, 200, 553, 72, 72, 72, 72, 48, 48, 48, 48, 315, 72, 72, 72, - 48, 48, 48, 196, 48, 200, 370, 72, 72, 72, 72, 72, 72, 48, 204, 554, - 48, 48, 48, 555, 556, 557, 558, 559, 48, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 9, 9, 11, 11, 270, 560, 72, 72, 72, 72, 72, 72, - 48, 48, 48, 48, 561, 562, 563, 563, 564, 565, 72, 72, 72, 72, 566, 567, - 48, 48, 48, 48, 48, 48, 48, 74, 48, 48, 48, 48, 48, 199, 72, 72, - 196, 72, 72, 72, 72, 72, 72, 72, 48, 200, 72, 72, 72, 568, 569, 48, - 48, 48, 48, 48, 48, 48, 48, 206, 48, 48, 48, 48, 48, 48, 71, 151, - 196, 570, 571, 72, 72, 72, 72, 72, 209, 209, 209, 209, 209, 209, 209, 325, - 209, 209, 572, 209, 209, 209, 573, 574, 575, 209, 576, 209, 209, 209, 577, 72, - 209, 209, 209, 209, 578, 72, 72, 72, 72, 72, 72, 72, 72, 72, 270, 579, - 209, 209, 209, 209, 209, 286, 270, 452, 9, 580, 11, 581, 582, 583, 242, 9, - 584, 585, 586, 587, 588, 9, 580, 11, 589, 590, 11, 591, 592, 593, 594, 9, - 595, 11, 9, 580, 11, 581, 582, 11, 242, 9, 584, 594, 9, 595, 11, 9, - 580, 11, 596, 9, 597, 598, 599, 600, 11, 601, 9, 602, 603, 604, 605, 11, - 606, 9, 607, 11, 608, 609, 609, 609, 32, 32, 32, 610, 32, 32, 611, 612, - 613, 614, 45, 72, 72, 72, 72, 72, 615, 616, 617, 72, 72, 72, 72, 72, - 48, 48, 151, 618, 619, 72, 72, 72, 72, 72, 72, 72, 48, 48, 620, 621, - 48, 48, 48, 48, 622, 623, 72, 72, 9, 9, 584, 11, 624, 370, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 488, 270, 270, 625, 626, 72, 72, 72, 72, - 488, 270, 627, 628, 72, 72, 72, 72, 629, 48, 630, 631, 632, 633, 634, 635, - 636, 206, 637, 206, 72, 72, 72, 638, 209, 209, 326, 209, 209, 209, 209, 209, - 209, 324, 335, 639, 639, 639, 209, 325, 640, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 641, 72, 72, 72, 642, 209, 643, 209, 209, 326, 577, 644, 325, 72, - 209, 209, 209, 209, 209, 209, 209, 645, 209, 209, 209, 209, 209, 646, 424, 424, - 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 209, 209, 209, 577, 326, 72, - 326, 209, 209, 209, 646, 176, 209, 209, 646, 209, 641, 644, 72, 72, 72, 72, - 209, 209, 209, 209, 209, 209, 209, 647, 209, 209, 209, 209, 648, 209, 209, 209, - 209, 209, 209, 209, 209, 324, 641, 649, 286, 209, 577, 286, 643, 286, 72, 72, - 209, 650, 209, 209, 287, 72, 72, 192, 48, 48, 48, 48, 48, 204, 72, 72, - 48, 48, 48, 205, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, - 48, 48, 469, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 101, 72, - 48, 204, 72, 72, 72, 72, 72, 72, 48, 48, 48, 48, 71, 72, 72, 72, - 651, 72, 652, 652, 652, 652, 652, 652, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 72, 391, 391, 391, 391, 391, 391, 391, 653, - 391, 391, 391, 391, 391, 391, 391, 654, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, - 2, 2, 5, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, - 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, - 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, - 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 26, 26, 26, 26, 26, 26, 31, 31, 50, 31, - 31, 26, 51, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, - 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, - 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, - 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, - 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, - 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, - 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, - 123, 127, 128, 129, 130, 122, 131, 26, 132, 133, 134, 132, 132, 132, 132, 132, - 133, 134, 135, 132, 136, 132, 132, 132, 137, 138, 139, 140, 138, 138, 141, 142, - 139, 143, 144, 138, 145, 138, 146, 26, 147, 148, 148, 148, 148, 148, 148, 149, - 148, 148, 148, 150, 26, 26, 26, 26, 151, 152, 153, 153, 154, 153, 153, 155, - 156, 155, 153, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, - 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, - 166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, - 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, - 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 182, 181, 183, 184, 185, 186, 26, 187, 187, 188, 26, - 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 199, 200, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 201, 199, 199, 199, 199, 199, 202, 178, 178, - 178, 178, 178, 178, 178, 178, 203, 26, 204, 204, 204, 205, 204, 206, 204, 206, - 207, 204, 208, 208, 208, 209, 210, 26, 211, 211, 211, 211, 211, 212, 211, 211, - 211, 213, 211, 214, 194, 194, 194, 194, 215, 215, 215, 216, 217, 217, 217, 217, - 217, 217, 217, 218, 217, 217, 217, 219, 217, 220, 217, 220, 217, 221, 9, 9, - 222, 26, 26, 26, 26, 26, 26, 26, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 224, 223, 223, 223, 223, 223, 225, 226, 226, 226, 226, 226, 226, 226, 226, - 227, 227, 227, 227, 227, 227, 228, 229, 230, 230, 230, 230, 230, 230, 230, 231, - 230, 232, 233, 233, 233, 233, 233, 233, 18, 234, 165, 165, 165, 165, 165, 235, - 226, 26, 236, 9, 237, 238, 239, 240, 2, 2, 2, 2, 241, 242, 2, 2, - 2, 2, 2, 243, 244, 245, 2, 246, 2, 2, 2, 2, 2, 2, 2, 247, - 9, 9, 9, 9, 9, 9, 9, 248, 14, 14, 249, 249, 14, 14, 14, 14, - 249, 249, 14, 250, 14, 14, 14, 249, 14, 14, 14, 14, 14, 14, 251, 14, - 251, 14, 252, 253, 14, 14, 254, 255, 0, 256, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 257, 0, 258, 259, 0, 260, 2, 261, 0, 0, 0, 0, - 26, 26, 9, 9, 9, 9, 222, 26, 0, 0, 0, 0, 262, 263, 4, 0, - 0, 264, 0, 0, 2, 2, 2, 2, 2, 265, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 26, 26, 26, - 0, 266, 26, 26, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 269, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 271, 270, 270, - 270, 270, 270, 271, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 272, 273, 165, 165, 165, 165, 166, 167, 274, 274, - 274, 274, 274, 274, 274, 275, 276, 275, 170, 170, 172, 26, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 266, 26, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 280, 26, 26, 26, 0, 281, 282, 0, 0, 0, 283, 284, 0, 285, - 286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 296, 0, 0, 294, 294, 294, 294, - 0, 0, 0, 0, 281, 26, 291, 291, 169, 169, 169, 296, 0, 0, 0, 0, - 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, - 0, 0, 0, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 299, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 301, 300, 300, 300, 300, 300, 300, - 302, 26, 303, 303, 303, 303, 303, 303, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 305, 26, 26, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 306, 26, 0, 0, 0, 0, 307, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 308, 2, 2, 2, 2, 2, 2, - 309, 310, 26, 26, 26, 26, 311, 2, 312, 312, 312, 312, 312, 313, 0, 314, - 315, 315, 315, 315, 315, 315, 315, 26, 316, 316, 316, 316, 316, 316, 316, 316, - 317, 318, 316, 319, 53, 53, 53, 53, 320, 320, 320, 320, 320, 321, 322, 322, - 322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331, 26, - 330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334, - 335, 26, 26, 336, 337, 337, 338, 26, 339, 339, 339, 26, 172, 172, 2, 2, - 2, 2, 2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345, 26, 169, 169, - 296, 346, 169, 169, 169, 169, 169, 345, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 347, 26, 26, 26, 26, 348, 26, 349, 350, 25, 25, 351, 352, - 353, 25, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 354, 26, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 355, - 26, 26, 31, 31, 31, 31, 31, 31, 31, 31, 356, 31, 31, 31, 31, 31, - 31, 26, 26, 26, 26, 26, 31, 357, 9, 9, 0, 314, 9, 358, 0, 0, - 0, 0, 359, 0, 260, 281, 50, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 360, 361, 0, 0, 0, 1, 2, 2, 3, - 1, 2, 2, 3, 362, 291, 290, 291, 291, 291, 291, 363, 169, 169, 169, 296, - 364, 364, 364, 365, 260, 260, 26, 366, 367, 368, 367, 367, 369, 367, 367, 370, - 367, 371, 367, 371, 26, 26, 26, 26, 367, 367, 367, 367, 367, 367, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 372, 373, 0, 0, 0, 0, 0, 374, 0, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 255, 0, 375, 376, 26, 26, 26, - 26, 26, 0, 0, 0, 0, 0, 377, 378, 378, 378, 379, 380, 380, 380, 380, - 380, 380, 381, 26, 382, 0, 0, 281, 383, 383, 383, 383, 384, 385, 386, 386, - 386, 387, 388, 388, 388, 388, 388, 389, 390, 390, 390, 391, 392, 392, 392, 392, - 393, 392, 394, 26, 26, 26, 26, 26, 395, 395, 395, 395, 395, 395, 395, 395, - 395, 395, 396, 396, 396, 396, 396, 396, 397, 397, 397, 398, 397, 399, 400, 400, - 400, 400, 401, 400, 400, 400, 400, 401, 402, 402, 402, 402, 402, 26, 403, 403, - 403, 403, 403, 403, 404, 405, 26, 26, 406, 406, 406, 406, 406, 406, 406, 406, - 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, 407, 26, - 406, 406, 408, 26, 406, 26, 26, 26, 409, 410, 411, 411, 411, 411, 412, 413, - 414, 414, 415, 414, 416, 416, 416, 416, 417, 417, 417, 418, 419, 417, 26, 26, - 26, 26, 26, 26, 420, 420, 421, 422, 423, 423, 423, 424, 425, 425, 425, 426, - 26, 26, 26, 26, 26, 26, 26, 26, 427, 427, 427, 427, 428, 428, 428, 429, - 428, 428, 430, 428, 428, 428, 428, 428, 431, 432, 433, 434, 435, 435, 436, 437, - 435, 438, 435, 438, 439, 439, 439, 439, 440, 440, 440, 440, 26, 26, 26, 26, - 441, 441, 441, 441, 442, 443, 442, 26, 444, 444, 444, 444, 444, 444, 445, 446, - 447, 447, 448, 447, 449, 449, 450, 449, 451, 451, 452, 453, 26, 454, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 455, 455, 455, 455, 455, 455, 455, 455, - 455, 456, 26, 26, 26, 26, 26, 26, 457, 457, 457, 457, 457, 457, 458, 26, - 457, 457, 457, 457, 457, 457, 458, 459, 460, 460, 460, 460, 460, 26, 460, 461, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 31, 31, 31, 462, 463, 463, 463, 463, 463, 464, 465, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 466, 466, 466, 466, 466, 26, 467, 467, - 467, 467, 467, 468, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 469, 469, - 469, 470, 26, 26, 471, 471, 472, 26, 473, 473, 473, 473, 473, 473, 473, 473, - 473, 474, 475, 473, 473, 473, 26, 476, 477, 477, 477, 477, 477, 477, 477, 477, - 478, 479, 480, 480, 480, 481, 480, 482, 483, 483, 483, 483, 483, 483, 484, 483, - 483, 26, 485, 485, 485, 485, 486, 26, 487, 487, 487, 487, 487, 487, 487, 487, - 487, 487, 487, 487, 488, 138, 489, 26, 490, 490, 491, 490, 490, 490, 490, 492, - 26, 26, 26, 26, 26, 26, 26, 26, 493, 494, 495, 496, 495, 497, 498, 498, - 498, 498, 498, 498, 498, 499, 498, 500, 501, 502, 503, 504, 504, 505, 506, 507, - 502, 508, 509, 510, 511, 512, 512, 26, 513, 513, 513, 513, 513, 513, 513, 513, - 513, 513, 513, 514, 515, 26, 26, 26, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 26, 516, 517, 26, 26, 26, 26, 518, 518, 518, 518, 518, 518, 519, 518, - 518, 518, 518, 519, 26, 26, 26, 26, 520, 520, 520, 520, 520, 520, 520, 520, - 521, 26, 520, 522, 199, 523, 26, 26, 524, 524, 524, 524, 524, 524, 524, 525, - 524, 526, 26, 26, 26, 26, 26, 26, 527, 527, 527, 528, 527, 529, 527, 527, - 26, 26, 26, 26, 26, 26, 26, 26, 530, 530, 530, 530, 530, 530, 530, 531, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 532, 532, 532, 532, - 532, 532, 532, 532, 532, 532, 533, 534, 535, 536, 537, 538, 538, 538, 539, 540, - 535, 26, 538, 541, 26, 26, 26, 26, 26, 26, 26, 26, 542, 543, 542, 542, - 542, 542, 542, 543, 544, 26, 26, 26, 545, 545, 545, 545, 545, 545, 545, 545, - 545, 26, 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, 547, 26, 26, 26, - 548, 548, 548, 548, 548, 548, 548, 549, 550, 551, 550, 550, 550, 550, 552, 550, - 553, 26, 550, 550, 550, 554, 555, 555, 555, 555, 556, 555, 555, 557, 558, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 559, 560, 561, 561, 561, 561, 559, 562, - 561, 26, 561, 563, 564, 565, 566, 566, 566, 567, 568, 569, 566, 570, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 571, 571, 571, 572, 26, 26, 26, 26, 26, 26, 573, 26, - 108, 108, 108, 108, 108, 108, 574, 575, 576, 576, 576, 576, 576, 576, 576, 576, - 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 577, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 576, 576, 576, 576, 576, 576, 576, 576, - 576, 576, 576, 576, 576, 578, 579, 26, 576, 576, 576, 576, 576, 576, 576, 576, - 580, 26, 26, 26, 26, 26, 26, 26, 581, 581, 581, 581, 581, 581, 581, 581, - 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 582, 581, 583, - 26, 26, 26, 26, 26, 26, 26, 26, 584, 584, 584, 584, 584, 584, 584, 584, - 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, - 585, 26, 26, 26, 26, 26, 26, 26, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 586, - 587, 587, 587, 588, 587, 589, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 590, 590, 590, 591, 591, 26, 592, 592, 592, 592, 592, 592, 592, 592, - 593, 26, 592, 594, 594, 592, 592, 595, 592, 592, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 598, 598, 598, 598, 598, 598, 598, 598, - 598, 599, 598, 598, 598, 598, 598, 598, 598, 600, 598, 598, 26, 26, 26, 26, - 26, 26, 26, 26, 601, 26, 347, 26, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, - 602, 602, 602, 602, 602, 602, 602, 26, 603, 603, 603, 603, 603, 603, 603, 603, - 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, - 603, 603, 604, 26, 26, 26, 26, 26, 602, 605, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 606, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 26, 26, 26, 26, - 26, 26, 607, 26, 608, 26, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, - 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, - 609, 609, 609, 609, 609, 609, 609, 610, 611, 611, 611, 611, 611, 611, 611, 611, - 611, 611, 611, 611, 611, 612, 611, 613, 611, 614, 611, 615, 281, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 616, 26, 0, 0, 0, 0, 260, 361, 0, 0, - 0, 0, 0, 0, 617, 618, 0, 619, 620, 621, 0, 0, 0, 622, 0, 0, - 0, 0, 0, 0, 0, 623, 26, 26, 14, 14, 14, 14, 14, 14, 14, 14, - 249, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 260, 26, 0, 0, 0, 623, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 257, 624, 625, 0, 626, - 627, 0, 0, 0, 0, 0, 0, 0, 269, 628, 257, 257, 0, 0, 0, 629, - 630, 631, 632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 268, 0, 0, 0, 0, 0, 0, 633, 633, 633, 633, 633, 633, 633, 633, - 633, 633, 633, 633, 633, 633, 633, 633, 633, 634, 26, 635, 636, 633, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 271, 270, 270, 637, 638, 639, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 640, 640, 640, 640, 640, 641, 640, 642, - 640, 643, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 644, 644, 644, 644, 644, 644, 644, 645, 646, 646, 646, 646, 646, 646, 646, 646, - 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, - 647, 646, 648, 26, 26, 26, 26, 26, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 650, 649, 651, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 361, 0, 0, 0, 0, 0, 0, 0, 375, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 361, 0, 0, 0, 0, 0, 0, 616, - 26, 26, 26, 26, 26, 26, 26, 26, 652, 31, 31, 31, 653, 654, 655, 656, - 657, 658, 653, 659, 653, 655, 655, 660, 31, 661, 31, 662, 663, 661, 31, 662, - 26, 26, 26, 26, 26, 26, 354, 26, 0, 0, 0, 0, 0, 281, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 26, 0, 260, 361, 0, - 361, 0, 361, 0, 0, 0, 616, 26, 0, 0, 0, 0, 0, 616, 26, 26, - 26, 26, 26, 26, 664, 0, 0, 0, 665, 26, 0, 0, 0, 0, 0, 281, - 0, 623, 314, 26, 616, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 26, 0, 375, 0, 375, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 623, 0, 281, 26, 26, 0, 281, 0, 0, 0, 0, 0, 0, - 0, 26, 0, 314, 0, 0, 0, 0, 0, 26, 0, 0, 0, 616, 314, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 281, 26, 0, 616, 375, 266, 260, 26, 0, 0, 0, 623, 260, 26, - 266, 26, 260, 26, 26, 26, 26, 26, 0, 0, 359, 0, 0, 0, 0, 0, - 0, 266, 26, 26, 26, 26, 0, 314, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 280, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 299, 26, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347, 26, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 666, 26, 26, 26, 277, 277, 277, 280, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 667, 26, 26, 26, 26, 26, 26, 668, 26, 26, 26, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, - 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, - 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, - 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, - 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, - 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, - 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, - 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, - 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, - 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, - 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, - 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, - 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, - 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, - 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, - 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, - 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, - 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, - 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, - 1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, - 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, - 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, - 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, - 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, - 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, - 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, - 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, - 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, - 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, - 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, - 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, - 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, - 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, - 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, - 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, - 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, - 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, - 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, - 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, - 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, - 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, - 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, - 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, - 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, - 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, - 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, - 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, - 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, - 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, - 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, - 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, - 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, - 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, - 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, - 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, - 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, - 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, - 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, - 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, - 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, - 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, - 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, - 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, - 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, - 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, - 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, - 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, - 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, - 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, - 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, - 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, - 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, - 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, - 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, - 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, - 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, - 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, - 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, - 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, - 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, - 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, - 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, - 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, - 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, - 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, - 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, - 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, - 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, - 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, - 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, - 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, - 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, - 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, - 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, - 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, - 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, - 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, - 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, - 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, - 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, - 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, - 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, - 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, - 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, - 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, - 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, - 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, - 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, - 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, - 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, - 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, - 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, - 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, - 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, - 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, - 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, - 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, - 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, - 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, - 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, - 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, - 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, - 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, - 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, - 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, - 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, - 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, - 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, - 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, - 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, - 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, - 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, - 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, - 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, - 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, - 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, - 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, - 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, - 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, - 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, - 817, 818, 819, 820, 821, 935, 0, 0, -}; -static const int16_t -_hb_ucd_i16[196] = -{ - 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, - 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, - 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, - -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, - 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, - 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, - 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, - 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, - -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, - 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, - -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, - -1, 0, 1, -1, -}; - -static inline uint_fast8_t -_hb_ucd_gc (unsigned u) -{ - return u<1114110u?_hb_ucd_u8[6504+(((_hb_ucd_u8[1264+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; -} -static inline uint_fast8_t -_hb_ucd_ccc (unsigned u) -{ - return u<125259u?_hb_ucd_u8[8768+(((_hb_ucd_u8[7792+(((_hb_ucd_u8[7120+(((_hb_ucd_u8[6874+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0; -} -static inline unsigned -_hb_ucd_b4 (const uint8_t* a, unsigned i) -{ - return (a[i>>1]>>((i&1u)<<2))&15u; -} -static inline int_fast16_t -_hb_ucd_bmg (unsigned u) -{ - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9508+(((_hb_ucd_u8[9388+(((_hb_ucd_b4(9260+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; -} -static inline uint_fast8_t -_hb_ucd_sc (unsigned u) -{ - return u<918000u?_hb_ucd_u8[10974+(((_hb_ucd_u16[1960+(((_hb_ucd_u8[10286+(((_hb_ucd_u8[9836+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; -} -static inline uint_fast16_t -_hb_ucd_dm (unsigned u) -{ - return u<195102u?_hb_ucd_u16[5768+(((_hb_ucd_u8[16708+(((_hb_ucd_u8[16326+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; -} - - -#else - -static const uint8_t -_hb_ucd_u8[13344] = -{ - 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 6, 5, 5, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 5, 17, 15, 15, 18, 15, 19, 20, 21, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 23, - 5, 24, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 234, 70,235, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,236, + 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 96, 96, 96, 96, 96, 96, + 96, 96, 70, 70, 70, 70,238, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 70, 70, 70, 70, 70, 70,239, 96, 96, 96, 96, 96, 96, 96, + 96, 96,240, 96,241,242, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, + 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, + 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, + 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, + 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, + 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, + 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, + 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, + 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, + 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, + 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, + 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, + 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, + 2, 2, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, + 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, + 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, + 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, + 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, + 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, + 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, + 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, + 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, + 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, + 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, + 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, + 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, + 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, + 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, + 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, + 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, + 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, + 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, + 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, + 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, + 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, + 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, + 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, + 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, + 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, + 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, + 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, + 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, + 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, + 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, + 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, + 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, + 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, + 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, + 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, + 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, + 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, + 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, + 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, + 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, + 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, + 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, + 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, + 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, + 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, + 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, + 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, + 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, + 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, + 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, + 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, + 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, + 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, + 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, + 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, + 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, + 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, + 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, + 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, + 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, + 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, + 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, + 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, + 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, + 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, + 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, + 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, + 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, + 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, + 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, + 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, + 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, + 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 25, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, - 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, - 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, - 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, - 34, 34,109,110,111,112,113,114,115,116,117,111, 34, 34, 34,111, - 118,119,120,121,122,123,124,125, 34,126,127,111,128,129,130,131, - 132,133,134,135,136,137,138,111,139,140,111,141,142,143,144,111, - 145,146,147,148,149,150,111,111,151,152,153,154,111,155,111,156, - 34, 34, 34, 34, 34, 34, 34, 34,157, 34, 34,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34,158,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34,159,160,161, 34,111,111,111,111,162,163,164,165, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, - 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111, 34,166,111,111,111,111,111,111, - 67, 67,167,168,169,128, 65,111,170,171,172,173,174,175,176,177, - 67, 67, 67, 67,178,179,111,111,111,111,111,111,111,111,111,111, - 180,111,181,111,111,182,111,111,111,111,111,111,111,111,111,111, - 34,183,184,111,111,111,111,111,128,185,186,111, 34,187,111,111, - 67, 67,188, 67, 67,111, 67,189, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67,190,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 191,111,180,180,111,111,111,111,111,111,111,111,111,111,111,111, - 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, - 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, - 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, - 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, - 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, - 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, - 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, - 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, - 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, - 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10, - 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, - 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11, - 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, - 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53, - 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55, - 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61, - 43, 43, 43, 43, 43, 57, 59, 2, 62, 36, 36, 36, 36, 63, 43, 43, - 7, 7, 7, 7, 7, 2, 2, 36, 64, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 65, 43, 43, 43, 66, 47, 43, 43, 67, 68, 69, 43, 43, 36, - 7, 7, 7, 7, 7, 36, 70, 71, 2, 2, 2, 2, 2, 2, 2, 72, - 63, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 64, 36, - 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36, - 36, 36, 36, 36, 36, 63, 43, 43, 43, 43, 40, 21, 2, 40, 68, 20, - 36, 36, 36, 43, 43, 68, 43, 43, 43, 43, 68, 43, 68, 43, 43, 43, - 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 63, 43, 43, 2, - 36, 63, 43, 43, 43, 43, 43, 43, 43, 73, 43, 43, 43, 43, 43, 43, - 43, 74, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 74, 64, 75, - 76, 43, 43, 43, 74, 75, 76, 75, 63, 43, 43, 43, 36, 36, 36, 36, - 36, 43, 2, 7, 7, 7, 7, 7, 77, 36, 36, 36, 36, 36, 36, 36, - 63, 75, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 75, - 76, 43, 43, 74, 75, 75, 76, 36, 36, 36, 36, 79, 75, 75, 36, 36, - 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43, - 43, 74, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 75, - 76, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 64, 36, 36, 36, - 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 63, 2, 2, 2, 2, 2, - 76, 43, 43, 43, 74, 75, 76, 43, 60, 20, 20, 20, 80, 43, 43, 43, - 43, 75, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 76, - 76, 43, 43, 74, 75, 75, 76, 43, 43, 43, 43, 74, 75, 75, 36, 36, - 71, 27, 27, 27, 27, 27, 27, 27, 43, 64, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 75, 74, 75, 75, 75, 75, 75, 76, 43, - 36, 36, 36, 79, 75, 75, 75, 75, 75, 75, 75, 7, 7, 7, 7, 7, - 27, 81, 61, 61, 53, 61, 61, 61, 74, 75, 64, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 43, 74, 75, 75, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 82, 27, 27, 27, 81, - 63, 75, 65, 36, 36, 36, 36, 36, 75, 75, 75, 74, 75, 75, 43, 43, - 43, 43, 74, 75, 75, 75, 75, 36, 83, 36, 36, 36, 36, 36, 36, 36, - 43, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 64, 75, - 76, 43, 43, 75, 75, 75, 76, 70, 61, 61, 36, 79, 27, 27, 27, 84, - 27, 27, 27, 27, 81, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 74, - 75, 43, 43, 43, 75, 75, 75, 75, 7, 75, 2, 2, 2, 2, 2, 2, - 63, 36, 43, 43, 43, 43, 43, 85, 36, 36, 36, 68, 43, 43, 43, 57, - 7, 7, 7, 7, 7, 2, 2, 2, 63, 36, 43, 43, 43, 43, 64, 36, - 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36, - 70, 61, 2, 2, 2, 2, 2, 2, 2, 86, 86, 61, 43, 61, 61, 61, - 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 75, - 63, 43, 43, 43, 43, 43, 43, 74, 43, 43, 57, 43, 36, 36, 63, 43, - 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 69, 61, 61, 61, 61, - 2, 2, 86, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 79, 76, 43, - 74, 43, 43, 43, 76, 74, 76, 64, 36, 36, 36, 75, 43, 36, 36, 43, - 64, 75, 78, 79, 75, 75, 75, 36, 63, 43, 64, 36, 36, 36, 36, 36, - 36, 74, 76, 74, 75, 75, 76, 79, 7, 7, 7, 7, 7, 75, 76, 61, - 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 63, 43, - 2, 2, 2, 2, 87, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16, - 88, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 65, - 89, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 90, 91, 91, - 36, 36, 36, 36, 36, 58, 2, 92, 93, 36, 36, 36, 36, 36, 36, 36, - 36, 43, 43, 43, 43, 43, 43, 43, 36, 43, 57, 2, 2, 2, 2, 2, - 36, 36, 43, 76, 43, 43, 43, 75, 75, 75, 75, 74, 76, 43, 43, 43, - 43, 43, 2, 77, 2, 60, 63, 43, 7, 7, 7, 7, 7, 7, 7, 7, - 2, 2, 2, 94, 2, 56, 43, 59, 36, 95, 36, 36, 36, 36, 36, 36, - 36, 36, 63, 64, 36, 36, 36, 36, 36, 36, 36, 36, 63, 36, 36, 36, - 43, 74, 75, 76, 74, 75, 75, 75, 75, 74, 75, 75, 76, 43, 43, 43, - 61, 61, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 27, 27, 61, - 36, 36, 36, 63, 74, 76, 43, 2, 36, 36, 79, 74, 43, 43, 43, 43, - 74, 74, 76, 43, 43, 43, 74, 75, 75, 76, 43, 43, 43, 43, 43, 43, - 2, 2, 2, 77, 2, 2, 2, 2, 43, 43, 43, 43, 43, 43, 43, 96, - 43, 43, 78, 36, 36, 36, 36, 36, 36, 36, 74, 43, 43, 74, 74, 75, - 75, 74, 78, 36, 36, 36, 36, 36, 86, 61, 61, 61, 61, 47, 43, 43, - 43, 43, 61, 61, 61, 61, 61, 61, 43, 78, 36, 36, 36, 36, 36, 36, - 79, 43, 43, 75, 43, 76, 43, 36, 36, 36, 36, 74, 43, 75, 76, 76, - 43, 75, 75, 75, 75, 75, 2, 2, 36, 36, 75, 75, 75, 75, 43, 43, - 43, 43, 75, 43, 43, 57, 2, 2, 7, 7, 7, 7, 7, 7, 83, 36, - 36, 36, 36, 36, 40, 40, 40, 2, 43, 57, 43, 43, 43, 43, 43, 43, - 74, 43, 43, 43, 64, 36, 63, 36, 36, 36, 64, 79, 43, 36, 36, 36, - 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 44, 16, 16, - 16, 16, 16, 16, 44, 16, 16, 16, 16, 16, 16, 16, 16, 97, 40, 40, - 32, 32, 32, 16, 16, 16, 16, 32, 16, 16, 16, 16, 11, 11, 11, 11, - 16, 16, 16, 16, 34, 11, 11, 11, 16, 16, 16, 16, 98, 98, 98, 98, - 16, 16, 16, 16, 11, 11, 99,100, 41, 16, 16, 16, 11, 11, 99, 41, - 16, 16, 16, 16, 11, 11,101, 41,102,102,102,102,102,103, 59, 59, - 51, 51, 51, 2,104,105,104,105, 2, 2, 2, 2,106, 59, 59,107, - 2, 2, 2, 2,108,109, 2,110,111, 2,112,113, 2, 2, 2, 2, - 2, 9,111, 2, 2, 2, 2,114, 59, 59, 59, 59, 59, 59, 59, 59, - 115, 40, 27, 27, 27, 8,112,116, 27, 27, 27, 27, 27, 8,112, 91, - 20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,117, 48, - 96, 48, 96, 43, 43, 43, 43, 43, 61,118, 61,119, 61, 34, 11, 16, - 11, 32,119, 61, 46, 11, 11, 61, 61, 61,118,118,118, 11, 11,120, - 11, 11, 35, 36, 39, 61, 16, 11, 8, 8, 46, 16, 16, 26, 61,121, - 92, 92, 92, 92, 92, 92, 92, 92, 92,122,123, 92,124, 61, 61, 61, - 8, 8,125, 61, 61, 8, 61, 61,125, 26, 61,125, 61, 61, 61,125, - 61, 61, 61, 61, 61, 61, 61, 8, 61,125,125, 61, 61, 61, 61, 61, - 61, 61, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 61, 61, 61, 61, 4, 4, 61, 61, 8, 61, 61, 61,126,127, 61, 61, - 61, 61, 61, 61, 61, 61,125, 61, 61, 61, 61, 61, 61, 26, 8, 8, - 8, 8, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, - 8, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 27, 61, 61, - 61, 61, 61, 61, 61, 27, 27, 27, 61, 61, 61, 26, 61, 61, 61, 61, - 26, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, - 61, 61, 61, 61, 61, 61, 61, 26, 61, 61, 61, 61, 4, 4, 4, 4, - 4, 4, 4, 27, 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, - 8, 8,112,128, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, - 8,112,129,129,129,129,129,129,129,129,129,129,128, 8, 8, 8, - 8, 8, 8, 8, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, - 8, 8,125, 26, 8, 8,125, 61, 32, 11, 32, 34, 34, 34, 34, 11, - 32, 32, 34, 16, 16, 16, 40, 11, 32, 32,121, 61, 61,119, 34,130, - 43, 32, 16, 16, 50, 2, 87, 2, 36, 36, 36, 36, 36, 36, 36, 95, - 2, 2, 2, 2, 2, 2, 2, 56, 2,104,104, 2,108,109,104, 2, - 2, 2, 2, 6, 2, 94,104, 2,104, 4, 4, 4, 4, 2, 2, 77, - 2, 2, 2, 2, 2, 51, 2, 2, 94,131, 2, 2, 2, 2, 2, 2, - 61, 2, 2, 2, 2, 2, 2, 2, 1, 2,132,133, 4, 4, 4, 4, - 4, 61, 4, 4, 4, 4,134, 91,135, 92, 92, 92, 92, 43, 43, 75, - 136, 40, 40, 61, 92,137, 58, 61, 71, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 63,138,139, 62, 36, 36, 36, 36, 36, 58, 40, 62, - 61, 27, 27, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 61, 61, 61, - 61, 61, 61, 61, 27, 27, 27, 27,140, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 95, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,141, 2, - 32, 32, 32, 32, 32, 32, 32, 63, 48,142, 43, 43, 43, 43, 43, 77, - 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36, 92, 92, 92, 92, 92, - 43, 2, 2, 2, 2, 2, 2, 2, 41, 41, 41,139, 40, 40, 40, 40, - 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, - 44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,143, 34, 35, - 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, - 11, 11, 32, 32, 32, 32, 32, 32, 16, 32, 11, 11, 34, 16, 16, 16, - 16, 16, 34, 35, 40, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36, - 36, 79, 76, 74, 61, 61, 43, 43, 27, 27, 27, 61,144, 61, 61, 61, - 36, 36, 2, 2, 2, 2, 2, 2, 75, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 75, 75, 75, 75, 75, 75, 75, 75, 43, 43, 43, 43, 43, 2, - 43, 36, 36, 36, 2, 65, 65, 63, 36, 36, 36, 43, 43, 43, 43, 2, - 36, 36, 36, 63, 43, 43, 43, 43, 43, 75, 75, 75, 75, 75, 75,145, - 36, 63, 75, 43, 43, 75, 43, 75,145, 2, 2, 2, 2, 2, 2, 77, - 7, 7, 7, 7, 7, 7, 7, 2, 36, 36, 63, 62, 36, 36, 36, 36, - 36, 36, 36, 36, 63, 43, 43, 74, 76, 74, 76, 43, 43, 43, 43, 43, - 36, 63, 36, 36, 36, 36, 74, 75, 7, 7, 7, 7, 7, 7, 2, 2, - 62, 36, 36, 70, 61, 79, 74, 36, 64, 43, 64, 63, 64, 36, 36, 43, - 36, 36, 36, 36, 36, 36, 95, 2, 36, 36, 36, 36, 36, 79, 43, 75, - 2, 95,146, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16,100, 40, 40, - 16, 16, 16, 16, 97, 41, 41, 41, 36, 79, 76, 75, 74,145, 76, 43, - 147,147,147,147,147,147,147,147,148,148,148,148,148,148,148,148, - 16, 16, 16, 16, 16, 16, 35, 64, 36, 36, 36, 36,149, 36, 36, 36, - 36, 41, 41, 41, 41, 41, 41, 41, 41,150, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36,129,151,151,151,151,151,151,151,151, - 36, 36, 36, 36, 36, 36,144, 61, 2, 2, 2,152,113, 2, 2, 2, - 6,153,154,129,129,129,129,129,129,129,113,152,113, 2,110,155, - 2, 2, 2, 2,134,129,129,113, 2,156, 8, 8, 60, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36,157, 2, 2, 3, 2, 4, 5, 6, 2, - 16, 16, 16, 16, 16, 17, 18,112,113, 4, 2, 36, 36, 36, 36, 36, - 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40, - 20,158, 53, 20, 26, 8,125, 61, 61, 61, 61, 61,159, 59, 61, 61, - 2, 2, 2, 87, 27, 27, 27, 27, 27, 27, 27, 81, 61, 61, 61, 61, - 92, 92,124, 27, 81, 61, 61, 61, 61, 61, 61, 61, 61, 27, 61, 61, - 61, 61, 61, 61, 61, 61, 47, 43,160,160,160,160,160,160,160,160, - 161, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 84, 36, - 133, 36, 36, 36, 36, 92, 92, 92, 36, 36, 36, 36, 36, 36, 36, 58, - 162, 92, 92, 92, 92, 92, 92, 92, 36, 36, 36, 58, 27, 27, 27, 27, - 36, 36, 36, 70,140, 27, 27, 27, 36, 36, 36,163, 27, 27, 27, 27, - 36, 36, 36, 36, 36,163, 27, 27, 36, 36, 36, 27, 27, 27, 27, 30, - 36, 36, 36, 36, 36, 36, 27, 36, 63, 43, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,163, 30, - 36, 36, 36, 36, 36, 36,163, 27, 36, 36, 36, 36, 71, 36, 36, 36, - 36, 36, 63, 43, 43,161, 27, 27, 36, 36, 36, 36, 58, 2, 2, 2, - 36, 36, 36, 36, 27, 27, 27, 27, 16, 16, 16, 16, 16, 27, 27, 27, - 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 63,164, 51, - 27, 27, 27, 84, 36, 36, 36, 36,161, 27, 30, 2, 2, 2, 2, 2, - 36, 36,163, 27, 27, 27, 27, 27, 76, 78, 36, 36, 36, 36, 36, 36, - 43, 43, 43, 57, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,165, - 75, 76, 43, 74, 76, 57, 72, 2, 2, 2, 2, 2, 2, 2, 72, 59, - 36, 36, 36, 63, 43, 43, 76, 43, 43, 43, 43, 7, 7, 7, 7, 7, - 2, 2, 79, 78, 36, 36, 36, 36, 36, 63, 2, 36, 36, 36, 36, 36, - 36, 79, 75, 43, 43, 43, 43, 74, 78, 36, 58, 2, 56, 43, 57, 76, - 7, 7, 7, 7, 7, 58, 58, 2, 87, 27, 27, 27, 27, 27, 27, 27, - 36, 36, 36, 36, 36, 36, 75, 76, 43, 75, 74, 43, 2, 2, 2, 43, - 36, 36, 36, 36, 36, 36, 36, 63, 74, 75, 75, 75, 75, 75, 75, 75, - 36, 36, 36, 79, 75, 75, 78, 36, 36, 75, 75, 43, 43, 43, 43, 43, - 36, 36, 79, 75, 43, 43, 43, 43, 75, 43, 74, 64, 36, 58, 2, 2, - 7, 7, 7, 7, 7, 2, 2, 64, 75, 76, 43, 43, 74, 74, 75, 76, - 74, 43, 36, 65, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 79, - 75, 43, 43, 43, 75, 75, 43, 76, 57, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 36, 36, 43, 43, 75, 76, 43, 43, 43, 74, 76, 76, - 57, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 63, 76, 75, - 43, 43, 43, 76, 36, 36, 36, 36, 75, 43, 43, 76, 43, 43, 43, 43, - 7, 7, 7, 7, 7, 27, 2, 86, 43, 43, 43, 43, 76, 57, 2, 2, - 27, 27, 27, 27, 27, 27, 27, 84, 75, 75, 75, 75, 75, 76, 74, 64, - 78, 76, 2, 2, 2, 2, 2, 2, 79, 75, 43, 43, 43, 43, 75, 75, - 64, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 63, 43, 43, 43, 43, 64, 36, 36, 36, 63, 43, 43, 74, 63, 43, 57, - 2, 2, 2, 56, 43, 43, 43, 43, 63, 43, 43, 74, 76, 43, 36, 36, - 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 74, 43, 2, 65, 2, - 43, 43, 43, 43, 43, 43, 43, 76, 58, 2, 2, 2, 2, 2, 2, 2, - 2, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 74, 43, 43, 43, - 74, 43, 76, 43, 43, 43, 43, 43, 43, 43, 43, 63, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 75, 75, 75, 43, 74, 76, 76, 36, 36, 36, 36, - 36, 63, 74,145, 2, 2, 2, 2, 27, 27, 81, 61, 61, 61, 53, 20, - 144, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 21, - 43, 43, 57, 2, 2, 2, 2, 2, 43, 43, 43, 57, 2, 2, 61, 61, - 40, 40, 86, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7,166, 27, 27, - 27, 84, 36, 36, 36, 36, 36, 36, 27, 27, 27, 30, 2, 2, 2, 2, - 79, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, - 43, 67, 40, 40, 40, 40, 40, 40, 40, 77, 43, 43, 43, 43, 43, 43, - 36, 36, 36, 36, 36, 36, 47, 57, 61, 61,167, 76, 43, 61,167, 75, - 75,168, 59, 59, 59, 73, 43, 43, 43, 69, 47, 43, 43, 43, 61, 61, - 61, 61, 61, 61, 61, 43, 43, 61, 61, 43, 69, 61, 61, 61, 61, 61, - 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, - 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, - 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, - 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, - 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 16, 7, - 43, 43, 43, 69, 61, 47, 43, 43, 43, 43, 43, 43, 43, 43, 69, 61, - 61, 61, 47, 61, 61, 61, 61, 61, 61, 61, 69, 21, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 56, 43, 43, 43, 43, 43, 67, 40, 40, 40, 40, - 7, 7, 7, 7, 7, 7, 7, 70, 36, 36, 36, 36, 36, 36, 43, 43, - 7, 7, 7, 7, 7, 7, 7,169, 16, 16, 43, 43, 43, 67, 40, 40, - 27, 27, 27, 27, 27, 27,140, 27,170, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27,140, 27, 27, 27, 27, 27, 27, 81, 61, - 61, 61, 61, 61, 61, 25, 41, 41, 0, 0, 29, 21, 21, 21, 23, 21, - 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, - 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, - 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, - 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, - 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, - 6, 5, 9, 21, 25, 9, 26, 12, 11, 11, 9, 6, 5, 21, 17, 17, - 17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21, 7, 21, 1, 1, - 21, 23, 26, 26, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, - 6, 12, 12, 26, 7, 26, 26, 7, 21, 1, 1, 12, 12, 10, 10, 10, - 10, 12, 21, 6, 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, - 15, 7, 12, 23, 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, - 14, 14, 14, 7, 17, 21, 7, 6, 11, 12, 5, 6, 8, 8, 8, 24, - 5, 24, 9, 24, 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, - 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, - 18, 6, 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, - 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 22, 21, - 26, 6, 7, 14, 17, 22, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, - 26, 15, 6, 21, 11, 21, 24, 9, 23, 26, 10, 21, 6, 10, 4, 4, - 3, 3, 7, 25, 24, 7, 22, 22, 21, 22, 17, 16, 16, 22, 16, 16, - 25, 17, 7, 1, 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, 7, 15, - 12, 17, 13, 12, 13, 15, 26, 10, 10, 1, 13, 23, 23, 15, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, - 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, - 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 34, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, - 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, - 9, 10, 0, 11, 12, 13, 0, 14, 15, 16, 15, 17, 15, 18, 15, 18, - 15, 18, 0, 18, 0, 19, 15, 18, 20, 18, 0, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 0, 0, 0, 0, 0, 0, 33, 0, 0, 34, 0, 0, 35, 0, - 36, 0, 0, 0, 37, 38, 39, 40, 41, 42, 43, 44, 45, 0, 0, 46, - 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 49, - 0, 50, 0, 51, 52, 0, 53, 0, 0, 0, 0, 0, 0, 54, 55, 56, - 0, 0, 0, 0, 57, 0, 0, 58, 59, 60, 61, 62, 0, 0, 63, 64, - 0, 0, 0, 65, 0, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 69, - 0, 70, 0, 0, 71, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, - 73, 0, 0, 0, 0, 0, 74, 0, 0, 75, 0, 0, 0, 76, 77, 0, - 78, 61, 0, 79, 80, 0, 0, 81, 82, 83, 0, 0, 0, 84, 0, 85, - 0, 0, 50, 86, 50, 0, 87, 0, 88, 0, 0, 0, 77, 0, 0, 0, - 89, 90, 0, 91, 92, 93, 94, 0, 0, 0, 0, 0, 50, 0, 0, 0, - 0, 95, 96, 0, 0, 0, 0, 97, 98, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 99, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,101,102, 0, 0,103, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, - 98, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0,106, - 0,107, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, - 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, - 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, - 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 28, 29, - 0, 0, 0, 30, 31, 32, 0, 0, 31, 0, 0, 33, 31, 0, 0, 0, - 31, 34, 0, 0, 0, 0, 0, 35, 36, 0, 0, 0, 0, 0, 0, 37, - 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 41, 0, 42, - 0, 0, 0, 43, 44, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 46, - 47, 0, 0, 0, 0, 48, 0, 0, 0, 49, 0, 49, 0, 50, 0, 0, - 0, 0, 51, 0, 0, 0, 0, 52, 0, 53, 0, 0, 0, 0, 54, 55, - 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 0, 58, 49, 0, 59, 60, - 0, 0, 61, 0, 0, 0, 62, 63, 0, 0, 0, 64, 0, 65, 66, 67, - 68, 69, 1, 70, 0, 71, 72, 73, 0, 0, 74, 75, 0, 0, 0, 76, - 0, 0, 1, 1, 0, 0, 77, 0, 0, 78, 0, 0, 0, 0, 74, 79, - 0, 80, 0, 0, 0, 0, 0, 75, 81, 0, 82, 0, 49, 0, 1, 75, - 0, 0, 83, 0, 0, 84, 0, 0, 0, 0, 0, 85, 54, 0, 0, 0, - 0, 0, 0, 86, 87, 0, 0, 81, 0, 0, 31, 0, 0, 88, 0, 0, - 0, 0, 89, 0, 0, 0, 0, 47, 0, 0, 57, 0, 0, 0, 0, 90, - 91, 0, 0, 92, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 95, 0, - 96, 57, 0, 0, 81, 0, 0, 76, 0, 0, 0, 97, 98, 0, 0, 99, - 100, 0, 0, 0, 0, 0, 0,101, 0, 0,102, 0, 0, 0, 0,103, - 31, 0,104,105,106, 33, 0, 0,107, 0, 0, 0,108, 0, 0, 0, - 0, 0, 0,109, 0, 0,110, 0, 0, 0, 0,111, 85, 0, 0, 0, - 0, 0, 54, 0, 0, 0, 0, 49,112, 0, 0, 0, 0,113, 0, 0, - 114, 0, 0, 0, 0,112, 0, 0, 0, 0, 0,115, 0, 0, 0,116, - 0, 0, 0,117, 0,118, 0, 0, 0, 0,119,120,121, 0,122, 0, - 123, 0, 0, 0,124,125,126, 0, 0, 0,127, 0, 0,128, 0, 0, - 129, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, - 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, - 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, - 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, - 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, - 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, - 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, - 52, 1, 1, 1, 53, 21, 43, 54, 55, 21, 35, 1, 0, 0, 0, 56, - 0, 0, 0, 57, 58, 59, 0, 0, 0, 0, 0, 60, 0, 61, 0, 0, - 0, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, - 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 69, 0, 0, 70, 71, 0, - 72, 73, 74, 75, 76, 77, 0, 0, 0, 78, 0, 0, 0, 79, 80, 0, - 0, 0, 0, 47, 0, 0, 0, 49, 0, 63, 0, 0, 64, 0, 0, 81, - 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, 63, 0, 0, 0, - 0, 49, 1, 85, 1, 54, 15, 86, 84, 0, 0, 0, 0, 56, 0, 0, - 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 87, 0, 0, 88, 0, 0, - 87, 0, 0, 0, 0, 79, 0, 0, 89, 9, 12, 4, 90, 8, 91, 47, - 0, 59, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, - 97, 1, 98, 59, 81, 99,100, 4, 59, 0, 0, 0, 0, 0, 0, 19, - 50, 0, 0, 0, 0, 0, 0, 62, 0, 0,101,102, 0, 0,103, 0, - 0, 1, 1, 50, 0, 0, 0, 38, 0, 64, 0, 0, 0, 0, 0, 63, - 0, 0, 52, 69, 62, 0, 0, 0, 79, 0, 0, 0,104,105, 59, 38, - 81, 0, 0, 0, 0, 0, 0,106, 1, 14, 4, 12, 0, 38, 89, 0, - 0, 0, 0,107, 0, 0,108, 62, 0,109, 0, 0, 0, 1, 0, 0, - 0, 0, 19, 59, 0,110, 14, 54, 0, 0,111, 0, 89, 0, 0, 0, - 62, 63, 0, 0, 63, 0, 88, 0, 0,111, 0, 0, 0, 0,112, 0, - 0, 0, 79, 56, 0, 38, 1, 59, 1, 59, 0, 0, 64, 88, 0, 0, - 113, 0, 0, 0, 56, 0, 0, 0, 0,113, 0, 0, 0, 0, 62, 0, - 0, 0, 0, 80, 0, 62, 0, 0, 0, 0, 57, 0, 88,114, 0, 0, - 8, 91, 0, 0, 1, 89, 0, 0,115, 0, 0, 0, 0, 0, 0,116, - 0,117,118,119,120, 0, 52, 4,121, 49, 23, 0, 0, 0, 38, 50, - 38, 59, 0, 0, 1, 89, 1, 1, 1, 1, 39, 1, 48,104, 89, 0, - 0, 0, 0, 1, 4,121, 0, 0, 0, 1,122, 0, 0, 0, 0, 0, - 230,230,230,230,230,232,220,220,220,220,232,216,220,220,220,220, - 220,202,202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, - 1,220,220,220,220,230,230,230,230,240,230,220,220,220,230,230, - 230,220,220, 0,230,230,230,220,220,220,220,230,232,220,220,230, - 233,234,234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230, - 230,230,220,230,230,230,222,220,230,230,220,220,230,222,228,230, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, - 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, - 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, - 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230, - 230,220, 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220, - 220,230,220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, - 0,230,230,230,230,230, 0, 0, 0,220,220,220, 0, 0, 0,220, - 230,230, 0,220,230,220,220,220, 27, 28, 29,230, 7, 0, 0, 0, - 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, - 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, - 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, - 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, - 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, - 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, - 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0, - 230, 0, 0,220,230,220, 0,220, 0, 0, 9, 9, 0, 0, 7, 0, - 230,230,230, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220, - 202,230,230,230,230,230,232,228,228,220, 0,230,233,220,230,220, - 230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, - 0, 0,218,228,232,222,224,224, 0, 8, 8, 0,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 9, 7, 0, 0, 7, 9, 0, - 0, 0, 9, 7, 9, 9, 0, 0, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, - 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, - 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, - 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, - 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, - 23, 3, 3, 3, 3, 3, 3, 3, 24, 3, 3, 3, 3, 3, 3, 3, - 3, 25, 3, 3, 26, 27, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, - 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, - 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, - 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, - 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, - 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, - 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, - 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, - 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, - 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, - 6, 55, 0, 14, 19, 1, 0, 0, 0, 19, 56, 31, 0, 0, 0, 0, - 0, 0, 0, 57, 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, - 0, 0, 0, 58, 59, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, - 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, - 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, - 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, - 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, - 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, - 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, - 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, - 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, - 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, - 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, - 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, - 0, 0, 0, 45, 8, 9, 1, 0, 1, 0, 1, 1, 8, 21, 21, 9, - 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, - 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, - 11, 11, 11, 12, 12, 12, 12, 13, 14, 15, 16, 17, 18, 12, 19, 12, - 20, 12, 12, 12, 12, 21, 22, 22, 22, 23, 12, 12, 12, 12, 24, 25, - 12, 12, 26, 27, 28, 29, 30, 31, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 32, 12, 33, 7, 7, 34, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 35, 0, 0, 1, 2, 2, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, - 33, 34, 35, 35, 35, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 2, 2, 51, 51, 52, 53, 54, 55, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 56, 56, 56, 56, - 56, 56, 58, 59, 60, 61, 56, 62, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 56, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 71, 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 73, 74, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, - 88, 89, 89, 89, 90, 89, 91, 92, 93, 94, 95, 95, 96, 97, 87, 98, - 99,100,101,102,103, 87,104,104,104, 87,105,106,107,108,109,110, - 111,112,113,114,115, 87, 89,116,117,118,119,120,121,122,123,124, - 125, 87,126,127, 87,128,129,130,131, 87,132,133,134,135,136,137, - 87, 87,138,139,140,141, 87,142, 87,143,144,144,144,144,144,144, - 144,144,144,144,144, 87, 87, 87, 87, 87,145,145,145,145,145,145, - 145,145,145, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87,146,146,146,146,146, 87, 87, 87,147,147,147,147,148,149, - 150,150, 87, 87, 87, 87,151,151,152,153,154,154,154,154,154,154, - 154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, - 155,155,155,155,154, 87, 87, 87, 87, 87,156,157,158,159,159,159, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87,160,161, 87, 87, 87, 87, 87, 87, 56, 56,162,163, 51, 56, - 56, 87, 56, 56, 56, 56, 56, 56, 56, 56,164,164,164,164,164,164, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,165, 87,166, 87, 87,167, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,168,168,169, 87, 87, 87, - 87, 87, 56, 56, 56, 87, 89, 89, 87, 87, 56, 56, 56, 56,170, 87, - 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, - 62, 62, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 62, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, - 62, 87, 87, 87, 87, 87, 87, 87, 87, 87, 56, 87,171,171, 0, 1, - 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 1, 2, - 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, - 8, 9, 10, 11, 11, 11, 11, 11, 12, 11, 13, 13, 13, 13, 13, 13, - 13, 13, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 16, 16, - 16, 16, 16, 17, 18, 18, 18, 18, 18, 18, 19, 20, 21, 21, 22, 23, - 21, 24, 21, 21, 21, 21, 21, 25, 21, 21, 26, 26, 26, 26, 26, 21, - 21, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, - 26, 26, 21, 21, 21, 21, 21, 21, 31, 21, 32, 32, 32, 32, 32, 33, - 34, 32, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, - 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, - 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, - 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, - 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, - 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 52, 52, 52, 52, 52, - 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, - 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 57, 57, 57, 57, - 58, 57, 59, 59, 60, 61, 62, 62, 63, 63, 64, 64, 64, 64, 64, 64, - 64, 64, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 55, 55, 55, - 55, 55, 67, 67, 67, 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, - 64, 64, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 8, 8, 8, - 8, 8, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, - 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 13, 50, 50, 50, 73, 77, - 78, 79, 4, 4, 80, 4, 4, 81, 82, 83, 4, 4, 4, 84, 8, 8, - 8, 8, 11, 11, 11, 11, 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, - 0, 86, 0, 4, 0, 0, 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, - 4, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, - 4, 4, 92, 92, 92, 92, 92, 92, 92, 92, 50, 50, 50, 93, 93, 93, - 93, 93, 53, 53, 53, 53, 53, 53, 13, 13, 94, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, - 99, 99, 99,100,101,102,102,102,102,103,104,104,104,105, 52, 52, - 52, 52, 52, 0,104,104, 0, 0, 0,102, 52, 52, 0, 0, 0, 0, - 52,106, 0, 0, 0, 0, 0,102,102,107,102,102,102,102,102,108, - 0, 0, 94, 94, 94, 94, 0, 0, 0, 0,109,109,109,109,109,109, - 109,109,109,109,109,109,109,110,110,110,111,111,111,111,111,111, - 111,111,111,111,111,111, 13, 13, 13, 13, 13, 13,112,112,112,112, - 112,112, 0, 0,113, 4, 4, 4, 4, 4,114, 4, 4, 4, 4, 4, - 4, 4,115,115,115, 0,116,116,116,116,117,117,117,117,117,117, - 32, 32,118,118,119,120,120,120, 52, 52,121,121,121,121,122,121, - 49, 49,123,123,123,123,123,123, 49, 49,124,124,124,124,124,124, - 125,125, 53, 53, 53, 4, 4,126,127, 54, 54, 54, 54, 54,125,125, - 125,125,128,128,128,128,128,128,128,128, 4,129, 18, 18, 18, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,130, 0, 21, - 21, 21, 8, 0,131, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, - 21,132, 0, 0, 1, 2, 1, 2,133,101,102,134, 52, 52, 52, 52, - 0, 0,135,135,135,135,135,135,135,135, 0, 0, 0, 0, 11, 11, - 11, 11, 11, 0, 11, 11, 11, 0, 0,136,137,137,138,138,138,138, - 139, 0,140,140,140,141,141,142,142,142,143,143,144,144,144,144, - 144,144,145,145,145,145,145,146,146,146,147,147,147,148,148,148, - 148,148,149,149,149,150,150,150,150,150,151,151,151,151,151,151, - 151,151,152,152,152,152,153,153,154,154,155,155,155,155,155,155, - 156,156,157,157,158,158,158,158,158,158,159,159,160,160,160,160, - 160,160,161,161,161,161,161,161,162,162,163,163,163,163,164,164, - 164,164,165,165,165,165,166,166,167,167,168,168,168,168,168,168, - 168,168,169,169,169,169,169,169,169,169,170,170,170,170,170,170, - 170,170,171,171,171,171,171,171,171,171,172,172,172,172,172,172, - 172,172,173,173,173,174,174,174,174,174,175,175,175,175,175,175, - 176,176,177,177,177,177,177,177,177,177,178,178,178,178,178,179, - 179,179,180,180,180,180,180,181,181,181,182,182,182,182,182,182, - 183, 43,184,184,184,184,184,184,184,184,185,185,185,186,186,186, - 186,186,187,187,187,188,187,187,187,187,189,189,189,189,189,189, - 189,189,190,190,190,190,190,190,190,190,191,191,191,191,191,191, - 191,191,192,192,192,192,192,192, 66, 66,193,193,193,193,193,193, - 193,193,194,194,194,194,194,194,194,194,195,195,195,195,195,195, - 195,195,196,196,196,196,196,196,196,196,197,197,197,197,197,197, - 197,197,198,198,198,198,198,198,198,198,199,199,199,199,199,200, - 200,200,200,200,200,200,201,201,201,201,202,202,202,202,202,202, - 202,203,203,203,203,203,203,203,203,203,204,204,204,204,204,204, - 205,205,205,205,205,205,205,205,205,205,206,206,206,206,206,206, - 206,206,110,110,110,110, 39, 39, 39, 39,207,207,207,207,207,207, - 207,207,208,208,208,208,208,208,208,208,209,209,209,209,209,209, - 209,209,112,112,112,112,112,112,112,112,112,112,112,112,210,210, - 210,210,211,211,211,211,211,211,211,211,212,212,212,212,212,212, - 212,212,213,213,213,213,213,213,213,213,214,214,214,214,214,214, - 214,214,214,214,214,214,214,214,215, 94,216,216,216,216,216,216, - 216,216,217,217,217,217,217,217,217,217,218, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 219,220,220,220,220,220,220,220,220,220,221,221,221,221,221,221, - 221,221,221,221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 222,223,224, 0,225, 0, 0, 0, 0, 0,226,226,226,226,226,226, - 226,226, 91, 91, 91, 91, 91, 91, 91, 91,227,227,227,227,227,227, - 227,227,228,228,228,228,228,228,228,228,229,229,229,229,229,229, - 229,229,230,230,230,230,230,230,230,230,231, 0, 0, 0, 0, 0, - 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, - 2, 2, 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, - 2, 2, 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, - 8, 10, 8, 11, 8, 8, 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, - 14, 14, 14, 15, 14, 14, 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, - 19, 19, 19, 19, 19, 19, 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, - 20, 20, 22, 20, 24, 7, 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, - 20, 21, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, - 30, 30, 31, 31, 31, 31, 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, - 33, 33, 33, 36, 33, 33, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, - 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, - 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, - 46, 47, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, - 52, 52, 53, 53, 53, 53, 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, - 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, - 60, 60, 60, 60, 61, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, - 0, 0, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, - 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, - 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, - 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, - 7, 7, 83, 7, 84, 85, 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, - 2, 89, 90, 87, 91, 2, 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, - 0, 86, 1, 0, 0, 94, 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, - 0, 4, 97, 97, 97, 97, 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, - 99, 99,100,100,100,100, 0,101, 0, 0,102,100,103,104, 0, 0, - 100, 0,105,106,106,106,106,106,106,106,106,106,107,105,108,109, - 109,109,109,109,109,109,109,109,110,108,111,111,111,111,112, 55, - 55, 55, 55, 55, 55,113,109,109,109,110,109,109, 0, 0,114,114, - 114,114,115,115,115,115,116,116,116,116,117,117,117,117, 96, 2, - 2, 2, 2, 2, 94, 2,118,118,118,118,119,119,119,119,120,120, - 120,120,121,121,121,121,121,121,121,122,123,123,123,123,124,124, - 124,124,124,124,124,125,126,126,126,126,127,127,127,127,128,128, - 128,128, 2, 2, 3, 2, 2,129,130, 0,131,131,131,131,132, 17, - 17, 18, 20, 20, 20,133, 7, 7, 7,134, 20, 20, 20, 23, 0,135, - 109,109,109,109,109,136,137,137,137,137, 0, 0, 0,138,139,139, - 139,139,140,140,140,140, 84, 0, 0, 0,141,141,141,141,142,142, - 142,142,143,143,143,143,144,144,144,144,145,145,145,145,146,146, - 146,146,147,147,147,147,148,148,148,148,149,149,149,149,150,150, - 150,150,151,151,151,151,152,152,152,152,153,153,153,153,154,154, - 154,154,155,155,155,155,156,156,156,156,157,157,157,157,158,158, - 158,158,159,159,159,159,160,160,160,160,161,161,161,161,162,162, - 162,162,163,163,163,163,164,164,164,164,165,165,165,165,166,166, - 166,166,167,167,167,167,168,168,168,168,169,169,169,169,170,170, - 170,170,171,171,171,171,172,172,172,172,173,173,173,173,174,174, - 174,174,175,175,175,175,176,176,176,176,177,177,177,177,178,178, - 178,178,179,179,179,179,180,180,180,180,181,181,181,181,182,182, - 182,182,183,183,183,183,184, 45, 45, 45,185,185,185,185,186,186, - 186,186,187,187,187,187,188,188,188,188,188,188,189,188,190,190, - 190,190,191,191,191,191,192,192,192,192,193,193,193,193,194,194, - 194,194,195,195,195,195,196,196,196,196,197,197,197,197,198,198, - 198,198,199,199,199,199,200,200,200,200,201,201,201,201,202,202, - 202,202,203,203,203,203,204,204,204,204,205,205,205,205,206,206, - 206,206,207,207,207,207,208,208,208,208,209,209,209,209,210,210, - 210,210,211,211,211,211,212,212,212,212,213,213,213,213,214,214, - 214,214,215,215,215,215,216,217,217,217,218,218,218,218,217,217, - 217,217,219,106,106,106,106,109,109,109,220,220,220,220,221,221, - 221,221, 0,222, 86, 0, 0, 0,222, 7, 82,138, 7, 0, 0, 0, - 223, 86,224,224,224,224,225,225,225,225,226,226,226,226,227,227, - 227,227,228,228,228,228,229, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, - 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, - 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, - 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, - 4, 4, 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, - 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, - 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, - 64, 64, 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, - 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, - 5, 5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, - 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, - 36, 36, 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, - 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, - 35, 0, 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, - 0, 0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, - 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, - 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, - 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, - 73, 73, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, - 0, 0, 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, - 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, - 19, 9, 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, - 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, - 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, - 12, 0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, - 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, - 84, 0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, - 19, 19, 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, - 0, 0, 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, - 49, 49, 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, - 42, 42, 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, - 59, 59, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135, - 135,135,106,106,106,106,104,104,104,104,110,110,110,110, 47, 47, - 47, 47, 81, 81, 81, 81,120,120,120,120,116,116,116,116,128,128, - 128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, - 97, 97, 57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117,112,112, - 112,112, 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122, - 122,122, 89, 89, 89, 89,130,130,130,130,144,144,144,144,156,156, - 156,156,147,147,147,147,148,148,148,148,153,153,153,153,149,149, - 149,149, 94, 94, 94, 94, 85, 85, 85, 85,101,101,101,101, 96, 96, - 96, 96,111,111,111,111,100,100,100,100,100, 36, 36, 36,108,108, - 108,108,129,129,129,129,109,109,109,109,107,107,107,107,107,107, - 107, 1,137,137,137,137,124,124,124,124,123,123,123,123,114,114, - 114,114,102,102,102,102,126,126,126,126,142,142,142,142,125,125, - 125,125,154,154,154,154,150,150,150,150,141,141,141,141,140,140, - 140,140,121,121,121,121,133,133,133,133,134,134,134,134,138,138, - 138,138,143,143,143,143,145,145,145,145, 63, 63, 63, 63, 80, 80, - 80, 80,127,127,127,127,115,115,115,115,103,103,103,103,119,119, - 119,119,146,146,146,146, 99, 99, 99, 99,136,139, 0, 0,155,155, - 155,155,136,136,136,136, 17, 15, 15, 15,139,139,139,139,105,105, - 105,105, 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151,151, - 151,151,152,152,152,152,113,113,113,113,132,132,132,132, 15, 0, - 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, + 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, + 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 2, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, + 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, + 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, + 86, 86, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 2, 2, + 2, 2, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 19, 19, 19, 19, + 19, 19, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 2, 2, 2, + 2, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, + 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 2, 2, 2, 0, 0, 2, 2, 2, 2, + 2, 2, 65, 65, 65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 2, 2, + 75, 75, 75, 75, 2, 2, 2, 2, 2, 2, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 74, 12, 12, 12, 12, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, + 84, 84, 33, 33, 33, 33, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, 68, 68, 68, 68, + 2, 2, 68, 68, 2, 2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 2, 2, 2, 2, 2, 2, 2, 2, 92, 92, 92, + 92, 92, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 2, 2, 30, 30, 30, 30, 30, 30, 2, 19, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 9, 19, 19, 19, 19, 0, 0, 2, 2, + 2, 2, 87, 87, 87, 87, 87, 87, 2, 2, 87, 87, 2, 2, 2, 2, + 2, 2, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, + 12, 12, 13, 13, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, + 19, 2, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 14, 14, 14, 14, 14, 2, + 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 3, 3, 3, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, + 2, 3, 1, 1, 1, 1, 1, 1, 6, 6, 0, 0, 0, 2, 0, 0, + 0, 0, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 12, 12, + 12, 12, 2, 2, 12, 12, 12, 2, 2, 2, 2, 0, 0, 0, 0, 0, + 2, 2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 2, 49, 49, 49, 2, 49, 49, + 2, 49, 49, 49, 49, 49, 49, 49, 2, 2, 49, 49, 49, 2, 2, 2, + 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 2, 2, 2, 2, 2, + 2, 2, 0, 0, 0, 0, 0, 1, 2, 2, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, + 0, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 2, 2, 2, 2, 2,118,118,118,118,118,118, + 118,118,118,118,118, 2, 2, 2, 2, 2, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 2, 2, 2, 2, 59, 59, 59, 59, 59, 59, + 2, 2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, 51, 51, 51, 51, + 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 2, 2, 50, 50, 2, 2, 2, 2, 2, 2,135,135,135,135,135,135, + 135,135,135,135,135,135, 2, 2, 2, 2,106,106,106,106,106,106, + 106,106,104,104,104,104,104,104,104,104,104,104,104,104, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2,104,161,161,161,161,161,161, + 161,161,161,161,161, 2,161,161,161,161,161,161,161, 2,161,161, + 2,161,161,161, 2,161,161,161,161,161,161,161, 2,161,161, 2, + 2, 2,110,110,110,110,110,110,110,110,110,110,110,110,110,110, + 110, 2,110,110,110,110,110,110, 2, 2, 19, 19, 19, 19, 19, 19, + 2, 19, 19, 2, 19, 19, 19, 19, 19, 19, 47, 47, 47, 47, 47, 47, + 2, 2, 47, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, + 2, 47, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 2, 81,120,120,120,120,120,120,120,120,116,116,116,116,116,116, + 116,116,116,116,116,116,116,116,116, 2, 2, 2, 2, 2, 2, 2, + 2,116,128,128,128,128,128,128,128,128,128,128,128, 2,128,128, + 2, 2, 2, 2, 2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 98, 98, + 98, 98, 97, 97, 97, 97, 97, 97, 97, 97, 2, 2, 2, 2, 97, 97, + 97, 97, 2, 2, 97, 97, 97, 97, 97, 97, 57, 57, 57, 57, 2, 57, + 57, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, + 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, + 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 88, 88, 88, 88, 88, 88, + 88, 88,117,117,117,117,117,117,117,117,112,112,112,112,112,112, + 112,112,112,112,112,112,112,112,112, 2, 2, 2, 2,112,112,112, + 112,112, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 2, 2, 2, 78, 78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 2, 2, 2, 2, 2,122,122,122,122,122,122, + 122,122,122,122, 2, 2, 2, 2, 2, 2, 2,122,122,122,122, 2, + 2, 2, 2,122,122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 2, 2, 2, 2, 2, 2, 2,130,130,130,130,130,130, + 130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2,130,130,130,130, + 130,130,144,144,144,144,144,144,144,144,144,144, 2, 2, 2, 2, + 2, 2,156,156,156,156,156,156,156,156,156,156, 2,156,156,156, + 2, 2,156,156, 2, 2, 2, 2, 2, 2,147,147,147,147,147,147, + 147,147,148,148,148,148,148,148,148,148,148,148, 2, 2, 2, 2, + 2, 2,158,158,158,158,158,158,158,158,158,158, 2, 2, 2, 2, + 2, 2,153,153,153,153,153,153,153,153,153,153,153,153, 2, 2, + 2, 2,149,149,149,149,149,149,149,149,149,149,149,149,149,149, + 149, 2, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 2, 2, 2, 2, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 2, 2, + 2, 94, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 85, 2, 2,101,101,101,101,101,101, + 101,101,101, 2, 2, 2, 2, 2, 2, 2,101,101, 2, 2, 2, 2, + 2, 2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 2, + 96, 96,111,111,111,111,111,111,111,111,111,111,111,111,111,111, + 111, 2,100,100,100,100,100,100,100,100, 2, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 2, 2, 2,108,108,108,108,108,108, + 108,108,108,108, 2,108,108,108,108,108,108,108,108,108,108,108, + 108, 2,129,129,129,129,129,129,129, 2,129, 2,129,129,129,129, + 2,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, + 2,129,129,129, 2, 2, 2, 2, 2, 2,109,109,109,109,109,109, + 109,109,109,109,109, 2, 2, 2, 2, 2,109,109, 2, 2, 2, 2, + 2, 2,107,107,107,107, 2,107,107,107,107,107,107,107,107, 2, + 2,107,107, 2, 2,107,107,107,107,107,107,107,107,107,107,107, + 107,107,107, 2,107,107,107,107,107,107,107, 2,107,107, 2,107, + 107,107,107,107, 2, 1,107,107,107,107,107, 2, 2,107,107,107, + 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2, 2, 2, 2,107, + 107,107,107,107,107,107, 2, 2,107,107,107,107,107,107,107, 2, + 2, 2,137,137,137,137,137,137,137,137,137,137,137,137, 2,137, + 137,137,137,137, 2, 2, 2, 2, 2, 2,124,124,124,124,124,124, + 124,124,124,124, 2, 2, 2, 2, 2, 2,123,123,123,123,123,123, + 123,123,123,123,123,123,123,123, 2, 2,114,114,114,114,114,114, + 114,114,114,114,114,114,114, 2, 2, 2,114,114, 2, 2, 2, 2, + 2, 2, 32, 32, 32, 32, 32, 2, 2, 2,102,102,102,102,102,102, + 102,102,102,102, 2, 2, 2, 2, 2, 2,126,126,126,126,126,126, + 126,126,126,126,126, 2, 2,126,126,126,126,126,126,126, 2, 2, + 2, 2,126,126,126,126,126,126,126, 2,142,142,142,142,142,142, + 142,142,142,142,142,142, 2, 2, 2, 2,125,125,125,125,125,125, + 125,125,125,125,125, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2,125,154,154,154,154,154,154,154, 2, 2,154, 2, 2,154,154, + 154,154,154,154,154,154, 2,154,154, 2,154,154,154,154,154,154, + 154,154,154,154,154,154,154,154, 2,154,154, 2, 2,154,154,154, + 154,154,154,154, 2, 2, 2, 2, 2, 2,150,150,150,150,150,150, + 150,150, 2, 2,150,150,150,150,150,150,150,150,150,150,150, 2, + 2, 2,141,141,141,141,141,141,141,141,140,140,140,140,140,140, + 140,140,140,140,140, 2, 2, 2, 2, 2,121,121,121,121,121,121, + 121,121,121, 2, 2, 2, 2, 2, 2, 2,133,133,133,133,133,133, + 133,133,133, 2,133,133,133,133,133,133,133,133,133,133,133,133, + 133, 2,133,133,133,133,133,133, 2, 2,133,133,133,133,133, 2, + 2, 2,134,134,134,134,134,134,134,134, 2, 2,134,134,134,134, + 134,134, 2,134,134,134,134,134,134,134,134,134,134,134,134,134, + 134, 2,138,138,138,138,138,138,138, 2,138,138, 2,138,138,138, + 138,138,138,138,138,138,138,138,138,138, 2, 2,138, 2,138,138, + 2,138,138,138, 2, 2, 2, 2, 2, 2,143,143,143,143,143,143, + 2,143,143, 2,143,143,143,143,143,143,143,143,143,143,143,143, + 143,143,143,143,143,143,143,143,143, 2,143,143, 2,143,143,143, + 143,143,143, 2, 2, 2, 2, 2, 2, 2,143,143, 2, 2, 2, 2, + 2, 2,145,145,145,145,145,145,145,145,145, 2, 2, 2, 2, 2, + 2, 2, 86, 2, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 2, 2, 2, 2, 2, 2, 63, 63, 63, 63, 63, 63, + 63, 2, 63, 63, 63, 63, 63, 2, 2, 2, 63, 63, 63, 63, 2, 2, + 2, 2,157,157,157,157,157,157,157,157,157,157,157, 2, 2, 2, + 2, 2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 2, 80, 2, 2, 2, 2, 2, 2, 2,127,127,127,127,127,127, + 127,127,127,127,127,127,127,127,127, 2, 79, 2, 2, 2, 2, 2, + 2, 2,115,115,115,115,115,115,115,115,115,115,115,115,115,115, + 115, 2,115,115, 2, 2, 2, 2,115,115,159,159,159,159,159,159, + 159,159,159,159,159,159,159,159,159, 2,159,159, 2, 2, 2, 2, + 2, 2,103,103,103,103,103,103,103,103,103,103,103,103,103,103, + 2, 2,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 2, 2,119,119, 2,119,119,119,119,119, 2, 2, 2, 2, 2,119, + 119,119,146,146,146,146,146,146,146,146,146,146,146, 2, 2, 2, + 2, 2, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, + 2, 99, 2, 2, 2, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, + 2, 2,136,136,136,136,136,136,136,136,155,155,155,155,155,155, + 155,155,155,155,155,155,155,155, 2, 2,136, 2, 2, 2, 2, 2, + 2, 2, 17, 17, 17, 17, 2, 17, 17, 17, 17, 17, 17, 17, 2, 17, + 17, 2, 17, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 2, 2, 2, + 2, 2, 15, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, + 17, 17,139,139,139,139,139,139,139,139,139,139,139,139, 2, 2, + 2, 2,105,105,105,105,105,105,105,105,105,105,105, 2, 2, 2, + 2, 2,105,105,105,105,105, 2, 2, 2,105, 2, 2, 2, 2, 2, + 2, 2,105,105, 2, 2,105,105,105,105, 1, 1, 1, 1, 1, 1, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 0, 0, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,131,131,131,131,131,131, + 131,131,131,131,131,131, 2, 2, 2, 2, 2, 2, 2,131,131,131, + 131,131, 2,131,131,131,131,131,131,131, 56, 56, 56, 56, 56, 56, + 56, 2, 56, 2, 2, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 2, + 56, 56, 56, 56, 56, 2, 2, 2, 2, 2,151,151,151,151,151,151, + 151,151,151,151,151,151,151, 2, 2, 2,151,151,151,151,151,151, + 2, 2,151,151, 2, 2, 2, 2,151,151,160,160,160,160,160,160, + 160,160,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, + 152,152,152,152, 2, 2, 2, 2, 2,152, 30, 30, 30, 30, 2, 30, + 30, 2,113,113,113,113,113,113,113,113,113,113,113,113,113, 2, + 2,113,113,113,113,113,113,113,113, 2,132,132,132,132,132,132, + 132,132,132,132,132,132, 2, 2, 2, 2,132,132, 2, 2, 2, 2, + 132,132, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, + 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, + 3, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, + 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 2, 3, + 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 15, 0, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 13, 2, 2, 2, 2, 2, + 2, 2, 13, 13, 13, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, + 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -6424,104 +5046,376 @@ _hb_ucd_u8[13344] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[4848] = +_hb_ucd_u16[9200] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, - 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, - 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, - 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, - 47, 64, 65, 66, 47, 67, 47, 47, 47, 47, 47, 47, 47, 68, 69, 32, - 70, 47, 47, 71, 72, 73, 74, 75, 76, 47, 47, 77, 78, 79, 80, 81, - 82, 47, 47, 83, 84, 85, 86, 87, 82, 47, 47, 77, 88, 47, 80, 89, - 90, 47, 47, 91, 92, 93, 80, 94, 95, 47, 47, 96, 97, 98, 99, 100, - 101, 47, 47, 102, 103, 104, 80, 105, 106, 47, 47, 91, 107, 108, 80, 109, - 110, 47, 47, 111, 112, 113, 80, 114, 90, 47, 47, 47, 115, 116, 99, 117, - 47, 47, 47, 118, 119, 120, 66, 66, 47, 47, 47, 121, 122, 123, 47, 47, - 124, 125, 126, 127, 47, 47, 47, 128, 129, 32, 32, 130, 131, 132, 66, 66, - 47, 47, 133, 134, 120, 135, 136, 137, 138, 139, 9, 9, 9, 11, 11, 140, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 141, 142, 143, - 47, 144, 9, 9, 9, 9, 9, 145, 146, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 147, 47, 148, 149, 47, 47, 47, 47, 150, 151, - 47, 152, 47, 153, 47, 152, 47, 152, 47, 47, 47, 154, 155, 156, 157, 143, - 158, 157, 47, 47, 159, 47, 47, 47, 160, 47, 161, 47, 47, 47, 47, 47, - 47, 47, 162, 163, 164, 47, 47, 47, 47, 47, 47, 47, 47, 165, 144, 144, - 47, 166, 47, 47, 47, 167, 168, 169, 157, 157, 170, 171, 32, 32, 32, 32, - 172, 47, 47, 173, 174, 120, 175, 176, 177, 47, 178, 61, 47, 47, 179, 180, - 47, 47, 181, 182, 183, 61, 47, 184, 11, 9, 9, 9, 66, 185, 186, 187, - 11, 11, 188, 27, 27, 27, 189, 190, 11, 191, 27, 27, 32, 32, 32, 32, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 192, 13, 13, 13, 13, 13, 13, - 193, 193, 193, 193, 193, 194, 193, 11, 195, 195, 195, 196, 197, 198, 198, 197, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 27, 208, 208, 208, 209, 210, 32, - 211, 212, 213, 214, 215, 143, 216, 216, 217, 218, 219, 144, 220, 221, 144, 222, - 223, 223, 223, 223, 223, 223, 223, 223, 224, 144, 225, 144, 144, 144, 144, 226, - 144, 227, 223, 228, 144, 229, 230, 144, 144, 144, 144, 144, 144, 144, 143, 143, - 143, 231, 144, 144, 144, 144, 232, 143, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 233, 234, 144, 144, 235, 144, 144, 144, 144, 144, 144, 236, 144, - 144, 144, 144, 144, 144, 144, 237, 238, 143, 239, 144, 144, 240, 223, 241, 223, - 242, 243, 223, 223, 223, 244, 223, 245, 144, 144, 144, 223, 246, 144, 144, 144, - 9, 9, 9, 11, 11, 11, 247, 248, 13, 13, 13, 13, 13, 13, 249, 250, - 11, 11, 11, 47, 47, 47, 251, 252, 47, 47, 47, 47, 47, 47, 32, 32, - 253, 254, 255, 256, 257, 258, 66, 66, 259, 260, 261, 262, 263, 47, 47, 47, - 47, 264, 146, 47, 47, 47, 47, 265, 47, 266, 47, 47, 144, 144, 144, 47, - 144, 144, 267, 144, 268, 269, 144, 144, 267, 144, 144, 269, 144, 144, 144, 144, - 47, 47, 47, 47, 144, 144, 144, 144, 47, 270, 47, 47, 47, 47, 47, 47, - 47, 144, 144, 144, 144, 47, 47, 184, 271, 47, 61, 47, 13, 13, 272, 273, - 13, 274, 47, 47, 47, 47, 275, 276, 31, 277, 278, 279, 13, 13, 13, 280, - 281, 282, 283, 284, 285, 11, 11, 286, 287, 47, 288, 289, 47, 47, 47, 290, - 291, 47, 47, 292, 293, 157, 32, 294, 61, 47, 295, 47, 296, 297, 47, 47, - 70, 47, 47, 298, 299, 300, 301, 61, 47, 47, 302, 303, 304, 305, 47, 306, - 47, 47, 47, 307, 58, 308, 309, 310, 47, 47, 47, 11, 11, 311, 312, 11, - 11, 11, 11, 11, 47, 47, 313, 157, 314, 314, 314, 314, 314, 314, 314, 314, - 315, 315, 315, 315, 315, 315, 315, 315, 11, 316, 317, 47, 47, 47, 47, 47, - 47, 47, 47, 318, 31, 319, 47, 47, 47, 47, 47, 320, 321, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 322, 32, 323, 32, 324, 325, 326, 327, 47, - 47, 47, 47, 47, 47, 47, 47, 328, 329, 2, 3, 4, 5, 330, 331, 332, - 47, 333, 47, 47, 47, 47, 334, 335, 336, 143, 143, 337, 216, 216, 216, 338, - 339, 144, 144, 144, 144, 144, 144, 340, 341, 341, 341, 341, 341, 341, 341, 341, - 47, 47, 47, 47, 47, 47, 342, 143, 47, 47, 343, 47, 344, 47, 47, 60, - 47, 345, 47, 47, 47, 346, 216, 216, 9, 9, 145, 11, 11, 47, 47, 47, - 47, 47, 157, 9, 9, 145, 11, 11, 47, 47, 47, 47, 47, 47, 345, 66, - 47, 47, 47, 47, 47, 347, 47, 348, 47, 47, 349, 143, 143, 143, 47, 350, - 47, 351, 47, 345, 66, 66, 66, 66, 47, 47, 47, 352, 143, 143, 143, 143, - 353, 47, 47, 354, 143, 66, 47, 355, 47, 356, 143, 143, 357, 47, 358, 66, - 47, 47, 47, 359, 47, 360, 47, 360, 47, 359, 142, 143, 143, 143, 143, 143, - 9, 9, 9, 9, 11, 11, 11, 361, 47, 47, 362, 157, 157, 157, 157, 157, - 143, 143, 143, 143, 143, 143, 143, 143, 47, 47, 363, 47, 47, 47, 47, 47, - 47, 356, 364, 47, 60, 365, 66, 66, 47, 47, 47, 47, 366, 143, 47, 47, - 367, 47, 47, 354, 368, 369, 370, 371, 177, 47, 47, 372, 373, 47, 47, 157, - 95, 47, 374, 375, 376, 47, 47, 377, 177, 47, 47, 378, 379, 380, 381, 143, - 47, 47, 382, 383, 32, 32, 32, 32, 47, 47, 359, 47, 47, 384, 169, 157, - 90, 47, 47, 111, 385, 386, 387, 32, 47, 47, 47, 388, 389, 390, 47, 47, - 47, 47, 47, 391, 392, 157, 157, 157, 47, 47, 393, 394, 395, 396, 32, 32, - 47, 47, 47, 397, 398, 157, 66, 66, 47, 47, 399, 400, 157, 157, 157, 157, - 47, 141, 401, 402, 144, 144, 144, 144, 47, 47, 382, 403, 66, 66, 66, 66, - 9, 9, 9, 9, 11, 11, 126, 404, 47, 47, 47, 405, 406, 157, 157, 157, - 47, 47, 47, 47, 47, 407, 408, 409, 410, 47, 47, 411, 412, 413, 47, 47, - 414, 415, 66, 66, 47, 47, 47, 47, 47, 47, 393, 416, 417, 126, 143, 418, - 47, 152, 419, 420, 32, 32, 32, 32, 47, 47, 47, 353, 421, 157, 47, 47, - 422, 423, 157, 157, 157, 157, 157, 157, 47, 47, 47, 47, 47, 47, 47, 424, - 47, 47, 47, 47, 143, 425, 426, 427, 216, 216, 216, 216, 216, 216, 216, 66, - 47, 47, 47, 205, 205, 205, 205, 205, 47, 47, 47, 47, 47, 47, 300, 66, - 47, 47, 47, 47, 47, 47, 47, 428, 47, 47, 47, 429, 430, 431, 432, 47, - 9, 9, 9, 9, 9, 9, 11, 11, 143, 433, 66, 66, 66, 66, 66, 66, - 47, 47, 47, 47, 384, 434, 409, 409, 435, 436, 27, 27, 27, 27, 437, 409, - 47, 438, 205, 205, 205, 205, 205, 205, 144, 144, 144, 144, 144, 144, 439, 440, - 441, 144, 442, 144, 144, 144, 144, 144, 144, 144, 144, 144, 443, 144, 144, 144, - 9, 444, 11, 445, 446, 11, 193, 9, 447, 448, 9, 449, 11, 9, 444, 11, - 445, 446, 11, 193, 9, 447, 448, 9, 449, 11, 9, 444, 11, 445, 446, 11, - 193, 9, 447, 448, 9, 449, 11, 9, 444, 11, 193, 9, 450, 451, 452, 453, - 11, 454, 9, 455, 456, 457, 458, 11, 459, 9, 460, 11, 461, 157, 157, 157, - 32, 32, 32, 462, 32, 32, 463, 464, 465, 466, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 47, 467, 468, 144, 144, 144, - 47, 47, 47, 47, 47, 47, 469, 470, 47, 47, 47, 47, 349, 32, 32, 32, - 9, 9, 447, 11, 471, 300, 66, 66, 143, 143, 472, 473, 143, 143, 143, 143, - 143, 143, 474, 143, 143, 143, 143, 143, 47, 47, 47, 47, 47, 47, 47, 223, - 475, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 476, - 144, 144, 144, 144, 144, 144, 144, 157, 205, 205, 205, 205, 205, 205, 205, 205, + 13, 13, 13, 42, 9, 43, 11, 11, 44, 45, 32, 46, 47, 48, 49, 50, + 51, 52, 48, 48, 53, 32, 54, 55, 48, 48, 48, 48, 48, 56, 57, 58, + 59, 60, 48, 32, 61, 48, 48, 48, 48, 48, 62, 63, 64, 48, 65, 66, + 48, 67, 68, 69, 48, 70, 71, 48, 72, 73, 48, 48, 74, 32, 75, 32, + 76, 48, 48, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 83, 84, 91, 92, 93, 94, 95, 96, 97, 84, 98, 99, 100, 88, 101, + 102, 83, 84, 103, 104, 105, 88, 106, 107, 108, 109, 110, 111, 112, 94, 113, + 114, 115, 84, 116, 117, 118, 88, 119, 120, 115, 84, 121, 122, 123, 88, 124, + 125, 115, 48, 126, 127, 128, 88, 129, 130, 131, 48, 132, 133, 134, 94, 135, + 136, 48, 48, 137, 138, 139, 140, 140, 141, 48, 142, 143, 144, 145, 140, 140, + 146, 147, 148, 149, 150, 48, 151, 152, 153, 154, 32, 155, 156, 157, 140, 140, + 48, 48, 158, 159, 160, 161, 162, 163, 164, 165, 9, 9, 166, 11, 11, 167, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 168, 169, 48, 48, + 168, 48, 48, 170, 171, 172, 48, 48, 48, 171, 48, 48, 48, 173, 174, 175, + 48, 176, 9, 9, 9, 9, 9, 177, 178, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 179, 48, 180, 181, 48, 48, 48, 48, 182, 183, + 48, 184, 48, 185, 48, 186, 187, 188, 48, 48, 48, 189, 190, 191, 192, 193, + 194, 192, 48, 48, 195, 48, 48, 196, 197, 48, 198, 48, 48, 48, 48, 199, + 48, 200, 201, 202, 203, 48, 204, 205, 48, 48, 206, 48, 207, 208, 209, 209, + 48, 210, 48, 48, 48, 211, 212, 213, 192, 192, 214, 215, 216, 140, 140, 140, + 217, 48, 48, 218, 219, 160, 220, 221, 222, 48, 223, 64, 48, 48, 224, 225, + 48, 48, 226, 227, 228, 64, 48, 229, 230, 9, 9, 231, 232, 233, 234, 235, + 11, 11, 236, 27, 27, 27, 237, 238, 11, 239, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 240, 13, 13, 13, 13, 13, 13, + 241, 242, 241, 241, 242, 243, 241, 244, 245, 245, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 272, 273, 274, 275, 209, 276, 277, 209, 278, + 279, 279, 279, 279, 279, 279, 279, 279, 280, 209, 281, 209, 209, 209, 209, 282, + 209, 283, 279, 284, 209, 285, 286, 209, 209, 209, 287, 140, 288, 140, 271, 271, + 271, 289, 209, 209, 209, 209, 290, 271, 209, 209, 209, 209, 209, 209, 209, 209, + 209, 209, 209, 291, 292, 209, 209, 293, 209, 209, 209, 209, 209, 209, 294, 209, + 209, 209, 209, 209, 209, 209, 295, 296, 271, 297, 209, 209, 298, 279, 299, 279, + 300, 301, 279, 279, 279, 302, 279, 303, 209, 209, 209, 279, 304, 209, 209, 305, + 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, + 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, + 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, + 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325, + 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331, + 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48, + 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, + 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, + 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, + 13, 343, 48, 48, 48, 48, 344, 345, 31, 346, 347, 348, 13, 13, 13, 349, + 350, 351, 352, 353, 354, 355, 140, 356, 357, 48, 358, 359, 48, 48, 48, 360, + 361, 48, 48, 362, 363, 192, 32, 364, 64, 48, 365, 48, 366, 367, 48, 151, + 76, 48, 48, 368, 369, 370, 371, 372, 48, 48, 373, 374, 375, 376, 48, 377, + 48, 48, 48, 378, 379, 380, 381, 382, 383, 384, 315, 11, 11, 385, 386, 11, + 11, 11, 11, 11, 48, 48, 387, 192, 48, 48, 388, 48, 389, 48, 48, 206, + 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, + 48, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 207, 140, 140, + 392, 393, 394, 395, 396, 48, 48, 48, 48, 48, 48, 397, 398, 399, 48, 48, + 48, 48, 48, 400, 209, 48, 48, 48, 48, 401, 48, 48, 402, 140, 140, 403, + 32, 404, 32, 405, 406, 407, 408, 409, 48, 48, 48, 48, 48, 48, 48, 410, + 411, 2, 3, 4, 5, 412, 413, 414, 48, 415, 48, 200, 416, 417, 418, 419, + 420, 48, 172, 421, 204, 204, 140, 140, 48, 48, 48, 48, 48, 48, 48, 71, + 422, 271, 271, 423, 272, 272, 272, 424, 425, 426, 427, 140, 140, 209, 209, 428, + 140, 140, 140, 140, 140, 140, 140, 140, 48, 151, 48, 48, 48, 100, 429, 430, + 48, 48, 431, 48, 432, 48, 48, 433, 48, 434, 48, 48, 435, 436, 140, 140, + 9, 9, 437, 11, 11, 48, 48, 48, 48, 204, 192, 9, 9, 438, 11, 439, + 48, 48, 440, 48, 48, 48, 441, 442, 442, 443, 444, 445, 140, 140, 140, 140, + 48, 48, 48, 314, 48, 199, 440, 140, 446, 27, 27, 447, 140, 140, 140, 140, + 448, 48, 48, 449, 48, 450, 48, 451, 48, 200, 452, 140, 140, 140, 48, 453, + 48, 454, 48, 455, 140, 140, 140, 140, 48, 48, 48, 456, 271, 457, 271, 271, + 458, 459, 48, 460, 461, 462, 48, 463, 48, 464, 140, 140, 465, 48, 466, 467, + 48, 48, 48, 468, 48, 469, 48, 470, 48, 471, 472, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 196, 140, 140, 140, 9, 9, 9, 473, 11, 11, 11, 474, + 48, 48, 475, 192, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 271, 476, + 48, 48, 477, 478, 140, 140, 140, 140, 48, 464, 479, 48, 62, 480, 140, 48, + 481, 140, 140, 48, 482, 140, 48, 314, 483, 48, 48, 484, 485, 457, 486, 487, + 222, 48, 48, 488, 489, 48, 196, 192, 490, 48, 491, 492, 493, 48, 48, 494, + 222, 48, 48, 495, 496, 497, 498, 499, 48, 97, 500, 501, 140, 140, 140, 140, + 502, 503, 504, 48, 48, 505, 506, 192, 507, 83, 84, 508, 509, 510, 511, 512, + 48, 48, 48, 513, 514, 515, 478, 140, 48, 48, 48, 516, 517, 192, 140, 140, + 48, 48, 518, 519, 520, 521, 140, 140, 48, 48, 48, 522, 523, 192, 524, 140, + 48, 48, 525, 526, 192, 140, 140, 140, 48, 173, 527, 528, 314, 140, 140, 140, + 48, 48, 500, 529, 140, 140, 140, 140, 140, 140, 9, 9, 11, 11, 148, 530, + 531, 532, 48, 533, 534, 192, 140, 140, 140, 140, 535, 48, 48, 536, 537, 140, + 538, 48, 48, 539, 540, 541, 48, 48, 542, 543, 544, 48, 48, 48, 48, 196, + 84, 48, 518, 545, 546, 148, 175, 547, 48, 548, 549, 550, 140, 140, 140, 140, + 551, 48, 48, 552, 553, 192, 554, 48, 555, 556, 192, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 48, 557, 140, 140, 140, 100, 271, 558, 559, 560, + 48, 207, 140, 140, 140, 140, 140, 140, 272, 272, 272, 272, 272, 272, 561, 562, + 48, 48, 48, 48, 388, 140, 140, 140, 140, 48, 48, 48, 48, 48, 48, 563, + 48, 48, 200, 564, 140, 140, 140, 140, 48, 48, 48, 48, 314, 140, 140, 140, + 48, 48, 48, 196, 48, 200, 370, 48, 48, 48, 48, 200, 192, 48, 204, 565, + 48, 48, 48, 566, 567, 568, 569, 570, 48, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 9, 9, 11, 11, 271, 571, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 572, 573, 574, 574, 575, 576, 140, 140, 140, 140, 577, 578, + 48, 48, 48, 48, 48, 48, 48, 440, 48, 48, 48, 48, 48, 199, 140, 140, + 196, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 579, + 48, 48, 580, 140, 140, 580, 581, 48, 48, 48, 48, 48, 48, 48, 48, 206, + 48, 48, 48, 48, 48, 48, 71, 151, 196, 582, 583, 140, 140, 140, 140, 140, + 32, 32, 584, 32, 585, 209, 209, 209, 209, 209, 209, 209, 323, 140, 140, 140, + 209, 209, 209, 209, 209, 209, 209, 324, 209, 209, 586, 209, 209, 209, 587, 588, + 589, 209, 590, 209, 209, 209, 288, 140, 209, 209, 209, 209, 591, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 271, 592, 209, 209, 209, 209, 209, 287, 271, 461, + 9, 593, 11, 594, 595, 596, 241, 9, 597, 598, 599, 600, 601, 9, 593, 11, + 602, 603, 11, 604, 605, 606, 607, 9, 608, 11, 9, 593, 11, 594, 595, 11, + 241, 9, 597, 607, 9, 608, 11, 9, 593, 11, 609, 9, 610, 611, 612, 613, + 11, 614, 9, 615, 616, 617, 618, 11, 619, 9, 620, 11, 621, 622, 622, 622, + 32, 32, 32, 623, 32, 32, 624, 625, 626, 627, 45, 140, 140, 140, 140, 140, + 628, 629, 140, 140, 140, 140, 140, 140, 630, 631, 632, 140, 140, 140, 140, 140, + 48, 48, 151, 633, 634, 140, 140, 140, 140, 48, 635, 140, 48, 48, 636, 637, + 140, 140, 140, 140, 140, 140, 638, 200, 48, 48, 48, 48, 639, 585, 140, 140, + 9, 9, 597, 11, 640, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 498, + 271, 271, 641, 642, 140, 140, 140, 140, 498, 271, 643, 644, 140, 140, 140, 140, + 645, 48, 646, 647, 648, 649, 650, 651, 652, 206, 653, 206, 140, 140, 140, 654, + 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 655, 655, 655, 209, 324, + 656, 209, 209, 209, 209, 209, 209, 209, 209, 209, 657, 140, 140, 140, 658, 209, + 659, 209, 209, 325, 660, 661, 324, 140, 209, 209, 209, 209, 209, 209, 209, 662, + 209, 209, 209, 209, 209, 663, 426, 426, 209, 209, 209, 209, 209, 209, 209, 323, + 209, 209, 209, 209, 209, 660, 325, 427, 325, 209, 209, 209, 664, 176, 209, 209, + 664, 209, 657, 661, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 657, 665, + 287, 209, 426, 288, 324, 176, 664, 287, 209, 666, 209, 209, 288, 140, 140, 192, + 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 196, 48, 48, 48, 48, + 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140, + 48, 48, 48, 48, 71, 140, 140, 140, 667, 140, 668, 668, 668, 668, 668, 668, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, + 391, 391, 391, 391, 391, 391, 391, 669, 391, 391, 391, 391, 391, 391, 391, 670, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, + 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, + 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, + 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, + 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, + 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, + 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, + 31, 50, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 52, 31, 31, 31, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, + 56, 57, 58, 59, 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, + 68, 69, 70, 71, 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, + 80, 81, 82, 83, 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, + 92, 93, 94, 95, 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, + 103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, + 113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, + 122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, + 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, + 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, + 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, + 150, 151, 152, 152, 153, 152, 152, 154, 155, 154, 152, 156, 26, 26, 26, 26, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 157, 157, 157, 159, 158, 157, + 157, 157, 157, 158, 157, 157, 157, 160, 157, 160, 161, 162, 26, 26, 26, 26, + 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 164, 164, 164, 164, 165, 166, 164, 164, 164, 164, 164, 167, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 170, 171, 170, 169, 169, 169, 169, + 169, 170, 169, 169, 169, 169, 170, 171, 170, 169, 171, 169, 169, 169, 169, 169, + 169, 169, 170, 169, 169, 169, 169, 169, 169, 169, 169, 172, 169, 169, 169, 173, + 169, 169, 169, 174, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 176, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 178, 178, 178, 179, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 180, 182, + 183, 183, 184, 185, 186, 186, 187, 26, 188, 188, 189, 26, 190, 191, 192, 26, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 194, 193, 195, 193, 195, + 196, 197, 197, 198, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 199, + 197, 197, 197, 197, 197, 200, 177, 177, 177, 177, 177, 177, 177, 177, 201, 26, + 202, 202, 202, 203, 202, 204, 202, 204, 205, 202, 206, 206, 206, 207, 208, 26, + 209, 209, 209, 209, 209, 210, 209, 209, 209, 211, 209, 212, 193, 193, 193, 193, + 213, 213, 213, 214, 215, 215, 215, 215, 215, 215, 215, 216, 215, 215, 215, 217, + 215, 218, 215, 218, 215, 219, 9, 9, 9, 220, 26, 26, 26, 26, 26, 26, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 222, 221, 221, 221, 221, 221, 223, + 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 226, 227, + 228, 228, 228, 228, 228, 228, 228, 229, 228, 230, 231, 231, 231, 231, 231, 231, + 18, 232, 164, 164, 164, 164, 164, 233, 224, 26, 234, 9, 235, 236, 237, 238, + 2, 2, 2, 2, 239, 240, 2, 2, 2, 2, 2, 241, 242, 243, 2, 244, + 2, 2, 2, 2, 2, 2, 2, 245, 9, 9, 9, 9, 9, 9, 9, 9, + 14, 14, 246, 246, 14, 14, 14, 14, 246, 246, 14, 247, 14, 14, 14, 246, + 14, 14, 14, 14, 14, 14, 248, 14, 248, 14, 249, 250, 14, 14, 251, 252, + 0, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 255, 256, + 0, 257, 2, 258, 0, 0, 0, 0, 259, 26, 9, 9, 9, 9, 260, 26, + 0, 0, 0, 0, 261, 262, 4, 0, 0, 263, 0, 0, 2, 2, 2, 2, + 2, 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 257, 26, 26, 26, 0, 265, 26, 26, 0, 0, 0, 0, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, 0, + 0, 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 2, 2, 2, 2, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 270, 271, + 164, 164, 164, 164, 165, 166, 272, 272, 272, 272, 272, 272, 272, 273, 274, 273, + 169, 169, 171, 26, 171, 171, 171, 171, 171, 171, 171, 171, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, + 276, 276, 276, 277, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 278, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 26, 26, 26, 0, 280, + 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, + 292, 293, 293, 293, 293, 293, 294, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 295, 0, 0, 293, 293, 293, 293, 0, 0, 0, 0, 280, 26, 290, 290, + 168, 168, 168, 295, 0, 0, 0, 0, 0, 0, 0, 0, 168, 168, 168, 296, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 290, 290, 290, 290, 297, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, + 276, 276, 276, 276, 276, 276, 276, 276, 0, 0, 0, 0, 0, 0, 0, 0, + 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 299, 298, 298, 298, 298, 298, 298, 300, 26, 301, 301, 301, 301, 301, 301, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 303, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 26, + 0, 0, 0, 0, 305, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 306, 2, 2, 2, 2, 2, 2, 2, 307, 308, 309, 26, 26, 310, 2, + 311, 311, 311, 311, 311, 312, 0, 313, 314, 314, 314, 314, 314, 314, 314, 26, + 315, 315, 315, 315, 315, 315, 315, 315, 316, 317, 315, 318, 53, 53, 53, 53, + 319, 319, 319, 319, 319, 320, 321, 321, 321, 321, 322, 323, 168, 168, 168, 324, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 326, 325, 327, 163, 163, 163, 328, + 329, 329, 329, 329, 329, 329, 330, 26, 329, 331, 329, 332, 163, 163, 163, 163, + 333, 333, 333, 333, 333, 333, 333, 333, 334, 26, 26, 335, 336, 336, 337, 26, + 338, 338, 338, 26, 171, 171, 2, 2, 2, 2, 2, 339, 340, 341, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, 336, 336, 336, 336, 336, 342, 336, 343, + 168, 168, 168, 168, 344, 26, 168, 168, 295, 345, 168, 168, 168, 168, 168, 344, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 279, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 346, 26, 26, 26, 26, + 347, 26, 348, 349, 25, 25, 350, 351, 352, 25, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 353, 26, 354, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 355, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 356, 31, 31, 31, 31, 31, 31, 357, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 313, 9, 358, 0, 0, 0, 0, 359, 0, 257, 280, 360, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 361, + 362, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 363, 290, 289, 290, + 290, 290, 290, 364, 168, 168, 168, 295, 365, 365, 365, 366, 257, 257, 26, 367, + 368, 369, 368, 368, 370, 368, 368, 371, 368, 372, 368, 372, 26, 26, 26, 26, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 373, + 374, 0, 0, 0, 0, 0, 375, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 252, 0, 376, 377, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 378, + 379, 379, 379, 380, 381, 381, 381, 381, 381, 381, 382, 26, 383, 0, 0, 280, + 384, 384, 384, 384, 385, 386, 387, 387, 387, 388, 389, 389, 389, 389, 389, 390, + 391, 391, 391, 392, 393, 393, 393, 393, 394, 393, 395, 26, 26, 26, 26, 26, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, + 398, 398, 398, 399, 398, 400, 401, 401, 401, 401, 402, 401, 401, 401, 401, 402, + 403, 403, 403, 403, 403, 26, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, + 407, 408, 409, 407, 410, 407, 410, 411, 26, 26, 26, 26, 26, 26, 26, 26, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 413, 26, 412, 412, 414, 26, 412, 26, 26, 26, + 415, 2, 2, 2, 2, 2, 416, 307, 26, 26, 26, 26, 26, 26, 26, 26, + 417, 418, 419, 419, 419, 419, 420, 421, 422, 422, 423, 422, 424, 424, 424, 424, + 425, 425, 425, 426, 427, 425, 26, 26, 26, 26, 26, 26, 428, 428, 429, 430, + 431, 431, 431, 432, 433, 433, 433, 434, 26, 26, 26, 26, 26, 26, 26, 26, + 435, 435, 435, 435, 436, 436, 436, 437, 436, 436, 438, 436, 436, 436, 436, 436, + 439, 440, 441, 442, 443, 443, 444, 445, 443, 446, 443, 446, 447, 447, 447, 447, + 448, 448, 448, 448, 26, 26, 26, 26, 449, 449, 449, 449, 450, 451, 450, 26, + 452, 452, 452, 452, 452, 452, 453, 454, 455, 455, 456, 455, 457, 457, 458, 457, + 459, 459, 460, 461, 26, 462, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 463, 463, 463, 463, 463, 463, 463, 463, 463, 464, 26, 26, 26, 26, 26, 26, + 465, 465, 465, 465, 465, 465, 466, 26, 465, 465, 465, 465, 465, 465, 466, 467, + 468, 468, 468, 468, 468, 26, 468, 469, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, + 470, 470, 470, 470, 470, 471, 472, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 473, 473, 473, 473, 473, 26, 474, 474, 474, 474, 474, 475, 26, 26, 476, 476, + 476, 477, 26, 26, 26, 26, 478, 478, 478, 479, 26, 26, 480, 480, 481, 26, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 483, 484, 482, 482, 482, 483, 485, + 486, 486, 486, 486, 486, 486, 486, 486, 487, 488, 489, 489, 489, 490, 489, 491, + 492, 492, 492, 492, 492, 492, 493, 492, 492, 26, 494, 494, 494, 494, 495, 26, + 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 497, 137, 498, 26, + 499, 499, 500, 499, 499, 499, 499, 501, 26, 26, 26, 26, 26, 26, 26, 26, + 502, 503, 504, 505, 504, 506, 507, 507, 507, 507, 507, 507, 507, 508, 507, 509, + 510, 511, 512, 513, 513, 514, 515, 516, 511, 517, 518, 519, 520, 521, 521, 26, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 523, 524, 26, 26, 26, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 26, 525, 526, 26, 26, 26, 26, + 527, 527, 527, 527, 527, 527, 528, 527, 527, 527, 527, 528, 26, 26, 26, 26, + 529, 529, 529, 529, 529, 529, 529, 529, 530, 26, 529, 531, 197, 532, 26, 26, + 533, 533, 533, 533, 533, 533, 533, 534, 533, 534, 26, 26, 26, 26, 26, 26, + 535, 535, 535, 536, 535, 537, 535, 535, 538, 26, 26, 26, 26, 26, 26, 26, + 539, 539, 539, 539, 539, 539, 539, 540, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, 542, 543, + 544, 545, 546, 547, 547, 547, 548, 549, 544, 26, 547, 550, 26, 26, 26, 26, + 26, 26, 26, 26, 551, 552, 551, 551, 551, 551, 551, 552, 553, 26, 26, 26, + 554, 554, 554, 554, 554, 554, 554, 554, 554, 26, 555, 555, 555, 555, 555, 555, + 555, 555, 555, 555, 556, 26, 177, 177, 557, 557, 557, 557, 557, 557, 557, 558, + 559, 560, 559, 559, 559, 559, 561, 559, 562, 26, 559, 559, 559, 563, 564, 564, + 564, 564, 565, 564, 564, 566, 567, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 568, 569, 570, 570, 570, 570, 568, 571, 570, 26, 570, 572, 573, 574, 575, 575, + 575, 576, 577, 578, 575, 579, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 580, 580, 580, 581, + 26, 26, 26, 26, 26, 26, 582, 26, 108, 108, 108, 108, 108, 108, 583, 584, + 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, + 585, 585, 585, 586, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 587, 588, 26, + 585, 585, 585, 585, 585, 585, 585, 585, 589, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, 591, 26, + 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 593, 592, 594, 26, 26, 26, 26, 26, 26, 26, 26, + 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + 595, 595, 595, 595, 595, 595, 595, 595, 596, 26, 26, 26, 26, 26, 26, 26, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 597, 598, 598, 598, 599, 598, 600, 601, 601, + 601, 601, 601, 601, 601, 601, 601, 602, 601, 603, 604, 604, 604, 605, 605, 26, + 606, 606, 606, 606, 606, 606, 606, 606, 607, 26, 606, 608, 608, 606, 606, 609, + 606, 606, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 611, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 612, 612, 612, 612, 612, 612, 612, 612, 612, 613, 612, 612, 612, 612, 612, 612, + 612, 614, 612, 612, 26, 26, 26, 26, 26, 26, 26, 26, 615, 26, 346, 26, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 26, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, 618, 26, 26, 26, 26, 26, + 616, 619, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 620, 621, + 622, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 623, 26, 26, 26, 26, 26, 624, 26, 625, 26, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 627, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 629, 628, 630, + 628, 631, 628, 632, 280, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 9, 9, 9, 9, 9, 633, 9, 9, 220, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 280, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 257, 362, 0, 0, 0, 0, 0, 0, 634, 635, 0, 636, + 637, 638, 0, 0, 0, 639, 0, 0, 0, 0, 0, 0, 0, 265, 26, 26, + 14, 14, 14, 14, 14, 14, 14, 14, 246, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 280, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 26, 0, 0, 0, 259, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, + 0, 0, 0, 254, 640, 641, 0, 642, 643, 0, 0, 0, 0, 0, 0, 0, + 268, 644, 254, 254, 0, 0, 0, 645, 646, 647, 648, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, + 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 650, 26, 651, 652, 649, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 2, 2, 2, 347, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 653, 269, 269, 654, 655, 656, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 657, 657, 657, 657, 657, 658, 657, 659, 657, 660, 26, 26, 26, 26, 26, 26, + 26, 26, 661, 661, 661, 662, 26, 26, 663, 663, 663, 663, 663, 663, 663, 664, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 171, 665, 169, 171, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 667, 666, 668, 26, 26, 26, 26, 26, + 669, 669, 669, 669, 669, 669, 669, 669, 669, 670, 669, 671, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 362, 0, + 0, 0, 0, 0, 0, 0, 376, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 362, 0, 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 26, 26, + 672, 31, 31, 31, 673, 674, 675, 676, 677, 678, 673, 679, 673, 675, 675, 680, + 31, 681, 31, 682, 683, 681, 31, 682, 26, 26, 26, 26, 26, 26, 51, 26, + 0, 0, 0, 0, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 280, 26, 0, 257, 362, 0, 362, 0, 362, 0, 0, 0, 275, 26, + 0, 0, 0, 0, 0, 275, 26, 26, 26, 26, 26, 26, 684, 0, 0, 0, + 685, 26, 0, 0, 0, 0, 0, 280, 0, 259, 313, 26, 275, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 686, 0, 376, 0, 376, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 280, 259, 26, + 0, 280, 0, 0, 0, 0, 0, 0, 0, 26, 0, 313, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 275, 313, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280, 26, 0, 275, 376, 376, + 257, 26, 0, 0, 0, 376, 0, 265, 275, 26, 0, 313, 0, 26, 257, 26, + 0, 0, 359, 0, 0, 0, 0, 0, 0, 265, 26, 26, 26, 26, 0, 313, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 687, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 279, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 346, 26, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 687, 26, 26, 26, + 276, 276, 276, 279, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 688, 26, 26, 26, 26, 26, 26, + 689, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, @@ -6731,25 +5625,1249 @@ _hb_ucd_u16[4848] = 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; static const int16_t -_hb_ucd_i16[92] = +_hb_ucd_i16[196] = { - 0, 0, 1, -1, 2, 0, -2, 0, 0, 2, 0, -2, 0, 16, 0, -16, - 0, 1, -1, 0, 3, 3, 3, -3, -3, -3, 0, 2016, 0, 2527, 1923, 1914, - 1918, 0, 2250, 0, 0, 138, 0, 7, -7, 0, -1, 1, 1824, 0, 2104, 0, - 2108, 2106, 0, 2106, 1316, 0, -1, -138, 8, 8, 8, 0, 7, 7, -8, -8, - -8, -7,-1316, 1, -1, 3, -3, 1, 0,-1914,-1918, 0, 0,-1923,-1824, 0, - 0,-2016,-2104, 0, 0,-2106,-2108,-2106,-2250, 0,-2527, 0, + 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, + 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, + 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, + -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, + 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, + 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, + 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, + 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, + -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, + 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, + -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, + -1, 0, 1, -1, +}; + +static inline uint_fast8_t +_hb_ucd_gc (unsigned u) +{ + return u<1114110u?_hb_ucd_u8[6664+(((_hb_ucd_u8[1296+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; +} +static inline uint_fast8_t +_hb_ucd_ccc (unsigned u) +{ + return u<125259u?_hb_ucd_u8[8984+(((_hb_ucd_u8[7960+(((_hb_ucd_u8[7288+(((_hb_ucd_u8[7042+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0; +} +static inline unsigned +_hb_ucd_b4 (const uint8_t* a, unsigned i) +{ + return (a[i>>1]>>((i&1u)<<2))&15u; +} +static inline int_fast16_t +_hb_ucd_bmg (unsigned u) +{ + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9728+(((_hb_ucd_u8[9608+(((_hb_ucd_b4(9480+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; +} +static inline uint_fast8_t +_hb_ucd_sc (unsigned u) +{ + return u<918000u?_hb_ucd_u8[11234+(((_hb_ucd_u16[2000+(((_hb_ucd_u8[10514+(((_hb_ucd_u8[10064+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; +} +static inline uint_fast16_t +_hb_ucd_dm (unsigned u) +{ + return u<195102u?_hb_ucd_u16[5888+(((_hb_ucd_u8[17136+(((_hb_ucd_u8[16754+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; +} + + +#else + +static const uint8_t +_hb_ucd_u8[13602] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 21, 21, 21, 21, 23, 7, 7, + 7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 21, 36, + 7, 7, 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 38, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71, + 67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67, + 79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34, + 85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, + 100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108, + 34, 34,109,110,111,112,113,114,115,116,117,118, 34, 34, 34,119, + 120,121,122,123,124,125,126,127, 34,128,129,111,130,131,132,133, + 134,135,136,137,138,139,140,111,141,142,111,143,144,145,146,111, + 147,148,149,150,151,152,111,111,153,154,155,156,111,157,111,158, + 34, 34, 34, 34, 34, 34, 34, 34,159, 34, 34,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,160, + 34, 34, 34, 34, 34, 34, 34, 34,161,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111, + 34, 34, 34, 34,162,163,164, 34,111,111,111,111,165,166,167,168, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,119, + 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111, 34,169,111,111,111,111,111,111, + 111,111,111,111,111,111,111,111,111,111,111,111,111,111,170, 67, + 67, 67,171,172,173,130, 65,111,174,175,176,177,178,179,180,181, + 67, 67, 67, 67,182,183,111,111,111,111,111,111,111,111,184,111, + 185,111,186,111,111,187,111,111,111,111,111,111,111,111,111, 34, + 34,188,189,111,111,111,111,111,130,190,191,111, 34,192,111,111, + 67, 67,193, 67, 67,111, 67,194, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67,195,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111, + 196,111,185,185,111,111,111,111,111,111,111,111,111,111,111,111, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, + 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 18, 19, 1, 20, 20, 21, 22, 23, 24, 25, + 26, 27, 15, 2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32, + 32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11, + 11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11, + 34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34, + 34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32, + 32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32, + 16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, + 40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, + 43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10, + 41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34, + 16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11, + 32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16, + 11, 11, 11, 11, 49, 2, 2, 2, 16, 16, 16, 16, 50, 51, 52, 53, + 54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55, + 56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 58, 2, 2, 2, 2, 2, 2, 59, 59, 59, 8, 9, 60, 2, 61, + 43, 43, 43, 43, 43, 57, 62, 2, 63, 36, 36, 36, 36, 64, 43, 43, + 7, 7, 7, 7, 7, 2, 2, 36, 65, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 66, 43, 43, 43, 67, 47, 43, 43, 68, 69, 70, 43, 43, 36, + 7, 7, 7, 7, 7, 36, 71, 72, 2, 2, 2, 2, 2, 2, 2, 73, + 64, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 65, 36, + 36, 36, 36, 43, 43, 43, 43, 43, 7, 7, 7, 7, 7, 36, 36, 36, + 36, 36, 36, 36, 36, 64, 43, 43, 43, 43, 40, 21, 2, 40, 69, 20, + 36, 36, 36, 43, 43, 69, 43, 43, 43, 43, 69, 43, 69, 43, 43, 43, + 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 64, 43, 43, 2, + 36, 36, 36, 36, 74, 36, 36, 36, 59, 59, 59, 59, 43, 43, 43, 43, + 36, 36, 36, 36, 75, 43, 43, 43, 43, 76, 43, 43, 43, 43, 43, 43, + 43, 77, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 77, 65, 78, + 79, 43, 43, 43, 77, 78, 79, 78, 64, 43, 43, 43, 36, 36, 36, 36, + 36, 43, 2, 7, 7, 7, 7, 7, 80, 36, 36, 36, 36, 36, 36, 36, + 64, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 78, + 79, 43, 43, 77, 78, 78, 79, 36, 36, 36, 36, 82, 78, 78, 36, 36, + 36, 43, 43, 7, 7, 7, 7, 7, 36, 20, 27, 27, 27, 53, 58, 43, + 43, 77, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 78, + 79, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 65, 36, 36, 36, + 36, 36, 36, 7, 7, 7, 7, 7, 43, 36, 64, 2, 2, 2, 2, 2, + 79, 43, 43, 43, 77, 78, 79, 43, 60, 20, 20, 20, 83, 43, 43, 43, + 43, 78, 81, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 65, 79, + 79, 43, 43, 77, 78, 78, 79, 43, 43, 43, 43, 77, 78, 78, 36, 36, + 72, 27, 27, 27, 27, 27, 27, 27, 43, 65, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 78, 77, 78, 78, 78, 78, 78, 79, 43, + 36, 36, 36, 82, 78, 78, 78, 78, 78, 78, 78, 7, 7, 7, 7, 7, + 27, 84, 61, 61, 53, 61, 61, 61, 77, 78, 65, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 65, 43, 77, 78, 78, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 36, 36, 36, 36, 7, 7, 7, 85, 27, 27, 27, 84, + 64, 78, 66, 36, 36, 36, 36, 36, 78, 78, 78, 77, 78, 78, 43, 43, + 43, 43, 77, 78, 78, 78, 81, 36, 86, 36, 36, 36, 36, 36, 36, 36, + 43, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 78, + 79, 43, 43, 78, 78, 78, 79, 71, 61, 61, 36, 82, 27, 27, 27, 87, + 27, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 77, + 78, 43, 43, 43, 78, 78, 78, 78, 7, 78, 2, 2, 2, 2, 2, 2, + 64, 36, 43, 43, 43, 43, 43, 88, 36, 36, 36, 69, 43, 43, 43, 57, + 7, 7, 7, 7, 7, 2, 2, 2, 64, 36, 43, 43, 43, 43, 65, 36, + 36, 36, 36, 40, 43, 43, 43, 43, 7, 7, 7, 7, 7, 7, 36, 36, + 71, 61, 2, 2, 2, 2, 2, 2, 2, 89, 89, 61, 43, 61, 61, 61, + 7, 7, 7, 7, 7, 27, 27, 27, 27, 27, 47, 47, 47, 4, 4, 78, + 64, 43, 43, 43, 43, 43, 43, 77, 43, 43, 57, 43, 36, 36, 64, 43, + 43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 70, 61, 61, 61, 61, + 2, 2, 89, 61, 21, 2, 2, 2, 36, 36, 36, 36, 36, 82, 79, 43, + 77, 43, 43, 43, 79, 77, 79, 65, 36, 36, 36, 78, 43, 36, 36, 43, + 65, 78, 81, 82, 78, 78, 78, 36, 64, 43, 65, 36, 36, 36, 36, 36, + 36, 77, 79, 77, 78, 78, 79, 82, 7, 7, 7, 7, 7, 78, 79, 61, + 16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 64, 43, + 2, 2, 2, 2, 90, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16, + 91, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 71, 66, + 92, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93, 94, 94, + 36, 36, 36, 36, 36, 58, 2, 95, 96, 36, 36, 36, 36, 36, 36, 36, + 36, 43, 77, 78, 78, 78, 78, 81, 36, 43, 97, 2, 2, 2, 2, 2, + 36, 43, 43, 43, 43, 43, 43, 43, 36, 36, 43, 79, 43, 43, 43, 78, + 78, 78, 78, 77, 79, 43, 43, 43, 43, 43, 2, 80, 2, 60, 64, 43, + 7, 7, 7, 7, 7, 7, 7, 7, 2, 2, 2, 98, 2, 56, 43, 76, + 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 64, 65, 36, 36, 36, 36, + 36, 36, 36, 36, 64, 36, 36, 36, 43, 77, 78, 79, 77, 78, 78, 78, + 78, 77, 78, 78, 79, 43, 43, 43, 61, 61, 2, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 27, 27, 61, 36, 36, 36, 64, 77, 79, 43, 2, + 36, 36, 82, 77, 43, 43, 43, 43, 77, 77, 79, 43, 43, 43, 77, 78, + 78, 79, 43, 43, 43, 43, 43, 43, 2, 2, 2, 80, 2, 2, 2, 2, + 43, 43, 43, 43, 43, 43, 43, 99, 43, 43, 81, 36, 36, 36, 36, 36, + 36, 36, 77, 43, 43, 77, 77, 78, 78, 77, 81, 36, 36, 36, 36, 36, + 89, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 21, 2, + 43, 81, 36, 36, 36, 36, 36, 36, 82, 43, 43, 78, 43, 79, 43, 36, + 36, 36, 36, 77, 43, 78, 79, 79, 43, 78, 78, 78, 78, 78, 2, 2, + 36, 36, 78, 78, 78, 78, 43, 43, 43, 43, 78, 43, 43, 57, 2, 2, + 7, 7, 7, 7, 7, 7, 86, 36, 36, 36, 36, 36, 40, 40, 40, 2, + 43, 57, 43, 43, 43, 43, 43, 43, 77, 43, 43, 43, 65, 36, 64, 36, + 36, 36, 65, 82, 43, 36, 36, 36, 16, 16, 16, 16, 16, 16, 40, 40, + 40, 40, 40, 40, 40, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16, + 16, 16, 16, 16, 16,100, 40, 40, 32, 32, 32, 16, 16, 16, 16, 32, + 16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 16, 34, 11, 11, 11, + 16, 16, 16, 16,101,101,101,101, 16, 16, 16, 16, 11, 11,102,103, + 41, 16, 16, 16, 11, 11,102, 41, 16, 16, 16, 16, 11, 11,104, 41, + 105,105,105,105,105,106, 59, 59, 51, 51, 51, 2,107,108,107,108, + 2, 2, 2, 2,109, 59, 59,110, 2, 2, 2, 2,111,112, 2,113, + 114, 2,115,116, 2, 2, 2, 2, 2, 9,114, 2, 2, 2, 2,117, + 59, 59, 59, 59, 59, 59, 59, 59,118, 40, 27, 27, 27, 8,115,119, + 27, 27, 27, 27, 27, 8,115, 94, 20, 20, 20, 20, 20, 20, 20, 20, + 43, 43, 43, 43, 43, 43,120, 48, 99, 48, 99, 43, 43, 43, 43, 43, + 61,121, 61,122, 61, 34, 11, 16, 11, 32,122, 61, 46, 11, 11, 61, + 61, 61,121,121,121, 11, 11,123, 11, 11, 35, 36, 39, 61, 16, 11, + 8, 8, 46, 16, 16, 26, 61,124, 95, 95, 95, 95, 95, 95, 95, 95, + 95,125,126, 95,127, 61, 61, 61, 8, 8,128, 61, 61, 8, 61, 61, + 128, 26, 61,128, 61, 61, 61,128, 61, 61, 61, 61, 61, 61, 61, 8, + 61,128,128, 61, 61, 61, 61, 61, 61, 61, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 61, 61, 61, 61, 4, 4, 61, 61, + 8, 61, 61, 61,129,130, 61, 61, 61, 61, 61, 61, 61, 61,128, 61, + 61, 61, 61, 61, 61, 26, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, + 27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27, + 61, 61, 61, 26, 61, 61, 61, 61, 26, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 8, 8, 8, 8, 61, 61, 61, 61, 61, 61, 61, 26, + 61, 61, 61, 61, 4, 4, 4, 4, 4, 4, 4, 27, 27, 27, 27, 27, + 27, 27, 61, 61, 61, 61, 61, 61, 8, 8,115,131, 8, 8, 8, 8, + 8, 8, 8, 4, 4, 4, 4, 4, 8,115,132,132,132,132,132,132, + 132,132,132,132,131, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, + 8, 8, 8, 8, 8, 8, 4, 8, 8, 8,128, 26, 8, 8,128, 61, + 32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11, + 32, 32,124, 61, 61,122, 34,133, 43, 32, 16, 16, 50, 2, 90, 2, + 36, 36, 36, 36, 36, 36, 36, 75, 2, 2, 2, 2, 2, 2, 2, 56, + 2,107,107, 2,111,112,107, 2, 2, 2, 2, 6, 2, 98,107, 2, + 107, 4, 4, 4, 4, 2, 2, 80, 2, 2, 2, 2, 2, 51, 2, 2, + 98,134, 2, 2, 2, 2, 2, 2, 61, 2,135,132,132,132,136, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 1, 2,137,138, 4, 4, 4, 4, + 4, 61, 4, 4, 4, 4,139, 94,140, 95, 95, 95, 95, 43, 43, 78, + 141, 40, 40, 61, 95,142, 58, 61, 72, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 64,143,144, 63, 36, 36, 36, 36, 36, 58, 40, 63, + 61, 27, 27, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 61, 61, 61, + 61, 61, 61, 61, 27, 27, 27, 27,145, 27, 27, 27, 27, 27, 27, 27, + 36, 36, 75, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,146, 2, + 32, 32, 32, 32, 32, 32, 32, 64, 48,147, 43, 43, 43, 43, 43, 80, + 32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36, 95, 95, 95, 95, 95, + 43, 2, 2, 2, 2, 2, 2, 2, 41, 41, 41,144, 40, 40, 40, 40, + 41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, + 44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,148, 34, 35, + 32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32, + 11, 11, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 34, 16, 16, 16, + 32, 16, 16, 32, 32, 16, 16, 16, 16, 40,149, 35, 40, 35, 36, 36, + 36, 65, 36, 65, 36, 64, 36, 36, 36, 82, 79, 77, 61, 61, 43, 43, + 27, 27, 27, 61,150, 61, 61, 61, 36, 36, 2, 2, 2, 2, 2, 2, + 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 78, 78, 78, 78, 78, 78, + 78, 78, 43, 43, 43, 43, 43, 2, 43, 36, 36, 36, 2, 66, 66, 64, + 36, 36, 36, 43, 43, 43, 43, 2, 36, 36, 36, 64, 43, 43, 43, 43, + 43, 78, 78, 78, 78, 78, 78, 97, 36, 64, 78, 43, 43, 78, 43, 78, + 97, 2, 2, 2, 2, 2, 2, 80, 7, 7, 7, 7, 7, 7, 7, 2, + 36, 36, 64, 63, 36, 36, 36, 36, 36, 36, 36, 36, 64, 43, 43, 77, + 79, 77, 79, 43, 43, 43, 43, 43, 36, 64, 36, 36, 36, 36, 77, 78, + 7, 7, 7, 7, 7, 7, 2, 2, 63, 36, 36, 71, 61, 82, 77, 36, + 65, 43, 65, 64, 65, 36, 36, 43, 36, 36, 36, 36, 36, 36, 75, 2, + 36, 36, 36, 36, 36, 82, 43, 78, 2, 75,151, 43, 43, 43, 43, 43, + 16, 16, 16, 16, 16,103, 40, 40, 16, 16, 16, 16,100, 41, 41, 41, + 36, 82, 79, 78, 77, 97, 79, 43,152,152,152,152,152,152,152,152, + 153,153,153,153,153,153,153,153, 16, 16, 16, 16, 16, 16, 35, 65, + 36, 36, 36, 36,154, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41, + 41, 74, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,132, + 36, 36, 36, 36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 36,150, 61, + 2, 2, 2,135,116, 2, 2, 2, 6,155,156,132,132,132,132,132, + 132,132,116,135,116, 2,113,157, 2, 2, 2, 2,139,132,132,116, + 2,158, 8, 8, 60, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36,159, + 2, 2, 3, 2, 4, 5, 6, 2, 16, 16, 16, 16, 16, 17, 18,115, + 116, 4, 2, 36, 36, 36, 36, 36, 63, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 40, 20,160, 53, 20, 26, 8,128, 61, + 61, 61, 61, 61,161, 59, 61, 61, 2, 2, 2, 90, 27, 27, 27, 27, + 27, 27, 27, 84, 61, 61, 61, 61, 95, 95,127, 27, 84, 61, 61, 61, + 61, 61, 61, 61, 61, 27, 61, 61, 61, 61, 61, 61, 61, 61, 47, 43, + 162,162,162,162,162,162,162,162,163, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 87, 36,138, 36, 36, 36, 36, 95, 95, 95, + 36, 36, 36, 36, 36, 36, 36, 58,164, 95, 95, 95, 95, 95, 95, 95, + 11, 11, 11, 32, 16, 16, 16, 16, 36, 36, 36, 58, 27, 27, 27, 27, + 36, 36, 36, 71,145, 27, 27, 27, 36, 36, 36,165, 27, 27, 27, 27, + 36, 36, 36, 36, 36,165, 27, 27, 36, 36, 36, 27, 27, 27, 27, 30, + 36, 36, 36, 36, 36, 36, 27, 36, 64, 43, 43, 43, 43, 43, 43, 43, + 36, 36, 36, 36, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36,165, 30, + 36, 36, 36, 36, 36, 36,165, 27, 36, 36, 36, 36, 72, 36, 36, 36, + 36, 36, 64, 43, 43,163, 27, 27, 36, 36, 36, 36, 58, 2, 2, 2, + 36, 36, 36, 36, 27, 27, 27, 27, 16, 16, 16, 16, 16, 27, 27, 27, + 36, 36, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 64,166, 51, + 27, 27, 27, 87, 36, 36, 36, 36,163, 27, 30, 2, 2, 2, 2, 2, + 36, 43, 43, 2, 2, 2, 2, 2, 36, 36,165, 27, 27, 27, 27, 27, + 79, 81, 36, 36, 36, 36, 36, 36, 43, 43, 43, 57, 2, 2, 2, 2, + 2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 7, 7, 7, + 65, 64, 65, 36, 36, 36, 36, 64, 78, 79, 43, 77, 79, 57, 73, 2, + 2, 43, 43, 43, 43, 43, 67, 59, 36, 36, 36, 64, 43, 43, 79, 43, + 43, 43, 43, 7, 7, 7, 7, 7, 2, 2, 82, 81, 36, 36, 36, 36, + 36, 64, 2, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 43, 77, + 81, 36, 58, 2, 56, 43, 57, 79, 7, 7, 7, 7, 7, 58, 58, 2, + 90, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 78, 79, + 43, 78, 77, 43, 2, 2, 2, 43, 36, 36, 36, 36, 36, 36, 36, 64, + 77, 78, 78, 78, 78, 78, 78, 78, 36, 36, 36, 82, 78, 78, 81, 36, + 36, 78, 78, 43, 43, 43, 43, 43, 36, 36, 82, 78, 43, 43, 43, 43, + 78, 43, 77, 65, 36, 58, 2, 2, 7, 7, 7, 7, 7, 2, 2, 65, + 78, 79, 43, 43, 77, 77, 78, 79, 77, 43, 36, 66, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 82, 78, 43, 43, 43, 78, 78, 43, 79, + 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 43, 43, + 78, 79, 43, 43, 43, 77, 79, 79, 57, 2, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 64, 79, 78, 43, 43, 43, 79, 58, 2, 2, 2, + 78, 43, 43, 79, 43, 43, 43, 43, 7, 7, 7, 7, 7, 27, 2, 89, + 43, 43, 43, 43, 79, 57, 2, 2, 27, 27, 27, 27, 27, 27, 27, 87, + 78, 78, 78, 78, 78, 79, 77, 65, 81, 79, 2, 2, 2, 2, 2, 2, + 82, 78, 43, 43, 43, 43, 78, 78, 65, 66, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 64, 43, 43, 43, 43, 65, 36, 36, + 36, 64, 43, 43, 77, 64, 43, 57, 2, 2, 2, 56, 43, 43, 43, 43, + 64, 43, 43, 77, 79, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, + 43, 43, 43, 77, 43, 2, 66, 2, 43, 43, 43, 43, 43, 43, 43, 79, + 58, 2, 2, 2, 2, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, + 43, 43, 43, 43, 77, 43, 43, 43, 77, 43, 79, 43, 43, 43, 43, 43, + 43, 43, 43, 64, 43, 43, 43, 43, 36, 36, 36, 36, 36, 78, 78, 78, + 43, 77, 79, 79, 36, 36, 36, 36, 36, 64, 77, 97, 2, 2, 2, 2, + 27, 27, 84, 61, 61, 61, 53, 20,150, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 21, 43, 43, 57, 2, 2, 2, 2, 2, + 43, 43, 43, 57, 2, 2, 61, 61, 40, 40, 89, 61, 61, 61, 61, 61, + 7, 7, 7, 7, 7,167, 27, 27, 27, 87, 36, 36, 36, 36, 36, 36, + 27, 27, 27, 30, 2, 2, 2, 2, 82, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 79, 43, 68, 40, 40, 40, 40, 40, 40, + 40, 80, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 47, 57, + 61, 61,168, 79, 43, 61,168, 78, 78,169, 59, 59, 59, 76, 43, 43, + 43, 70, 47, 43, 43, 43, 61, 61, 61, 61, 61, 61, 61, 43, 43, 61, + 61, 43, 70, 61, 61, 61, 61, 61, 11, 11, 11, 11, 11, 16, 16, 16, + 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11, + 11, 11, 11, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, + 11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, + 16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, + 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, + 16, 33, 16, 16, 16, 32, 16, 7, 43, 43, 43, 70, 61, 47, 43, 43, + 43, 43, 43, 43, 43, 43, 70, 61, 61, 61, 47, 61, 61, 61, 61, 61, + 61, 61, 70, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 56, 43, 43, + 16, 16, 16, 16, 16, 39, 16, 16, 43, 43, 43, 68, 40, 40, 40, 40, + 7, 7, 7, 7, 7, 7, 7, 71, 36, 36, 36, 36, 36, 36, 36, 43, + 36, 36, 36, 36, 36, 36, 43, 43, 7, 7, 7, 7, 7, 7, 7,170, + 16, 16, 43, 43, 43, 68, 40, 40, 27, 27, 27, 27, 27, 27,145, 27, + 171, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,145, + 27, 27, 27, 27, 27, 27, 84, 61, 61, 61, 61, 61, 61, 25, 41, 41, + 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, + 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, + 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, + 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, + 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5, + 6, 6, 24, 24, 6, 24, 12, 12, 6, 5, 9, 21, 25, 9, 26, 12, + 11, 11, 9, 6, 5, 21, 17, 17, 17, 26, 26, 23, 23, 12, 17, 12, + 21, 12, 12, 21, 7, 21, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, + 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, + 26, 7, 21, 1, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, + 21, 6, 10, 7, 7, 10, 23, 7, 15, 26, 13, 21, 13, 7, 15, 7, + 12, 23, 21, 26, 21, 15, 17, 7, 29, 7, 7, 22, 18, 18, 14, 14, + 14, 7, 10, 21, 17, 21, 11, 12, 5, 6, 8, 8, 8, 24, 5, 24, + 9, 24, 29, 29, 29, 1, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, + 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15, 6, 18, 6, + 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, + 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 22, 21, 21, 22, + 18, 17, 26, 6, 7, 14, 17, 22, 26, 14, 17, 6, 14, 6, 12, 24, + 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, + 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 7, 1, + 25, 24, 26, 1, 2, 2, 12, 15, 21, 14, 7, 15, 12, 17, 13, 15, + 26, 10, 10, 1, 13, 23, 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 35, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, + 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, + 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, + 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, + 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, + 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, + 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, + 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, + 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, + 75, 0, 0, 76, 77, 0, 0, 78, 79, 0, 80, 62, 0, 81, 82, 0, + 0, 83, 84, 85, 0, 0, 0, 86, 0, 87, 0, 0, 51, 88, 51, 0, + 89, 0, 90, 0, 0, 0, 79, 0, 0, 0, 91, 92, 0, 93, 94, 95, + 96, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 97, 98, 0, 0, 0, + 0, 99,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,101, 0, 0, + 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103,104, 0, 0,105, + 0, 0, 0, 0, 0, 0,106, 0, 0, 0,100, 0, 0, 0, 0, 0, + 107,108, 0, 0, 0, 0, 0, 0, 0,109, 0,110, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, + 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, + 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, + 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, + 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, + 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, + 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, + 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, + 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, + 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, + 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, + 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, + 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, + 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, + 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, + 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, + 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, + 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, + 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0,100, 93, + 0, 0,101, 0, 0, 0, 84, 0, 0,102, 0, 0, 0,103,104, 0, + 0,105,106, 0, 0, 0, 0, 0, 0,107, 0, 0,108, 0, 0, 0, + 0,109, 33, 0,110,111,112, 35, 0, 0,113, 0, 0, 0,114, 0, + 0, 0, 0, 0, 0,115, 0, 0,116, 0, 0, 0, 0,117, 88, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 52,118, 0, 0, 0, 0,119, + 0, 0,120, 0, 0, 0, 0,118, 0, 0, 0, 0, 0,121, 0, 0, + 0,122, 0, 0, 0,123, 0,124, 0, 0, 0, 0,125,126,127, 0, + 128, 0,129, 0, 0, 0,130,131,132, 0, 0, 0, 35, 0, 0, 0, + 133, 0, 0,134, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, + 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, + 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, + 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, + 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, + 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, + 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, + 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, + 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, + 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, + 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, + 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, + 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, + 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, + 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, + 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, + 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, + 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, + 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0, 0, 0, + 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102, 0, 0, + 103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, + 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0,105,106, + 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12, 84, 0, + 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61, 0,110, + 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0,111, 14, 52,112, 41, + 0, 0, 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, + 0, 0, 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, + 78, 55, 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, + 0, 0, 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, + 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 8, 91, + 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, 0,118, + 119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, 38, 58, + 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, 0, 0, + 0, 1, 4,122, 0, 0, 0, 1,123, 0, 0, 0, 0, 0,230,230, + 230,230,230,232,220,220,220,220,232,216,220,220,220,220,220,202, + 202,220,220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220, + 220,220,220,230,230,230,230,240,230,220,220,220,230,230,230,220, + 220, 0,230,230,230,220,220,220,220,230,232,220,220,230,233,234, + 234,233,234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230, + 220,230,230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, + 25, 0,230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, + 30, 31, 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, + 0, 0, 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, + 0, 0, 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230, + 220,230,220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230, + 230,230,230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, + 0,220, 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230, + 220,230,230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107, + 107,107,118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, + 0,220, 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0, + 130,130,130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0, + 220, 0, 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, + 0, 0, 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, + 0,220,230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, + 7, 0,230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230, + 230,230,230,230,232,228,228,220,218,230,233,220,230,220,230,230, + 1, 1, 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0, + 218,228,232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0, + 230,230,220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1, + 220, 0, 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, + 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, + 1, 0, 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216, + 216, 0,220,220,220, 0,230,230, 7, 0, 16, 17, 17, 17, 17, 17, + 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,129,169, + 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, + 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, + 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, + 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, + 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, + 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, + 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, + 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, + 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, + 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, + 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, + 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, + 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, + 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, + 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 11, 12, 12, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 12, 21, 12, 12, 12, 12, 22, + 23, 23, 23, 24, 12, 12, 12, 25, 26, 27, 12, 28, 29, 30, 31, 32, + 33, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, + 12, 36, 7, 7, 37, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 38, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 2, 2, 51, 51, 52, 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 57, 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61, + 56, 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 71, + 62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 74, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89, + 91, 92, 93, 94, 95, 95, 96, 97, 87, 98, 99,100,101,102,103,104, + 105,105,105, 2,106,107,108,109,110,111,112,113,114,115,116, 87, + 89,117,118,119,120,121,122,123,124,125,126, 87,127,128, 87,129, + 130,131,132, 87,133,134,135,136,137,138, 87, 87,139,140,141,142, + 87,143, 87,144,145,145,145,145,145,145,145,145,145,145,145, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87,146,147,147,147,147,147,147,147,147,147, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,148,148,148,148, + 148, 87, 87, 87,149,149,149,149,150,151,152,152, 87, 87, 87, 87, + 153,153,154,155,156,156,156,156,156,156,156,156,156,156,156,156, + 156,156,156,156,156,156,156,156,156,156,157,157,157,157,156, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87,158,159,160,161,162,162,162, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,163,164, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87,165, 56, 56, 56,166,167, 51, 56, 56, 87, 56, 56, 56, 56, + 56, 56, 56, 56,168,168,168,168,168,168, 87, 87, 87, 87, 87, 87, + 87, 87, 2, 87,169, 87,170, 87, 87,171, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 33,172,172,173, 87, 87, 87, 87, 87, 56, 56, 56, 87, + 89, 89, 87, 87, 56, 56, 56, 56,174, 87, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 87, 87, 87, 87, + 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, 62, 62, 87, 87, 87, 87, + 87, 87, 87, 87, 62, 62, 62, 62, 62, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 62, 62, 62, 62, 62, 62, 62, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 56, 87,175,175, 0, 1, 2, 2, 0, 1, 2, 2, + 2, 3, 4, 5, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, + 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, + 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 11, 11, + 11, 11, 12, 11, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 15, 16, 16, 16, 16, 16, 17, 18, 18, + 18, 18, 18, 18, 19, 20, 21, 21, 22, 23, 21, 24, 21, 21, 21, 21, + 21, 25, 21, 21, 26, 26, 26, 26, 26, 21, 21, 21, 27, 27, 27, 27, + 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 26, 21, 21, 21, 21, 21, + 21, 21, 31, 21, 32, 32, 32, 32, 32, 33, 34, 32, 35, 35, 35, 35, + 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, + 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, + 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, + 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, + 43, 43, 43, 43, 44, 44, 44, 45, 44, 44, 44, 44, 46, 46, 46, 46, + 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 48, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, + 50, 50, 50, 51, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, + 55, 55, 55, 55, 56, 56, 57, 57, 57, 57, 58, 57, 59, 59, 60, 61, + 62, 62, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 55, 55, 55, 55, 55, 67, 67, 67, 67, + 67, 68, 68, 68, 69, 69, 69, 69, 69, 69, 64, 64, 70, 70, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 8, 8, 8, 8, 8, 72, 72, 72, 72, + 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, + 75, 76, 76, 76, 13, 50, 50, 50, 73, 77, 78, 79, 4, 4, 80, 4, + 4, 81, 82, 83, 4, 4, 4, 84, 8, 8, 8, 8, 11, 11, 11, 11, + 11, 11, 11, 11, 85, 0, 0, 0, 0, 0, 0, 86, 0, 4, 0, 0, + 0, 8, 8, 8, 0, 0, 87, 88, 89, 0, 4, 4, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 90, + 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 4, 4, 92, 92, 92, 92, + 92, 92, 92, 92, 50, 50, 50, 93, 93, 93, 93, 93, 53, 53, 53, 53, + 53, 53, 13, 13, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 0, 95, 0, 96, 97, 98, 99, 99, 99, 99,100,101,102, + 102,102,102,103,104,104,104,105, 52, 52, 52, 52, 52, 0,104,104, + 0, 0, 0,102, 52, 52, 0, 0, 0, 0, 52,106, 0, 0, 0, 0, + 0,102,102,107,102,102,102,102,102,108, 0, 0, 94, 94, 94, 94, + 0, 0, 0, 0,109,109,109,109,109,109,109,109,109,109,109,109, + 109,110,110,110,111,111,111,111,111,111,111,111,111,111,111,111, + 13, 13, 13, 13, 13, 13,112,112,112,112,112,112, 0, 0,113, 4, + 4, 4, 4, 4,114, 4, 4, 4, 4, 4, 4, 4,115,115,115, 0, + 116,116,116,116,117,117,117,117,117,117, 32, 32,118,118,119,120, + 120,120, 52, 52,121,121,121,121,122,121, 49, 49,123,123,123,123, + 123,123, 49, 49,124,124,124,124,124,124,125,125, 53, 53, 53, 4, + 4,126,127, 54, 54, 54, 54, 54,125,125,125,125,128,128,128,128, + 128,128,128,128, 4,129, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21,130, 21, 21, 21, 21, 8, 0,131, 0, + 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21,132, 0, 0, 1, 2, + 1, 2,133,101,102,134, 52, 52, 52, 52, 0, 0,135,135,135,135, + 135,135,135,135, 0, 0, 0, 0, 11, 11, 11, 11, 11, 0, 11, 11, + 11, 0, 0,136,137,137,138,138,138,138,139, 0,140,140,140,141, + 141,142,142,142,143,143,144,144,144,144,144,144,145,145,145,145, + 145,146,146,146,147,147,147,148,148,148,148,148,149,149,149,150, + 150,150,150,151,151,151,151,151,151,151,151,151,152,152,152,152, + 152,152,152,152,153,153,153,153,154,154,155,155,156,156,156,156, + 156,156,157,157,158,158,159,159,159,159,159,159,160,160,161,161, + 161,161,161,161,162,162,162,162,162,162,163,163,164,164,164,164, + 165,165,165,165,166,166,166,166,167,167,168,168,169,169,169,169, + 169,169,169,169,170,170,170,170,170,170,170,170,171,171,171,171, + 171,171,171,171,172,172,172,172,172,172,172,172,173,173,173,173, + 173,173,173,173,174,174,174,175,175,175,175,176,176,176,176,177, + 177,177,178,178,179,179,179,179,179,179,179,179,180,180,180,180, + 180,181,181,181,182,182,182,182,182,183,183,183,184,184,184,184, + 184,184,185, 43,186,186,186,186,186,186,186,186,187,187,187,188, + 188,188,188,188,189,189,189,190,189,189,189,189,191,191,191,191, + 191,191,191,191,192,192,192,192,192,192,192,192,193,193,193,193, + 193,193,193,193,194,194,194,194,194,194, 66, 66,195,195,195,195, + 195,195,195,195,196,196,196,196,196,196,196,196,197,197,197,197, + 197,197,197,197,198,198,198,198,198,198,198,198,199,199,199,199, + 199,199,199,199,200,200,200,200,200,200,200,200,201,201,201,201, + 201,202,202,202,202,202,202, 55,203,203,203,203,204,204,204,204, + 204,204,204,205,205,205,205,205,205,205,205,205,206,206,206,206, + 206,206,207,207,207,207,207,207,207,207,207,207,208,208,208,208, + 208,208,208,208,110,110,110,110, 39, 39, 39, 39,209,209,209,209, + 209,209,209,209,210,210,210,210,210,210,210,210,211,211,211,211, + 211,211,211,211,212,212,212,212,212,212,212,212,112,112,112,112, + 112,112,112,112,112,112,112,112,213,213,213,214,214,214,214,214, + 214,215,215,215,216,216,216,216,216,216,216,216,217,217,217,217, + 217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218, + 218,218,219, 94,220,220,220,220,220,220,220,220,221,221,221,221, + 221,221,221,221,102,102,102,102,102,102,102,102,222, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,102,102, + 102, 99,223,224,224,224,224,224,224,224,224,224,225,225,225,225, + 225,225,225,225,225,225, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,226,227,228, 0,229, 0, + 0, 0, 0, 0,230,230,230,230,230,230,230,230, 91, 91, 91, 91, + 91, 91, 91, 91,231,231,231,231,231,231,231,231,232,232,232,232, + 233,233,233,233,234,234,234,234,234,234,234,234,235,235,235,235, + 235,235,235,235,236, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, + 8, 8, 8, 8, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, + 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, + 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 8, 10, 8, 11, 8, 8, + 8, 8, 8, 8, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 14, 14, + 16, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 19, 19, 19, 19, 19, + 20, 21, 20, 22, 20, 20, 23, 23, 20, 20, 20, 20, 22, 20, 24, 7, + 7, 25, 20, 20, 26, 20, 20, 20, 20, 20, 20, 21, 27, 27, 27, 27, + 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, + 32, 20, 20, 20, 33, 33, 33, 33, 34, 35, 33, 33, 33, 36, 33, 33, + 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, + 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, + 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 48, 48, 48, 48, + 49, 49, 49, 49, 49, 50, 51, 49, 52, 52, 52, 52, 53, 53, 53, 53, + 53, 53, 54, 53, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, + 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 61, 62, + 63, 63, 63, 63, 64, 64, 64, 64, 64, 65, 0, 0, 66, 66, 66, 66, + 67, 67, 67, 67, 68, 68, 68, 68, 69, 70, 71, 71, 71, 71, 71, 71, + 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, + 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, + 80, 80, 80, 80, 81, 81, 81, 81, 82, 7, 7, 7, 83, 7, 84, 85, + 0, 84, 86, 0, 2, 87, 88, 2, 2, 2, 2, 89, 90, 87, 91, 2, + 2, 2, 92, 2, 2, 2, 2, 93, 0, 0, 0, 86, 1, 0, 0, 94, + 0, 95, 96, 0, 4, 0, 0, 0, 0, 0, 0, 4, 97, 97, 97, 97, + 98, 98, 98, 98, 13, 13, 13, 13, 99, 99, 99, 99,100,100,100,100, + 0,101, 0, 0,102,100,103,104, 0, 0,100, 0,105,106,106,106, + 106,106,106,106,106,106,107,105,108,109,109,109,109,109,109,109, + 109,109,110,108,111,111,111,111,112, 55, 55, 55, 55, 55, 55,113, + 109,109,109,110,109,109, 0, 0,114,114,114,114,115,115,115,115, + 116,116,116,116,117,117,117,117, 96, 2, 2, 2, 2, 2, 94, 2, + 118,118,118,118,119,119,119,119,120,120,120,120,121,121,121,121, + 121,121,121,122,123,123,123,123,124,124,124,124,124,124,124,125, + 126,126,126,126,127,127,127,127,128,128,128,128, 2, 2, 3, 2, + 2,129,130, 0,131,131,131,131,132, 17, 17, 18, 20, 20, 20,133, + 7, 7, 7,134, 20, 20, 20, 23, 0,135,109,109,109,109,109,136, + 137,137,137,137, 0, 0, 0,138,139,139,139,139,140,140,140,140, + 84, 0, 0, 0,141,141,141,141,142,142,142,142,143,143,143,143, + 144,144,144,144,145,145,145,145,146,146,146,146,147,147,147,147, + 148,148,148,148,149,149,149,149,150,150,150,150,151,151,151,151, + 152,152,152,152,153,153,153,153,154,154,154,154,155,155,155,155, + 156,156,156,156,157,157,157,157,158,158,158,158,159,159,159,159, + 160,160,160,160,161,161,161,161,162,162,162,162,163,163,163,163, + 164,164,164,164,165,165,165,165,166,166,166,166,167,167,167,167, + 168,168,168,168,169,169,169,169,170,170,170,170,171,171,171,171, + 172,172,172,172,173,173,173,173,174,174,174,174,175,175,175,175, + 176,176,176,176,177,177,177,177,178,178,178,178,179,179,179,179, + 180,180,180,180,181,181,181,181,182,182,182,182,183,183,183,183, + 184,184,184,184,185,185,185,185,186, 45, 45, 45,187,187,187,187, + 188,188,188,188,189,189,189,189,190,190,190,190,190,190,191,190, + 192,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195, + 196,196,196,196,197,197,197,197,198,198,198,198,199,199,199,199, + 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, + 204,204,204,204,205,205,205,205,206,206,206,206,207,207,207,207, + 208,208,208,208,209,209,209,209,210,210,210,210,211,211,211,211, + 212,212,212,212,213,213,213,213,214,214,214,214,215,215,215,215, + 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, + 220,221,221,221,222,222,222,222,221,221,221,221,223,106,106,106, + 106,109,109,109,224,224,224,224,225,225,225,225, 0,226, 86, 0, + 0, 0,226, 7, 82,138, 7, 0, 0, 0,227, 86,228,228,228,228, + 229,229,229,229,230,230,230,230,231,231,231,231,232,232,232,232, + 233,233,233,233,234, 0, 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, + 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 0, 9, 9, 0, 9, 0, 9, 9, 55, 55, 55, 55, 55, 55, + 6, 6, 6, 6, 6, 1, 1, 6, 6, 4, 4, 4, 4, 4, 4, 4, + 4, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 0, 3, 3, + 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, + 1, 3, 3, 3, 37, 37, 37, 37, 38, 38, 38, 38, 64, 64, 64, 64, + 90, 90, 90, 90, 95, 95, 95, 95, 3, 3, 0, 3, 7, 7, 7, 7, + 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, + 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21, 22, 22, 22, 22, + 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20, 36, 36, 36, 36, + 24, 24, 24, 24, 24, 24, 24, 0, 18, 18, 18, 18, 25, 25, 25, 25, + 25, 0, 0, 0, 0, 25, 25, 25, 33, 33, 33, 33, 8, 8, 8, 8, + 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 29, 29, 29, 29, + 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 0, + 0, 0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44, 44, 0, 0, 0, + 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31, 32, 32, 0, 0, + 32, 0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 52, 52, 52, 52, + 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91, 62, 62, 62, 62, + 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 73, 73, 73, 73, + 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 0, 0, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, + 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, + 0, 0, 0, 19, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, + 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13, 0, 13, 0, 13, + 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 1, 1, 0, 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12, 12, 0, + 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, + 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75, 69, 69, 69, 69, + 69, 69, 0, 69, 74, 74, 74, 74, 84, 84, 84, 84, 84, 84, 84, 0, + 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87, 19, 9, 19, 19, + 19, 19, 0, 0, 2, 2, 2, 2, 19, 19, 19, 4, 3, 3, 0, 0, + 1, 1, 6, 6, 0, 0, 17, 17, 17, 17, 0, 0, 49, 49, 49, 49, + 0, 1, 1, 1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42, + 41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59, + 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135, + 106,106,106,106,104,104,104,104,161,161,161,161,110,110,110,110, + 47, 47, 47, 47, 81, 81, 81, 81,120,120,120,120,116,116,116,116, + 128,128,128,128, 66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, + 97, 97, 97, 97, 57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117, + 112,112,112,112, 78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82, + 122,122,122,122, 89, 89, 89, 89,130,130,130,130,144,144,144,144, + 156,156,156,156,147,147,147,147,148,148,148,148,158,158,158,158, + 153,153,153,153,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85, + 101,101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100, + 100, 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109, + 107,107,107,107,107,107,107, 1,137,137,137,137,124,124,124,124, + 123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126, + 142,142,142,142,125,125,125,125,154,154,154,154,150,150,150,150, + 141,141,141,141,140,140,140,140,121,121,121,121,133,133,133,133, + 134,134,134,134,138,138,138,138,143,143,143,143,145,145,145,145, + 63, 63, 63, 63,157,157,157,157, 80, 80, 80, 80,127,127,127,127, + 115,115,115,115,159,159,159,159,103,103,103,103,119,119,119,119, + 146,146,146,146, 99, 99, 99, 99,136,139, 13, 13,155,155,155,155, + 136,136,136,136, 17, 15, 15, 15,139,139,139,139,105,105,105,105, + 0, 0, 0, 1, 0, 0, 1, 1,131,131,131,131,151,151,151,151, + 160,160,160,160,152,152,152,152,113,113,113,113,132,132,132,132, + 15, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, + 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, + 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, + 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, + 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, + 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, + 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, + 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, + 101,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, + 0, 0,108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0, + 115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, + 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,128,129,130,131,132,133,134,135,136,137,138,139,140,141, + 142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, + 0, 0, 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, + 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, + 0, 0,173,174,175,176,177,178,179,180,181,182,183,184,185,186, + 187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202, + 203,204,205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, + 3, 4, +}; +static const uint16_t +_hb_ucd_u16[4888] = +{ + 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, + 13, 13, 13, 24, 25, 11, 11, 11, 11, 26, 11, 27, 28, 29, 30, 31, + 32, 32, 32, 32, 32, 32, 32, 33, 34, 35, 36, 11, 37, 38, 13, 39, + 9, 9, 9, 11, 11, 11, 13, 13, 40, 13, 13, 13, 41, 13, 13, 13, + 13, 13, 13, 35, 9, 42, 11, 11, 43, 44, 32, 45, 46, 47, 47, 48, + 49, 50, 47, 47, 51, 32, 52, 53, 47, 47, 47, 47, 47, 54, 55, 56, + 57, 58, 47, 32, 59, 47, 47, 47, 47, 47, 60, 53, 61, 47, 62, 63, + 47, 64, 65, 66, 47, 67, 47, 47, 68, 69, 47, 47, 70, 32, 71, 32, + 72, 47, 47, 73, 74, 75, 76, 77, 78, 47, 47, 79, 80, 81, 82, 83, + 84, 47, 47, 85, 86, 87, 88, 89, 84, 47, 47, 79, 90, 47, 82, 91, + 92, 47, 47, 93, 94, 95, 82, 96, 97, 47, 47, 98, 99, 100, 101, 102, + 103, 47, 47, 104, 105, 106, 82, 107, 108, 47, 47, 93, 109, 110, 82, 111, + 112, 47, 47, 113, 114, 115, 82, 116, 92, 47, 47, 47, 117, 118, 101, 119, + 47, 47, 47, 120, 121, 122, 66, 66, 47, 47, 47, 123, 124, 125, 47, 47, + 126, 127, 128, 129, 47, 47, 47, 130, 131, 32, 32, 132, 133, 134, 66, 66, + 47, 47, 135, 136, 122, 137, 138, 139, 140, 141, 9, 9, 9, 11, 11, 142, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 143, 144, 145, + 47, 146, 9, 9, 9, 9, 9, 147, 148, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 149, 47, 150, 151, 47, 47, 47, 47, 152, 153, + 47, 154, 47, 155, 47, 156, 47, 156, 47, 47, 47, 157, 158, 159, 160, 145, + 161, 160, 47, 47, 162, 47, 47, 47, 163, 47, 164, 47, 47, 47, 47, 47, + 47, 47, 165, 166, 167, 47, 47, 47, 47, 47, 47, 47, 47, 168, 146, 146, + 47, 169, 47, 47, 47, 170, 171, 172, 160, 160, 173, 174, 32, 32, 32, 32, + 175, 47, 47, 176, 177, 122, 178, 179, 180, 47, 181, 61, 47, 47, 182, 183, + 47, 47, 184, 185, 186, 61, 47, 187, 11, 9, 9, 9, 66, 188, 189, 190, + 11, 11, 191, 27, 27, 27, 192, 193, 11, 194, 27, 27, 32, 32, 32, 32, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 195, 13, 13, 13, 13, 13, 13, + 196, 196, 196, 196, 196, 197, 196, 11, 198, 198, 198, 199, 200, 201, 201, 200, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 27, 211, 211, 211, 212, 213, 32, + 214, 215, 216, 217, 218, 145, 219, 219, 220, 221, 222, 146, 223, 224, 146, 225, + 226, 226, 226, 226, 226, 226, 226, 226, 227, 146, 228, 146, 146, 146, 146, 229, + 146, 230, 226, 231, 146, 232, 233, 146, 146, 146, 146, 146, 146, 146, 145, 145, + 145, 234, 146, 146, 146, 146, 235, 145, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 236, 237, 146, 146, 238, 146, 146, 146, 146, 146, 146, 239, 146, + 146, 146, 146, 146, 146, 146, 240, 241, 145, 242, 146, 146, 243, 226, 244, 226, + 245, 246, 226, 226, 226, 247, 226, 248, 146, 146, 146, 226, 249, 146, 146, 146, + 9, 9, 9, 11, 11, 11, 250, 251, 13, 13, 13, 13, 13, 13, 252, 253, + 11, 11, 11, 47, 47, 47, 254, 255, 47, 47, 47, 47, 47, 47, 32, 32, + 256, 257, 258, 259, 260, 261, 262, 262, 263, 264, 265, 266, 267, 47, 47, 47, + 47, 268, 148, 47, 47, 47, 47, 269, 47, 270, 47, 47, 146, 146, 146, 47, + 146, 146, 271, 146, 272, 273, 146, 146, 271, 146, 146, 273, 146, 146, 146, 146, + 47, 47, 47, 47, 146, 146, 146, 146, 47, 274, 47, 47, 47, 47, 47, 47, + 47, 146, 146, 146, 146, 47, 47, 187, 275, 47, 61, 47, 13, 13, 276, 277, + 13, 278, 47, 47, 47, 47, 279, 280, 31, 281, 282, 283, 13, 13, 13, 284, + 285, 286, 287, 288, 289, 290, 11, 291, 292, 47, 293, 294, 47, 47, 47, 295, + 296, 47, 47, 297, 298, 160, 32, 299, 61, 47, 300, 47, 301, 302, 47, 47, + 72, 47, 47, 303, 304, 305, 306, 61, 47, 47, 307, 308, 309, 310, 47, 311, + 47, 47, 47, 312, 58, 313, 314, 315, 47, 47, 47, 11, 11, 316, 317, 11, + 11, 11, 11, 11, 47, 47, 318, 160, 319, 319, 319, 319, 319, 319, 319, 319, + 320, 320, 320, 320, 320, 320, 320, 320, 11, 321, 322, 47, 47, 47, 47, 47, + 47, 47, 47, 323, 31, 324, 47, 47, 47, 47, 47, 325, 146, 47, 47, 47, + 47, 47, 47, 47, 326, 146, 146, 327, 32, 328, 32, 329, 330, 331, 332, 47, + 47, 47, 47, 47, 47, 47, 47, 333, 334, 2, 3, 4, 5, 335, 336, 337, + 47, 338, 47, 47, 47, 47, 339, 340, 341, 145, 145, 342, 219, 219, 219, 343, + 344, 146, 146, 146, 146, 146, 146, 345, 346, 346, 346, 346, 346, 346, 346, 346, + 47, 47, 47, 47, 47, 47, 347, 145, 47, 47, 348, 47, 349, 47, 47, 60, + 47, 350, 47, 47, 47, 351, 219, 219, 9, 9, 147, 11, 11, 47, 47, 47, + 47, 47, 160, 9, 9, 147, 11, 11, 47, 47, 47, 47, 47, 47, 350, 9, + 9, 352, 11, 11, 11, 11, 11, 11, 27, 27, 27, 27, 27, 27, 27, 27, + 47, 47, 47, 47, 47, 353, 47, 354, 47, 47, 355, 145, 145, 145, 47, 356, + 47, 357, 47, 350, 66, 66, 66, 66, 47, 47, 47, 358, 145, 145, 145, 145, + 359, 47, 47, 360, 145, 66, 47, 361, 47, 362, 145, 145, 363, 47, 364, 66, + 47, 47, 47, 365, 47, 366, 47, 366, 47, 365, 144, 145, 145, 145, 145, 145, + 9, 9, 9, 9, 11, 11, 11, 367, 47, 47, 368, 160, 160, 160, 160, 160, + 145, 145, 145, 145, 145, 145, 145, 145, 47, 47, 369, 47, 47, 47, 47, 47, + 47, 362, 370, 47, 60, 371, 66, 47, 372, 66, 66, 47, 373, 145, 47, 47, + 374, 47, 47, 360, 375, 376, 377, 378, 180, 47, 47, 379, 380, 47, 47, 160, + 97, 47, 381, 382, 383, 47, 47, 384, 180, 47, 47, 385, 386, 387, 388, 145, + 47, 47, 389, 390, 32, 32, 32, 32, 47, 47, 365, 47, 47, 391, 172, 160, + 92, 47, 47, 113, 392, 393, 394, 32, 47, 47, 47, 395, 396, 397, 47, 47, + 47, 47, 47, 398, 399, 160, 160, 160, 47, 47, 400, 401, 402, 403, 32, 32, + 47, 47, 47, 404, 405, 160, 66, 66, 47, 47, 406, 407, 160, 160, 160, 160, + 47, 143, 408, 409, 47, 47, 47, 47, 47, 47, 389, 410, 66, 66, 66, 66, + 9, 9, 9, 9, 11, 11, 128, 411, 47, 47, 47, 412, 413, 160, 160, 160, + 47, 47, 47, 47, 47, 414, 415, 416, 417, 47, 47, 418, 419, 420, 47, 47, + 421, 422, 66, 47, 47, 47, 47, 47, 47, 47, 400, 423, 424, 128, 145, 425, + 47, 156, 426, 427, 32, 32, 32, 32, 47, 47, 47, 359, 428, 160, 47, 47, + 429, 430, 160, 160, 160, 160, 160, 160, 47, 47, 47, 47, 47, 47, 47, 431, + 47, 47, 47, 47, 145, 432, 433, 434, 219, 219, 219, 219, 219, 219, 219, 66, + 47, 47, 47, 47, 47, 47, 47, 424, 47, 47, 47, 208, 208, 208, 208, 208, + 47, 47, 47, 47, 47, 47, 305, 47, 47, 47, 47, 47, 160, 47, 47, 435, + 47, 47, 47, 436, 437, 438, 439, 47, 9, 9, 9, 9, 9, 9, 11, 11, + 145, 440, 66, 66, 66, 66, 66, 66, 47, 47, 47, 47, 391, 441, 416, 416, + 442, 443, 27, 27, 27, 27, 444, 416, 47, 445, 208, 208, 208, 208, 208, 208, + 32, 32, 32, 32, 32, 146, 146, 146, 146, 146, 146, 146, 146, 146, 446, 447, + 448, 146, 449, 146, 146, 146, 146, 146, 146, 146, 146, 146, 450, 146, 146, 146, + 9, 451, 11, 452, 453, 11, 196, 9, 454, 455, 9, 456, 11, 9, 451, 11, + 452, 453, 11, 196, 9, 454, 455, 9, 456, 11, 9, 451, 11, 452, 453, 11, + 196, 9, 454, 455, 9, 456, 11, 9, 451, 11, 196, 9, 457, 458, 459, 460, + 11, 461, 9, 462, 463, 464, 465, 11, 466, 9, 467, 11, 468, 160, 160, 160, + 32, 32, 32, 469, 32, 32, 470, 471, 472, 473, 32, 32, 32, 32, 32, 32, + 474, 11, 11, 11, 11, 11, 11, 11, 32, 32, 32, 32, 32, 32, 32, 32, + 47, 47, 47, 475, 476, 146, 146, 146, 47, 47, 477, 32, 47, 47, 478, 479, + 47, 47, 47, 47, 355, 32, 32, 32, 9, 9, 454, 11, 480, 305, 66, 66, + 145, 145, 481, 482, 145, 145, 145, 145, 145, 145, 483, 145, 145, 145, 145, 145, + 47, 47, 47, 47, 47, 47, 47, 226, 484, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 485, 146, 146, 146, 146, 146, 146, 146, 160, + 208, 208, 208, 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, + 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, + 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, + 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, + 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, + 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, + 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, + 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, + 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, + 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, + 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, + 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, + 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, + 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, + 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, + 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, + 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, + 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, + 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, + 1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, + 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, + 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, + 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, + 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, + 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, + 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, + 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, + 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, + 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, + 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, + 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, + 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, + 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, + 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, + 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, + 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, + 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, + 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, + 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, + 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, + 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, + 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, + 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, + 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, + 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, + 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, + 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, + 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, + 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, + 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, + 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, + 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, + 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, + 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, + 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, + 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, + 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, + 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, + 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, + 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, + 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, + 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, + 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, + 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, + 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, + 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, + 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, + 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, + 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, + 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, + 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, + 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, + 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, + 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, + 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, + 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, + 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, + 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, + 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, + 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, + 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, + 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, + 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, + 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, + 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, + 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, + 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, + 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, + 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, + 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, + 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, + 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, + 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, + 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, + 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, + 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, + 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, + 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, + 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, + 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, + 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, + 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, + 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, + 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, + 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, + 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, + 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, + 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, + 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, + 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, + 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, + 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, + 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, + 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, + 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, + 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, + 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, + 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, + 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, + 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, + 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, + 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, + 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, + 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, + 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, + 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, + 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, + 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, + 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, + 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, + 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, + 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, + 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, + 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, + 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, + 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, + 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, + 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, + 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, + 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, + 817, 818, 819, 820, 821, 935, 0, 0, +}; +static const int16_t +_hb_ucd_i16[196] = +{ + 0, 0, 0, 0, 1, -1, 0, 0, 2, 0, -2, 0, 0, 0, 0, 2, + 0, -2, 0, 0, 0, 0, 0, 16, 0, 0, 0, -16, 0, 0, 1, -1, + 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, 0, 3, 3, 3, -3, + -3, -3, 0, 0, 0, 2016, 0, 0, 0, 0, 0, 2527, 1923, 1914, 1918, 0, + 2250, 0, 0, 0, 0, 0, 0, 138, 0, 7, 0, 0, -7, 0, 0, 0, + 1, -1, 1, -1, -1, 1, -1, 0, 1824, 0, 0, 0, 0, 0, 2104, 0, + 2108, 2106, 0, 2106, 1316, 0, 0, 0, 0, 1, -1, 1, -1, -138, 0, 0, + 1, -1, 8, 8, 8, 0, 7, 7, 0, 0, -8, -8, -8, -7, -7, 0, + 1, -1, 0, 2,-1316, 1, -1, 0, -1, 1, -1, 1, -1, 3, 1, -1, + -3, 1, -1, 1, -1, 0, 0,-1914,-1918, 0, 0,-1923,-1824, 0, 0, 0, + 0,-2016, 0, 0, 1, -1, 0, 1, 0, 0,-2104, 0, 0, 0, 0,-2106, + -2108,-2106, 0, 0, 1, -1,-2250, 0, 0, 0,-2527, 0, 0, -2, 0, 1, + -1, 0, 1, -1, }; static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[4920+(((_hb_ucd_u8[1104+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>3>>5])<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114112u?_hb_ucd_u8[5056+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[6796+(((_hb_ucd_u8[6276+(((_hb_ucd_u8[5844+(((_hb_ucd_u8[5508+(((_hb_ucd_u8[5262+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[6970+(((_hb_ucd_u8[6426+(((_hb_ucd_u8[5982+(((_hb_ucd_u8[5646+(((_hb_ucd_u8[5400+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -6759,17 +6877,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7672+(((_hb_ucd_u8[7448+(((_hb_ucd_u8[7352+(((_hb_ucd_b4(7288+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7714+(((_hb_ucd_u8[7594+(((_hb_ucd_b4(7466+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11242+(((_hb_ucd_u8[10314+(((_hb_ucd_u8[8938+(((_hb_ucd_u8[8362+(((_hb_ucd_u8[7912+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918016u?_hb_ucd_u8[11480+(((_hb_ucd_u8[10532+(((_hb_ucd_u8[9124+(((_hb_ucd_u8[8500+(((_hb_ucd_u8[8050+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1536+(((_hb_ucd_u8[12544+(((_hb_ucd_u8[12162+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[1576+(((_hb_ucd_u8[12802+(((_hb_ucd_u8[12420+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #endif diff --git a/thirdparty/harfbuzz/src/hb-ucd.cc b/thirdparty/harfbuzz/src/hb-ucd.cc index ad72a26c04..baea224a25 100644 --- a/thirdparty/harfbuzz/src/hb-ucd.cc +++ b/thirdparty/harfbuzz/src/hb-ucd.cc @@ -203,9 +203,7 @@ hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, } -#if HB_USE_ATEXIT static void free_static_ucd_funcs (); -#endif static struct hb_ucd_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucd_unicode_funcs_lazy_loader_t> { @@ -222,21 +220,17 @@ static struct hb_ucd_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_ hb_unicode_funcs_make_immutable (funcs); -#if HB_USE_ATEXIT - atexit (free_static_ucd_funcs); -#endif + hb_atexit (free_static_ucd_funcs); return funcs; } } static_ucd_funcs; -#if HB_USE_ATEXIT -static +static inline void free_static_ucd_funcs () { static_ucd_funcs.free_instance (); } -#endif hb_unicode_funcs_t * hb_ucd_get_unicode_funcs () diff --git a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh index eb7776eecb..c216379201 100644 --- a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh +++ b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh @@ -6,14 +6,14 @@ * * on file with this header: * - * # emoji-data.txt - * # Date: 2020-01-28, 20:52:38 GMT - * # © 2020 Unicode®, Inc. + * # emoji-data-14.0.0.txt + * # Date: 2021-08-26, 17:22:22 GMT + * # © 2021 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use, see http://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Version: 13.0 + * # Used with Emoji Version 14.0 and subsequent minor revisions (if any) * # * # For documentation and usage, see http://www.unicode.org/reports/tr51 */ @@ -24,36 +24,42 @@ #include "hb-unicode.hh" static const uint8_t -_hb_emoji_u8[448] = +_hb_emoji_u8[544] = { - 0, 0, 0, 0, 33, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 17, 17, 17, 50, 20, 21, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,118,152, + 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, 84,118, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 7, 9, 10, 11, 0, - 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, - 7, 7, 7, 14, 15, 16, 17, 18, 19, 20, 7, 7, 7, 7, 7, 21, - 7, 7, 7, 7, 22, 23, 7, 7, 7, 24, 7, 14, 0, 25, 0, 26, - 27, 28, 29, 14, 30, 31, 7, 7, 7, 7, 7, 14, 0, 0, 0, 0, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 22, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 1, 0, 2, 0, 0, - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,254, 7, 3, - 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, - 159,255,243,255,255,255,255,255,255,255,255,255,255,255,255,255, - 31, 0,255,255,255,255,255,255, 31,255, 3, 0, 0, 0, 8, 0, - 0, 0, 24, 0,120, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 16, 0, 96, 0, 0, 8, 0, 0, 0, 0, - 255,255,255,255,255,255,255,127, 0, 96, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,240, 1, 64, 0, 0,254, 3, 0,224,255,255, - 255,255,255,255, 31, 0, 0, 0,254,127, 0, 0, 0, 0,252,115, - 0,254,255,255,255,255,255,255,255,255,255,255,255,255,255, 3, - 255,255,255,255,255,255,255, 31,192,255,255,255,255,255,255,255, - 255,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,127, - 0, 0,224,255,255,255,255,127, 0,112, 0, 0, 0, 0, 0, 0, - 0,127, 0,124, 0, 0, 0, 0, 0,127, 0, 0, 0,192,255,255, - 0,240,255,255,255,255,255,243,159,255,255,255,255,255,255,255, + 2, 3, 0, 0, 4, 0, 5, 0, 0, 0, 0, 0, 6, 0, 7, 8, + 0, 0, 0, 9, 0, 0, 10, 11, 12, 13, 14, 13, 15, 16, 17, 0, + 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, 0, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, + 13, 13, 13, 13, 23, 24, 25, 26, 27, 28, 13, 13, 13, 13, 13, 29, + 13, 13, 13, 13, 30, 31, 13, 13, 13, 32, 13, 13, 0, 33, 0, 34, + 35, 36, 37, 13, 38, 39, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 30, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 2, 0, 0,240, 3, 0, 6, 0, 0, + 0, 0, 0, 12, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0,128, 0, 0, 0,254, 15, 7, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 12, 64, 0, 1, 0, 0, 0, 0, 0, 0,120, + 191,255,247,255,255,255,255,255,255,255,255,255,255,255,255,255, + 63, 0,255,255,255,255,255,255, 63,255, 87, 32, 2, 1, 24, 0, + 144, 80,184, 0,248, 0, 0, 0, 0, 0,224, 0, 2, 0, 1,128, + 0, 0, 0, 0, 0, 0, 48, 0,224, 0, 0, 24, 0, 0, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, + 0, 0,128, 2, 0, 0, 0, 0, 0,224, 0, 0, 0,128, 0, 0, + 0, 0, 0, 0, 0,240, 3,192, 0, 64,254, 7, 0,224,255,255, + 255,255,255,255, 63, 0, 0, 0,254,255, 0, 4, 0,128,252,247, + 0,254,255,255,255,255,255,255,255,255,255,255,255,255,255, 7, + 255,255,255,255,255,255,255, 63,192,255,255,255,255,255,255,255, + 255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240,255, + 0, 0,224,255,255,255,255,255, 0,240, 0, 0, 0, 0, 0, 0, + 0,255, 0,252, 0, 0, 0, 0, 0,255, 0, 0, 0,192,255,255, + 0,240,255,255,255,255,255,247,191,255,255,255,255,255,255,255, }; static inline unsigned @@ -69,7 +75,7 @@ _hb_emoji_b1 (const uint8_t* a, unsigned i) static inline uint_fast8_t _hb_emoji_is_Extended_Pictographic (unsigned u) { - return u<131069u?_hb_emoji_b1(192+_hb_emoji_u8,((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>6>>4))<<4)+((u>>6)&15u))])<<6)+((u)&63u)):0; + return u<131070u?_hb_emoji_b1(224+_hb_emoji_u8,((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>6>>4))<<4)+((u>>6)&15u))])<<6)+((u)&63u)):0; } diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc index d7f6a6e130..83ead6398b 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.cc +++ b/thirdparty/harfbuzz/src/hb-unicode.cc @@ -268,7 +268,7 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) hb_unicode_funcs_destroy (ufuncs->parent); - free (ufuncs); + hb_free (ufuncs); } /** @@ -276,7 +276,7 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) * @ufuncs: The Unicode-functions structure * @key: The user-data key * @data: A pointer to the user data - * @destroy: (optional): A callback to call when @data is not needed anymore + * @destroy: (nullable): A callback to call when @data is not needed anymore * @replace: Whether to replace an existing data with the same key * * Attaches a user-data key/data pair to the specified Unicode-functions structure. @@ -340,7 +340,7 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) * Tests whether the specified Unicode-functions structure * is immutable. * - * Return value: %true if @ufuncs is immutable, false otherwise + * Return value: %true if @ufuncs is immutable, %false otherwise * * Since: 0.9.2 **/ @@ -421,7 +421,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * Calls the composition function of the specified * Unicode-functions structure @ufuncs. * - * Return value: %true if @a and @b composed, false otherwise + * Return value: %true if @a and @b composed, %false otherwise * * Since: 0.9.2 **/ @@ -446,7 +446,7 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, * Calls the decomposition function of the specified * Unicode-functions structure @ufuncs. * - * Return value: %true if @ab was decomposed, false otherwise + * Return value: %true if @ab was decomposed, %false otherwise * * Since: 0.9.2 **/ @@ -469,7 +469,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, * Fetches the compatibility decomposition of a Unicode * code point. Deprecated. * - * Return value: + * Return value: length of @decomposed. * * Since: 0.9.2 * Deprecated: 2.0.0 diff --git a/thirdparty/harfbuzz/src/hb-unicode.h b/thirdparty/harfbuzz/src/hb-unicode.h index 7ea0848c0f..c04ee15a09 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.h +++ b/thirdparty/harfbuzz/src/hb-unicode.h @@ -28,7 +28,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -41,7 +41,9 @@ HB_BEGIN_DECLS /** - * HB_UNICODE_MAX + * HB_UNICODE_MAX: + * + * Maximum valid Unicode code point. * * Since: 1.9.0 **/ @@ -427,7 +429,7 @@ typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs, * The method must return an #hb_bool_t indicating the success * of the composition. * - * Return value: True is @a,@b composed, false otherwise + * Return value: %true is @a,@b composed, %false otherwise * **/ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, @@ -451,7 +453,7 @@ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, * output parameters (if successful). The method must return an * #hb_bool_t indicating the success of the composition. * - * Return value: True if @ab decomposed, false otherwise + * Return value: %true if @ab decomposed, %false otherwise * **/ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, @@ -467,7 +469,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, * @ufuncs: A Unicode-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_unicode_combining_class_func_t. * @@ -483,7 +485,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, * @ufuncs: A Unicode-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_unicode_general_category_func_t. * @@ -499,7 +501,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, * @ufuncs: A Unicode-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_unicode_mirroring_func_t. * @@ -515,7 +517,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, * @ufuncs: A Unicode-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_unicode_script_func_t. * @@ -531,7 +533,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, * @ufuncs: A Unicode-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_unicode_compose_func_t. * @@ -547,7 +549,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, * @ufuncs: A Unicode-functions structure * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign * @user_data: Data to pass to @func - * @destroy: (optional): The function to call when @user_data is not needed anymore + * @destroy: (nullable): The function to call when @user_data is not needed anymore * * Sets the implementation function for #hb_unicode_decompose_func_t. * @@ -624,40 +626,12 @@ HB_EXTERN hb_script_t hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); -/** - * hb_unicode_compose: - * @ufuncs: The Unicode-functions structure - * @a: The first code point to compose - * @b: The second code point to compose - * @ab: (out): The composed code point - * - * Composes the code point sequence @a,@b by canonical equivalence into - * code point @ab. - * - * Return value: True is @a,@b composed, false otherwise - * - * Since: 0.9.2 - **/ HB_EXTERN hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab); -/** - * hb_unicode_decompose: - * @ufuncs: The Unicode-functions structure - * @ab: The code point to decompose - * @a: (out): The first decomposed code point - * @b: (out): The second decomposed code point - * - * Decomposes code point @ab by canonical equivalence, into code points - * @a and @b. - * - * Return value: True if @ab decomposed, false otherwise - * - * Since: 0.9.2 - **/ HB_EXTERN hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab, diff --git a/thirdparty/harfbuzz/src/hb-unicode.hh b/thirdparty/harfbuzz/src/hb-unicode.hh index 34d66d7aa3..0a79944107 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.hh +++ b/thirdparty/harfbuzz/src/hb-unicode.hh @@ -289,8 +289,8 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); #define HB_MODIFIED_COMBINING_CLASS_CCC15 18 /* tsere */ #define HB_MODIFIED_COMBINING_CLASS_CCC16 19 /* segol */ #define HB_MODIFIED_COMBINING_CLASS_CCC17 20 /* patah */ -#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats */ -#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam */ +#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats & qamats qatan */ +#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam & holam haser for vav*/ #define HB_MODIFIED_COMBINING_CLASS_CCC20 24 /* qubuts */ #define HB_MODIFIED_COMBINING_CLASS_CCC21 12 /* dagesh */ #define HB_MODIFIED_COMBINING_CLASS_CCC22 25 /* meteg */ @@ -359,6 +359,13 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) +#define HB_UNICODE_GENERAL_CATEGORY_IS_LETTER(gen_cat) \ + (FLAG_UNSAFE (gen_cat) & \ + (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER))) /* * Ranges, used for bsearch tables. diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc index 48a5dc50ad..3dc4c0937d 100644 --- a/thirdparty/harfbuzz/src/hb-uniscribe.cc +++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc @@ -44,6 +44,7 @@ #include "hb-uniscribe.h" +#include "hb-ms-feature-ranges.hh" #include "hb-open-file.hh" #include "hb-ot-name-table.hh" #include "hb-ot-layout.h" @@ -238,30 +239,26 @@ struct hb_uniscribe_shaper_funcs_t } }; -#if HB_USE_ATEXIT -static void free_static_uniscribe_shaper_funcs (); -#endif +static inline void free_static_uniscribe_shaper_funcs (); static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t<hb_uniscribe_shaper_funcs_t, hb_uniscribe_shaper_funcs_lazy_loader_t> { static hb_uniscribe_shaper_funcs_t *create () { - hb_uniscribe_shaper_funcs_t *funcs = (hb_uniscribe_shaper_funcs_t *) calloc (1, sizeof (hb_uniscribe_shaper_funcs_t)); + hb_uniscribe_shaper_funcs_t *funcs = (hb_uniscribe_shaper_funcs_t *) hb_calloc (1, sizeof (hb_uniscribe_shaper_funcs_t)); if (unlikely (!funcs)) return nullptr; funcs->init (); -#if HB_USE_ATEXIT - atexit (free_static_uniscribe_shaper_funcs); -#endif + hb_atexit (free_static_uniscribe_shaper_funcs); return funcs; } static void destroy (hb_uniscribe_shaper_funcs_t *p) { - free ((void *) p); + hb_free ((void *) p); } static hb_uniscribe_shaper_funcs_t *get_null () { @@ -269,13 +266,11 @@ static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t<hb_unis } } static_uniscribe_shaper_funcs; -#if HB_USE_ATEXIT -static +static inline void free_static_uniscribe_shaper_funcs () { static_uniscribe_shaper_funcs.free_instance (); } -#endif static hb_uniscribe_shaper_funcs_t * hb_uniscribe_shaper_get_funcs () @@ -284,44 +279,6 @@ hb_uniscribe_shaper_get_funcs () } -struct active_feature_t { - OPENTYPE_FEATURE_RECORD rec; - unsigned int order; - - HB_INTERNAL static int cmp (const void *pa, const void *pb) { - const active_feature_t *a = (const active_feature_t *) pa; - const active_feature_t *b = (const active_feature_t *) pb; - return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 : - a->order < b->order ? -1 : a->order > b->order ? 1 : - a->rec.lParameter < b->rec.lParameter ? -1 : a->rec.lParameter > b->rec.lParameter ? 1 : - 0; - } - bool operator== (const active_feature_t *f) - { return cmp (this, f) == 0; } -}; - -struct feature_event_t { - unsigned int index; - bool start; - active_feature_t feature; - - HB_INTERNAL static int cmp (const void *pa, const void *pb) - { - const feature_event_t *a = (const feature_event_t *) pa; - const feature_event_t *b = (const feature_event_t *) pb; - return a->index < b->index ? -1 : a->index > b->index ? 1 : - a->start < b->start ? -1 : a->start > b->start ? 1 : - active_feature_t::cmp (&a->feature, &b->feature); - } -}; - -struct range_record_t { - TEXTRANGE_PROPERTIES props; - unsigned int index_first; /* == start */ - unsigned int index_last; /* == end - 1 */ -}; - - /* * shaper face data */ @@ -391,7 +348,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) unsigned int name_table_offset = (length + 3) & ~3; new_length = name_table_offset + padded_name_table_length; - void *new_sfnt_data = calloc (1, new_length); + void *new_sfnt_data = hb_calloc (1, new_length); if (!new_sfnt_data) { hb_blob_destroy (blob); @@ -441,7 +398,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) } else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */ { - free (new_sfnt_data); + hb_free (new_sfnt_data); hb_blob_destroy (blob); return nullptr; } @@ -453,20 +410,20 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name) hb_blob_destroy (blob); return hb_blob_create ((const char *) new_sfnt_data, new_length, - HB_MEMORY_MODE_WRITABLE, new_sfnt_data, free); + HB_MEMORY_MODE_WRITABLE, new_sfnt_data, hb_free); } hb_uniscribe_face_data_t * _hb_uniscribe_shaper_face_data_create (hb_face_t *face) { - hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_face_data_t)); + hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) hb_calloc (1, sizeof (hb_uniscribe_face_data_t)); if (unlikely (!data)) return nullptr; data->funcs = hb_uniscribe_shaper_get_funcs (); if (unlikely (!data->funcs)) { - free (data); + hb_free (data); return nullptr; } @@ -477,7 +434,7 @@ _hb_uniscribe_shaper_face_data_create (hb_face_t *face) blob = _hb_rename_font (blob, data->face_name); if (unlikely (!blob)) { - free (data); + hb_free (data); return nullptr; } @@ -488,7 +445,7 @@ _hb_uniscribe_shaper_face_data_create (hb_face_t *face) if (unlikely (!data->fh)) { DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); - free (data); + hb_free (data); return nullptr; } @@ -499,7 +456,7 @@ void _hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data) { RemoveFontMemResourceEx (data->fh); - free (data); + hb_free (data); } @@ -533,7 +490,7 @@ populate_log_font (LOGFONTW *lf, hb_uniscribe_font_data_t * _hb_uniscribe_shaper_font_data_create (hb_font_t *font) { - hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t)); + hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) hb_calloc (1, sizeof (hb_uniscribe_font_data_t)); if (unlikely (!data)) return nullptr; @@ -580,7 +537,7 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data) DeleteObject (data->hfont); if (data->script_cache) ScriptFreeCache (&data->script_cache); - free (data); + hb_free (data); } /** @@ -635,109 +592,6 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, const hb_uniscribe_font_data_t *font_data = font->data.uniscribe; hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs; - /* - * Set up features. - */ - hb_vector_t<OPENTYPE_FEATURE_RECORD> feature_records; - hb_vector_t<range_record_t> range_records; - if (num_features) - { - /* Sort features by start/end events. */ - hb_vector_t<feature_event_t> feature_events; - for (unsigned int i = 0; i < num_features; i++) - { - active_feature_t feature; - feature.rec.tagFeature = hb_uint32_swap (features[i].tag); - feature.rec.lParameter = features[i].value; - feature.order = i; - - feature_event_t *event; - - event = feature_events.push (); - event->index = features[i].start; - event->start = true; - event->feature = feature; - - event = feature_events.push (); - event->index = features[i].end; - event->start = false; - event->feature = feature; - } - feature_events.qsort (); - /* Add a strategic final event. */ - { - active_feature_t feature; - feature.rec.tagFeature = 0; - feature.rec.lParameter = 0; - feature.order = num_features + 1; - - feature_event_t *event = feature_events.push (); - event->index = 0; /* This value does magic. */ - event->start = false; - event->feature = feature; - } - - /* Scan events and save features for each range. */ - hb_vector_t<active_feature_t> active_features; - unsigned int last_index = 0; - for (unsigned int i = 0; i < feature_events.length; i++) - { - feature_event_t *event = &feature_events[i]; - - if (event->index != last_index) - { - /* Save a snapshot of active features and the range. */ - range_record_t *range = range_records.push (); - - unsigned int offset = feature_records.length; - - active_features.qsort (); - for (unsigned int j = 0; j < active_features.length; j++) - { - if (!j || active_features[j].rec.tagFeature != feature_records[feature_records.length - 1].tagFeature) - { - feature_records.push (active_features[j].rec); - } - else - { - /* Overrides value for existing feature. */ - feature_records[feature_records.length - 1].lParameter = active_features[j].rec.lParameter; - } - } - - /* Will convert to pointer after all is ready, since feature_records.array - * may move as we grow it. */ - range->props.potfRecords = reinterpret_cast<OPENTYPE_FEATURE_RECORD *> (offset); - range->props.cotfRecords = feature_records.length - offset; - range->index_first = last_index; - range->index_last = event->index - 1; - - last_index = event->index; - } - - if (event->start) - { - active_features.push (event->feature); - } - else - { - active_feature_t *feature = active_features.find (&event->feature); - if (feature) - active_features.remove (feature - active_features.arrayZ); - } - } - - if (!range_records.length) /* No active feature found. */ - num_features = 0; - - /* Fixup the pointers. */ - for (unsigned int i = 0; i < range_records.length; i++) - { - range_record_t *range = &range_records[i]; - range->props.potfRecords = (OPENTYPE_FEATURE_RECORD *) feature_records + reinterpret_cast<uintptr_t> (range->props.potfRecords); - } - } - #define FAIL(...) \ HB_STMT_START { \ DEBUG_MSG (UNISCRIBE, nullptr, __VA_ARGS__); \ @@ -856,8 +710,23 @@ retry: nullptr, nullptr, &lang_count, &lang_tag); OPENTYPE_TAG language_tag = hb_uint32_swap (lang_count ? lang_tag : HB_TAG_NONE); - hb_vector_t<TEXTRANGE_PROPERTIES*> range_properties; - hb_vector_t<int> range_char_counts; + + /* + * Set up features. + */ + static_assert ((sizeof (TEXTRANGE_PROPERTIES) == sizeof (hb_ms_features_t)), ""); + static_assert ((sizeof (OPENTYPE_FEATURE_RECORD) == sizeof (hb_ms_feature_t)), ""); + hb_vector_t<hb_ms_feature_t> feature_records; + hb_vector_t<hb_ms_range_record_t> range_records; + bool has_features = false; + if (num_features) + has_features = hb_ms_setup_features (features, + num_features, + feature_records, + range_records); + + hb_vector_t<hb_ms_features_t*> range_properties; + hb_vector_t<uint32_t> range_char_counts; unsigned int glyphs_offset = 0; unsigned int glyphs_len; @@ -867,42 +736,14 @@ retry: unsigned int chars_offset = items[i].iCharPos; unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; - if (num_features) - { - range_properties.shrink (0); - range_char_counts.shrink (0); - - range_record_t *last_range = &range_records[0]; - - for (unsigned int k = chars_offset; k < chars_offset + item_chars_len; k++) - { - range_record_t *range = last_range; - while (log_clusters[k] < range->index_first) - range--; - while (log_clusters[k] > range->index_last) - range++; - if (!range_properties.length || - &range->props != range_properties[range_properties.length - 1]) - { - TEXTRANGE_PROPERTIES **props = range_properties.push (); - int *c = range_char_counts.push (); - if (unlikely (!props || !c)) - { - range_properties.shrink (0); - range_char_counts.shrink (0); - break; - } - *props = &range->props; - *c = 1; - } - else - { - range_char_counts[range_char_counts.length - 1]++; - } - - last_range = range; - } - } + if (has_features) + hb_ms_make_feature_ranges (feature_records, + range_records, + item_chars_len, + chars_offset, + log_clusters, + range_properties, + range_char_counts); /* Asking for glyphs in logical order circumvents at least * one bug in Uniscribe. */ @@ -914,8 +755,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ, - range_properties.arrayZ, + (int *) range_char_counts.arrayZ, + (TEXTRANGE_PROPERTIES**) range_properties.arrayZ, range_properties.length, pchars + chars_offset, item_chars_len, @@ -955,8 +796,8 @@ retry: &items[i].a, script_tags[i], language_tag, - range_char_counts.arrayZ, - range_properties.arrayZ, + (int *) range_char_counts.arrayZ, + (TEXTRANGE_PROPERTIES**) range_properties.arrayZ, range_properties.length, pchars + chars_offset, log_clusters + chars_offset, diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 079b94a6b4..110d457caf 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -69,7 +69,7 @@ struct hb_vector_t void fini () { - free (arrayZ); + hb_free (arrayZ); init (); } void fini_deep () @@ -80,7 +80,12 @@ struct hb_vector_t fini (); } - void reset () { resize (0); } + void reset () + { + if (unlikely (in_error ())) + allocated = length; // Big hack! + resize (0); + } hb_vector_t& operator = (const hb_vector_t &o) { @@ -172,6 +177,11 @@ struct hb_vector_t Type *push (T&& v) { Type *p = push (); + if (p == &Crap (Type)) + // If push failed to allocate then don't copy v, since this may cause + // the created copy to leak memory since we won't have stored a + // reference to it. + return p; *p = hb_forward<T> (v); return p; } @@ -181,7 +191,7 @@ struct hb_vector_t /* Allocate for size but don't adjust length. */ bool alloc (unsigned int size) { - if (unlikely (allocated < 0)) + if (unlikely (in_error ())) return false; if (likely (size <= (unsigned) allocated)) @@ -195,11 +205,11 @@ struct hb_vector_t Type *new_array = nullptr; bool overflows = - (int) new_allocated < 0 || + (int) in_error () || (new_allocated < (unsigned) allocated) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type)); if (likely (!overflows)) - new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type)); + new_array = (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type)); if (unlikely (!new_array)) { @@ -305,7 +315,7 @@ struct hb_sorted_vector_t : hb_vector_t<Type> { return as_array ().bsearch (x, not_found); } template <typename T> bool bfind (const T &x, unsigned int *i = nullptr, - hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE, unsigned int to_store = (unsigned int) -1) const { return as_array ().bfind (x, i, not_found, to_store); } }; diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index da377b9df6..70325f88eb 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#ifndef HB_H_IN +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) #error "Include <hb.h> instead." #endif @@ -36,12 +36,41 @@ HB_BEGIN_DECLS -#define HB_VERSION_MAJOR 2 -#define HB_VERSION_MINOR 7 -#define HB_VERSION_MICRO 4 +/** + * HB_VERSION_MAJOR: + * + * The major component of the library version available at compile-time. + */ +#define HB_VERSION_MAJOR 3 +/** + * HB_VERSION_MINOR: + * + * The minor component of the library version available at compile-time. + */ +#define HB_VERSION_MINOR 0 +/** + * HB_VERSION_MICRO: + * + * The micro component of the library version available at compile-time. + */ +#define HB_VERSION_MICRO 0 -#define HB_VERSION_STRING "2.7.4" +/** + * HB_VERSION_STRING: + * + * A string literal containing the library version available at compile-time. + */ +#define HB_VERSION_STRING "3.0.0" +/** + * HB_VERSION_ATLEAST: + * @major: the major component of the version number + * @minor: the minor component of the version number + * @micro: the micro component of the version number + * + * Tests the library version at compile-time against a minimum value, + * as three integer components. + */ #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) diff --git a/thirdparty/harfbuzz/src/hb.hh b/thirdparty/harfbuzz/src/hb.hh index 274a0e98db..829b5a1ab7 100644 --- a/thirdparty/harfbuzz/src/hb.hh +++ b/thirdparty/harfbuzz/src/hb.hh @@ -62,7 +62,6 @@ /* Error. Should never happen. */ #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR -#pragma GCC diagnostic error "-Wc++11-narrowing" #pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" @@ -75,6 +74,7 @@ #pragma GCC diagnostic error "-Wmissing-braces" #pragma GCC diagnostic error "-Wmissing-declarations" #pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wnarrowing" #pragma GCC diagnostic error "-Wnested-externs" #pragma GCC diagnostic error "-Wold-style-definition" #pragma GCC diagnostic error "-Wpointer-arith" @@ -117,6 +117,9 @@ #pragma GCC diagnostic ignored "-Wshadow" // TODO fix #pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations" // TODO fix #pragma GCC diagnostic ignored "-Wunused-parameter" // TODO fix +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic ignored "-Wunused-result" // TODO fix +#endif #endif /* Ignored intentionally. */ @@ -126,6 +129,7 @@ #pragma GCC diagnostic ignored "-Wformat-zero-length" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang +#pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834 #pragma GCC diagnostic ignored "-Wstrict-aliasing" #pragma GCC diagnostic ignored "-Wtype-limits" #pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it @@ -175,15 +179,18 @@ #include "hb-aat.h" #define HB_AAT_H_IN -#include <limits.h> -#include <math.h> -#include <float.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <assert.h> -#include <stdio.h> -#include <stdarg.h> +#include <cassert> +#include <cfloat> +#include <climits> +#ifdef _MSC_VER +# define _USE_MATH_DEFINES +#endif +#include <cmath> +#include <cstdarg> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <cstring> #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) #ifdef __MINGW32_VERSION @@ -219,10 +226,15 @@ extern "C" void* hb_malloc_impl(size_t size); extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); extern "C" void* hb_realloc_impl(void *ptr, size_t size); extern "C" void hb_free_impl(void *ptr); -#define malloc hb_malloc_impl -#define calloc hb_calloc_impl -#define realloc hb_realloc_impl -#define free hb_free_impl +#define hb_malloc hb_malloc_impl +#define hb_calloc hb_calloc_impl +#define hb_realloc hb_realloc_impl +#define hb_free hb_free_impl +#else +#define hb_malloc malloc +#define hb_calloc calloc +#define hb_realloc realloc +#define hb_free free #endif @@ -244,12 +256,8 @@ extern "C" void hb_free_impl(void *ptr); #endif #if defined(__GNUC__) && (__GNUC__ >= 3) -#define HB_PURE_FUNC __attribute__((pure)) -#define HB_CONST_FUNC __attribute__((const)) #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) #else -#define HB_PURE_FUNC -#define HB_CONST_FUNC #define HB_PRINTF_FUNC(format_idx, arg_idx) #endif #if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__) @@ -338,7 +346,6 @@ extern "C" void hb_free_impl(void *ptr); #else # define HB_NODISCARD #endif -#define hb_success_t HB_NODISCARD bool /* https://github.com/harfbuzz/harfbuzz/issues/1852 */ #if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__))) @@ -379,7 +386,7 @@ extern "C" void hb_free_impl(void *ptr); # define HB_NO_SETLOCALE # define HB_NO_ERRNO # endif -# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# elif !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # ifndef HB_NO_GETENV # define HB_NO_GETENV # endif @@ -394,13 +401,16 @@ extern "C" void hb_free_impl(void *ptr); #endif #ifndef HB_NO_ERRNO -# include <errno.h> +# include <cerrno> #else static int HB_UNUSED _hb_errno = 0; # undef errno # define errno _hb_errno #endif +#define HB_STMT_START do +#define HB_STMT_END while (0) + #if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT) /* atexit() is only safe to be called from shared libraries on certain * platforms. Whitelist. @@ -429,192 +439,30 @@ static int HB_UNUSED _hb_errno = 0; */ # define HB_USE_ATEXIT 1 # endif -#endif +#endif /* defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT) */ #ifdef HB_NO_ATEXIT # undef HB_USE_ATEXIT #endif #ifndef HB_USE_ATEXIT # define HB_USE_ATEXIT 0 #endif - -#define HB_STMT_START do -#define HB_STMT_END while (0) - -/* Static-assert as expression. */ -template <unsigned int cond> class hb_assert_constant_t; -template <> class hb_assert_constant_t<1> {}; -#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) +#if !HB_USE_ATEXIT +# define hb_atexit(_) HB_STMT_START { if (0) (_) (); } HB_STMT_END +#else /* HB_USE_ATEXIT */ +# ifdef HAVE_ATEXIT +# define hb_atexit atexit +# else + template <void (*function) (void)> struct hb_atexit_t { ~hb_atexit_t () { function (); } }; +# define hb_atexit(f) static hb_atexit_t<f> _hb_atexit_##__LINE__; +# endif +#endif /* Lets assert int types. Saves trouble down the road. */ -static_assert ((sizeof (int8_t) == 1), ""); -static_assert ((sizeof (uint8_t) == 1), ""); -static_assert ((sizeof (int16_t) == 2), ""); -static_assert ((sizeof (uint16_t) == 2), ""); -static_assert ((sizeof (int32_t) == 4), ""); -static_assert ((sizeof (uint32_t) == 4), ""); -static_assert ((sizeof (int64_t) == 8), ""); -static_assert ((sizeof (uint64_t) == 8), ""); static_assert ((sizeof (hb_codepoint_t) == 4), ""); static_assert ((sizeof (hb_position_t) == 4), ""); static_assert ((sizeof (hb_mask_t) == 4), ""); static_assert ((sizeof (hb_var_int_t) == 4), ""); -#define HB_DELETE_COPY_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete -#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ - TypeName() = delete; \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete - - -/* Flags */ - -/* Enable bitwise ops on enums marked as flags_t */ -/* To my surprise, looks like the function resolver is happy to silently cast - * one enum to another... So this doesn't provide the type-checking that I - * originally had in mind... :(. - * - * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 - */ -#ifdef _MSC_VER -# pragma warning(disable:4200) -# pragma warning(disable:4800) -#endif -#define HB_MARK_AS_FLAG_T(T) \ - extern "C++" { \ - static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ - static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ - static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ - static inline T operator ~ (T r) { return T (~(unsigned int) r); } \ - static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ - static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ - static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ - } \ - static_assert (true, "") - -/* Useful for set-operations on small enums. - * For example, for testing "x ∈ {x1, x2, x3}" use: - * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) - */ -#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) -#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) -#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) -#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) -#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) - - -/* Size signifying variable-sized array */ -#ifndef HB_VAR_ARRAY -#define HB_VAR_ARRAY 1 -#endif - -static inline float -_hb_roundf (float x) { return floorf (x + .5f); } -#define roundf(x) _hb_roundf(x) - -/* Endian swap, used in Windows related backends */ -static inline uint16_t hb_uint16_swap (const uint16_t v) -{ return (v >> 8) | (v << 8); } -static inline uint32_t hb_uint32_swap (const uint32_t v) -{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } - -/* - * Big-endian integers. Here because fundamental. - */ - -template <typename Type, int Bytes> struct BEInt; - -template <typename Type> -struct BEInt<Type, 1> -{ - public: - BEInt<Type, 1>& operator = (Type V) - { - v = V; - return *this; - } - operator Type () const { return v; } - private: uint8_t v; -}; -template <typename Type> -struct BEInt<Type, 2> -{ - public: - BEInt<Type, 2>& operator = (Type V) - { - v[0] = (V >> 8) & 0xFF; - v[1] = (V ) & 0xFF; - return *this; - } - operator Type () const - { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ - defined(__BYTE_ORDER) && \ - (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) - /* Spoon-feed the compiler a big-endian integer with alignment 1. - * https://github.com/harfbuzz/harfbuzz/pull/1398 */ - struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; -#if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) this)->v); -#else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) this)->v; -#endif -#endif - return (v[0] << 8) - + (v[1] ); - } - private: uint8_t v[2]; -}; -template <typename Type> -struct BEInt<Type, 3> -{ - public: - BEInt<Type, 3>& operator = (Type V) - { - v[0] = (V >> 16) & 0xFF; - v[1] = (V >> 8) & 0xFF; - v[2] = (V ) & 0xFF; - return *this; - } - operator Type () const - { - return (v[0] << 16) - + (v[1] << 8) - + (v[2] ); - } - private: uint8_t v[3]; -}; -template <typename Type> -struct BEInt<Type, 4> -{ - public: - BEInt<Type, 4>& operator = (Type V) - { - v[0] = (V >> 24) & 0xFF; - v[1] = (V >> 16) & 0xFF; - v[2] = (V >> 8) & 0xFF; - v[3] = (V ) & 0xFF; - return *this; - } - operator Type () const - { - return (v[0] << 24) - + (v[1] << 16) - + (v[2] << 8) - + (v[3] ); - } - private: uint8_t v[4]; -}; - - -/* - * For lack of a better place, put Zawgyi script hack here. - * https://github.com/harfbuzz/harfbuzz/issues/1162 - */ - -#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) - /* Headers we include for everyone. Keep topologically sorted by dependency. * They express dependency amongst themselves, but no other file should include |