diff options
Diffstat (limited to 'thirdparty')
140 files changed, 4225 insertions, 5216 deletions
diff --git a/thirdparty/README.md b/thirdparty/README.md index 0eb227d0f9..b05f074bd6 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -174,7 +174,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 2.7.4 (7236c7e29cef1c2d76c7a284c5081ff4d3aa1127, 2020) +- Version: 2.8.0 (03538e872a0610a65fad692b33d3646f387cf578, 2021) - License: MIT Files extracted from upstream source: @@ -355,17 +355,20 @@ Files extracted from upstream repository: ## miniupnpc -- Upstream: https://github.com/miniupnp/miniupnp/tree/master/miniupnpc -- Version: git (44366328661826603982d1e0d7ebb4062c5f2bfc, 2020) +- Upstream: https://github.com/miniupnp/miniupnp +- Version: 2.2.2 (81029a860baf1f727903e5b85307903b3f40cbc8, 2021) - License: BSD-3-Clause Files extracted from upstream source: - All `*.c` and `*.h` files from `miniupnpc` to `thirdparty/miniupnpc/miniupnpc` -- Remove `test*`, `minihttptestserver.c` and `wingenminiupnpcstrings.c` +- Remove the following test or sample files: + `listdevices.c minihttptestserver.c miniupnpcmodule.c upnpc.c upnperrors.* test* wingenminiupnpcstrings.c` +- `LICENSE` -The only modified file is miniupnpcstrings.h, which was created for Godot -(it is usually autogenerated by cmake). +The only modified file is `miniupnpcstrings.h`, which was created for Godot +(it is usually autogenerated by cmake). Bump the version number for miniupnpc in that +file when upgrading. ## minizip diff --git a/thirdparty/harfbuzz/NEWS b/thirdparty/harfbuzz/NEWS index f09c2fafd1..321c550188 100644 --- a/thirdparty/harfbuzz/NEWS +++ b/thirdparty/harfbuzz/NEWS @@ -1,3 +1,18 @@ +Overview of changes leading to 2.8.0 +Tuesday, March 16, 2021 +==================================== +- Shape joining scripts other than Arabic/Syriac using the Universal Shaping Engine. + Previously these were shaped using the generalized Arabic shaper. (David Corbett) +- Fix regression in shaping of U+0B55 ORIYA SIGN OVERLINE. (David Corbett) +- Update language tags. (David Corbett) +- Variations: reduce error: do not round each interpolated delta. (Just van Rossum) +- Documentation improvements. (Khaled Hosny, Nathan Willis) +- Subsetter improvements: subsets most, if not all, lookup types now. (Garret Rieger, Qunxin Liu) +- Fuzzer-found fixes and other improvements when memory failures happen. (Behdad) +- Removed most atomic implementations now that we have C++11 atomic impl. (Behdad) +- General codebase upkeep; using more C++11 features: constexpr constructors, etc. (Behdad) + + Overview of changes leading to 2.7.4 Sunday, December 27, 2020 ==================================== diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index 75d523f5fc..98ed20d8eb 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -510,7 +510,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 +576,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 +597,7 @@ struct StateTable if (unlikely (stop < states)) return_trace (false); for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++) - num_entries = hb_max (num_entries, *p + 1); + num_entries = hb_max (num_entries, *p + 1u); state_pos = max_state + 1; } } @@ -729,7 +729,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 +745,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; }; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index 04027a61be..e3bc268d26 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -337,9 +337,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)); @@ -499,7 +499,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 +525,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; } } @@ -733,17 +733,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 +763,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 +784,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.cc b/thirdparty/harfbuzz/src/hb-aat-layout.cc index 74ebaa64ec..0e9f2b4954 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout.cc +++ b/thirdparty/harfbuzz/src/hb-aat-layout.cc @@ -227,7 +227,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 */ @@ -294,7 +294,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 */ @@ -325,7 +325,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 +350,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 +374,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 +388,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-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index 98de61f3e8..bc170b0546 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); @@ -988,32 +1153,24 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o struct hb_bitwise_and { 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 { 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 { 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 { 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) } diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index 568cd02c79..02bd8d81c2 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -142,7 +142,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> bool lfind (const T &x, unsigned *pos = nullptr) 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; 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-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc index e340bc346d..71b1b1fc4f 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. @@ -116,7 +113,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. @@ -237,7 +234,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 +296,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 +362,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 +435,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; diff --git a/thirdparty/harfbuzz/src/hb-blob.h b/thirdparty/harfbuzz/src/hb-blob.h index 00e41f3ce3..86f12788d2 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. 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..8cad6ab8e6 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -218,9 +218,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 +230,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; @@ -290,9 +284,6 @@ 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; @@ -303,9 +294,6 @@ hb_buffer_t::remove_output () void hb_buffer_t::clear_output () { - if (unlikely (hb_object_is_immutable (this))) - return; - have_output = true; have_positions = false; @@ -316,9 +304,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; @@ -333,15 +318,19 @@ hb_buffer_t::swap_buffers () { if (unlikely (!successful)) return; + assert (idx <= len); + if (unlikely (!next_glyphs (len - idx))) return; + assert (have_output); have_output = false; if (out_info != info) { - hb_glyph_info_t *tmp_string; - tmp_string = info; + hb_glyph_info_t *tmp; + tmp = info; info = out_info; - out_info = tmp_string; + out_info = tmp; + pos = (hb_glyph_position_t *) out_info; } @@ -353,31 +342,6 @@ hb_buffer_t::swap_buffers () 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) { @@ -768,7 +732,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 +759,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 +1101,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 +1186,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 +1204,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 +1291,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 */ @@ -1501,20 +1471,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 +1521,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 +1741,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,6 +1752,11 @@ 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])); @@ -1902,8 +1875,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 +1967,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..8b432b5f96 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.hh +++ b/thirdparty/harfbuzz/src/hb-buffer.hh @@ -139,7 +139,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,7 +186,7 @@ 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_NODISCARD bool has_separate_output () const { return info != out_info; } HB_INTERNAL void reset (); @@ -210,86 +210,89 @@ struct hb_buffer_t 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 +332,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 +352,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 +363,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 +375,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); diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index ddbcaa064c..7bb878b217 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -675,8 +675,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 +1003,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 +1044,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 +1077,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. * - * Return value: Alpha channel value of the given color + * Fetches the alpha channel of the given @color. + * + * Return value: Alpha channel value * * Since: 2.1.0 */ @@ -1069,9 +1093,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 +1109,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 +1125,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..532fd428cb 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,164 @@ 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_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 +485,208 @@ 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*/ /* 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 +731,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 +775,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 +799,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 +827,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-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc index 7b6b2bd5ef..461bd20e65 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); @@ -346,7 +348,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 +404,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 +860,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 +882,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, @@ -1062,7 +1064,7 @@ resize_and_retry: hb_position_t x_offset = (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 */ @@ -1078,7 +1080,7 @@ resize_and_retry: hb_position_t y_offset = (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 */ diff --git a/thirdparty/harfbuzz/src/hb-deprecated.h b/thirdparty/harfbuzz/src/hb-deprecated.h index 43f89a4c4e..5f19125789 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, @@ -73,6 +112,11 @@ 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 +126,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 +143,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 +160,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 +168,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 +192,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 +215,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..a07302159c 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -957,6 +957,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 +976,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.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..61bd4af7b1 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -89,8 +89,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,7 +100,7 @@ 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 @@ -235,7 +235,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 **/ @@ -299,7 +299,7 @@ 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. @@ -360,7 +360,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 **/ @@ -756,7 +756,7 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) 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()) + if (unlikely (data->tables.in_error())) return false; entry->tag = tag; 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..37a0e7fe85 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -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 **/ @@ -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. @@ -2212,10 +2218,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 * @@ -2319,7 +2329,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..b82c1a67bd 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -84,7 +84,7 @@ 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; }; @@ -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; @@ -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++) @@ -661,7 +661,7 @@ _hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data /** * 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 +771,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 +814,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. @@ -884,8 +884,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, diff --git a/thirdparty/harfbuzz/src/hb-gdi.cc b/thirdparty/harfbuzz/src/hb-gdi.cc index 3a67cef160..dc4659c7f6 100644 --- a/thirdparty/harfbuzz/src/hb-gdi.cc +++ b/thirdparty/harfbuzz/src/hb-gdi.cc @@ -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-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..9dafe654c8 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -195,6 +195,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 +289,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-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index 981c5c218c..f7018150e4 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -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..3bd5a979b0 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 \ diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc index f898bd8f92..f115da2bb8 100644 --- a/thirdparty/harfbuzz/src/hb-map.cc +++ b/thirdparty/harfbuzz/src/hb-map.cc @@ -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 **/ @@ -230,7 +230,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 **/ @@ -253,6 +253,9 @@ hb_map_has (const hb_map_t *map, void hb_map_clear (hb_map_t *map) { + if (unlikely (hb_object_is_immutable (map))) + return; + return map->clear (); } 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..84fe1d549b 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -97,8 +97,6 @@ struct hb_hashmap_t void reset () { - if (unlikely (hb_object_is_immutable (this))) - return; successful = true; clear (); } @@ -171,8 +169,6 @@ struct hb_hashmap_t void clear () { - if (unlikely (hb_object_is_immutable (this))) - return; if (items) for (auto &_ : hb_iter (items, mask + 1)) _.clear (); @@ -181,6 +177,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; } diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index 4c0898b1b7..e40d9fd178 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. */ @@ -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) || @@ -292,6 +298,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-mutex.hh b/thirdparty/harfbuzz/src/hb-mutex.hh index 56392d049b..2fc8d7ee58 100644 --- a/thirdparty/harfbuzz/src/hb-mutex.hh +++ b/thirdparty/harfbuzz/src/hb-mutex.hh @@ -73,24 +73,6 @@ 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; diff --git a/thirdparty/harfbuzz/src/hb-object.hh b/thirdparty/harfbuzz/src/hb-object.hh index 39845a70e7..f3048b1c3e 100644 --- a/thirdparty/harfbuzz/src/hb-object.hh +++ b/thirdparty/harfbuzz/src/hb-object.hh @@ -140,9 +140,7 @@ 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)} +#define HB_REFERENCE_COUNT_INIT {0} struct hb_reference_count_t { @@ -152,9 +150,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 +195,10 @@ 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; }; -#define HB_OBJECT_HEADER_STATIC \ - { \ - HB_REFERENCE_COUNT_INIT, \ - HB_ATOMIC_INT_INIT (false), \ - HB_ATOMIC_PTR_INIT (nullptr) \ - } +#define HB_OBJECT_HEADER_STATIC {} /* diff --git a/thirdparty/harfbuzz/src/hb-open-file.hh b/thirdparty/harfbuzz/src/hb-open-file.hh index ac13dd23c3..54c07ff13c 100644 --- a/thirdparty/harfbuzz/src/hb-open-file.hh +++ b/thirdparty/harfbuzz/src/hb-open-file.hh @@ -48,7 +48,7 @@ namespace OT { */ struct OpenTypeFontFile; -struct OffsetTable; +struct OpenTypeOffsetTable; struct TTCHeader; @@ -78,7 +78,7 @@ typedef struct TableRecord DEFINE_SIZE_STATIC (16); } OpenTypeTable; -typedef struct OffsetTable +typedef struct OpenTypeOffsetTable { friend struct OpenTypeFontFile; @@ -218,7 +218,7 @@ struct TTCHeaderVersion1 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ - LArrayOf<LOffsetTo<OffsetTable>> + LArrayOf<LOffsetTo<OpenTypeOffsetTable>> table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index 99634b76f0..dc0ae1d989 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); }; diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh index e5286cd792..864a27f458 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh @@ -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); 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-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..878e02ff17 100644 --- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh @@ -95,7 +95,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 +131,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 +170,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]) { @@ -696,7 +696,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 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) { diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh index aaa1c37c64..e285acec3d 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; @@ -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; diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index 92a49bb4f4..e2a1ff4662 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -214,7 +214,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); 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-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-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh index 5470bd96da..5352156f02 100644 --- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh @@ -186,7 +186,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))); } @@ -944,9 +944,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: 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-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 6ab950a322..0ba7e3c061 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -1128,7 +1128,7 @@ 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); }) @@ -1251,8 +1251,9 @@ struct CoverageFormat1 { /* TODO Speed up, using hb_set_next() and bsearch()? */ unsigned int count = glyphArray.len; + const HBGlyphID *arr = glyphArray.arrayZ; for (unsigned int i = 0; i < count; i++) - if (glyphs->has (glyphArray[i])) + if (glyphs->has (arr[i])) return true; return false; } @@ -1356,18 +1357,21 @@ 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. */ + unsigned count = rangeRecord.len; + const RangeRecord *arr = rangeRecord.arrayZ; + for (unsigned i = 0; i < count; i++) + if (arr[i].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. */ + unsigned count = rangeRecord.len; + const RangeRecord *arr = rangeRecord.arrayZ; + for (unsigned i = 0; i < count; i++) { + const RangeRecord &range = arr[i]; if (range.value <= index && index < (unsigned int) range.value + (range.last - range.first) && range.intersects (glyphs)) @@ -1502,7 +1506,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 = @@ -1729,7 +1733,7 @@ struct ClassDefFormat1 hb_map_t *klass_map = nullptr /*OUT*/) 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; @@ -1784,7 +1788,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 +1806,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,8 +1819,12 @@ 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; } @@ -1898,7 +1906,7 @@ struct ClassDefFormat2 hb_map_t *klass_map = nullptr /*OUT*/) 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; @@ -1961,11 +1969,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,8 +1995,12 @@ 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; } diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index 2217d298fb..f523e35c00 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -566,6 +566,26 @@ struct AnchorMatrix return_trace (true); } + bool subset (hb_subset_context_t *c, + unsigned cols, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + + auto indexes = + + hb_range (rows * cols) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % cols); }) + ; + + out->serialize (c->serializer, + (unsigned) rows, + this, + c->plan->layout_variation_idx_map, + indexes); + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const { TRACE_SANITIZE (this); @@ -755,7 +775,7 @@ struct SinglePosFormat1 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 = @@ -870,7 +890,7 @@ struct SinglePosFormat2 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 (); @@ -1129,7 +1149,7 @@ 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 (); @@ -1250,7 +1270,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); @@ -1441,7 +1461,7 @@ struct PairPosFormat2 }) ; - 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; auto it = @@ -1728,7 +1748,7 @@ struct CursivePosFormat1 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); @@ -1904,7 +1924,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); @@ -2025,10 +2045,37 @@ 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 : OffsetListOf<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); + + matrix->serialize_subset (c, + _.second, + this, + class_count, + klass_mapping); + } + return_trace (this->len); + } +}; struct MarkLigPosFormat1 { @@ -2130,8 +2177,56 @@ 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 (c->serializer, out) + .serialize (c->serializer, new_mark_coverage)) + 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)); + + auto new_ligature_coverage = + + hb_iter (this + ligatureCoverage) + | hb_filter (glyphset) + | hb_map_retains_sorting (glyph_map) + ; + + if (!out->ligatureCoverage.serialize (c->serializer, out) + .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 @@ -2164,6 +2259,7 @@ struct MarkLigPosFormat1 DEFINE_SIZE_STATIC (12); }; + struct MarkLigPos { template <typename context_t, typename ...Ts> @@ -2288,7 +2384,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); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index 2f41d67819..5f10ecb7ee 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -356,7 +356,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); @@ -447,7 +447,7 @@ struct MultipleSubstFormat1 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); @@ -582,7 +582,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 = @@ -682,7 +682,7 @@ struct AlternateSubstFormat1 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); @@ -840,7 +840,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); @@ -1058,7 +1058,7 @@ struct LigatureSubstFormat1 bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset (); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; auto *out = c->serializer->start_embed (*this); diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index cb95e6dcd5..36a95ead15 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -89,7 +89,7 @@ struct hb_closure_context_t : bool is_lookup_done (unsigned int lookup_index) { - if (done_lookups->in_error ()) + if (unlikely (done_lookups->in_error ())) return true; /* Have we visited this lookup with the current set of glyphs? */ @@ -146,7 +146,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 +162,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 +659,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 +670,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); } }; @@ -1044,7 +1043,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()); @@ -1188,7 +1187,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 +1225,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 +1272,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); } @@ -1389,9 +1389,11 @@ struct Rule 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)); @@ -1521,14 +1523,13 @@ struct RuleSet ; } - 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); }) ; } @@ -1647,9 +1648,16 @@ struct ContextFormat1 void closure_lookups (hb_closure_lookups_context_t *c) const { - + hb_iter (ruleSet) + struct ContextClosureLookupContext lookup_context = { + {intersects_glyph}, + 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 +1708,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); @@ -1791,10 +1799,24 @@ struct ContextFormat2 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}, + &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 +1882,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)) @@ -1945,6 +1967,8 @@ struct ContextFormat3 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); } @@ -2010,6 +2034,7 @@ struct ContextFormat3 for (const OffsetTo<Coverage>& offset : coverages) { + /* TODO(subset) This looks like should not be necessary to write this way. */ auto *o = c->serializer->allocate_size<OffsetTo<Coverage>> (OffsetTo<Coverage>::static_size); if (unlikely (!o)) return_trace (false); if (!o->serialize_subset (c, offset, this)) return_trace (false); @@ -2238,9 +2263,11 @@ struct ChainRule 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); @@ -2296,11 +2323,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, @@ -2328,12 +2351,19 @@ struct ChainRule | hb_map (mapping)); const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead); - HBUINT16 lookupCount; - lookupCount = lookupRecord.len; - if (!c->copy (lookupCount)) return_trace (nullptr); - 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); } @@ -2351,7 +2381,7 @@ struct ChainRule 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)) @@ -2424,14 +2454,14 @@ struct ChainRuleSet ; } - 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); }) ; } @@ -2552,9 +2582,16 @@ struct ChainContextFormat1 void closure_lookups (hb_closure_lookups_context_t *c) const { - + hb_iter (ruleSet) + struct ChainContextClosureLookupContext lookup_context = { + {intersects_glyph}, + {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 +2641,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); @@ -2701,9 +2738,28 @@ struct ChainContextFormat2 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}, + {&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,24 +2835,23 @@ 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; + auto last_non_zero = c->serializer->snapshot (); for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet) | hb_filter (input_klass_map, hb_first) | hb_map (hb_second)) @@ -2812,19 +2867,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)); @@ -2908,6 +2964,9 @@ struct ChainContextFormat3 void closure_lookups (hb_closure_lookups_context_t *c) const { + if (!intersects (c->glyphs)) + return; + const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead); @@ -2986,13 +3045,16 @@ struct ChainContextFormat3 TRACE_SERIALIZE (this); auto *out = c->serializer->start_embed<OffsetArrayOf<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 @@ -3113,6 +3175,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 LOffsetTo<typename T::SubTable> &> (extensionOffset); + auto& dest_offset = + reinterpret_cast<LOffsetTo<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 +3223,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 { @@ -3320,20 +3412,34 @@ struct GSUBGPOS return_trace (true); } - void closure_features (const hb_map_t *lookup_indexes, /* IN */ - hb_set_t *feature_indexes /* OUT */) const + void prune_features (const hb_map_t *lookup_indices, /* IN */ + hb_set_t *feature_indices /* IN/OUT */) const { - unsigned int feature_count = hb_min (get_feature_count (), (unsigned) HB_MAX_FEATURES); - for (unsigned i = 0; i < feature_count; i++) +#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_indices, &alternate_feature_indices); + if (unlikely (alternate_feature_indices.in_error())) { + feature_indices->successful = false; + return; + } +#endif + + for (unsigned i : feature_indices->iter()) { const Feature& f = get_feature (i); - if ((!f.featureParams.is_null ()) || f.intersects_lookup_indexes (lookup_indexes)) - feature_indexes->add (i); - } + + if (f.featureParams.is_null () + && !f.intersects_lookup_indexes (lookup_indices) #ifndef HB_NO_VAR - if (version.to_int () >= 0x00010001u) - (this+featureVars).closure_features (lookup_indexes, feature_indexes); + && !alternate_feature_indices.has (i) #endif + ) + feature_indices->del (i); + } } unsigned int get_size () const diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index f25f0f9e23..89df949b26 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 @@ -268,7 +268,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 +322,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 * @@ -350,7 +350,7 @@ 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 * @@ -410,9 +410,9 @@ 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 * @@ -437,14 +437,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 +481,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 +504,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,9 +577,9 @@ 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 * @@ -591,14 +602,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,10 +637,10 @@ 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 * @@ -655,7 +666,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 +674,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 +699,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 +708,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 +742,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 +750,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 +772,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 +781,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,11 +807,11 @@ 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 * @@ -827,11 +838,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 * @@ -868,7 +879,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 +888,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 +921,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 * @@ -944,7 +955,7 @@ 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. @@ -1101,7 +1112,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 @@ -1152,7 +1163,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 +1202,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 +1254,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 @@ -1268,11 +1279,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 * @@ -1310,7 +1321,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 @@ -1331,7 +1342,7 @@ hb_ot_layout_has_substitution (hb_face_t *face) * 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 **/ @@ -1488,7 +1499,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 +1574,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 +1623,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 +1698,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 +1782,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, if (applied) ret = true; else - buffer->next_glyph (); + (void) buffer->next_glyph (); } return ret; } @@ -1907,7 +1920,7 @@ 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. @@ -1964,7 +1977,7 @@ 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. 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..ac61bc70de 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -315,12 +315,13 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) } 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) 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-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.cc b/thirdparty/harfbuzz/src/hb-ot-name.cc index 10122b8c2e..4588226e6e 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,7 +150,7 @@ 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. * @@ -177,7 +177,7 @@ 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. * @@ -203,7 +203,7 @@ 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. * 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..8e98f87f4e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh @@ -177,15 +177,14 @@ struct OS2 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); - + + hb_set_set (&unicodes, c->plan->unicodes); + + unicode_glyphid_map.iter () | hb_filter (c->plan->glyphs_requested, hb_second) | hb_map (hb_first) diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index 8586331cd4..f22d6e244d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -87,7 +87,6 @@ struct 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); return_trace (true); } 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..1f244f940c 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 diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc index f5915f43ae..dbedd6af0c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc @@ -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..dd204b23c1 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-indic-table.cc @@ -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 @@ -404,7 +404,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { }; /* Table items: 1792; occupancy: 70% */ -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..a4f2d9a847 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" @@ -337,19 +338,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 +752,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 +783,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 +948,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 +955,16 @@ 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); 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..82ab186a41 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-khmer-machine.hh @@ -1,211 +1,179 @@ - #line 1 "hb-ot-shape-complex-khmer-machine.rl" /* - * Copyright © 2011,2012 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2011,2012 Google, Inc. +* +* This is part of HarfBuzz, a text shaping library. +* +* Permission is hereby granted, without written agreement and without +* license or royalty fees, to use, copy, modify, and distribute this +* software and its documentation for any purpose, provided that the +* above copyright notice and the following two paragraphs appear in +* all copies of this software. +* +* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +* +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH #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 41 "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 59 "hb-ot-shape-complex-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { - 5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u, - 5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, - 5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u, - 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u, - 5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u, - 0 + 2u, 8u, 2u, 6u, 2u, 8u, 2u, 6u, + 0u, 0u, 2u, 6u, 2u, 8u, 2u, 6u, + 2u, 8u, 2u, 6u, 2u, 6u, 2u, 8u, + 2u, 6u, 0u, 0u, 2u, 6u, 2u, 8u, + 2u, 6u, 2u, 8u, 2u, 6u, 2u, 8u, + 0u, 11u, 2u, 11u, 2u, 11u, 2u, 11u, + 7u, 7u, 2u, 7u, 2u, 11u, 2u, 11u, + 2u, 11u, 0u, 0u, 2u, 8u, 2u, 11u, + 2u, 11u, 7u, 7u, 2u, 7u, 2u, 11u, + 2u, 11u, 0u, 0u, 2u, 11u, 2u, 11u, + 0u }; -static const char _khmer_syllable_machine_key_spans[] = { - 22, 17, 22, 17, 16, 17, 22, 17, - 22, 17, 17, 22, 17, 16, 17, 22, - 17, 22, 17, 22, 29, 25, 25, 25, - 1, 18, 25, 25, 25, 16, 22, 25, - 25, 1, 18, 25, 25, 16, 25, 25 +static const signed char _khmer_syllable_machine_char_class[] = { + 0, 0, 1, 1, 2, 2, 1, 1, + 1, 1, 3, 3, 1, 4, 1, 0, + 1, 1, 1, 5, 6, 7, 1, 1, + 1, 8, 9, 10, 11, 0 }; static const short _khmer_syllable_machine_index_offsets[] = { - 0, 23, 41, 64, 82, 99, 117, 140, - 158, 181, 199, 217, 240, 258, 275, 293, - 316, 334, 357, 375, 398, 428, 454, 480, - 506, 508, 527, 553, 579, 605, 622, 645, - 671, 697, 699, 718, 744, 770, 787, 813 + 0, 7, 12, 19, 24, 25, 30, 37, + 42, 49, 54, 59, 66, 71, 72, 77, + 84, 89, 96, 101, 108, 120, 130, 140, + 150, 151, 157, 167, 177, 187, 188, 195, + 205, 215, 216, 222, 232, 242, 243, 253, + 0 }; -static const char _khmer_syllable_machine_indicies[] = { - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, - 3, 0, 0, 0, 0, 4, 0, 1, - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, - 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 0, 0, 0, 0, 4, 0, - 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 6, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 0, 7, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10, 0, 0, - 0, 0, 4, 0, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 11, 11, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 4, 0, 11, 11, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 0, 14, - 14, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 15, - 13, 14, 14, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 15, 16, 16, 16, 16, 17, 16, - 18, 18, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 17, 16, 19, 19, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 19, 16, 20, 20, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 21, 16, 22, 22, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 23, 16, 16, - 16, 16, 17, 16, 22, 22, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 23, 16, 24, 24, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 25, 16, - 16, 16, 16, 17, 16, 24, 24, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 25, 16, 14, - 14, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 26, 15, - 16, 16, 16, 16, 17, 16, 28, 28, - 27, 27, 29, 29, 27, 27, 27, 27, - 2, 2, 27, 30, 27, 28, 27, 27, - 27, 27, 15, 19, 27, 27, 27, 17, - 23, 25, 21, 27, 32, 32, 31, 31, - 31, 31, 31, 31, 31, 33, 31, 31, - 31, 31, 31, 2, 3, 6, 31, 31, - 31, 4, 10, 12, 8, 31, 34, 34, - 31, 31, 31, 31, 31, 31, 31, 35, - 31, 31, 31, 31, 31, 31, 3, 6, - 31, 31, 31, 4, 10, 12, 8, 31, - 5, 5, 31, 31, 31, 31, 31, 31, - 31, 35, 31, 31, 31, 31, 31, 31, - 4, 6, 31, 31, 31, 31, 31, 31, - 8, 31, 6, 31, 7, 7, 31, 31, - 31, 31, 31, 31, 31, 35, 31, 31, - 31, 31, 31, 31, 8, 6, 31, 36, - 36, 31, 31, 31, 31, 31, 31, 31, - 35, 31, 31, 31, 31, 31, 31, 10, - 6, 31, 31, 31, 4, 31, 31, 8, - 31, 37, 37, 31, 31, 31, 31, 31, - 31, 31, 35, 31, 31, 31, 31, 31, - 31, 12, 6, 31, 31, 31, 4, 10, - 31, 8, 31, 34, 34, 31, 31, 31, - 31, 31, 31, 31, 33, 31, 31, 31, - 31, 31, 31, 3, 6, 31, 31, 31, - 4, 10, 12, 8, 31, 28, 28, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 28, 31, 14, 14, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 15, 38, - 38, 38, 38, 17, 38, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 41, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 18, - 18, 39, 39, 39, 39, 39, 39, 39, - 41, 39, 39, 39, 39, 39, 39, 17, - 19, 39, 39, 39, 39, 39, 39, 21, - 39, 19, 39, 20, 20, 39, 39, 39, - 39, 39, 39, 39, 41, 39, 39, 39, - 39, 39, 39, 21, 19, 39, 42, 42, - 39, 39, 39, 39, 39, 39, 39, 41, - 39, 39, 39, 39, 39, 39, 23, 19, - 39, 39, 39, 17, 39, 39, 21, 39, - 43, 43, 39, 39, 39, 39, 39, 39, - 39, 41, 39, 39, 39, 39, 39, 39, - 25, 19, 39, 39, 39, 17, 23, 39, - 21, 39, 44, 44, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, - 39, 44, 39, 45, 45, 39, 39, 39, - 39, 39, 39, 39, 30, 39, 39, 39, - 39, 39, 26, 15, 19, 39, 39, 39, - 17, 23, 25, 21, 39, 40, 40, 39, - 39, 39, 39, 39, 39, 39, 30, 39, - 39, 39, 39, 39, 39, 15, 19, 39, - 39, 39, 17, 23, 25, 21, 39, 0 +static const signed char _khmer_syllable_machine_indicies[] = { + 1, 0, 0, 2, 3, 0, 4, 1, + 0, 0, 0, 3, 1, 0, 0, 0, + 3, 0, 4, 5, 0, 0, 0, 4, + 6, 7, 0, 0, 0, 8, 9, 0, + 0, 0, 10, 0, 4, 9, 0, 0, + 0, 10, 11, 0, 0, 0, 12, 0, + 4, 11, 0, 0, 0, 12, 14, 13, + 13, 13, 15, 14, 16, 16, 16, 15, + 16, 17, 18, 16, 16, 16, 17, 19, + 20, 16, 16, 16, 21, 22, 16, 16, + 16, 23, 16, 17, 22, 16, 16, 16, + 23, 24, 16, 16, 16, 25, 16, 17, + 24, 16, 16, 16, 25, 14, 16, 16, + 26, 15, 16, 17, 29, 28, 30, 2, + 31, 28, 15, 19, 17, 23, 25, 21, + 33, 32, 34, 2, 3, 6, 4, 10, + 12, 8, 35, 32, 36, 32, 3, 6, + 4, 10, 12, 8, 5, 32, 36, 32, + 4, 6, 32, 32, 32, 8, 6, 7, + 32, 36, 32, 8, 6, 37, 32, 36, + 32, 10, 6, 4, 32, 32, 8, 38, + 32, 36, 32, 12, 6, 4, 10, 32, + 8, 35, 32, 34, 32, 3, 6, 4, + 10, 12, 8, 29, 14, 39, 39, 39, + 15, 39, 17, 41, 40, 42, 40, 15, + 19, 17, 23, 25, 21, 18, 40, 42, + 40, 17, 19, 40, 40, 40, 21, 19, + 20, 40, 42, 40, 21, 19, 43, 40, + 42, 40, 23, 19, 17, 40, 40, 21, + 44, 40, 42, 40, 25, 19, 17, 23, + 40, 21, 45, 46, 40, 31, 26, 15, + 19, 17, 23, 25, 21, 41, 40, 31, + 40, 15, 19, 17, 23, 25, 21, 0 }; -static const char _khmer_syllable_machine_trans_targs[] = { - 20, 1, 28, 22, 23, 3, 24, 5, - 25, 7, 26, 9, 27, 20, 10, 31, - 20, 32, 12, 33, 14, 34, 16, 35, - 18, 36, 39, 20, 21, 30, 37, 20, - 0, 29, 2, 4, 6, 8, 20, 20, - 11, 13, 15, 17, 38, 19 +static const signed char _khmer_syllable_machine_index_defaults[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 28, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 39, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 0 }; -static const char _khmer_syllable_machine_trans_actions[] = { - 1, 0, 2, 2, 2, 0, 0, 0, - 2, 0, 2, 0, 2, 3, 0, 4, - 5, 2, 0, 0, 0, 2, 0, 2, - 0, 2, 4, 8, 2, 9, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, - 0, 0, 0, 0, 4, 0 +static const signed char _khmer_syllable_machine_cond_targs[] = { + 20, 1, 28, 22, 23, 3, 24, 5, + 25, 7, 26, 9, 27, 20, 10, 31, + 20, 32, 12, 33, 14, 34, 16, 35, + 18, 36, 39, 20, 20, 21, 30, 37, + 20, 0, 29, 2, 4, 6, 8, 20, + 20, 11, 13, 15, 17, 38, 19, 0 }; -static const char _khmer_syllable_machine_to_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 +static const signed char _khmer_syllable_machine_cond_actions[] = { + 1, 0, 2, 2, 2, 0, 0, 0, + 2, 0, 2, 0, 2, 3, 0, 4, + 5, 2, 0, 0, 0, 2, 0, 2, + 0, 2, 4, 0, 8, 2, 9, 0, + 10, 0, 0, 0, 0, 0, 0, 11, + 12, 0, 0, 0, 0, 4, 0, 0 }; -static const char _khmer_syllable_machine_from_state_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 +static const signed char _khmer_syllable_machine_to_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; -static const unsigned char _khmer_syllable_machine_eof_trans[] = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 0, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 39, 40, - 40, 40, 40, 40, 40, 40, 40, 40 +static const signed char _khmer_syllable_machine_from_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const signed char _khmer_syllable_machine_eof_trans[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 14, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 28, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 40, 41, + 41, 41, 41, 41, 41, 41, 41, 41, + 0 }; static const int khmer_syllable_machine_start = 20; @@ -215,156 +183,271 @@ 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; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \ + for (unsigned int i = ts; i < te; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END static void find_syllables_khmer (hb_buffer_t *buffer) { - unsigned int p, pe, eof, ts, te, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 242 "hb-ot-shape-complex-khmer-machine.hh" + unsigned int p, pe, eof, ts, te, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 210 "hb-ot-shape-complex-khmer-machine.hh" { - cs = khmer_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)khmer_syllable_machine_start; + ts = 0; + te = 0; + act = 0; } - -#line 100 "hb-ot-shape-complex-khmer-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int syllable_serial = 1; - -#line 258 "hb-ot-shape-complex-khmer-machine.hh" + +#line 106 "hb-ot-shape-complex-khmer-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int syllable_serial = 1; + +#line 226 "hb-ot-shape-complex-khmer-machine.hh" { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _khmer_syllable_machine_from_state_actions[cs] ) { - case 7: + unsigned int _trans = 0; + const unsigned char * _keys; + const signed char * _inds; + int _ic; + _resume: {} + if ( p == pe && p != eof ) + goto _out; + switch ( _khmer_syllable_machine_from_state_actions[cs] ) { + case 7: { + { #line 1 "NONE" - {ts = p;} - break; -#line 272 "hb-ot-shape-complex-khmer-machine.hh" - } - - _keys = _khmer_syllable_machine_trans_keys + (cs<<1); - _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs]; - - _slen = _khmer_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) && - ( info[p].khmer_category()) <= _keys[1] ? - ( info[p].khmer_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _khmer_syllable_machine_trans_targs[_trans]; - - if ( _khmer_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _khmer_syllable_machine_trans_actions[_trans] ) { - case 2: + {ts = p;}} + +#line 241 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + } + + if ( p == eof ) { + if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_khmer_syllable_machine_eof_trans[cs] - 1; + } + } + else { + _keys = ( _khmer_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _khmer_syllable_machine_indicies + (_khmer_syllable_machine_index_offsets[cs])); + + if ( (info[p].khmer_category()) <= 29 && (info[p].khmer_category()) >= 1 ) { + _ic = (int)_khmer_syllable_machine_char_class[(int)(info[p].khmer_category()) - 1]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs]; + } + + } + cs = (int)_khmer_syllable_machine_cond_targs[_trans]; + + if ( _khmer_syllable_machine_cond_actions[_trans] != 0 ) { + + switch ( _khmer_syllable_machine_cond_actions[_trans] ) { + case 2: { + { #line 1 "NONE" - {te = p+1;} - break; - case 8: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p+1;{ found_syllable (non_khmer_cluster); }} - break; - case 10: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} - break; - case 12: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 11: -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {te = p;p--;{ found_syllable (non_khmer_cluster); }} - break; - case 1: -#line 74 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} - break; - case 5: -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; - case 3: + {te = p+1;}} + +#line 279 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 8: { + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_non_khmer_cluster); } + }} + +#line 292 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 10: { + { +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_consonant_syllable); } + }} + +#line 305 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 12: { + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_broken_cluster); } + }} + +#line 318 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 11: { + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p = p - 1;{ +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_non_khmer_cluster); } + }} + +#line 331 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 1: { + { +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + {p = ((te))-1; + { +#line 80 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_consonant_syllable); } + }} + +#line 345 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 5: { + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {p = ((te))-1; + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_broken_cluster); } + }} + +#line 359 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 3: { + { #line 1 "NONE" - { switch( act ) { - case 2: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - case 3: - {{p = ((te))-1;} found_syllable (non_khmer_cluster); } - break; - } - } - break; - case 4: + {switch( act ) { + case 2: { + p = ((te))-1; + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_broken_cluster); } + break; + } + case 3: { + p = ((te))-1; + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + found_syllable (khmer_non_khmer_cluster); } + break; + } + }} + } + +#line 385 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 4: { + { #line 1 "NONE" - {te = p+1;} -#line 75 "hb-ot-shape-complex-khmer-machine.rl" - {act = 2;} - break; - case 9: + {te = p+1;}} + +#line 395 "hb-ot-shape-complex-khmer-machine.hh" + + { +#line 81 "hb-ot-shape-complex-khmer-machine.rl" + {act = 2;}} + +#line 401 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + case 9: { + { #line 1 "NONE" - {te = p+1;} -#line 76 "hb-ot-shape-complex-khmer-machine.rl" - {act = 3;} - break; -#line 342 "hb-ot-shape-complex-khmer-machine.hh" - } - -_again: - switch ( _khmer_syllable_machine_to_state_actions[cs] ) { - case 6: + {te = p+1;}} + +#line 411 "hb-ot-shape-complex-khmer-machine.hh" + + { +#line 82 "hb-ot-shape-complex-khmer-machine.rl" + {act = 3;}} + +#line 417 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + } + + } + + if ( p == eof ) { + if ( cs >= 20 ) + goto _out; + } + else { + switch ( _khmer_syllable_machine_to_state_actions[cs] ) { + case 6: { + { #line 1 "NONE" - {ts = 0;} - break; -#line 351 "hb-ot-shape-complex-khmer-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _khmer_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } + {ts = 0;}} + +#line 437 "hb-ot-shape-complex-khmer-machine.hh" + + + break; + } + } + + p += 1; + goto _resume; + } + _out: {} } - - } - -#line 108 "hb-ot-shape-complex-khmer-machine.rl" - + +#line 114 "hb-ot-shape-complex-khmer-machine.rl" + } #undef found_syllable 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..dddba142a3 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" @@ -140,27 +141,6 @@ 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]; }; @@ -171,8 +151,6 @@ data_create_khmer (const hb_ot_shape_plan_t *plan) 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); @@ -186,15 +164,6 @@ data_destroy_khmer (void *data) 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 +290,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..bc5dcb904c 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" /* @@ -97,17 +98,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 +255,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..46509abee2 --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc @@ -0,0 +1,100 @@ +/* + * 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) +{ + 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; + 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..c80b8fee1d --- /dev/null +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.hh @@ -0,0 +1,41 @@ +/* + * 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); + + +#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..b4b2b75100 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-machine.hh @@ -1,300 +1,348 @@ - #line 1 "hb-ot-shape-complex-use-machine.rl" /* - * Copyright © 2015 Mozilla Foundation. - * Copyright © 2015 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ +* Copyright © 2015 Mozilla Foundation. +* Copyright © 2015 Google, Inc. +* +* This is part of HarfBuzz, a text shaping library. +* +* Permission is hereby granted, without written agreement and without +* license or royalty fees, to use, copy, modify, and distribute this +* software and its documentation for any purpose, provided that the +* above copyright notice and the following two paragraphs appear in +* all copies of this software. +* +* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR +* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN +* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +* +* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, +* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO +* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +* +* Mozilla Author(s): Jonathan Kew +* Google Author(s): Behdad Esfahbod +*/ #ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH #define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH #include "hb.hh" -#include "hb-ot-shape-complex-machine-index.hh" +#include "hb-ot-shape-complex-syllabic.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 39 "hb-ot-shape-complex-use-machine.hh" + +#line 57 "hb-ot-shape-complex-use-machine.hh" +#define use_syllable_machine_ex_B 1u +#define use_syllable_machine_ex_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 99 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 1u, 1u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, - 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, - 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, - 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, - 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, - 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, - 22u, 48u, 11u, 48u, 1u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, - 41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0 + 1u, 1u, 1u, 1u, 0u, 37u, 5u, 34u, + 5u, 34u, 1u, 1u, 10u, 34u, 11u, 34u, + 12u, 33u, 13u, 33u, 14u, 33u, 31u, 32u, + 32u, 32u, 12u, 34u, 12u, 34u, 12u, 34u, + 1u, 1u, 12u, 34u, 11u, 34u, 11u, 34u, + 11u, 34u, 10u, 34u, 10u, 34u, 10u, 34u, + 5u, 34u, 1u, 34u, 7u, 7u, 3u, 3u, + 5u, 34u, 27u, 28u, 28u, 28u, 5u, 34u, + 10u, 34u, 11u, 34u, 12u, 33u, 13u, 33u, + 14u, 33u, 31u, 32u, 32u, 32u, 12u, 34u, + 12u, 34u, 12u, 34u, 12u, 34u, 11u, 34u, + 11u, 34u, 11u, 34u, 10u, 34u, 10u, 34u, + 10u, 34u, 5u, 34u, 1u, 34u, 1u, 1u, + 3u, 3u, 7u, 7u, 1u, 34u, 5u, 34u, + 27u, 28u, 28u, 28u, 1u, 4u, 36u, 38u, + 35u, 38u, 35u, 37u, 0u }; -static const char _use_syllable_machine_key_spans[] = { - 1, 1, 52, 38, 38, 1, 27, 26, - 24, 23, 22, 2, 1, 25, 25, 25, - 1, 25, 26, 26, 26, 27, 27, 27, - 38, 48, 1, 1, 38, 2, 1, 38, - 27, 26, 24, 23, 22, 2, 1, 25, - 25, 25, 25, 26, 26, 26, 27, 27, - 27, 38, 48, 1, 1, 1, 48, 38, - 2, 1, 5, 3, 4, 3 +static const signed char _use_syllable_machine_char_class[] = { + 0, 1, 2, 2, 3, 4, 2, 2, + 2, 2, 2, 5, 6, 7, 2, 2, + 2, 2, 8, 9, 2, 2, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 2, 24, 25, 26, + 2, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 0 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 2, 4, 57, 96, 135, 137, 165, - 192, 217, 241, 264, 267, 269, 295, 321, - 347, 349, 375, 402, 429, 456, 484, 512, - 540, 579, 628, 630, 632, 671, 674, 676, - 715, 743, 770, 795, 819, 842, 845, 847, - 873, 899, 925, 951, 978, 1005, 1032, 1060, - 1088, 1116, 1155, 1204, 1206, 1208, 1210, 1259, - 1298, 1301, 1303, 1309, 1313, 1318 + 0, 1, 2, 40, 70, 100, 101, 126, + 150, 172, 193, 213, 215, 216, 239, 262, + 285, 286, 309, 333, 357, 381, 406, 431, + 456, 486, 520, 521, 522, 552, 554, 555, + 585, 610, 634, 656, 677, 697, 699, 700, + 723, 746, 769, 792, 816, 840, 864, 889, + 914, 939, 969, 1003, 1004, 1005, 1006, 1040, + 1070, 1072, 1073, 1077, 1080, 1084, 0 +}; + +static const signed char _use_syllable_machine_indicies[] = { + 1, 2, 4, 5, 6, 7, 8, 1, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 13, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 9, 36, 6, 37, + 39, 40, 38, 38, 38, 41, 42, 43, + 44, 45, 46, 47, 41, 48, 5, 49, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 56, 57, 58, 59, 40, 39, 40, + 38, 38, 38, 41, 42, 43, 44, 45, + 46, 47, 41, 48, 49, 49, 50, 51, + 52, 53, 54, 55, 38, 38, 38, 56, + 57, 58, 59, 40, 39, 41, 42, 43, + 44, 45, 38, 38, 38, 38, 38, 38, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 42, 57, 58, 59, 61, 42, 43, + 44, 45, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 53, 54, 55, 38, 38, + 38, 38, 57, 58, 59, 61, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 57, 58, 59, 44, 45, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 57, 58, + 59, 45, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 57, 58, 59, 57, 58, 58, + 43, 44, 45, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 53, 54, 55, 38, + 38, 38, 38, 57, 58, 59, 61, 43, + 44, 45, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 54, 55, 38, 38, + 38, 38, 57, 58, 59, 61, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 55, 38, 38, 38, + 38, 57, 58, 59, 61, 63, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 57, 58, 59, 61, 42, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 50, + 51, 52, 53, 54, 55, 38, 38, 38, + 42, 57, 58, 59, 61, 42, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 51, 52, 53, 54, 55, 38, 38, 38, + 42, 57, 58, 59, 61, 42, 43, 44, + 45, 38, 38, 38, 38, 38, 38, 38, + 38, 52, 53, 54, 55, 38, 38, 38, + 42, 57, 58, 59, 61, 41, 42, 43, + 44, 45, 38, 47, 41, 38, 38, 38, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 42, 57, 58, 59, 61, 41, 42, + 43, 44, 45, 38, 38, 41, 38, 38, + 38, 50, 51, 52, 53, 54, 55, 38, + 38, 38, 42, 57, 58, 59, 61, 41, + 42, 43, 44, 45, 46, 47, 41, 38, + 38, 38, 50, 51, 52, 53, 54, 55, + 38, 38, 38, 42, 57, 58, 59, 61, + 39, 40, 38, 38, 38, 41, 42, 43, + 44, 45, 46, 47, 41, 48, 38, 49, + 50, 51, 52, 53, 54, 55, 38, 38, + 38, 56, 57, 58, 59, 40, 39, 60, + 60, 60, 60, 60, 60, 60, 60, 60, + 42, 43, 44, 45, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 53, 54, 55, + 60, 60, 60, 60, 57, 58, 59, 61, + 65, 7, 39, 40, 38, 38, 38, 41, + 42, 43, 44, 45, 46, 47, 41, 48, + 5, 49, 50, 51, 52, 53, 54, 55, + 12, 67, 38, 56, 57, 58, 59, 40, + 12, 67, 67, 1, 70, 69, 69, 69, + 13, 14, 15, 16, 17, 18, 19, 13, + 20, 22, 22, 23, 24, 25, 26, 27, + 28, 69, 69, 69, 32, 33, 34, 35, + 70, 13, 14, 15, 16, 17, 69, 69, + 69, 69, 69, 69, 23, 24, 25, 26, + 27, 28, 69, 69, 69, 14, 33, 34, + 35, 71, 14, 15, 16, 17, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 26, + 27, 28, 69, 69, 69, 69, 33, 34, + 35, 71, 15, 16, 17, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 33, 34, 35, + 16, 17, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 33, 34, 35, 17, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 33, 34, + 35, 33, 34, 34, 15, 16, 17, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 26, 27, 28, 69, 69, 69, 69, 33, + 34, 35, 71, 15, 16, 17, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 27, 28, 69, 69, 69, 69, 33, 34, + 35, 71, 15, 16, 17, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 28, 69, 69, 69, 69, 33, 34, 35, + 71, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 33, 34, 35, 71, + 14, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 23, 24, 25, 26, 27, 28, + 69, 69, 69, 14, 33, 34, 35, 71, + 14, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 69, 24, 25, 26, 27, 28, + 69, 69, 69, 14, 33, 34, 35, 71, + 14, 15, 16, 17, 69, 69, 69, 69, + 69, 69, 69, 69, 25, 26, 27, 28, + 69, 69, 69, 14, 33, 34, 35, 71, + 13, 14, 15, 16, 17, 69, 19, 13, + 69, 69, 69, 23, 24, 25, 26, 27, + 28, 69, 69, 69, 14, 33, 34, 35, + 71, 13, 14, 15, 16, 17, 69, 69, + 13, 69, 69, 69, 23, 24, 25, 26, + 27, 28, 69, 69, 69, 14, 33, 34, + 35, 71, 13, 14, 15, 16, 17, 18, + 19, 13, 69, 69, 69, 23, 24, 25, + 26, 27, 28, 69, 69, 69, 14, 33, + 34, 35, 71, 1, 70, 69, 69, 69, + 13, 14, 15, 16, 17, 18, 19, 13, + 20, 69, 22, 23, 24, 25, 26, 27, + 28, 69, 69, 69, 32, 33, 34, 35, + 70, 1, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 14, 15, 16, 17, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 26, 27, 28, 69, 69, 69, 69, 33, + 34, 35, 71, 1, 73, 10, 5, 69, + 69, 5, 1, 70, 10, 69, 69, 13, + 14, 15, 16, 17, 18, 19, 13, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 69, 32, 33, 34, 35, 70, + 1, 70, 69, 69, 69, 13, 14, 15, + 16, 17, 18, 19, 13, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 69, 69, + 69, 32, 33, 34, 35, 70, 29, 30, + 30, 5, 72, 72, 5, 75, 74, 36, + 36, 75, 74, 75, 36, 74, 37, 0 }; -static const char _use_syllable_machine_indicies[] = { - 1, 0, 2, 0, 3, 4, 5, 5, - 6, 7, 5, 5, 5, 5, 5, 1, - 8, 9, 5, 5, 5, 5, 10, 11, - 5, 5, 12, 13, 14, 15, 16, 17, - 18, 12, 19, 20, 21, 22, 23, 24, - 5, 25, 26, 27, 5, 28, 29, 30, - 31, 32, 33, 34, 8, 35, 5, 36, - 5, 38, 39, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 40, 41, 42, 43, - 44, 45, 46, 40, 47, 4, 48, 49, - 50, 51, 37, 52, 53, 54, 37, 37, - 37, 37, 55, 56, 57, 58, 39, 37, - 38, 39, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 40, 41, 42, 43, 44, - 45, 46, 40, 47, 48, 48, 49, 50, - 51, 37, 52, 53, 54, 37, 37, 37, - 37, 55, 56, 57, 58, 39, 37, 38, - 59, 40, 41, 42, 43, 44, 37, 37, - 37, 37, 37, 37, 49, 50, 51, 37, - 52, 53, 54, 37, 37, 37, 37, 41, - 56, 57, 58, 60, 37, 41, 42, 43, - 44, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 52, 53, 54, 37, 37, - 37, 37, 37, 56, 57, 58, 60, 37, - 42, 43, 44, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 56, 57, 58, - 37, 43, 44, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 56, 57, 58, - 37, 44, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 56, 57, 58, 37, - 56, 57, 37, 57, 37, 42, 43, 44, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 52, 53, 54, 37, 37, 37, - 37, 37, 56, 57, 58, 60, 37, 42, - 43, 44, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 53, 54, 37, - 37, 37, 37, 37, 56, 57, 58, 60, - 37, 42, 43, 44, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 54, 37, 37, 37, 37, 37, 56, 57, - 58, 60, 37, 62, 61, 42, 43, 44, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 56, 57, 58, 60, 37, 41, - 42, 43, 44, 37, 37, 37, 37, 37, - 37, 49, 50, 51, 37, 52, 53, 54, - 37, 37, 37, 37, 41, 56, 57, 58, - 60, 37, 41, 42, 43, 44, 37, 37, - 37, 37, 37, 37, 37, 50, 51, 37, - 52, 53, 54, 37, 37, 37, 37, 41, - 56, 57, 58, 60, 37, 41, 42, 43, - 44, 37, 37, 37, 37, 37, 37, 37, - 37, 51, 37, 52, 53, 54, 37, 37, - 37, 37, 41, 56, 57, 58, 60, 37, - 40, 41, 42, 43, 44, 37, 46, 40, - 37, 37, 37, 49, 50, 51, 37, 52, - 53, 54, 37, 37, 37, 37, 41, 56, - 57, 58, 60, 37, 40, 41, 42, 43, - 44, 37, 37, 40, 37, 37, 37, 49, - 50, 51, 37, 52, 53, 54, 37, 37, - 37, 37, 41, 56, 57, 58, 60, 37, - 40, 41, 42, 43, 44, 45, 46, 40, - 37, 37, 37, 49, 50, 51, 37, 52, - 53, 54, 37, 37, 37, 37, 41, 56, - 57, 58, 60, 37, 38, 39, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 40, - 41, 42, 43, 44, 45, 46, 40, 47, - 37, 48, 49, 50, 51, 37, 52, 53, - 54, 37, 37, 37, 37, 55, 56, 57, - 58, 39, 37, 38, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 41, 42, 43, 44, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 52, - 53, 54, 59, 59, 59, 59, 59, 56, - 57, 58, 60, 59, 64, 63, 6, 65, - 38, 39, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 40, 41, 42, 43, 44, - 45, 46, 40, 47, 4, 48, 49, 50, - 51, 37, 52, 53, 54, 37, 11, 66, - 37, 55, 56, 57, 58, 39, 37, 11, - 66, 67, 66, 67, 1, 69, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 12, - 13, 14, 15, 16, 17, 18, 12, 19, - 21, 21, 22, 23, 24, 68, 25, 26, - 27, 68, 68, 68, 68, 31, 32, 33, - 34, 69, 68, 12, 13, 14, 15, 16, - 68, 68, 68, 68, 68, 68, 22, 23, - 24, 68, 25, 26, 27, 68, 68, 68, - 68, 13, 32, 33, 34, 70, 68, 13, - 14, 15, 16, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 25, 26, 27, - 68, 68, 68, 68, 68, 32, 33, 34, - 70, 68, 14, 15, 16, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 32, - 33, 34, 68, 15, 16, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 32, - 33, 34, 68, 16, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 32, 33, - 34, 68, 32, 33, 68, 33, 68, 14, - 15, 16, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 25, 26, 27, 68, - 68, 68, 68, 68, 32, 33, 34, 70, - 68, 14, 15, 16, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 26, - 27, 68, 68, 68, 68, 68, 32, 33, - 34, 70, 68, 14, 15, 16, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 27, 68, 68, 68, 68, 68, - 32, 33, 34, 70, 68, 14, 15, 16, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 32, 33, 34, 70, 68, 13, - 14, 15, 16, 68, 68, 68, 68, 68, - 68, 22, 23, 24, 68, 25, 26, 27, - 68, 68, 68, 68, 13, 32, 33, 34, - 70, 68, 13, 14, 15, 16, 68, 68, - 68, 68, 68, 68, 68, 23, 24, 68, - 25, 26, 27, 68, 68, 68, 68, 13, - 32, 33, 34, 70, 68, 13, 14, 15, - 16, 68, 68, 68, 68, 68, 68, 68, - 68, 24, 68, 25, 26, 27, 68, 68, - 68, 68, 13, 32, 33, 34, 70, 68, - 12, 13, 14, 15, 16, 68, 18, 12, - 68, 68, 68, 22, 23, 24, 68, 25, - 26, 27, 68, 68, 68, 68, 13, 32, - 33, 34, 70, 68, 12, 13, 14, 15, - 16, 68, 68, 12, 68, 68, 68, 22, - 23, 24, 68, 25, 26, 27, 68, 68, - 68, 68, 13, 32, 33, 34, 70, 68, - 12, 13, 14, 15, 16, 17, 18, 12, - 68, 68, 68, 22, 23, 24, 68, 25, - 26, 27, 68, 68, 68, 68, 13, 32, - 33, 34, 70, 68, 1, 69, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 12, - 13, 14, 15, 16, 17, 18, 12, 19, - 68, 21, 22, 23, 24, 68, 25, 26, - 27, 68, 68, 68, 68, 31, 32, 33, - 34, 69, 68, 1, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 13, 14, 15, 16, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 25, - 26, 27, 68, 68, 68, 68, 68, 32, - 33, 34, 70, 68, 1, 71, 72, 68, - 9, 68, 4, 68, 68, 68, 4, 68, - 68, 68, 68, 68, 1, 69, 9, 68, - 68, 68, 68, 68, 68, 68, 68, 12, - 13, 14, 15, 16, 17, 18, 12, 19, - 20, 21, 22, 23, 24, 68, 25, 26, - 27, 68, 28, 29, 68, 31, 32, 33, - 34, 69, 68, 1, 69, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 12, 13, - 14, 15, 16, 17, 18, 12, 19, 20, - 21, 22, 23, 24, 68, 25, 26, 27, - 68, 68, 68, 68, 31, 32, 33, 34, - 69, 68, 28, 29, 68, 29, 68, 4, - 71, 71, 71, 4, 71, 74, 73, 35, - 73, 35, 74, 73, 74, 73, 35, 73, - 36, 73, 0 +static const signed char _use_syllable_machine_index_defaults[] = { + 0, 0, 6, 38, 38, 60, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 62, 38, 38, 38, 38, 38, 38, 38, + 38, 60, 64, 66, 38, 68, 68, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 72, 69, 69, 69, 69, + 69, 69, 72, 74, 74, 74, 0 }; -static const char _use_syllable_machine_trans_targs[] = { - 2, 31, 42, 2, 3, 2, 26, 28, - 51, 52, 54, 29, 32, 33, 34, 35, - 36, 46, 47, 48, 55, 49, 43, 44, - 45, 39, 40, 41, 56, 57, 58, 50, - 37, 38, 2, 59, 61, 2, 4, 5, - 6, 7, 8, 9, 10, 21, 22, 23, - 24, 18, 19, 20, 13, 14, 15, 25, - 11, 12, 2, 2, 16, 2, 17, 2, - 27, 2, 30, 2, 2, 0, 1, 2, - 53, 2, 60 +static const signed char _use_syllable_machine_cond_targs[] = { + 2, 31, 42, 2, 2, 3, 2, 26, + 28, 51, 52, 54, 29, 32, 33, 34, + 35, 36, 46, 47, 48, 55, 49, 43, + 44, 45, 39, 40, 41, 56, 57, 58, + 50, 37, 38, 2, 59, 61, 2, 4, + 5, 6, 7, 8, 9, 10, 21, 22, + 23, 24, 18, 19, 20, 13, 14, 15, + 25, 11, 12, 2, 2, 16, 2, 17, + 2, 27, 2, 30, 2, 2, 0, 1, + 2, 53, 2, 60, 0 }; -static const char _use_syllable_machine_trans_actions[] = { - 1, 2, 2, 5, 0, 6, 0, 0, - 0, 0, 2, 0, 2, 2, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 0, 0, 0, 2, - 0, 0, 7, 0, 0, 8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 10, 0, 11, 0, 12, - 0, 13, 0, 14, 15, 0, 0, 16, - 0, 17, 0 +static const signed char _use_syllable_machine_cond_actions[] = { + 1, 2, 2, 0, 5, 0, 6, 0, + 0, 0, 0, 2, 0, 2, 2, 0, + 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 0, 0, + 2, 0, 0, 7, 0, 0, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 0, 11, 0, + 12, 0, 13, 0, 14, 15, 0, 0, + 16, 0, 17, 0, 0 }; -static const char _use_syllable_machine_to_state_actions[] = { - 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 +static const signed char _use_syllable_machine_to_state_actions[] = { + 0, 0, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }; -static const char _use_syllable_machine_from_state_actions[] = { - 0, 0, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 +static const signed char _use_syllable_machine_from_state_actions[] = { + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 }; -static const short _use_syllable_machine_eof_trans[] = { - 1, 1, 0, 38, 38, 60, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 62, 38, 38, 38, 38, 38, 38, 38, - 38, 60, 64, 66, 38, 68, 68, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 72, 69, 69, 69, 69, - 69, 69, 72, 74, 74, 74 +static const signed char _use_syllable_machine_eof_trans[] = { + 1, 1, 4, 39, 39, 61, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 63, 39, 39, 39, 39, 39, 39, 39, + 39, 61, 65, 67, 39, 69, 69, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 73, 70, 70, 70, 70, + 70, 70, 73, 75, 75, 75, 0 }; static const int use_syllable_machine_start = 2; @@ -304,185 +352,376 @@ 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; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END +HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ + for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ + 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; - auto p = - + hb_iter (info, buffer->len) - | hb_enumerate - | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); }, - hb_second) - | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) - { - if (p.second.use_category() == USE_ZWNJ) - for (unsigned i = p.first + 1; i < buffer->len; ++i) - if (not_standard_default_ignorable (info[i])) - return !_hb_glyph_info_is_unicode_mark (&info[i]); - return true; - }) - | hb_enumerate - | machine_index - ; - auto pe = p + p.len (); - auto eof = +pe; - auto ts = +p; - auto te = +p; - unsigned int act HB_UNUSED; - int cs; - -#line 355 "hb-ot-shape-complex-use-machine.hh" + hb_glyph_info_t *info = buffer->info; + auto p = + + hb_iter (info, buffer->len) + | hb_enumerate + | hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); }, + hb_second) + | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) + { + if (p.second.use_category() == USE(ZWNJ)) + for (unsigned i = p.first + 1; i < buffer->len; ++i) + if (not_standard_default_ignorable (info[i])) + return !_hb_glyph_info_is_unicode_mark (&info[i]); + return true; + }) + | hb_enumerate + | machine_index + ; + auto pe = p + p.len (); + auto eof = +pe; + auto ts = +p; + auto te = +p; + unsigned int act HB_UNUSED; + int cs; + +#line 443 "hb-ot-shape-complex-use-machine.hh" { - cs = use_syllable_machine_start; - ts = 0; - te = 0; - act = 0; + cs = (int)use_syllable_machine_start; + ts = 0; + te = 0; } - -#line 198 "hb-ot-shape-complex-use-machine.rl" - - - unsigned int syllable_serial = 1; - -#line 368 "hb-ot-shape-complex-use-machine.hh" + +#line 260 "hb-ot-shape-complex-use-machine.rl" + + + unsigned int syllable_serial = 1; + +#line 455 "hb-ot-shape-complex-use-machine.hh" { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 4: + unsigned int _trans = 0; + const unsigned char * _keys; + const signed char * _inds; + int _ic; + _resume: {} + if ( p == pe && p != eof ) + goto _out; + switch ( _use_syllable_machine_from_state_actions[cs] ) { + case 4: { + { #line 1 "NONE" - {ts = p;} - break; -#line 382 "hb-ot-shape-complex-use-machine.hh" - } - - _keys = _use_syllable_machine_trans_keys + (cs<<1); - _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; - - _slen = _use_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) && - ( (*p).second.second.use_category()) <= _keys[1] ? - ( (*p).second.second.use_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _use_syllable_machine_trans_targs[_trans]; - - if ( _use_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 2: + {ts = p;}} + +#line 470 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + } + + if ( p == eof ) { + if ( _use_syllable_machine_eof_trans[cs] > 0 ) { + _trans = (unsigned int)_use_syllable_machine_eof_trans[cs] - 1; + } + } + else { + _keys = ( _use_syllable_machine_trans_keys + ((cs<<1))); + _inds = ( _use_syllable_machine_indicies + (_use_syllable_machine_index_offsets[cs])); + + if ( ((*p).second.second.use_category()) <= 52 ) { + _ic = (int)_use_syllable_machine_char_class[(int)((*p).second.second.use_category()) - 0]; + if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) + _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); + else + _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; + } + else { + _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; + } + + } + cs = (int)_use_syllable_machine_cond_targs[_trans]; + + if ( _use_syllable_machine_cond_actions[_trans] != 0 ) { + + switch ( _use_syllable_machine_cond_actions[_trans] ) { + case 2: { + { #line 1 "NONE" - {te = p+1;} - break; - case 5: -#line 141 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (independent_cluster); }} - break; - case 9: -#line 144 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (standard_cluster); }} - break; - case 7: -#line 149 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (broken_cluster); }} - break; - case 6: -#line 150 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (non_cluster); }} - break; - case 10: -#line 142 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (virama_terminated_cluster); }} - break; - case 11: -#line 143 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (sakot_terminated_cluster); }} - break; - case 8: -#line 144 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (standard_cluster); }} - break; - case 13: -#line 145 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} - break; - case 12: -#line 146 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (numeral_cluster); }} - break; - case 14: -#line 147 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (symbol_cluster); }} - break; - case 17: -#line 148 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (hieroglyph_cluster); }} - break; - case 15: -#line 149 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 16: -#line 150 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (non_cluster); }} - break; - case 1: -#line 149 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; -#line 460 "hb-ot-shape-complex-use-machine.hh" - } - -_again: - switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 3: + {te = p+1;}} + +#line 508 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 5: { + { +#line 163 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 163 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_independent_cluster); } + }} + +#line 521 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 9: { + { +#line 166 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 166 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_standard_cluster); } + }} + +#line 534 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 7: { + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 171 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_broken_cluster); } + }} + +#line 547 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 6: { + { +#line 172 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ +#line 172 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_non_cluster); } + }} + +#line 560 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 10: { + { +#line 164 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 164 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_virama_terminated_cluster); } + }} + +#line 573 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 11: { + { +#line 165 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 165 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_sakot_terminated_cluster); } + }} + +#line 586 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 8: { + { +#line 166 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 166 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_standard_cluster); } + }} + +#line 599 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 13: { + { +#line 167 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 167 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_number_joiner_terminated_cluster); } + }} + +#line 612 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 12: { + { +#line 168 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 168 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_numeral_cluster); } + }} + +#line 625 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 14: { + { +#line 169 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 169 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_symbol_cluster); } + }} + +#line 638 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 17: { + { +#line 170 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 170 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_hieroglyph_cluster); } + }} + +#line 651 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 15: { + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 171 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_broken_cluster); } + }} + +#line 664 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 16: { + { +#line 172 "hb-ot-shape-complex-use-machine.rl" + {te = p;p = p - 1;{ +#line 172 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_non_cluster); } + }} + +#line 677 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + case 1: { + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + {p = ((te))-1; + { +#line 171 "hb-ot-shape-complex-use-machine.rl" + found_syllable (use_broken_cluster); } + }} + +#line 691 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + } + + } + + if ( p == eof ) { + if ( cs >= 2 ) + goto _out; + } + else { + switch ( _use_syllable_machine_to_state_actions[cs] ) { + case 3: { + { #line 1 "NONE" - {ts = 0;} - break; -#line 469 "hb-ot-shape-complex-use-machine.hh" + {ts = 0;}} + +#line 711 "hb-ot-shape-complex-use-machine.hh" + + + break; + } + } + + p += 1; + goto _resume; + } + _out: {} } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _use_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _use_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 203 "hb-ot-shape-complex-use-machine.rl" - + +#line 265 "hb-ot-shape-complex-use-machine.rl" + } #undef found_syllable 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..a35894ce81 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-use-table.hh @@ -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 @@ -767,7 +768,7 @@ 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, #define use_offset_0x11800u 5848 @@ -1066,7 +1067,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { }; /* Table items: 8824; occupancy: 79% */ -USE_TABLE_ELEMENT_TYPE +static inline uint8_t hb_use_get_category (hb_codepoint_t u) { switch (u >> 12) @@ -1154,7 +1155,7 @@ hb_use_get_category (hb_codepoint_t u) default: break; } - return USE_O; + return USE(O); } #undef B @@ -1198,5 +1199,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..0d0b7e771e 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. @@ -69,11 +67,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[] = @@ -186,22 +184,6 @@ data_destroy_use (void *data) 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 +221,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 +235,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 +249,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 +261,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 +271,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 +318,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 +341,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 +350,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 +369,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 +423,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 +436,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..1037626998 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc @@ -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..19e24b9f30 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: 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..86ab0b4268 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -534,9 +534,7 @@ 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 (); } 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-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index f1c391cf0e..87830b5462 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-02-12 04:08 PM" /> + * File-Date: 2021-03-05 */ #ifndef HB_OT_TAG_TABLE_HH @@ -169,6 +169,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 */ @@ -358,6 +359,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 */ @@ -834,6 +836,7 @@ static const LangTag ot_languages[] = { {"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 +993,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 */ @@ -1520,6 +1523,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) */ @@ -2808,6 +2813,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 +2899,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..fc145a41f7 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. diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index 4d4e6dcae4..7e4eaaad95 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -652,8 +652,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 ()); 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-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index 024b4d1c99..1675e8448a 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 @@ -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: diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh index 4566153a59..fe29bdf96e 100644 --- a/thirdparty/harfbuzz/src/hb-serialize.hh +++ b/thirdparty/harfbuzz/src/hb-serialize.hh @@ -256,10 +256,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; } @@ -523,7 +524,7 @@ struct hb_serialize_context_t template <typename 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> *) (parent->head + link.position)); assert (0 == off); check_assign (off, offset); } diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc index 3b4059ad32..86bf70034c 100644 --- a/thirdparty/harfbuzz/src/hb-set.cc +++ b/thirdparty/harfbuzz/src/hb-set.cc @@ -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,7 +162,7 @@ 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 **/ @@ -183,6 +183,9 @@ hb_set_allocation_successful (const hb_set_t *set) void hb_set_clear (hb_set_t *set) { + if (unlikely (hb_object_is_immutable (set))) + return; + set->clear (); } @@ -209,7 +212,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 **/ @@ -298,7 +301,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 **/ @@ -316,7 +319,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 **/ @@ -447,7 +450,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 +466,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 +484,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 +505,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 +528,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 +552,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..0ad27f4bbd 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) diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index b6e2086a2e..ae8b5eb10f 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -244,7 +244,7 @@ struct hb_set_t bool resize (unsigned int count) { - if (unlikely (!successful)) return false; + if (unlikely (count > pages.length && !successful)) return false; if (!pages.resize (count) || !page_map.resize (count)) { pages.resize (page_map.length); @@ -256,19 +256,14 @@ struct hb_set_t void reset () { - if (unlikely (hb_object_is_immutable (this))) - return; - clear (); successful = true; + clear (); } void clear () { - if (unlikely (hb_object_is_immutable (this))) - return; - population = 0; - page_map.resize (0); - pages.resize (0); + if (resize (0)) + population = 0; } bool is_empty () const { @@ -278,6 +273,7 @@ struct hb_set_t return false; return true; } + explicit operator bool () const { return !is_empty (); } void dirty () { population = UINT_MAX; } @@ -389,6 +385,11 @@ struct hb_set_t { 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++) { @@ -396,11 +397,12 @@ struct hb_set_t if (m < ds || de < m) page_map[write_index++] = page_map[i]; } - compact (write_index); + compact (compact_workspace, write_index); resize (write_index); } } + public: void del_range (hb_codepoint_t a, hb_codepoint_t b) { @@ -512,20 +514,37 @@ struct hb_set_t return true; } - void compact (unsigned int length) + 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) { - 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; + assert(workspace.length == pages.length); + hb_vector_t<unsigned>& old_index_to_page_map_index = workspace; - for (uint32_t i = 0; i < length; i++) + hb_fill (old_index_to_page_map_index.writer(), 0xFFFFFFFF); + /* TODO(iter) Rewrite as dagger? */ + 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<uint32_t>& 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++) @@ -543,6 +562,9 @@ struct hb_set_t template <typename Op> void process (const Op& op, const hb_set_t *other) { + const bool passthru_left = op (1, 0); + const bool passthru_right = op (0, 1); + if (unlikely (!successful)) return; dirty (); @@ -554,11 +576,17 @@ struct hb_set_t 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 (!Op::passthru_left) + 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 @@ -575,27 +603,27 @@ struct hb_set_t } else if (page_map[a].major < other->page_map[b].major) { - if (Op::passthru_left) + if (passthru_left) count++; a++; } else { - if (Op::passthru_right) + if (passthru_right) count++; b++; } } - if (Op::passthru_left) + if (passthru_left) count += na - a; - if (Op::passthru_right) + if (passthru_right) count += nb - b; - if (!Op::passthru_left) + if (!passthru_left) { na = write_index; next_page = write_index; - compact (write_index); + compact (compact_workspace, write_index); } if (!resize (count)) @@ -619,7 +647,7 @@ struct hb_set_t else if (page_map[a - 1].major > other->page_map[b - 1].major) { a--; - if (Op::passthru_left) + if (passthru_left) { count--; page_map[count] = page_map[a]; @@ -628,7 +656,7 @@ struct hb_set_t else { b--; - if (Op::passthru_right) + if (passthru_right) { count--; page_map[count].major = other->page_map[b].major; @@ -637,14 +665,14 @@ struct hb_set_t } } } - if (Op::passthru_left) + if (passthru_left) while (a) { a--; count--; page_map[count] = page_map [a]; } - if (Op::passthru_right) + if (passthru_right) while (b) { b--; @@ -655,6 +683,9 @@ struct hb_set_t } assert (!count); if (pages.length > newCount) + // This resize() doesn't need to be checked because we can't get here + // if the set is currently in_error() and this only resizes downwards + // which will always succeed if the set is not in_error(). resize (newCount); } diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc index 65a5fc4512..0d9eaddaa6 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc @@ -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 **/ @@ -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 **/ 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.cc b/thirdparty/harfbuzz/src/hb-shape.cc index a3debce397..c442f4403b 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -111,10 +111,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 +146,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-style.cc b/thirdparty/harfbuzz/src/hb-style.cc index 86b9f7da5f..2f45d119f9 100644 --- a/thirdparty/harfbuzz/src/hb-style.cc +++ b/thirdparty/harfbuzz/src/hb-style.cc @@ -65,6 +65,7 @@ typedef enum { 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; diff --git a/thirdparty/harfbuzz/src/hb-style.h b/thirdparty/harfbuzz/src/hb-style.h index 1209c79e94..f5776cee58 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 diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 24beada3e8..d055783a4d 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -88,10 +88,17 @@ _gsub_closure_glyphs_lookups_features (hb_face_t *face, &lookup_indices); _remap_indexes (&lookup_indices, gsub_lookups); - //closure features + // Collect and prune features hb_set_t feature_indices; - gsub->closure_features (gsub_lookups, &feature_indices); + hb_ot_layout_collect_features (face, + HB_OT_TAG_GSUB, + nullptr, + nullptr, + nullptr, + &feature_indices); + gsub->prune_features (gsub_lookups, &feature_indices); _remap_indexes (&feature_indices, gsub_features); + gsub.destroy (); } @@ -114,9 +121,15 @@ _gpos_closure_lookups_features (hb_face_t *face, &lookup_indices); _remap_indexes (&lookup_indices, gpos_lookups); - //closure features + // Collect and prune features hb_set_t feature_indices; - gpos->closure_features (gpos_lookups, &feature_indices); + hb_ot_layout_collect_features (face, + HB_OT_TAG_GPOS, + nullptr, + nullptr, + nullptr, + &feature_indices); + gpos->prune_features (gpos_lookups, &feature_indices); _remap_indexes (&feature_indices, gpos_features); gpos.destroy (); } @@ -243,7 +256,11 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #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 diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index e9f603dd1d..cc9cb7a1a2 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -172,12 +172,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); } }; diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc index d7f6a6e130..7470bb1b6e 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.cc +++ b/thirdparty/harfbuzz/src/hb-unicode.cc @@ -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-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 079b94a6b4..13517a9c29 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -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) { @@ -181,7 +186,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,7 +200,7 @@ 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)) diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index da377b9df6..6db58c3f7c 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 +/** + * HB_VERSION_MAJOR: + * + * The major component of the library version available at compile-time. + */ #define HB_VERSION_MAJOR 2 -#define HB_VERSION_MINOR 7 -#define HB_VERSION_MICRO 4 +/** + * HB_VERSION_MINOR: + * + * The minor component of the library version available at compile-time. + */ +#define HB_VERSION_MINOR 8 +/** + * 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 "2.8.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..18516581c7 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" @@ -126,6 +126,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 +176,15 @@ #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> +#include <cmath> +#include <cstdarg> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <cstring> #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__) #ifdef __MINGW32_VERSION @@ -244,12 +245,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__) @@ -394,7 +391,7 @@ 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 @@ -440,181 +437,12 @@ static int HB_UNUSED _hb_errno = 0; #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>)) - /* 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 diff --git a/thirdparty/miniupnpc/LICENSE b/thirdparty/miniupnpc/LICENSE index 1460310752..6ddd381baa 100644 --- a/thirdparty/miniupnpc/LICENSE +++ b/thirdparty/miniupnpc/LICENSE @@ -1,5 +1,5 @@ -MiniUPnP Project -Copyright (c) 2005-2019, Thomas BERNARD +MiniUPnPc +Copyright (c) 2005-2020, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without @@ -24,3 +24,4 @@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c new file mode 100644 index 0000000000..7e586d7da2 --- /dev/null +++ b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.c @@ -0,0 +1,79 @@ +/* $Id: addr_is_reserved.c,v 1.4 2021/03/02 23:40:32 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ + * Author : Thomas BERNARD + * copyright (c) 2005-2021 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENSE file. */ +#ifdef _WIN32 +/* Win32 Specific includes and defines */ +#include <winsock2.h> +#include <ws2tcpip.h> +#if !defined(_MSC_VER) +#include <stdint.h> +#else /* !defined(_MSC_VER) */ +typedef unsigned long uint32_t; +#endif /* !defined(_MSC_VER) */ +#else /* _WIN32 */ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#endif /* _WIN32 */ + +/* List of IP address blocks which are private / reserved and therefore not suitable for public external IP addresses */ +#define IP(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) +#define MSK(m) (32-(m)) +static const struct { uint32_t address; uint32_t rmask; } reserved[] = { + { IP( 0, 0, 0, 0), MSK( 8) }, /* RFC1122 "This host on this network" */ + { IP( 10, 0, 0, 0), MSK( 8) }, /* RFC1918 Private-Use */ + { IP(100, 64, 0, 0), MSK(10) }, /* RFC6598 Shared Address Space */ + { IP(127, 0, 0, 0), MSK( 8) }, /* RFC1122 Loopback */ + { IP(169, 254, 0, 0), MSK(16) }, /* RFC3927 Link-Local */ + { IP(172, 16, 0, 0), MSK(12) }, /* RFC1918 Private-Use */ + { IP(192, 0, 0, 0), MSK(24) }, /* RFC6890 IETF Protocol Assignments */ + { IP(192, 0, 2, 0), MSK(24) }, /* RFC5737 Documentation (TEST-NET-1) */ + { IP(192, 31, 196, 0), MSK(24) }, /* RFC7535 AS112-v4 */ + { IP(192, 52, 193, 0), MSK(24) }, /* RFC7450 AMT */ + { IP(192, 88, 99, 0), MSK(24) }, /* RFC7526 6to4 Relay Anycast */ + { IP(192, 168, 0, 0), MSK(16) }, /* RFC1918 Private-Use */ + { IP(192, 175, 48, 0), MSK(24) }, /* RFC7534 Direct Delegation AS112 Service */ + { IP(198, 18, 0, 0), MSK(15) }, /* RFC2544 Benchmarking */ + { IP(198, 51, 100, 0), MSK(24) }, /* RFC5737 Documentation (TEST-NET-2) */ + { IP(203, 0, 113, 0), MSK(24) }, /* RFC5737 Documentation (TEST-NET-3) */ + { IP(224, 0, 0, 0), MSK( 4) }, /* RFC1112 Multicast */ + { IP(240, 0, 0, 0), MSK( 4) }, /* RFC1112 Reserved for Future Use + RFC919 Limited Broadcast */ +}; +#undef IP +#undef MSK + +/** + * @return 1 or 0 + */ +int addr_is_reserved(const char * addr_str) +{ + uint32_t addr_n, address; + size_t i; + +#if defined(_WIN32) && (!defined(_WIN32_WINNT_VISTA) || (_WIN32_WINNT < _WIN32_WINNT_VISTA)) + addr_n = inet_addr(addr_str); + if (addr_n == INADDR_NONE) + return 1; +#else + /* was : addr_n = inet_addr(addr_str); */ + if (inet_pton(AF_INET, addr_str, &addr_n) <= 0) { + /* error */ + return 1; + } +#endif + + address = ntohl(addr_n); + + for (i = 0; i < sizeof(reserved)/sizeof(reserved[0]); ++i) { + if ((address >> reserved[i].rmask) == (reserved[i].address >> reserved[i].rmask)) + return 1; + } + + return 0; +} diff --git a/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h new file mode 100644 index 0000000000..f8b5d66a09 --- /dev/null +++ b/thirdparty/miniupnpc/miniupnpc/addr_is_reserved.h @@ -0,0 +1,14 @@ +/* $Id: $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project: miniupnp + * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2020 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef ADDR_IS_RESERVED_H_INCLUDED +#define ADDR_IS_RESERVED_H_INCLUDED + +int addr_is_reserved(const char * addr_str); + +#endif /* ADDR_IS_RESERVED_H_INCLUDED */ diff --git a/thirdparty/miniupnpc/miniupnpc/connecthostport.c b/thirdparty/miniupnpc/miniupnpc/connecthostport.c index f3982e1a77..79f832b8db 100644 --- a/thirdparty/miniupnpc/miniupnpc/connecthostport.c +++ b/thirdparty/miniupnpc/miniupnpc/connecthostport.c @@ -1,8 +1,8 @@ -/* $Id: connecthostport.c,v 1.22 2019/10/13 17:22:08 nanard Exp $ */ +/* $Id: connecthostport.c,v 1.24 2020/11/09 19:26:53 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2010-2019 Thomas Bernard + * Copyright (c) 2010-2020 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -19,7 +19,7 @@ #include <ws2tcpip.h> #include <io.h> #define MAXHOSTNAMELEN 64 -#define snprintf _snprintf +#include "win32_snprintf.h" #define herror #define socklen_t int #else /* #ifdef _WIN32 */ diff --git a/thirdparty/miniupnpc/miniupnpc/listdevices.c b/thirdparty/miniupnpc/miniupnpc/listdevices.c deleted file mode 100644 index bd9ba57efc..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/listdevices.c +++ /dev/null @@ -1,197 +0,0 @@ -/* $Id: listdevices.c,v 1.6 2015/07/23 20:40:08 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2013-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#ifdef _WIN32 -#include <winsock2.h> -#endif /* _WIN32 */ -#include "miniupnpc.h" - -struct upnp_dev_list { - struct upnp_dev_list * next; - char * descURL; - struct UPNPDev * * array; - size_t count; - size_t allocated_count; -}; - -#define ADD_DEVICE_COUNT_STEP 16 - -void add_device(struct upnp_dev_list * * list_head, struct UPNPDev * dev) -{ - struct upnp_dev_list * elt; - size_t i; - - if(dev == NULL) - return; - for(elt = *list_head; elt != NULL; elt = elt->next) { - if(strcmp(elt->descURL, dev->descURL) == 0) { - for(i = 0; i < elt->count; i++) { - if (strcmp(elt->array[i]->st, dev->st) == 0 && strcmp(elt->array[i]->usn, dev->usn) == 0) { - return; /* already found */ - } - } - if(elt->count >= elt->allocated_count) { - struct UPNPDev * * tmp; - elt->allocated_count += ADD_DEVICE_COUNT_STEP; - tmp = realloc(elt->array, elt->allocated_count * sizeof(struct UPNPDev *)); - if(tmp == NULL) { - fprintf(stderr, "Failed to realloc(%p, %lu)\n", elt->array, (unsigned long)(elt->allocated_count * sizeof(struct UPNPDev *))); - return; - } - elt->array = tmp; - } - elt->array[elt->count++] = dev; - return; - } - } - elt = malloc(sizeof(struct upnp_dev_list)); - if(elt == NULL) { - fprintf(stderr, "Failed to malloc(%lu)\n", (unsigned long)sizeof(struct upnp_dev_list)); - return; - } - elt->next = *list_head; - elt->descURL = strdup(dev->descURL); - if(elt->descURL == NULL) { - fprintf(stderr, "Failed to strdup(%s)\n", dev->descURL); - free(elt); - return; - } - elt->allocated_count = ADD_DEVICE_COUNT_STEP; - elt->array = malloc(ADD_DEVICE_COUNT_STEP * sizeof(struct UPNPDev *)); - if(elt->array == NULL) { - fprintf(stderr, "Failed to malloc(%lu)\n", (unsigned long)(ADD_DEVICE_COUNT_STEP * sizeof(struct UPNPDev *))); - free(elt->descURL); - free(elt); - return; - } - elt->array[0] = dev; - elt->count = 1; - *list_head = elt; -} - -void free_device(struct upnp_dev_list * elt) -{ - free(elt->descURL); - free(elt->array); - free(elt); -} - -int main(int argc, char * * argv) -{ - const char * searched_device = NULL; - const char * * searched_devices = NULL; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int ipv6 = 0; - unsigned char ttl = 2; - int error = 0; - struct UPNPDev * devlist = 0; - struct UPNPDev * dev; - struct upnp_dev_list * sorted_list = NULL; - struct upnp_dev_list * dev_array; - int i; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - - for(i = 1; i < argc; i++) { - if(strcmp(argv[i], "-6") == 0) - ipv6 = 1; - else if(strcmp(argv[i], "-d") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-d"); - return 1; - } - searched_device = argv[i]; - } else if(strcmp(argv[i], "-t") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-t"); - return 1; - } - ttl = (unsigned char)atoi(argv[i]); - } else if(strcmp(argv[i], "-l") == 0) { - if(++i >= argc) { - fprintf(stderr, "-l option needs at least one argument\n"); - return 1; - } - searched_devices = (const char * *)(argv + i); - break; - } else if(strcmp(argv[i], "-m") == 0) { - if(++i >= argc) { - fprintf(stderr, "-m option needs one argument\n"); - return 1; - } - multicastif = argv[i]; - } else { - printf("usage : %s [options] [-l <device1> <device2> ...]\n", argv[0]); - printf("options :\n"); - printf(" -6 : use IPv6\n"); - printf(" -m address/ifname : network interface to use for multicast\n"); - printf(" -d <device string> : search only for this type of device\n"); - printf(" -l <device1> <device2> ... : search only for theses types of device\n"); - printf(" -t ttl : set multicast TTL. Default value is 2.\n"); - printf(" -h : this help\n"); - return 1; - } - } - - if(searched_device) { - printf("searching UPnP device type %s\n", searched_device); - devlist = upnpDiscoverDevice(searched_device, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } else if(searched_devices) { - printf("searching UPnP device types :\n"); - for(i = 0; searched_devices[i]; i++) - printf("\t%s\n", searched_devices[i]); - devlist = upnpDiscoverDevices(searched_devices, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error, 1); - } else { - printf("searching all UPnP devices\n"); - devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } - if(devlist) { - for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) { - printf("%3d: %-48s\n", i, dev->st); - printf(" %s\n", dev->descURL); - printf(" %s\n", dev->usn); - add_device(&sorted_list, dev); - } - putchar('\n'); - for (dev_array = sorted_list; dev_array != NULL ; dev_array = dev_array->next) { - printf("%s :\n", dev_array->descURL); - for(i = 0; (unsigned)i < dev_array->count; i++) { - printf("%2d: %s\n", i+1, dev_array->array[i]->st); - printf(" %s\n", dev_array->array[i]->usn); - } - putchar('\n'); - } - freeUPNPDevlist(devlist); - while(sorted_list != NULL) { - dev_array = sorted_list; - sorted_list = sorted_list->next; - free_device(dev_array); - } - } else { - printf("no device found.\n"); - } - - return 0; -} - diff --git a/thirdparty/miniupnpc/miniupnpc/minisoap.c b/thirdparty/miniupnpc/miniupnpc/minisoap.c index f92b36ce89..78606672d5 100644 --- a/thirdparty/miniupnpc/miniupnpc/minisoap.c +++ b/thirdparty/miniupnpc/miniupnpc/minisoap.c @@ -1,8 +1,8 @@ -/* $Id: minisoap.c,v 1.25 2017/04/21 10:03:24 nanard Exp $ */ +/* $Id: minisoap.c,v 1.30 2020/11/09 19:27:42 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2018 Thomas Bernard + * Copyright (c) 2005-2020 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * @@ -13,7 +13,7 @@ #ifdef _WIN32 #include <io.h> #include <winsock2.h> -#define snprintf _snprintf +#include "win32_snprintf.h" #else #include <unistd.h> #include <sys/types.h> diff --git a/thirdparty/miniupnpc/miniupnpc/minissdpc.c b/thirdparty/miniupnpc/miniupnpc/minissdpc.c index a3b1283da5..0ef7e12cfb 100644 --- a/thirdparty/miniupnpc/miniupnpc/minissdpc.c +++ b/thirdparty/miniupnpc/miniupnpc/minissdpc.c @@ -1,15 +1,15 @@ -/* $Id: minissdpc.c,v 1.40 2019/04/23 12:12:55 nanard Exp $ */ +/* $Id: minissdpc.c,v 1.47 2021/03/02 23:38:30 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp - * Web : http://miniupnp.free.fr/ + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2019 Thomas Bernard + * copyright (c) 2005-2021 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ -/*#include <syslog.h>*/ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <time.h> #include <sys/types.h> #if defined (__NetBSD__) #include <net/if.h> @@ -20,7 +20,7 @@ #include <ws2tcpip.h> #include <io.h> #include <iphlpapi.h> -#define snprintf _snprintf +#include "win32_snprintf.h" #if !defined(_MSC_VER) #include <stdint.h> #else /* !defined(_MSC_VER) */ @@ -33,6 +33,12 @@ typedef unsigned short uint16_t; #define strncasecmp memicmp #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ #endif /* #ifndef strncasecmp */ +#if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP +#define in6addr_any in6addr_any_init +static const IN6_ADDR in6addr_any_init = {0}; +#endif +#endif #endif /* _WIN32 */ #if defined(__amigaos__) || defined(__amigaos4__) #include <sys/socket.h> @@ -66,7 +72,7 @@ struct sockaddr_un { #define HAS_IP_MREQN #endif -#if !defined(HAS_IP_MREQN) && !defined(_WIN32) +#ifndef _WIN32 #include <sys/ioctl.h> #if defined(__sun) || defined(__HAIKU__) #include <sys/sockio.h> @@ -445,6 +451,36 @@ parseMSEARCHReply(const char * reply, int size, } } +#if defined(CLOCK_MONOTONIC_FAST) +#define UPNP_CLOCKID CLOCK_MONOTONIC_FAST +#elif defined(CLOCK_MONOTONIC) +#define UPNP_CLOCKID CLOCK_MONOTONIC +#endif + +static int upnp_gettimeofday(struct timeval * tv) +{ +#if defined(_WIN32) +#if defined(_WIN32_WINNT_VISTA) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) + ULONGLONG ts = GetTickCount64(); +#else + DWORD ts = GetTickCount(); +#endif + tv->tv_sec = (long)(ts / 1000); + tv->tv_usec = (ts % 1000) * 1000; + return 0; /* success */ +#elif defined(CLOCK_MONOTONIC_FAST) || defined(CLOCK_MONOTONIC) + struct timespec ts; + int ret_code = clock_gettime(UPNP_CLOCKID, &ts); + if (ret_code == 0) + { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + } + return ret_code; +#else + return gettimeofday(tv, NULL); +#endif +} /* port upnp discover : SSDP protocol */ #define SSDP_PORT 1900 #define XSTR(s) STR(s) @@ -540,12 +576,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ if(!ipv6) { DWORD ifbestidx; - SOCKADDR_IN destAddr; - memset(&destAddr, 0, sizeof(destAddr)); - destAddr.sin_family = AF_INET; - destAddr.sin_addr.s_addr = inet_addr("223.255.255.255"); - destAddr.sin_port = 0; - if (GetBestInterfaceEx((struct sockaddr *)&destAddr, &ifbestidx) == NO_ERROR) { + if (GetBestInterface(inet_addr("223.255.255.255"), &ifbestidx) == NO_ERROR) { DWORD dwRetVal = NO_ERROR; PIP_ADAPTER_ADDRESSES pAddresses = NULL; ULONG outBufLen = 15360; @@ -672,6 +703,13 @@ ssdpDiscoverDevices(const char * const deviceTypes[], * MS Windows Vista and MS Windows Server 2008. * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ + if(ifindex == 0) + { + if(error) + *error = MINISSDPC_INVALID_INPUT; + fprintf(stderr, "Invalid multicast interface name %s\n", multicastif); + goto error; + } if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) { PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF"); @@ -683,10 +721,17 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif } else { struct in_addr mc_if; -#if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) +#if defined(_WIN32) +#if defined(_WIN32_WINNT_VISTA) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) InetPtonA(AF_INET, multicastif, &mc_if); #else - mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ + mc_if.s_addr = inet_addr(multicastif); /* old Windows SDK do not support InetPtoA() */ +#endif +#else + /* was : mc_if.s_addr = inet_addr(multicastif); */ /* ex: 192.168.x.x */ + if (inet_pton(AF_INET, multicastif, &mc_if.s_addr) <= 0) { + mc_if.s_addr = INADDR_NONE; + } #endif if(mc_if.s_addr != INADDR_NONE) { @@ -696,16 +741,11 @@ ssdpDiscoverDevices(const char * const deviceTypes[], PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } } else { -#ifdef HAS_IP_MREQN /* was not an ip address, try with an interface name */ +#ifndef _WIN32 +#ifdef HAS_IP_MREQN struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ - memset(&reqn, 0, sizeof(struct ip_mreqn)); - reqn.imr_ifindex = if_nametoindex(multicastif); - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#elif !defined(_WIN32) +#endif struct ifreq ifr; int ifrlen = sizeof(ifr); strncpy(ifr.ifr_name, multicastif, IFNAMSIZ); @@ -713,12 +753,30 @@ ssdpDiscoverDevices(const char * const deviceTypes[], if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0) { PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)"); + goto error; } mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; +#ifdef HAS_IP_MREQN + memset(&reqn, 0, sizeof(struct ip_mreqn)); + reqn.imr_address.s_addr = mc_if.s_addr; + reqn.imr_ifindex = if_nametoindex(multicastif); + if(reqn.imr_ifindex == 0) + { + if(error) + *error = MINISSDPC_INVALID_INPUT; + fprintf(stderr, "Invalid multicast ip address / interface name %s\n", multicastif); + goto error; + } + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); + } +#else if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } +#endif #else /* _WIN32 */ #ifdef DEBUG printf("Setting of multicast interface not supported with interface name.\n"); @@ -842,73 +900,84 @@ ssdpDiscoverDevices(const char * const deviceTypes[], /* Waiting for SSDP REPLY packet to M-SEARCH * if searchalltypes is set, enter the loop only * when the last deviceType is reached */ - if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { - n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); - if (n < 0) { - /* error */ - if(error) - *error = MINISSDPC_SOCKET_ERROR; - goto error; - } else if (n == 0) { - /* no data or Time Out */ -#ifdef DEBUG - printf("NODATA or TIMEOUT\n"); -#endif /* DEBUG */ - if (devlist && !searchalltypes) { - /* found some devices, stop now*/ + if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) { + struct timeval start = {0, 0}, current = {0, 0}; + upnp_gettimeofday(&start); + do { + n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); + if (n < 0) { + /* error */ if(error) - *error = MINISSDPC_SUCCESS; + *error = MINISSDPC_SOCKET_ERROR; goto error; - } - } else { - const char * descURL=NULL; - int urlsize=0; - const char * st=NULL; - int stsize=0; - const char * usn=NULL; - int usnsize=0; - parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); - if(st&&descURL) { + } else if (n == 0) { + /* no data or Time Out */ #ifdef DEBUG - printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", - stsize, st, usnsize, (usn?usn:""), urlsize, descURL); + printf("NODATA or TIMEOUT\n"); #endif /* DEBUG */ - for(tmp=devlist; tmp; tmp = tmp->pNext) { - if(strncmp(tmp->descURL, descURL, urlsize) == 0 && - tmp->descURL[urlsize] == '\0' && - strncmp(tmp->st, st, stsize) == 0 && - tmp->st[stsize] == '\0' && - (usnsize == 0 || strncmp(tmp->usn, usn, usnsize) == 0) && - tmp->usn[usnsize] == '\0') - break; - } - /* at the exit of the loop above, tmp is null if - * no duplicate device was found */ - if(tmp) - continue; - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(!tmp) { - /* memory allocation error */ + if (devlist && !searchalltypes) { + /* found some devices, stop now*/ if(error) - *error = MINISSDPC_MEMORY_ERROR; + *error = MINISSDPC_SUCCESS; goto error; } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - tmp->usn = tmp->st + 1 + stsize; - memcpy(tmp->buffer, descURL, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - if(usn != NULL) - memcpy(tmp->usn, usn, usnsize); - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = scope_id; - devlist = tmp; + } else { + const char * descURL=NULL; + int urlsize=0; + const char * st=NULL; + int stsize=0; + const char * usn=NULL; + int usnsize=0; + parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); + if(st&&descURL) { +#ifdef DEBUG + printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", + stsize, st, usnsize, (usn?usn:""), urlsize, descURL); +#endif /* DEBUG */ + for(tmp=devlist; tmp; tmp = tmp->pNext) { + if(strncmp(tmp->descURL, descURL, urlsize) == 0 && + tmp->descURL[urlsize] == '\0' && + strncmp(tmp->st, st, stsize) == 0 && + tmp->st[stsize] == '\0' && + (usnsize == 0 || strncmp(tmp->usn, usn, usnsize) == 0) && + tmp->usn[usnsize] == '\0') + break; + } + /* at the exit of the loop above, tmp is null if + * no duplicate device was found */ + if(tmp) + continue; + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize+3); + if(!tmp) { + /* memory allocation error */ + if(error) + *error = MINISSDPC_MEMORY_ERROR; + goto error; + } + tmp->pNext = devlist; + tmp->descURL = tmp->buffer; + tmp->st = tmp->buffer + 1 + urlsize; + tmp->usn = tmp->st + 1 + stsize; + memcpy(tmp->buffer, descURL, urlsize); + tmp->buffer[urlsize] = '\0'; + memcpy(tmp->st, st, stsize); + tmp->buffer[urlsize+1+stsize] = '\0'; + if(usn != NULL) + memcpy(tmp->usn, usn, usnsize); + tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; + tmp->scope_id = scope_id; + devlist = tmp; + } + if (upnp_gettimeofday(¤t) >= 0) { + /* exit the loop if delay is reached */ + long interval = (current.tv_sec - start.tv_sec) * 1000; + interval += (current.tv_usec - start.tv_usec) / 1000; + if (interval > (long)delay) + break; + } } - } - } while(n > 0); + } while(n > 0); + } if(ipv6) { /* switch linklocal flag */ if(linklocal) { @@ -923,4 +992,3 @@ error: closesocket(sudp); return devlist; } - diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpc.c b/thirdparty/miniupnpc/miniupnpc/miniupnpc.c index 95ab6cf56b..696af93237 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpc.c +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpc.c @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.c,v 1.154 2019/04/23 12:12:13 nanard Exp $ */ +/* $Id: miniupnpc.c,v 1.159 2021/03/02 23:36:32 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp - * Web : http://miniupnp.free.fr/ + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2019 Thomas Bernard + * copyright (c) 2005-2021 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #include <stdlib.h> @@ -15,7 +15,7 @@ #include <ws2tcpip.h> #include <io.h> #include <iphlpapi.h> -#define snprintf _snprintf +#include "win32_snprintf.h" #define strdup _strdup #ifndef strncasecmp #if defined(_MSC_VER) && (_MSC_VER >= 1400) @@ -61,6 +61,7 @@ #include "minixml.h" #include "upnpcommands.h" #include "connecthostport.h" +#include "addr_is_reserved.h" /* compare the beginning of a string with a constant string */ #define COMPARE(str, cstr) (0==strncmp(str, cstr, sizeof(cstr) - 1)) @@ -73,24 +74,6 @@ #define SERVICEPREFIX "u" #define SERVICEPREFIX2 'u' -/* check if an ip address is a private (LAN) address - * see https://tools.ietf.org/html/rfc1918 */ -static int is_rfc1918addr(const char * addr) -{ - /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ - if(COMPARE(addr, "192.168.")) - return 1; - /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ - if(COMPARE(addr, "10.")) - return 1; - /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ - if(COMPARE(addr, "172.")) { - if((atoi(addr + 4) | 0x0f) == 0x1f) - return 1; - } - return 0; -} - /* root description parsing */ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) { @@ -337,6 +320,8 @@ upnpDiscoverDevices(const char * const deviceTypes[], return devlist; } } +#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ + (void)minissdpdsock; /* unused */ #endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ /* direct discovery if minissdpd responses are not sufficient */ @@ -643,8 +628,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, /* checks that status is connected AND there is a external IP address assigned */ if(is_connected && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) + if(!addr_is_reserved(extIpAddr)) goto free_and_return; } FreeUPNPUrls(urls); @@ -665,8 +649,7 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, #endif if(is_connected && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.0"))) + if(!addr_is_reserved(extIpAddr)) goto free_and_return; } FreeUPNPUrls(urls); diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpc.h b/thirdparty/miniupnpc/miniupnpc/miniupnpc.h index 8ddc282bd1..3aef8ea443 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpc.h +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpc.h @@ -1,9 +1,9 @@ -/* $Id: miniupnpc.h,v 1.53 2018/05/07 11:05:16 nanard Exp $ */ +/* $Id: miniupnpc.h,v 1.58 2021/03/02 23:49:52 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project: miniupnp * http://miniupnp.free.fr/ * Author: Thomas Bernard - * Copyright (c) 2005-2018 Thomas Bernard + * Copyright (c) 2005-2021 Thomas Bernard * This software is subjects to the conditions detailed * in the LICENCE file provided within this distribution */ #ifndef MINIUPNPC_H_INCLUDED @@ -20,7 +20,7 @@ #define UPNPDISCOVER_MEMORY_ERROR (-102) /* versions : */ -#define MINIUPNPC_VERSION "2.1" +#define MINIUPNPC_VERSION "2.2.2" #define MINIUPNPC_API_VERSION 17 /* Source port: diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h b/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h index d4f79a7bd6..5986e58c76 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpc_socketdef.h @@ -7,7 +7,7 @@ #ifndef MINIUPNPC_SOCKETDEF_H_INCLUDED #define MINIUPNPC_SOCKETDEF_H_INCLUDED -#ifdef _MSC_VER +#ifdef _WIN32 #define ISINVALID(s) (INVALID_SOCKET==(s)) diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c b/thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c deleted file mode 100644 index d9341ab5bf..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpcmodule.c +++ /dev/null @@ -1,721 +0,0 @@ -/* $Id: miniupnpcmodule.c,v 1.34 2019/05/20 19:07:16 nanard Exp $*/ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Author : Thomas BERNARD - * website : https://miniupnp.tuxfamily.org/ - * copyright (c) 2007-2019 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include <Python.h> -#define MINIUPNP_STATICLIB -#include "structmember.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" - -#ifdef _WIN32 -#include <winsock2.h> -#endif - -/* for compatibility with Python < 2.4 */ -#ifndef Py_RETURN_NONE -#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None -#endif - -#ifndef Py_RETURN_TRUE -#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True -#endif - -#ifndef Py_RETURN_FALSE -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False -#endif - -/* for compatibility with Python < 3.0 */ -#ifndef PyVarObject_HEAD_INIT -#define PyVarObject_HEAD_INIT(type, size) \ - PyObject_HEAD_INIT(type) size, -#endif - -#ifndef Py_TYPE -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) -#endif - -typedef struct { - PyObject_HEAD - /* Type-specific fields go here. */ - struct UPNPDev * devlist; - struct UPNPUrls urls; - struct IGDdatas data; - unsigned int discoverdelay; /* value passed to upnpDiscover() */ - unsigned int localport; /* value passed to upnpDiscover() */ - char lanaddr[40]; /* our ip address on the LAN */ - char * multicastif; - char * minissdpdsocket; -} UPnPObject; - -static PyMemberDef UPnP_members[] = { - {"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr), - READONLY, "ip address on the LAN" - }, - {"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay), - 0/*READWRITE*/, "value in ms used to wait for SSDP responses" - }, - {"localport", T_UINT, offsetof(UPnPObject, localport), - 0/*READWRITE*/, - "If localport is set to UPNP_LOCAL_PORT_SAME(1) " - "SSDP packets will be sent from the source port " - "1900 (same as destination port), if set to " - "UPNP_LOCAL_PORT_ANY(0) system assign a source " - "port, any other value will be attempted as the " - "source port" - }, - /* T_STRING is allways readonly :( */ - {"multicastif", T_STRING, offsetof(UPnPObject, multicastif), - 0, "IP of the network interface to be used for multicast operations" - }, - {"minissdpdsocket", T_STRING, offsetof(UPnPObject, minissdpdsocket), - 0, "path of the MiniSSDPd unix socket" - }, - {NULL} -}; - - -static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds) -{ - char* multicastif = NULL; - char* minissdpdsocket = NULL; - static char *kwlist[] = { - "multicastif", "minissdpdsocket", "discoverdelay", - "localport", NULL - }; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist, - &multicastif, - &minissdpdsocket, - &self->discoverdelay, - &self->localport)) - return -1; - - if(self->localport>1 && - (self->localport>65534||self->localport<1024)) { - PyErr_SetString(PyExc_Exception, "Invalid localport value"); - return -1; - } - if(multicastif) - self->multicastif = strdup(multicastif); - if(minissdpdsocket) - self->minissdpdsocket = strdup(minissdpdsocket); - - return 0; -} - -static void -UPnPObject_dealloc(UPnPObject *self) -{ - freeUPNPDevlist(self->devlist); - FreeUPNPUrls(&self->urls); - free(self->multicastif); - free(self->minissdpdsocket); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyObject * -UPnP_discover(UPnPObject *self) -{ - struct UPNPDev * dev; - int i; - PyObject *res = NULL; - if(self->devlist) - { - freeUPNPDevlist(self->devlist); - self->devlist = 0; - } - Py_BEGIN_ALLOW_THREADS - self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/, - self->multicastif, - self->minissdpdsocket, - (int)self->localport, - 0/*ip v6*/, - 2/* TTL */, - 0/*error */); - Py_END_ALLOW_THREADS - /* Py_RETURN_NONE ??? */ - for(dev = self->devlist, i = 0; dev; dev = dev->pNext) - i++; - res = Py_BuildValue("i", i); - return res; -} - -static PyObject * -UPnP_selectigd(UPnPObject *self) -{ - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data, - self->lanaddr, sizeof(self->lanaddr)); -Py_END_ALLOW_THREADS - if(r) - { - return Py_BuildValue("s", self->urls.controlURL); - } - else - { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, "No UPnP device discovered"); - return NULL; - } -} - -static PyObject * -UPnP_totalbytesent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalbytereceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketsent(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_totalpacketreceived(UPnPObject *self) -{ - UNSIGNED_INTEGER i; -Py_BEGIN_ALLOW_THREADS - i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF, - self->data.CIF.servicetype); -Py_END_ALLOW_THREADS -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -static PyObject * -UPnP_statusinfo(UPnPObject *self) -{ - char status[64]; - char lastconnerror[64]; - unsigned int uptime = 0; - int r; - status[0] = '\0'; - lastconnerror[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype, - status, &uptime, lastconnerror); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror); -#else - return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_connectiontype(UPnPObject *self) -{ - char connectionType[64]; - int r; - connectionType[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetConnectionTypeInfo(self->urls.controlURL, - self->data.first.servicetype, - connectionType); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", connectionType); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_externalipaddress(UPnPObject *self) -{ - char externalIPAddress[40]; - int r; - externalIPAddress[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetExternalIPAddress(self->urls.controlURL, - self->data.first.servicetype, - externalIPAddress); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("s", externalIPAddress); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost, leaseDuration) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - unsigned int intLeaseDuration = 0; - char strLeaseDuration[12]; - int r; -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - if (!PyArg_ParseTuple(args, "HssHzz|I", &ePort, &proto, - &host, &iPort, &desc, &remoteHost, &intLeaseDuration)) -#else - if (!PyArg_ParseTuple(args, "HssHzz|i", &ePort, &proto, - &host, &iPort, &desc, &remoteHost, (int *)&intLeaseDuration)) -#endif - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - sprintf(strLeaseDuration, "%u", intLeaseDuration); - r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, strLeaseDuration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - Py_RETURN_TRUE; - } - else - { - // TODO: RAISE an Exception. See upnpcommands.h for errors codes. - // upnperrors.c - //Py_RETURN_FALSE; - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addanyportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - char reservedPort[6]; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration, reservedPort); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("i", atoi(reservedPort)); - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - - -/* DeletePortMapping(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - int r; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, proto, remoteHost); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* DeletePortMappingRange(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args) -{ - char extPortStart[6]; - unsigned short ePortStart; - char extPortEnd[6]; - unsigned short ePortEnd; - const char * proto; - unsigned char manage; - char manageStr[6]; - int r; - if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPortStart, "%hu", ePortStart); - sprintf(extPortEnd, "%hu", ePortEnd); - sprintf(manageStr, "%hu", (unsigned short)manage); - r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype, - extPortStart, extPortEnd, proto, manageStr); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - Py_RETURN_TRUE; - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -static PyObject * -UPnP_getportmappingnumberofentries(UPnPObject *self) -{ - unsigned int n = 0; - int r; -Py_BEGIN_ALLOW_THREADS - r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL, - self->data.first.servicetype, - &n); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", n); -#else - return Py_BuildValue("i", (int)n); -#endif - } else { - /* TODO: have our own exception type ! */ - PyErr_SetString(PyExc_Exception, strupnperror(r)); - return NULL; - } -} - -/* GetSpecificPortMapping(ePort, proto, remoteHost='') - * proto = 'UDP' or 'TCP' */ -static PyObject * -UPnP_getspecificportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - const char * proto; - const char * remoteHost = ""; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char desc[80]; - char enabled[4]; - char leaseDuration[16]; - if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost)) - return NULL; - extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0'; - desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0'; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - UPNP_GetSpecificPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - extPort, proto, remoteHost, - intClient, intPort, - desc, enabled, leaseDuration); -Py_END_ALLOW_THREADS - if(intClient[0]) - { - iPort = (unsigned short)atoi(intPort); - return Py_BuildValue("(s,H,s,O,i)", - intClient, iPort, desc, - PyBool_FromLong(atoi(enabled)), - atoi(leaseDuration)); - } - else - { - Py_RETURN_NONE; - } -} - -/* GetGenericPortMapping(index) */ -static PyObject * -UPnP_getgenericportmapping(UPnPObject *self, PyObject *args) -{ - int i, r; - char index[8]; - char intClient[40]; - char intPort[6]; - unsigned short iPort; - char extPort[6]; - unsigned short ePort; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; /* lease duration */ - unsigned int dur; - if(!PyArg_ParseTuple(args, "i", &i)) - return NULL; -Py_BEGIN_ALLOW_THREADS - snprintf(index, sizeof(index), "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL, - self->data.first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, rHost, - duration); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) - { - ePort = (unsigned short)atoi(extPort); - iPort = (unsigned short)atoi(intPort); - dur = (unsigned int)strtoul(duration, 0, 0); -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(H,s,(s,H),s,s,s,I)", - ePort, protocol, intClient, iPort, - desc, enabled, rHost, dur); -#else - return Py_BuildValue("(i,s,(s,i),s,s,s,i)", - (int)ePort, protocol, intClient, (int)iPort, - desc, enabled, rHost, (int)dur); -#endif - } - else - { - Py_RETURN_NONE; - } -} - -/* miniupnpc.UPnP object Method Table */ -static PyMethodDef UPnP_methods[] = { - {"discover", (PyCFunction)UPnP_discover, METH_NOARGS, - "discover UPnP IGD devices on the network" - }, - {"selectigd", (PyCFunction)UPnP_selectigd, METH_NOARGS, - "select a valid UPnP IGD among discovered devices" - }, - {"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS, - "return the total number of bytes sent by UPnP IGD" - }, - {"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS, - "return the total number of bytes received by UPnP IGD" - }, - {"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS, - "return the total number of packets sent by UPnP IGD" - }, - {"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS, - "return the total number of packets received by UPnP IGD" - }, - {"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS, - "return status and uptime" - }, - {"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS, - "return IGD WAN connection type" - }, - {"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS, - "return external IP address" - }, - {"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS, - "add a port mapping" - }, - {"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS, - "add a port mapping, IGD to select alternative if necessary" - }, - {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS, - "delete a port mapping" - }, - {"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS, - "delete a range of port mappings" - }, - {"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS, - "-- non standard --" - }, - {"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS, - "get details about a specific port mapping entry" - }, - {"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS, - "get all details about the port mapping at index" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject UPnPType = { - PyVarObject_HEAD_INIT(NULL, - 0) /*ob_size*/ - "miniupnpc.UPnP", /*tp_name*/ - sizeof(UPnPObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)UPnPObject_dealloc,/*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - "UPnP objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - UPnP_methods, /* tp_methods */ - UPnP_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)UPnP_init, /* tp_init */ - 0, /* tp_alloc */ -#ifndef _WIN32 - PyType_GenericNew,/*UPnP_new,*/ /* tp_new */ -#else - 0, -#endif -}; - -/* module methods */ -static PyMethodDef miniupnpc_methods[] = { - {NULL} /* Sentinel */ -}; - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "miniupnpc", /* m_name */ - "miniupnpc module.", /* m_doc */ - -1, /* m_size */ - miniupnpc_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; -#endif - -#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ -#define PyMODINIT_FUNC void -#endif - -PyMODINIT_FUNC -#if PY_MAJOR_VERSION >= 3 -PyInit_miniupnpc(void) -#else -initminiupnpc(void) -#endif -{ - PyObject* m; - -#ifdef _WIN32 - /* initialize Winsock. */ - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if (nResult != 0) - { - /* error code could be WSASYSNOTREADY WSASYSNOTREADY - * WSASYSNOTREADY WSASYSNOTREADY WSASYSNOTREADY */ -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - } - - UPnPType.tp_new = PyType_GenericNew; -#endif - if (PyType_Ready(&UPnPType) < 0) -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("miniupnpc", miniupnpc_methods, - "miniupnpc module."); -#endif - - Py_INCREF(&UPnPType); - PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType); - -#if PY_MAJOR_VERSION >= 3 - return m; -#endif -} - diff --git a/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h b/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h index a718cc7bbf..7b3d04074a 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h +++ b/thirdparty/miniupnpc/miniupnpc/miniupnpcstrings.h @@ -4,7 +4,7 @@ #include "core/version.h" #define OS_STRING VERSION_NAME "/1.0" -#define MINIUPNPC_VERSION_STRING "2.1" +#define MINIUPNPC_VERSION_STRING "2.2.2" #if 0 /* according to "UPnP Device Architecture 1.0" */ diff --git a/thirdparty/miniupnpc/miniupnpc/miniwget.c b/thirdparty/miniupnpc/miniupnpc/miniwget.c index 5c135f4efd..d5b7970632 100644 --- a/thirdparty/miniupnpc/miniupnpc/miniwget.c +++ b/thirdparty/miniupnpc/miniupnpc/miniwget.c @@ -1,8 +1,8 @@ -/* $Id: miniwget.c,v 1.78 2018/03/13 23:22:18 nanard Exp $ */ +/* $Id: miniwget.c,v 1.82 2020/05/29 21:14:22 nanard Exp $ */ /* Project : miniupnp - * Website : http://miniupnp.free.fr/ + * Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas Bernard - * Copyright (c) 2005-2018 Thomas Bernard + * Copyright (c) 2005-2020 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -15,7 +15,7 @@ #include <ws2tcpip.h> #include <io.h> #define MAXHOSTNAMELEN 64 -#define snprintf _snprintf +#include "win32_snprintf.h" #define socklen_t int #ifndef strncasecmp #if defined(_MSC_VER) && (_MSC_VER >= 1400) @@ -176,11 +176,14 @@ getHTTPResponse(SOCKET s, int * size, int * status_code) /* Status line * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ int sp; - for(sp = 0; sp < i; sp++) + for(sp = 0; sp < i - 1; sp++) if(header_buf[sp] == ' ') { if(*status_code < 0) - *status_code = atoi(header_buf + sp + 1); + { + if (header_buf[sp+1] >= '1' && header_buf[sp+1] <= '9') + *status_code = atoi(header_buf + sp + 1); + } else { #ifdef DEBUG diff --git a/thirdparty/miniupnpc/miniupnpc/portlistingparse.c b/thirdparty/miniupnpc/miniupnpc/portlistingparse.c index 18d967b877..162cf8b7ec 100644 --- a/thirdparty/miniupnpc/miniupnpc/portlistingparse.c +++ b/thirdparty/miniupnpc/miniupnpc/portlistingparse.c @@ -15,7 +15,7 @@ #if defined(__HAIKU__) /* rename our private function because Haiku already defines a atoui() function */ #define atoui atoui2 -#endif +#endif /* list of the elements */ static const struct { diff --git a/thirdparty/miniupnpc/miniupnpc/receivedata.c b/thirdparty/miniupnpc/miniupnpc/receivedata.c index 7b9cc5b778..7f187f6e56 100644 --- a/thirdparty/miniupnpc/miniupnpc/receivedata.c +++ b/thirdparty/miniupnpc/miniupnpc/receivedata.c @@ -1,8 +1,8 @@ -/* $Id: receivedata.c,v 1.7 2015/11/09 21:51:41 nanard Exp $ */ +/* $Id: receivedata.c,v 1.10 2021/03/02 23:33:07 nanard Exp $ */ /* Project : miniupnp * Website : http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2011-2014 Thomas Bernard + * Copyright (c) 2011-2021 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -92,7 +92,13 @@ receivedata(SOCKET socket, #endif /* DEBUG */ if(scope_id) *scope_id = src_addr6->sin6_scope_id; + } else { + if(scope_id) + *scope_id = 0; } +#else /* MINIUPNPC_GET_SRC_ADDR */ + if(scope_id) + *scope_id = 0; #endif /* MINIUPNPC_GET_SRC_ADDR */ return n; } diff --git a/thirdparty/miniupnpc/miniupnpc/upnpc.c b/thirdparty/miniupnpc/miniupnpc/upnpc.c deleted file mode 100644 index cb7f18b5f6..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/upnpc.c +++ /dev/null @@ -1,864 +0,0 @@ -/* $Id: upnpc.c,v 1.119 2018/03/13 23:34:46 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2020 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#ifdef _WIN32 -#include <winsock2.h> -#define snprintf _snprintf -#else -/* for IPPROTO_TCP / IPPROTO_UDP */ -#include <netinet/in.h> -#endif -#include <ctype.h> -#include "miniwget.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "portlistingparse.h" -#include "upnperrors.h" -#include "miniupnpcstrings.h" - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - static const char proto_udp[4] = { 'U', 'D', 'P', 0}; - int i, b; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); - if(b) - return proto_tcp; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); - if(b) - return proto_udp; - return 0; -} - -/* is_int() checks if parameter is an integer or not - * 1 for integer - * 0 for not an integer */ -int is_int(char const* s) -{ - if(s == NULL) - return 0; - while(*s) { - /* #define isdigit(c) ((c) >= '0' && (c) <= '9') */ - if(!isdigit(*s)) - return 0; - s++; - } - return 1; -} - -static void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - char externalIPAddress[40]; - char connectionType[64]; - char status[64]; - char lastconnerr[64]; - unsigned int uptime = 0; - unsigned int brUp, brDown; - time_t timenow, timestarted; - int r; - if(UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType) != UPNPCOMMAND_SUCCESS) - printf("GetConnectionTypeInfo failed.\n"); - else - printf("Connection Type : %s\n", connectionType); - if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) - printf("GetStatusInfo failed.\n"); - else - printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); - if(uptime > 0) { - timenow = time(NULL); - timestarted = timenow - uptime; - printf(" Time started : %s", ctime(×tarted)); - } - if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { - printf("GetLinkLayerMaxBitRates failed.\n"); - } else { - printf("MaxBitRateDown : %u bps", brDown); - if(brDown >= 1000000) { - printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); - } else if(brDown >= 1000) { - printf(" (%u Kbps)", brDown / 1000); - } - printf(" MaxBitRateUp %u bps", brUp); - if(brUp >= 1000000) { - printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); - } else if(brUp >= 1000) { - printf(" (%u Kbps)", brUp / 1000); - } - printf("\n"); - } - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) { - printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); - } else { - printf("ExternalIPAddress = %s\n", externalIPAddress); - } -} - -static void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -static void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - char index[6]; - char intClient[40]; - char intPort[6]; - char extPort[6]; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; - /*unsigned int num=0; - UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); - printf("PortMappingNumberOfEntries : %u\n", num);*/ - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - do { - snprintf(index, 6, "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, - data->first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" - " desc='%s' rHost='%s'\n", - i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); - */ - printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", - i, protocol, extPort, intClient, intPort, - desc, rHost, duration); - else - printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); - i++; - } while(r==0); -} - -static void NewListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - struct PortMappingParserData pdata; - struct PortMapping * pm; - - memset(&pdata, 0, sizeof(struct PortMappingParserData)); - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "TCP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "UDP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } -} - -/* Test function - * 1 - get connection type - * 2 - get extenal ip address - * 3 - Add port mapping - * 4 - get this port mapping from the IGD */ -static int SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto, - const char * leaseDuration, - const char * remoteHost, - const char * description, - int addAny) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - char reservedPort[6]; - char duration[16]; - int r; - - if(!iaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "invalid protocol\n"); - return -1; - } - - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetExternalIPAddress failed.\n"); - else - printf("ExternalIPAddress = %s\n", externalIPAddress); - - if (addAny) { - r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, remoteHost, leaseDuration, reservedPort); - if(r==UPNPCOMMAND_SUCCESS) - eport = reservedPort; - else - printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - } else { - r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, remoteHost, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - return -2; - } - } - - r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->first.servicetype, - eport, proto, remoteHost, - intClient, intPort, NULL/*desc*/, - NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", - r, strupnperror(r)); - return -2; - } else { - printf("InternalIP:Port = %s:%s\n", intClient, intPort); - printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", - externalIPAddress, eport, proto, intClient, intPort, duration); - } - return 0; -} - -static int -RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto, - const char * remoteHost) -{ - int r; - if(!proto || !eport) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMapping() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMapping() returned : %d\n", r); - } - return 0; -} - -static int -RemoveRedirectRange(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * ePortStart, char const * ePortEnd, - const char * proto, const char * manage) -{ - int r; - - if (!manage) - manage = "0"; - - if(!proto || !ePortStart || !ePortEnd) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMappingRange() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMappingRange() returned : %d\n", r); - } - return 0; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - int firewallEnabled = 0, inboundPinholeAllowed = 0; - - UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed); - printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed); - printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No"); - - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -/* Test function - * 1 - Add pinhole - * 2 - Check if pinhole is working from the IGD side */ -static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto, const char * lease_time) -{ - char uniqueID[8]; - /*int isWorking = 0;*/ - int r; - char proto_tmp[8]; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - if(atoi(proto) == 0) - { - const char * protocol; - protocol = protofix(proto); - if(protocol && (strcmp("TCP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP); - proto = proto_tmp; - } - else if(protocol && (strcmp("UDP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP); - proto = proto_tmp; - } - else - { - fprintf(stderr, "invalid protocol\n"); - return; - } - } - r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID); - if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - remoteaddr, eport, intaddr, iport, r, strupnperror(r)); - else - { - printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", - remoteaddr, eport, intaddr, iport, uniqueID); - /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/ - } -} - -/* Test function - * 1 - Check if pinhole is working from the IGD side - * 2 - Update pinhole */ -static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, - const char * uniqueID, const char * lease_time) -{ - int isWorking = 0; - int r; - - if(!uniqueID || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) - { - r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); - printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); - if(r!=UPNPCOMMAND_SUCCESS) - printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); - } -} - -/* Test function - * Get pinhole timeout - */ -static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto) -{ - int timeout = 0; - int r; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - - r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); - else - printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout); -} - -static void -GetPinholePackets(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, pinholePackets = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets); -} - -static void -CheckPinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, isWorking = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); -} - -static void -RemovePinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID); - printf("UPNP_DeletePinhole() returned : %d\n", r); -} - - -/* sample upnp client program */ -int main(int argc, char ** argv) -{ - char command = 0; - char ** commandargv = 0; - int commandargc = 0; - struct UPNPDev * devlist = 0; - char lanaddr[64] = "unset"; /* my ip address on the LAN */ - int i; - const char * rootdescurl = 0; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int localport = UPNP_LOCAL_PORT_ANY; - int retcode = 0; - int error = 0; - int ipv6 = 0; - unsigned char ttl = 2; /* defaulting to 2 */ - const char * description = 0; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2020 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n" - "for more information.\n"); - /* command line processing */ - for(i=1; i<argc; i++) - { - if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h")) - { - command = 0; - break; - } - if(argv[i][0] == '-') - { - if(argv[i][1] == 'u') - rootdescurl = argv[++i]; - else if(argv[i][1] == 'm') - { - multicastif = argv[++i]; - minissdpdpath = ""; /* Disable usage of minissdpd */ - } - else if(argv[i][1] == 'z') - { - char junk; - if(sscanf(argv[++i], "%d%c", &localport, &junk)!=1 || - localport<0 || localport>65535 || - (localport >1 && localport < 1024)) - { - fprintf(stderr, "Invalid localport '%s'\n", argv[i]); - localport = UPNP_LOCAL_PORT_ANY; - break; - } - } - else if(argv[i][1] == 'p') - minissdpdpath = argv[++i]; - else if(argv[i][1] == '6') - ipv6 = 1; - else if(argv[i][1] == 'e') - description = argv[++i]; - else if(argv[i][1] == 't') - ttl = (unsigned char)atoi(argv[++i]); - else - { - command = argv[i][1]; - i++; - commandargv = argv + i; - commandargc = argc - i; - break; - } - } - else - { - fprintf(stderr, "option '%s' invalid\n", argv[i]); - } - } - - if(!command - || (command == 'a' && commandargc<4) - || (command == 'd' && argc<2) - || (command == 'r' && argc<2) - || (command == 'A' && commandargc<6) - || (command == 'U' && commandargc<2) - || (command == 'D' && commandargc<1)) - { - fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration] [remote host]\n\t\tAdd port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -d external_port protocol [remote host]\n\t\tDelete port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); - fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); - fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration] [remote host]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); - fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]); - fprintf(stderr, "\nprotocol is UDP or TCP\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -e description : set description for port mapping.\n"); - fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n"); - fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); - fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n"); - fprintf(stderr, " -z localport : SSDP packets local (source) port (1024-65535).\n"); - fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); - fprintf(stderr, " -t ttl : set multicast TTL. Default value is 2.\n"); - return 1; - } - - if( rootdescurl - || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, - localport, ipv6, ttl, &error))) - { - struct UPNPDev * device; - struct UPNPUrls urls; - struct IGDdatas data; - if(devlist) - { - printf("List of UPNP devices found on the network :\n"); - for(device = devlist; device; device = device->pNext) - { - printf(" desc: %s\n st: %s\n\n", - device->descURL, device->st); - } - } - else if(!rootdescurl) - { - printf("upnpDiscover() error code=%d\n", error); - } - i = 1; - if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) - || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) - { - switch(i) { - case 1: - printf("Found valid IGD : %s\n", urls.controlURL); - break; - case 2: - printf("Found a (not connected?) IGD : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - case 3: - printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - default: - printf("Found device (igd ?) : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - } - printf("Local LAN ip address : %s\n", lanaddr); - #if 0 - printf("getting \"%s\"\n", urls.ipcondescURL); - descXML = miniwget(urls.ipcondescURL, &descXMLsize); - if(descXML) - { - /*fwrite(descXML, 1, descXMLsize, stdout);*/ - free(descXML); descXML = NULL; - } - #endif - - switch(command) - { - case 'l': - DisplayInfos(&urls, &data); - ListRedirections(&urls, &data); - break; - case 'L': - NewListRedirections(&urls, &data); - break; - case 'a': - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)&is_int(commandargv[4])?commandargv[4]:"0", - (commandargc > 4)&!is_int(commandargv[4])?commandargv[4]:(commandargc > 5)?commandargv[5]:NULL, - description, 0) < 0) - retcode = 2; - break; - case 'd': - if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL) < 0) - retcode = 2; - break; - case 'n': /* aNy */ - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)&is_int(commandargv[4])?commandargv[4]:"0", - (commandargc > 4)&!is_int(commandargv[4])?commandargv[4]:(commandargc > 5)?commandargv[5]:NULL, - description, 1) < 0) - retcode = 2; - break; - case 'N': - if (commandargc < 3) - fprintf(stderr, "too few arguments\n"); - - if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL) < 0) - retcode = 2; - break; - case 's': - GetConnectionStatus(&urls, &data); - break; - case 'r': - i = 0; - while(i<commandargc) - { - if(!is_int(commandargv[i])) { - /* 1st parameter not an integer : error */ - fprintf(stderr, "command -r : %s is not an port number\n", commandargv[i]); - retcode = 1; - break; - } else if(is_int(commandargv[i+1])){ - /* 2nd parameter is an integer : <port> <external_port> <protocol> */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i+1], commandargv[i+2], "0", NULL, - description, 0) < 0) - retcode = 2; - i+=3; /* 3 parameters parsed */ - } else { - /* 2nd parameter not an integer : <port> <protocol> */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i], commandargv[i+1], "0", NULL, - description, 0) < 0) - retcode = 2; - i+=2; /* 2 parameters parsed */ - } - } - break; - case 'A': - SetPinholeAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4], commandargv[5]); - break; - case 'U': - GetPinholeAndUpdate(&urls, &data, - commandargv[0], commandargv[1]); - break; - case 'C': - for(i=0; i<commandargc; i++) - { - CheckPinhole(&urls, &data, commandargv[i]); - } - break; - case 'K': - for(i=0; i<commandargc; i++) - { - GetPinholePackets(&urls, &data, commandargv[i]); - } - break; - case 'D': - for(i=0; i<commandargc; i++) - { - RemovePinhole(&urls, &data, commandargv[i]); - } - break; - case 'S': - GetFirewallStatus(&urls, &data); - break; - case 'G': - GetPinholeOutboundTimeout(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4]); - break; - case 'P': - printf("Presentation URL found:\n"); - printf(" %s\n", data.presentationurl); - break; - default: - fprintf(stderr, "Unknown switch -%c\n", command); - retcode = 1; - } - - FreeUPNPUrls(&urls); - } - else - { - fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n"); - retcode = 1; - } - freeUPNPDevlist(devlist); devlist = 0; - } - else - { - fprintf(stderr, "No IGD UPnP Device found on the network !\n"); - retcode = 1; - } -#ifdef _WIN32 - nResult = WSACleanup(); - if(nResult != NO_ERROR) { - fprintf(stderr, "WSACleanup() failed.\n"); - } -#endif /* _WIN32 */ - return retcode; -} - diff --git a/thirdparty/miniupnpc/miniupnpc/upnpdev.h b/thirdparty/miniupnpc/miniupnpc/upnpdev.h index f4ae174426..9b2cb431ba 100644 --- a/thirdparty/miniupnpc/miniupnpc/upnpdev.h +++ b/thirdparty/miniupnpc/miniupnpc/upnpdev.h @@ -1,8 +1,8 @@ -/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ +/* $Id: upnpdev.h,v 1.3 2020/05/29 15:57:42 nanard Exp $ */ /* Project : miniupnp - * Web : http://miniupnp.free.fr/ + * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ * Author : Thomas BERNARD - * copyright (c) 2005-2018 Thomas Bernard + * copyright (c) 2005-2020 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENSE file. */ #ifndef UPNPDEV_H_INCLUDED @@ -20,7 +20,15 @@ struct UPNPDev { char * st; char * usn; unsigned int scope_id; - char buffer[3]; +#if defined(__STDC_VERSION) && __STDC_VERSION__ >= 199901L + /* C99 flexible array member */ + char buffer[]; +#elif defined(__GNUC__) + char buffer[0]; +#else + /* Fallback to a hack */ + char buffer[1]; +#endif }; /* freeUPNPDevlist() diff --git a/thirdparty/miniupnpc/miniupnpc/upnperrors.c b/thirdparty/miniupnpc/miniupnpc/upnperrors.c deleted file mode 100644 index 4496e8622c..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/upnperrors.c +++ /dev/null @@ -1,112 +0,0 @@ -/* $Id: upnperrors.c,v 1.10 2019/08/24 08:49:53 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2007-2019 Thomas Bernard - * All Right reserved. - * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include <string.h> -#include "upnperrors.h" -#include "upnpcommands.h" -#include "miniupnpc.h" - -const char * strupnperror(int err) -{ - const char * s = NULL; - switch(err) { - case UPNPCOMMAND_SUCCESS: - s = "Success"; - break; - case UPNPCOMMAND_UNKNOWN_ERROR: - s = "Miniupnpc Unknown Error"; - break; - case UPNPCOMMAND_INVALID_ARGS: - s = "Miniupnpc Invalid Arguments"; - break; - case UPNPCOMMAND_INVALID_RESPONSE: - s = "Miniupnpc Invalid response"; - break; - case UPNPCOMMAND_HTTP_ERROR: - s = "Miniupnpc HTTP error"; - break; - case UPNPDISCOVER_SOCKET_ERROR: - s = "Miniupnpc Socket error"; - break; - case UPNPDISCOVER_MEMORY_ERROR: - case UPNPCOMMAND_MEM_ALLOC_ERROR: - s = "Miniupnpc Memory allocation error"; - break; - case 401: - s = "Invalid Action"; - break; - case 402: - s = "Invalid Args"; - break; - case 501: - s = "Action Failed"; - break; - case 606: - s = "Action not authorized"; - break; - case 701: - s = "PinholeSpaceExhausted"; - break; - case 702: - s = "FirewallDisabled"; - break; - case 703: - s = "InboundPinholeNotAllowed"; - break; - case 704: - s = "NoSuchEntry"; - break; - case 705: - s = "ProtocolNotSupported"; - break; - case 706: - s = "InternalPortWildcardingNotAllowed"; - break; - case 707: - s = "ProtocolWildcardingNotAllowed"; - break; - case 708: - s = "InvalidLayer2Address"; - break; - case 709: - s = "NoPacketSent"; - break; - case 713: - s = "SpecifiedArrayIndexInvalid"; - break; - case 714: - s = "NoSuchEntryInArray"; - break; - case 715: - s = "WildCardNotPermittedInSrcIP"; - break; - case 716: - s = "WildCardNotPermittedInExtPort"; - break; - case 718: - s = "ConflictInMappingEntry"; - break; - case 724: - s = "SamePortValuesRequired"; - break; - case 725: - s = "OnlyPermanentLeasesSupported"; - break; - case 726: - s = "RemoteHostOnlySupportsWildcard"; - break; - case 727: - s = "ExternalPortOnlySupportsWildcard"; - break; - default: - s = "UnknownError"; - break; - } - return s; -} diff --git a/thirdparty/miniupnpc/miniupnpc/upnperrors.h b/thirdparty/miniupnpc/miniupnpc/upnperrors.h deleted file mode 100644 index 8499d9a1c9..0000000000 --- a/thirdparty/miniupnpc/miniupnpc/upnperrors.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */ -/* (c) 2007-2015 Thomas Bernard - * All rights reserved. - * MiniUPnP Project. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#ifndef UPNPERRORS_H_INCLUDED -#define UPNPERRORS_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* strupnperror() - * Return a string description of the UPnP error code - * or NULL for undefinded errors */ -MINIUPNP_LIBSPEC const char * strupnperror(int err); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/miniupnpc/miniupnpc/win32_snprintf.h b/thirdparty/miniupnpc/miniupnpc/win32_snprintf.h new file mode 100644 index 0000000000..1fc284ecff --- /dev/null +++ b/thirdparty/miniupnpc/miniupnpc/win32_snprintf.h @@ -0,0 +1,71 @@ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * MiniUPnP project + * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ + * (c) 2020 Pali Rohár + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ + +#ifndef WIN32_SNPRINTF_H +#define WIN32_SNPRINTF_H + +#ifdef _WIN32 + +#include <stdio.h> + +/* snprintf is supported by: + * - Visual Studio 2015 or new + * - mingw32 with iso c ext + * - mingw-w64 with ansi stdio + * - mingw-w64 6.0.0 or new with ucrt + * - mingw-w64 8.0.0 or new with iso c ext + */ +#if ( \ + (defined(_MSC_VER) && _MSC_VER < 1900) /* Visual Studio older than 2015 */ || \ + (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__NO_ISOCEXT)) /* mingw32 without iso c ext */ || \ + (defined(__MINGW64_VERSION_MAJOR) && /* mingw-w64 not ... */ !( \ + (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO != 0)) /* ... with ansi stdio */ || \ + (__MINGW64_VERSION_MAJOR >= 6 && defined(_UCRT)) /* ... at least 6.0.0 with ucrt */ || \ + (__MINGW64_VERSION_MAJOR >= 8 && !defined(__NO_ISOCEXT)) /* ... at least 8.0.0 with iso c ext */ || \ + 0) || \ +0) + +/* _scprintf is supported by: + * - Visual Studio 2002 or new + * - msvcr70.dll or new + * - msvcrt.dll on Windows XP or new + */ +#if ( \ + (defined(_MSC_VER) && _MSC_VER < 1300) /* Visual Studio older than 2002 */ || \ + (defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x700) /* msvcrt older than 7.0 */ || \ +0) +#define CHECK_SCPRINTF 0 +#define IF_SCPRINTF(expr) 0 +#define ELSE_SCPRINTF(expr) expr +#else +#define CHECK_SCPRINTF 1 +#define IF_SCPRINTF(expr) expr +#define ELSE_SCPRINTF(expr) 0 +#endif + +/* Emulation of snprintf for win32 */ +#define snprintf(buf, size, fmt, ...) ( \ + (((size) != 0 && (buf) != NULL) ? ( /* _snprintf does not work with NULL buffer */ \ + _snprintf((buf), (size), (fmt), __VA_ARGS__), /* _snprintf returns -1 on overflow, so ignore its value */ \ + (((char *)buf)[(size_t)(size)-1] = 0), /* _snprintf does not fill nul byte on overflow */ \ + 0) : 0), \ + (CHECK_SCPRINTF ? IF_SCPRINTF( \ + _scprintf((fmt), __VA_ARGS__) /* calculate return value for snprintf via _scprintf */ \ + ) : ELSE_SCPRINTF( \ + ((size) != 0 && (buf) != NULL) ? \ + strlen((buf)) /* return just length of buffer */ \ + : \ + 1 /* no buffer, impossible to calculate, return just non-zero number */ \ + ) \ + ) \ +) + +#endif + +#endif /* _WIN32 */ + +#endif /* WIN32_SNPRINTF_H */ |