From 395451e15f7421ee7d3eb6469bb78cb80f1447df Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 23 Apr 2025 16:29:12 +0200 Subject: [PATCH] Upgrade Harfbuzz to 11.1.0 [ChangeLog][Third-Party Code] Upgraded Harfbuzz to version 11.1.0. Pick-to: 5.15 6.5 6.8 6.9 Task-number: QTBUG-136054 Change-Id: I388586c887a3ae30ecc7b07bb0b6a5c12d3b6caf Reviewed-by: Eirik Aavitsland --- src/3rdparty/harfbuzz-ng/CMakeLists.txt | 3 + src/3rdparty/harfbuzz-ng/README.md | 65 +- src/3rdparty/harfbuzz-ng/qt_attribution.json | 4 +- .../src/OT/Layout/Common/CoverageFormat1.hh | 2 +- .../src/OT/Layout/Common/CoverageFormat2.hh | 2 +- .../harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh | 24 +- .../src/OT/Layout/GPOS/PairPosFormat1.hh | 2 +- .../harfbuzz-ng/src/OT/Var/VARC/VARC.cc | 2 +- .../harfbuzz-ng/src/harfbuzz-subset.cc | 2 + .../harfbuzz-ng/src/hb-aat-layout-common.hh | 5 +- .../src/hb-aat-layout-trak-table.hh | 43 +- src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc | 13 +- src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh | 5 + src/3rdparty/harfbuzz-ng/src/hb-atomic.hh | 11 +- .../src/hb-buffer-deserialize-json.hh | 546 +++++++------ .../src/hb-buffer-deserialize-text-glyphs.hh | 480 ++++++----- src/3rdparty/harfbuzz-ng/src/hb-buffer.cc | 12 + src/3rdparty/harfbuzz-ng/src/hb-buffer.hh | 2 + src/3rdparty/harfbuzz-ng/src/hb-cache.hh | 29 +- src/3rdparty/harfbuzz-ng/src/hb-common.h | 432 +--------- src/3rdparty/harfbuzz-ng/src/hb-config.hh | 2 +- .../harfbuzz-ng/src/hb-coretext-font.cc | 7 +- src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 4 +- .../harfbuzz-ng/src/hb-directwrite-shape.cc | 2 +- .../harfbuzz-ng/src/hb-directwrite.hh | 28 +- src/3rdparty/harfbuzz-ng/src/hb-draw.h | 2 +- src/3rdparty/harfbuzz-ng/src/hb-face.cc | 2 +- src/3rdparty/harfbuzz-ng/src/hb-face.h | 2 +- src/3rdparty/harfbuzz-ng/src/hb-font.cc | 2 + src/3rdparty/harfbuzz-ng/src/hb-font.hh | 114 ++- src/3rdparty/harfbuzz-ng/src/hb-ft.cc | 96 +-- src/3rdparty/harfbuzz-ng/src/hb-mutex.hh | 6 + .../harfbuzz-ng/src/hb-ot-cff1-table.hh | 2 +- .../harfbuzz-ng/src/hb-ot-cff2-table.hh | 2 +- .../harfbuzz-ng/src/hb-ot-cmap-table.hh | 83 +- src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc | 335 +++----- .../harfbuzz-ng/src/hb-ot-hmtx-table.hh | 8 +- .../harfbuzz-ng/src/hb-ot-layout-common.hh | 51 +- .../harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh | 18 +- src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc | 9 +- src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh | 1 + .../harfbuzz-ng/src/hb-ot-math-table.hh | 18 + src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc | 14 + .../harfbuzz-ng/src/hb-ot-shape-fallback.cc | 9 +- src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc | 31 +- src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh | 2 + .../harfbuzz-ng/src/hb-ot-var-gvar-table.hh | 6 +- src/3rdparty/harfbuzz-ng/src/hb-script-list.h | 484 +++++++++++ src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh | 9 +- .../harfbuzz-ng/src/hb-subset-input.cc | 2 +- .../harfbuzz-ng/src/hb-subset-plan-layout.cc | 382 +++++++++ .../harfbuzz-ng/src/hb-subset-plan-var.cc | 388 +++++++++ .../harfbuzz-ng/src/hb-subset-plan.cc | 772 ++---------------- .../harfbuzz-ng/src/hb-subset-plan.hh | 70 ++ src/3rdparty/harfbuzz-ng/src/hb-subset.cc | 104 +++ src/3rdparty/harfbuzz-ng/src/hb-subset.h | 24 +- src/3rdparty/harfbuzz-ng/src/hb-version.h | 4 +- src/3rdparty/harfbuzz-ng/src/hb.hh | 3 +- 58 files changed, 2695 insertions(+), 2087 deletions(-) create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-script-list.h create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-subset-plan-layout.cc create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-subset-plan-var.cc diff --git a/src/3rdparty/harfbuzz-ng/CMakeLists.txt b/src/3rdparty/harfbuzz-ng/CMakeLists.txt index 3ed30e8ecc8..c23642e17dc 100644 --- a/src/3rdparty/harfbuzz-ng/CMakeLists.txt +++ b/src/3rdparty/harfbuzz-ng/CMakeLists.txt @@ -47,6 +47,7 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz src/hb-paint-extents.cc src/hb-paint-extents.hh src/hb-priority-queue.hh src/hb-repacker.hh + src/hb-script-list.h src/hb-set.cc src/hb-set.h src/hb-set.hh src/hb-set-digest.hh src/hb-shape.cc src/hb-shape.h @@ -64,8 +65,10 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz src/hb-subset-instancer-iup.cc src/hb-subset-instancer-iup.hh src/hb-subset-instancer-solver.cc src/hb-subset-plan.cc + src/hb-subset-plan-layout.cc src/hb-subset-plan-member-list.hh src/hb-subset-serialize.cc src/hb-subset-serialize.h + src/hb-subset-plan-var.cc src/hb-unicode.cc src/hb-unicode.h src/hb-unicode.hh src/hb-utf.hh src/hb-version.h diff --git a/src/3rdparty/harfbuzz-ng/README.md b/src/3rdparty/harfbuzz-ng/README.md index f94a83b54b6..6f94a58f312 100644 --- a/src/3rdparty/harfbuzz-ng/README.md +++ b/src/3rdparty/harfbuzz-ng/README.md @@ -2,7 +2,7 @@ [![macoOS CI Status](https://github.com/harfbuzz/harfbuzz/actions/workflows/macos-ci.yml/badge.svg)](https://github.com/harfbuzz/harfbuzz/actions/workflows/macos-ci.yml) [![Windows CI Status](https://github.com/harfbuzz/harfbuzz/actions/workflows/msvc-ci.yml/badge.svg)](https://github.com/harfbuzz/harfbuzz/actions/workflows/msvc-ci.yml) [![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main) -[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html) +[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#harfbuzz) [![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz) [![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/harfbuzz/harfbuzz/badge)](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz) @@ -35,13 +35,20 @@ will also find Win32/Win64 binary bundles that include `libharfbuzz` DLL, `hb-view.exe`, `hb-shape.exe`, and all dependencies. The canonical source tree is available on [github][4]. +Both development and user support discussion around HarfBuzz happens on +[github][4] as well. The API that comes with `hb.h` will not change incompatibly. Other, peripheral, headers are more likely to go through minor modifications, but again, we do our best to never change API in an incompatible way. We will never break the ABI. -If you are not sure whether Pango or HarfBuzz is right for you, read [Pango vs -HarfBuzz][5]. +The API and ABI are stable even across major version number jumps. In fact, +current HarfBuzz is API/ABI compatible all the way back to the 0.9.x series. +If one day we need to break the API/ABI, that would be called a new a library. + +As such, we bump the major version number only when we add major new features, +the minor version when there is new API, and the micro version when there +are bug fixes. ## Development @@ -51,26 +58,38 @@ For custom configurations, see [CONFIG.md](CONFIG.md). For testing and profiling, see [TESTING.md](TESTING.md). +For using with Python, see [README.python.md](README.python.md). There is also [uharfbuzz](https://github.com/harfbuzz/uharfbuzz). + For cross-compiling to Windows from Linux or macOS, see [README.mingw.md](README.mingw.md). +To report bugs or submit patches please use [github][4] issues and pull-requests. + +### Developer documents + To get a better idea of where HarfBuzz stands in the text rendering stack you may want to read [State of Text Rendering 2024][6]. Here are a few presentation slides about HarfBuzz at the Internationalization and Unicode Conference over the years: -* November 2014, [Unicode, OpenType, and HarfBuzz: Closing the Circle][7], -* October 2012, [HarfBuzz, The Free and Open Text Shaping Engine][8], -* October 2009, [HarfBuzz: the Free and Open Shaping Engine][9]. +- 2014 – [Unicode, OpenType, and HarfBuzz: Closing the Circle][7] +- 2012 – [HarfBuzz, The Free and Open Text Shaping Engine][8] +- 2016 – [Ten Years of HarfBuzz][20] +- 2009 – [HarfBuzz: the Free and Open Shaping Engine][9] -Both development and user support discussion around HarfBuzz happens on the -[github][4]. +More presentations and papers are available on [behdad][11]'s website. +In particular, the following _studies_ are relevant to HarfBuzz development: -To report bugs or submit patches please use [github][4] issues and -pull-requests. +- 2025 – [Subsetting][21] +- 2025 – [Caching][12] +- 2025 – [`hb-decycler`][13] +- 2022 – [`hb-iter`][14] +- 2022 – [A C library written in C++][15] +- 2022 – [The case of the slow `hb-ft` `>h_advance` function][18] +- 2022 – [PackTab: A static integer table packer][16] +- 2020 – [HarfBuzz OT+AAT "Unishaper"][19] +- 2014 – [Building the Indic Shaper][17] +- 2012 – [Memory Consumption][10] -For a comparison of old vs new HarfBuzz memory consumption see [this][10]. - - ## Name @@ -87,6 +106,8 @@ transliterated using the Latin script. It also means "talkative" or > TrueType that adds support for complex script rendering, and HarfBuzz is an > implementation of OpenType complex text shaping. +## Distribution +
Packaging status of HarfBuzz @@ -98,9 +119,19 @@ transliterated using the Latin script. It also means "talkative" or [2]: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html [3]: https://github.com/harfbuzz/harfbuzz/releases [4]: https://github.com/harfbuzz/harfbuzz -[5]: http://mces.blogspot.com/2009/11/pango-vs-harfbuzz.html [6]: http://behdad.org/text2024 -[7]: https://goo.gl/FSIQuC -[8]: https://goo.gl/2wSRu +[7]: https://docs.google.com/presentation/d/1x97pfbB1gbD53Yhz6-_yBUozQMVJ_5yMqqR_D-R7b7I/preview +[8]: https://docs.google.com/presentation/d/1ySTZaXP5XKFg0OpmHZM00v5b17GSr3ojnzJekl4U8qI/preview [9]: http://behdad.org/download/Presentations/slippy/harfbuzz_slides.pdf -[10]: https://goo.gl/woyty +[10]: https://docs.google.com/document/d/12jfNpQJzeVIAxoUSpk7KziyINAa1msbGliyXqguS86M/preview +[11]: https://behdad.org/ +[12]: https://docs.google.com/document/d/1_VgObf6Je0J8byMLsi7HCQHnKo2emGnx_ib_sHo-bt4/preview +[13]: https://docs.google.com/document/d/1Y-u08l9YhObRVObETZt1k8f_5lQdOix9TRH3zEXaoAw/preview +[14]: https://docs.google.com/document/d/1o-xvxCbgMe9JYFHLVnPjk01ZY_8Cj0vB9-KTI1d0nyk/preview +[15]: https://docs.google.com/document/d/18hI56KJpvXtwWbc9QSaz9zzhJwIMnrJ-zkAaKS-W-8k/preview +[16]: https://docs.google.com/document/d/1Xq3owVt61HVkJqbLFHl73il6pcTy6PdPJJ7bSouQiQw/preview +[17]: https://docs.google.com/document/d/1wMPwVNBvsIriamcyBO5aNs7Cdr8lmbwLJ8GmZBAswF4/preview +[18]: https://docs.google.com/document/d/1wskYbA-czBt57oH9gEuGf3sWbTx7bfOiEIcDs36-heo/preview +[19]: https://prezi.com/view/THNPJGFVDUCWoM20syev/ +[20]: https://behdad.org/doc/harfbuzz10years-slides.pdf +[21]: https://docs.google.com/document/d/1_vZrt97OorJ0jA1YzJ29LRcGr3YGrNJANdOABjVZGEs/preview diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json index f5ce2f40047..93fc920ed2f 100644 --- a/src/3rdparty/harfbuzz-ng/qt_attribution.json +++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json @@ -7,8 +7,8 @@ "Description": "HarfBuzz is an OpenType text shaping engine.", "Homepage": "http://harfbuzz.org", - "Version": "11.0.0", - "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/11.0.0", + "Version": "11.1.0", + "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/11.1.0", "PURL": "pkg:github/harfbuzz/harfbuzz@$", "CPE": "cpe:2.3:a:harfbuzz_project:harfbuzz:$:*:*:*:*:*:*:*", "License": "MIT License", diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh index cdba7a50523..ec47e7e80a6 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat1.hh @@ -77,7 +77,7 @@ struct CoverageFormat1_3 bool intersects (const hb_set_t *glyphs) const { - if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2) + if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len)) { for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh index dd577fd9098..bd6d1577a07 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh @@ -120,7 +120,7 @@ struct CoverageFormat2_4 bool intersects (const hb_set_t *glyphs) const { - if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len)) { for (auto g : *glyphs) if (get_coverage (g) != NOT_COVERED) diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh index 16b232a2ae7..79de21e5919 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh @@ -205,20 +205,19 @@ struct CaretValueFormat3 unsigned varidx = (this+deviceTable).get_variation_index (); hb_pair_t *new_varidx_delta; - if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) - return_trace (false); + if (c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) { + uint32_t new_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); + if (delta != 0) + { + if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); + } - uint32_t new_varidx = hb_first (*new_varidx_delta); - int delta = hb_second (*new_varidx_delta); - if (delta != 0) - { - if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); + if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } - if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) - return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); - if (!c->serializer->embed (deviceTable)) return_trace (false); @@ -1015,7 +1014,8 @@ struct GDEF hb_blob_ptr_t table; #ifndef HB_NO_GDEF_CACHE hb_vector_t mark_glyph_set_digests; - mutable hb_cache_t<21, 3, 8> glyph_props_cache; + mutable hb_cache_t<21, 3> glyph_props_cache; + static_assert (sizeof (glyph_props_cache) == 512, ""); #endif }; diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh index de67548c43a..5e3ac43f414 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -54,7 +54,7 @@ struct PairPosFormat1_3 { auto &cov = this+coverage; - if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4) + if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len)) { for (hb_codepoint_t g : glyphs->iter()) { diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc index 5b43f187f10..6dade65f371 100644 --- a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc +++ b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc @@ -392,7 +392,7 @@ VARC::get_path_at (const hb_varc_context_t &c, hb_ubytes_t record = (this+glyphRecords)[idx]; - float static_cache[sizeof (void *) * 16]; + VarRegionList::cache_t static_cache[sizeof (void *) * 16]; VarRegionList::cache_t *cache = parent_cache ? parent_cache : (this+varStore).create_cache (hb_array (static_cache)); diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc index a0accfb33f6..91aa91f8a9d 100644 --- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc @@ -57,6 +57,8 @@ #include "hb-subset-input.cc" #include "hb-subset-instancer-iup.cc" #include "hb-subset-instancer-solver.cc" +#include "hb-subset-plan-layout.cc" +#include "hb-subset-plan-var.cc" #include "hb-subset-plan.cc" #include "hb-subset-serialize.cc" #include "hb-subset.cc" diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh index 640778e454f..90df68d9f40 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh @@ -194,7 +194,10 @@ struct hb_aat_apply_context_t : HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph) { if (glyph == DELETED_GLYPH) - return delete_glyph (); + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED; + _hb_glyph_info_set_aat_deleted (&buffer->cur()); + } if (likely (using_buffer_glyph_set)) buffer_glyph_set->add (glyph); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh index 24c212c2c16..14a7d579447 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-trak-table.hh @@ -31,6 +31,7 @@ #include "hb-aat-layout-common.hh" #include "hb-ot-layout.hh" #include "hb-open-type.hh" +#include "hb-ot-stat-table.hh" /* * trak -- Tracking @@ -115,7 +116,7 @@ struct TrackTableEntry protected: F16DOT16 track; /* Track value for this record. */ - NameID trackNameID; /* The 'name' table index for this track. + OT::NameID trackNameID; /* The 'name' table index for this track. * (a short word or phrase like "loose" * or "very tight") */ NNOffset16To> @@ -200,6 +201,46 @@ struct trak float ptem = font->ptem > 0.f ? font->ptem : HB_CORETEXT_DEFAULT_FONT_SIZE; return font->em_scalef_y ((this+vertData).get_tracking (this, ptem, track)); } + hb_position_t get_tracking (hb_font_t *font, hb_direction_t dir, float track = 0.f) const + { +#ifndef HB_NO_STYLE + if (!font->face->table.STAT->has_data ()) + return 0; + return HB_DIRECTION_IS_HORIZONTAL (dir) ? + get_h_tracking (font, track) : + get_v_tracking (font, track); +#else + return 0; +#endif + } + + bool apply (hb_aat_apply_context_t *c, float track = 0.f) const + { + TRACE_APPLY (this); + + float ptem = c->font->ptem; + if (unlikely (ptem <= 0.f)) + { + /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ + ptem = HB_CORETEXT_DEFAULT_FONT_SIZE; + } + + hb_buffer_t *buffer = c->buffer; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + { + hb_position_t advance_to_add = get_h_tracking (c->font, track); + foreach_grapheme (buffer, start, end) + buffer->pos[start].x_advance += advance_to_add; + } + else + { + hb_position_t advance_to_add = get_v_tracking (c->font, track); + foreach_grapheme (buffer, start, end) + buffer->pos[start].y_advance += advance_to_add; + } + + return_trace (true); + } bool sanitize (hb_sanitize_context_t *c) const { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc index 37455446682..a48c4e0bcfe 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc @@ -34,7 +34,7 @@ #include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" -#include "hb-aat-layout-trak-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-layout-trak-table.hh" #include "hb-aat-ltag-table.hh" #include "hb-ot-layout-gsub-table.hh" @@ -394,6 +394,17 @@ hb_aat_layout_has_tracking (hb_face_t *face) return face->table.trak->has_data (); } +void +hb_aat_layout_track (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const AAT::trak& trak = *font->face->table.trak; + + AAT::hb_aat_apply_context_t c (plan, font, buffer); + trak.apply (&c); +} + /** * hb_aat_layout_get_feature_types: * @face: #hb_face_t to work upon diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh index 0e4ae6e7b3c..8b80fd7974b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.hh @@ -68,5 +68,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +HB_INTERNAL void +hb_aat_layout_track (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh index e92ccbca109..03f84725d45 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic.hh @@ -80,15 +80,14 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #include -#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel) #define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire) #define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release) -#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) -#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) -#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) -#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) -#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) +#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel)) +#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_relaxed)) +#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast::type> *> (AI)->store ((V), std::memory_order_release)) +#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_relaxed)) +#define hb_atomic_int_impl_get(AI) (reinterpret_cast::type> const *> (AI)->load (std::memory_order_acquire)) #define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast *> (P)->store ((V), std::memory_order_relaxed)) #define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast const *> (P)->load (std::memory_order_relaxed)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh index b5bb3f4b29a..e57b6163c8e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-json.hh @@ -32,38 +32,39 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 33 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 0u, 0u, 9u, 34u, 97u, 121u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, - 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 123u, - 9u, 123u, 9u, 123u, 0 + 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, + 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 98u, 98u, 9u, 123u, 9u, 123u, 9u, 123u, + 0 }; static const char _deserialize_json_key_spans[] = { - 0, 26, 21, 2, 1, 50, 49, 10, + 0, 26, 25, 2, 1, 50, 49, 10, 117, 117, 85, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 2, 1, 50, 49, 10, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 1, 50, 49, 59, 117, - 59, 117, 117, 1, 50, 49, 117, 115, - 115, 115 + 59, 117, 117, 1, 50, 49, 10, 117, + 1, 50, 49, 117, 1, 115, 115, 115 }; static const short _deserialize_json_index_offsets[] = { - 0, 0, 27, 49, 52, 54, 105, 155, - 166, 284, 402, 488, 606, 608, 659, 709, - 720, 838, 956, 958, 960, 1011, 1061, 1179, - 1297, 1300, 1302, 1353, 1403, 1414, 1532, 1650, - 1652, 1703, 1753, 1764, 1882, 2000, 2002, 2004, - 2055, 2105, 2223, 2341, 2343, 2394, 2444, 2504, - 2622, 2682, 2800, 2918, 2920, 2971, 3021, 3139, - 3255, 3371 + 0, 0, 27, 53, 56, 58, 109, 159, + 170, 288, 406, 492, 610, 612, 663, 713, + 724, 842, 960, 962, 964, 1015, 1065, 1183, + 1301, 1304, 1306, 1357, 1407, 1418, 1536, 1654, + 1656, 1707, 1757, 1768, 1886, 2004, 2006, 2008, + 2059, 2109, 2227, 2345, 2347, 2398, 2448, 2508, + 2626, 2686, 2804, 2922, 2924, 2975, 3025, 3036, + 3154, 3156, 3207, 3257, 3375, 3377, 3493, 3609 }; static const char _deserialize_json_indicies[] = { @@ -71,28 +72,28 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 1, 3, 1, 4, 5, - 1, 6, 7, 1, 1, 1, 1, 1, + 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 8, 1, 9, 10, 1, 11, 1, 11, - 11, 11, 11, 11, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 11, 1, + 9, 1, 8, 10, 10, 1, 11, 12, + 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 12, 1, 12, 12, 12, 12, 12, 1, + 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 12, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 13, 1, - 1, 14, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 1, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 1, 18, - 18, 18, 18, 18, 1, 1, 1, 1, + 1, 1, 1, 1, 14, 1, 14, 14, + 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 18, 1, + 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 19, 1, 1, 1, 1, 1, + 1, 1, 15, 1, 1, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 1, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 20, 20, 20, 20, 20, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 20, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -102,12 +103,12 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 20, 1, 21, 21, 21, - 21, 21, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 23, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, + 23, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -117,24 +118,24 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 22, 1, 22, 22, 22, 22, 22, + 1, 1, 1, 1, 1, 24, 1, 24, + 24, 24, 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 22, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 23, 1, + 1, 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 23, - 1, 18, 18, 18, 18, 18, 1, 1, + 1, 1, 1, 25, 1, 20, 20, 20, + 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 18, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 19, 1, 1, 1, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 1, 1, 1, 1, 1, 1, + 21, 1, 1, 1, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -142,26 +143,27 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 20, 1, 24, - 1, 24, 24, 24, 24, 24, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 22, 1, 26, 1, 26, 26, 26, + 26, 26, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 24, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 27, 1, + 27, 27, 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 25, 1, 25, 25, 25, 25, - 25, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 25, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 26, 1, 1, 27, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 1, 29, 30, + 1, 1, 1, 1, 28, 1, 1, 29, 30, 30, 30, 30, 30, 30, 30, 30, - 1, 31, 31, 31, 31, 31, 1, 1, + 30, 1, 31, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 1, 33, 33, 33, + 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 31, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 32, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -171,13 +173,13 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 33, 1, 31, - 31, 31, 31, 31, 1, 1, 1, 1, + 1, 35, 1, 33, 33, 33, 33, 33, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 32, 1, 1, 1, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, + 1, 1, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 34, 1, + 1, 1, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -185,26 +187,27 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 35, + 1, 36, 1, 37, 1, 37, 37, 37, + 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 33, 1, 34, 1, 35, - 1, 35, 35, 35, 35, 35, 1, 1, + 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 35, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 38, 1, + 38, 38, 38, 38, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 36, 1, 36, 36, 36, 36, - 36, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 39, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 1, 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 37, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 1, 39, 39, - 39, 39, 39, 1, 1, 1, 1, 1, + 1, 41, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -212,43 +215,43 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 43, 1, + 41, 41, 41, 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 39, 39, 39, 39, - 39, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 39, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, - 1, 1, 1, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 43, 1, 45, 46, + 1, 47, 1, 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 43, 44, 1, 45, 1, 45, - 45, 45, 45, 45, 1, 1, 1, 1, + 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 48, 1, 48, 48, + 48, 48, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 46, 1, 46, 46, 46, 46, 46, 1, + 1, 1, 49, 1, 1, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 1, + 52, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 46, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 47, 1, - 1, 48, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 1, 50, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 1, 52, - 52, 52, 52, 52, 1, 1, 1, 1, + 1, 1, 54, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -256,85 +259,57 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 54, 1, 52, 52, 52, - 52, 52, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 1, 1, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 54, 1, 55, 1, 55, 55, 55, - 55, 55, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 55, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 56, 1, - 56, 56, 56, 56, 56, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, + 1, 54, 54, 54, 54, 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 57, 1, 1, 58, - 59, 59, 59, 59, 59, 59, 59, 59, - 59, 1, 60, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 1, 62, 62, 62, - 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 62, 1, 1, 1, + 54, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 55, 1, 1, 1, + 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 56, 1, 57, + 1, 57, 57, 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 64, 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 1, 58, 58, 58, 58, + 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, - 1, 1, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 1, 1, 1, 1, + 1, 1, 1, 58, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 59, 1, 1, 60, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 1, 62, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 1, 64, 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 64, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 64, - 1, 65, 1, 66, 1, 66, 66, 66, - 66, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 67, 1, - 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 68, - 69, 69, 69, 69, 69, 69, 69, 69, - 69, 1, 70, 70, 70, 70, 70, 1, + 1, 1, 1, 1, 1, 66, 1, 64, + 64, 64, 64, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 70, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 71, 1, 1, + 1, 1, 65, 1, 1, 1, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -343,48 +318,42 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 66, 1, 67, 1, 68, + 1, 68, 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 72, 1, - 70, 70, 70, 70, 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 70, + 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 1, 1, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 69, 1, 69, 69, 69, 69, + 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 70, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 1, 72, 72, + 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 72, 1, 74, 1, - 74, 74, 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 75, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 77, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 1, 80, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 81, - 79, 82, 82, 82, 82, 82, 1, 1, + 1, 1, 74, 1, 72, 72, 72, 72, + 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 73, + 1, 1, 1, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 82, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -392,65 +361,32 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 74, 1, 76, 1, 76, 76, 76, 76, + 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 84, 1, 79, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 77, 1, 77, + 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 77, 1, + 78, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 79, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 1, 82, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 83, 81, 84, 84, 84, + 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 79, 1, 85, 85, 85, 85, 85, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 85, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 86, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 87, - 1, 85, 85, 85, 85, 85, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 85, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 86, 1, 1, 1, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 87, 1, 89, - 1, 89, 89, 89, 89, 89, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 89, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 90, 1, 90, 90, 90, 90, - 90, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 90, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 91, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 1, 85, 85, - 85, 85, 85, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 85, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 86, 1, 1, 1, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -459,24 +395,119 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 87, 1, 94, 94, 94, 94, - 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 94, 1, 1, 1, 1, + 1, 86, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 95, 1, + 1, 1, 1, 1, 1, 81, 1, 87, + 87, 87, 87, 87, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 87, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 88, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 96, 1, - 95, 95, 95, 95, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 95, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 89, 1, 87, 87, 87, + 87, 87, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 88, 1, 1, 1, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 89, 1, 91, 1, 91, 91, 91, + 91, 91, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 91, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 92, 1, + 92, 92, 92, 92, 92, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 92, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 93, 1, 1, 94, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 1, 23, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 1, 23, 23, 23, + 23, 23, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 23, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 24, 1, 97, 1, 97, 97, 97, + 97, 97, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 97, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 98, 1, + 98, 98, 98, 98, 98, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 98, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 99, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 1, 87, 87, 87, 87, 87, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 87, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 88, 1, 1, + 1, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 89, 1, + 8, 1, 102, 102, 102, 102, 102, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 102, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 103, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 104, 1, 103, 103, + 103, 103, 103, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -488,10 +519,10 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 96, 1, 23, 23, 23, 23, - 23, 1, 1, 1, 1, 1, 1, 1, + 104, 1, 25, 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 23, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -502,50 +533,51 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 96, 1, - 0 + 1, 1, 1, 1, 104, 1, 0 }; static const char _deserialize_json_trans_targs[] = { 1, 0, 2, 3, 18, 24, 37, 43, - 51, 4, 12, 5, 6, 7, 8, 11, - 8, 11, 9, 1, 10, 9, 10, 57, - 13, 14, 15, 16, 17, 16, 17, 9, - 1, 10, 19, 20, 21, 22, 23, 9, - 1, 10, 23, 25, 31, 26, 27, 28, - 29, 30, 29, 30, 9, 1, 10, 32, - 33, 34, 35, 36, 35, 36, 9, 1, - 10, 38, 39, 40, 41, 42, 9, 1, - 10, 42, 44, 45, 46, 49, 50, 46, - 47, 48, 9, 1, 10, 9, 1, 10, - 50, 52, 53, 49, 54, 54, 55, 56, + 51, 56, 60, 4, 12, 5, 6, 7, + 8, 11, 8, 11, 9, 1, 10, 9, + 10, 63, 13, 14, 15, 16, 17, 16, + 17, 9, 1, 10, 19, 20, 21, 22, + 23, 9, 1, 10, 23, 25, 31, 26, + 27, 28, 29, 30, 29, 30, 9, 1, + 10, 32, 33, 34, 35, 36, 35, 36, + 9, 1, 10, 38, 39, 40, 41, 42, + 9, 1, 10, 42, 44, 45, 46, 49, + 50, 46, 47, 48, 9, 1, 10, 9, + 1, 10, 50, 52, 53, 54, 9, 55, + 55, 57, 58, 49, 59, 59, 61, 62, 1 }; static const char _deserialize_json_trans_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 2, 2, 2, 0, 0, 3, - 0, 0, 1, 1, 1, 0, 0, 4, - 4, 4, 0, 0, 0, 1, 1, 5, - 5, 5, 0, 0, 0, 0, 0, 1, - 1, 1, 0, 0, 6, 6, 6, 0, - 0, 1, 1, 1, 0, 0, 7, 7, - 7, 0, 0, 0, 1, 1, 8, 8, - 8, 0, 0, 0, 1, 9, 9, 0, - 10, 0, 11, 11, 11, 12, 12, 12, - 10, 0, 0, 13, 13, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 0, 0, 2, 2, 2, 0, + 0, 3, 0, 0, 1, 1, 1, 0, + 0, 4, 4, 4, 0, 0, 0, 1, + 1, 5, 5, 5, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 6, 6, + 6, 0, 0, 1, 1, 1, 0, 0, + 7, 7, 7, 0, 0, 0, 1, 1, + 8, 8, 8, 0, 0, 0, 1, 9, + 9, 0, 10, 0, 11, 11, 11, 12, + 12, 12, 10, 0, 0, 1, 1, 1, + 0, 0, 0, 13, 13, 14, 0, 0, 15 }; -static const int deserialize_json_start = 55; -static const int deserialize_json_first_final = 55; +static const int deserialize_json_start = 61; +static const int deserialize_json_first_final = 61; static const int deserialize_json_error = 0; -static const int deserialize_json_en_main = 55; +static const int deserialize_json_en_main = 61; -#line 111 "hb-buffer-deserialize-json.rl" +#line 115 "hb-buffer-deserialize-json.rl" static hb_bool_t @@ -565,12 +597,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 569 "hb-buffer-deserialize-json.hh" +#line 594 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 574 "hb-buffer-deserialize-json.hh" +#line 597 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -680,7 +712,7 @@ _resume: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; -#line 684 "hb-buffer-deserialize-json.hh" +#line 689 "hb-buffer-deserialize-json.hh" } _again: @@ -692,7 +724,7 @@ _again: _out: {} } -#line 132 "hb-buffer-deserialize-json.rl" +#line 136 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh index fe70b4fc1d5..8fc54b36c46 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-glyphs.hh @@ -32,249 +32,344 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text-glyphs.hh" +#line 33 "hb-buffer-deserialize-text-glyphs.hh" static const unsigned char _deserialize_text_glyphs_trans_keys[] = { - 0u, 0u, 35u, 124u, 48u, 57u, 93u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 45u, 57u, - 48u, 57u, 35u, 124u, 35u, 124u, 35u, 124u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, + 0u, 0u, 35u, 124u, 48u, 57u, 60u, 124u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, + 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 62u, 62u, + 93u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, + 35u, 124u, 35u, 124u, 35u, 124u, 35u, 124u, 48u, 57u, 35u, 124u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 35u, 124u, 35u, 124u, 44u, 57u, 35u, 124u, 43u, 124u, - 48u, 124u, 35u, 124u, 35u, 124u, 35u, 124u, 0 + 35u, 124u, 48u, 62u, 44u, 57u, 44u, 57u, 44u, 57u, 48u, 124u, 35u, 124u, 35u, 124u, + 35u, 124u, 0 }; static const char _deserialize_text_glyphs_key_spans[] = { - 0, 90, 10, 32, 13, 10, 90, 13, - 10, 90, 90, 90, 10, 90, 13, 10, + 0, 90, 10, 65, 13, 10, 1, 13, + 10, 1, 13, 10, 1, 13, 10, 1, + 32, 13, 10, 90, 13, 10, 90, 90, + 90, 90, 90, 90, 10, 90, 13, 10, 1, 13, 10, 90, 90, 14, 90, 82, - 77, 90, 90, 90 + 90, 15, 14, 14, 14, 77, 90, 90, + 90 }; static const short _deserialize_text_glyphs_index_offsets[] = { - 0, 0, 91, 102, 135, 149, 160, 251, - 265, 276, 367, 458, 549, 560, 651, 665, - 676, 678, 692, 703, 794, 885, 900, 991, - 1074, 1152, 1243, 1334 + 0, 0, 91, 102, 168, 182, 193, 195, + 209, 220, 222, 236, 247, 249, 263, 274, + 276, 309, 323, 334, 425, 439, 450, 541, + 632, 723, 814, 905, 996, 1007, 1098, 1112, + 1123, 1125, 1139, 1150, 1241, 1332, 1347, 1438, + 1521, 1612, 1628, 1643, 1658, 1673, 1751, 1842, + 1933 }; static const char _deserialize_text_glyphs_indicies[] = { 1, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 0, 0, 5, 0, + 0, 0, 4, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 6, 7, 0, 0, 0, 0, + 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7, 0, 8, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 3, 10, + 0, 0, 8, 0, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 3, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 10, 3, - 11, 3, 3, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 3, 14, 15, + 3, 3, 3, 3, 3, 3, 3, 3, + 12, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 12, + 3, 13, 3, 3, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, - 3, 16, 3, 3, 3, 3, 3, 3, - 3, 3, 17, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 18, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 18, 3, 19, 3, 3, 20, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 3, 22, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 3, 24, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 25, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 25, 3, - 24, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 23, 23, 23, + 15, 3, 16, 3, 17, 3, 3, 18, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 3, 18, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 3, 20, 3, 21, + 3, 3, 22, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 3, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 3, + 24, 3, 25, 3, 3, 26, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 3, + 26, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 3, 28, 3, 29, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 29, 3, 30, 3, + 3, 31, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 3, 33, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 3, 35, + 3, 3, 3, 3, 3, 3, 3, 3, + 36, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 37, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 38, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 38, 3, 39, 3, 3, 40, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 3, + 42, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 3, 44, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 45, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 46, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 46, 3, 44, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 3, 3, 45, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 25, 3, 3, 3, 3, 3, + 46, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 25, 3, 16, 3, 3, 3, 3, - 3, 3, 3, 3, 17, 3, 3, 3, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 18, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 18, 3, 26, 27, - 27, 27, 27, 27, 27, 27, 27, 27, - 3, 28, 3, 3, 3, 3, 3, 3, - 3, 29, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 30, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 31, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 31, 3, 32, 3, 3, 33, + 3, 3, 3, 3, 3, 3, 3, 46, + 3, 35, 3, 3, 3, 3, 3, 3, + 3, 3, 36, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 3, 35, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 3, 37, 3, 38, - 3, 3, 39, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 3, 41, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 3, - 43, 3, 3, 3, 3, 3, 3, 3, - 44, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 37, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 45, 3, 3, 3, 3, 3, + 3, 3, 3, 38, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 45, 3, 43, 3, 3, 3, 3, - 3, 3, 3, 44, 3, 3, 3, 3, - 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 3, 3, 3, 3, 3, 3, + 3, 3, 38, 3, 1, 0, 0, 0, + 0, 0, 0, 0, 2, 3, 47, 0, + 0, 48, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 0, 0, 4, 5, 0, + 0, 6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 2, + 3, 0, 0, 0, 48, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 0, 0, + 4, 5, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 5, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 3, + 52, 3, 3, 3, 3, 3, 3, 3, + 53, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 54, 3, 3, 3, 55, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 45, 3, 3, + 3, 3, 56, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 45, 3, 37, 3, - 3, 3, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 3, 28, 3, 3, - 3, 3, 3, 3, 3, 29, 3, 3, - 3, 3, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 3, 3, 3, 3, - 3, 3, 30, 3, 3, 3, 3, 3, + 3, 56, 3, 57, 3, 3, 58, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 3, 60, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 3, 62, 3, 63, 3, + 3, 64, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 3, 66, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 3, 68, + 3, 3, 3, 3, 3, 3, 3, 69, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 31, + 70, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 71, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 71, 3, 68, 3, 3, 3, 3, 3, + 3, 3, 69, 3, 3, 3, 3, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 3, 3, 70, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 71, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 71, 3, 62, 3, 3, + 3, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 3, 52, 3, 3, 3, + 3, 3, 3, 3, 53, 3, 3, 3, + 3, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 3, 3, 54, 3, 3, + 3, 55, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 56, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 56, 3, 0, + 0, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 31, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 0, 3, 3, 0, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 0, 3, 1, 0, 0, 0, 0, 0, + 0, 0, 2, 16, 0, 0, 0, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 0, 0, 4, 5, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 0, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 3, + 3, 3, 3, 28, 3, 24, 3, 3, + 3, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 3, 20, 3, 3, 3, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 3, 16, 3, 3, 3, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 3, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 3, 3, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 0, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 3, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 10, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 10, - 3, 49, 48, 48, 48, 48, 48, 48, - 48, 50, 3, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 51, 48, 48, 52, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 53, 54, 55, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 55, 48, 57, 56, 56, 56, - 56, 56, 56, 56, 58, 3, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 59, 56, - 56, 60, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 61, 62, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 62, 56, 63, - 48, 48, 48, 48, 48, 48, 48, 64, - 3, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 65, 48, 48, 66, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 54, 67, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 67, 48, 0 + 3, 3, 3, 3, 3, 3, 12, 3, + 75, 74, 74, 74, 74, 74, 74, 74, + 76, 3, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 77, 78, 74, 74, 79, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 80, 81, 82, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 82, 74, 84, 83, 83, 83, 83, + 83, 83, 83, 85, 3, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 86, 87, 83, 83, + 88, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 89, 90, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 90, 83, 91, 74, + 74, 74, 74, 74, 74, 74, 92, 3, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 93, + 94, 74, 74, 95, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 81, + 96, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 96, + 74, 0 }; static const char _deserialize_text_glyphs_trans_targs[] = { - 1, 2, 4, 0, 12, 14, 23, 26, - 3, 24, 26, 5, 6, 11, 6, 11, - 2, 7, 26, 8, 9, 10, 9, 10, - 2, 26, 13, 22, 2, 4, 14, 26, - 15, 16, 21, 16, 21, 17, 18, 19, - 20, 19, 20, 2, 4, 26, 22, 24, - 1, 2, 4, 12, 14, 27, 23, 26, - 1, 2, 4, 12, 14, 23, 26, 2, - 4, 12, 14, 26 + 1, 2, 17, 0, 25, 28, 30, 39, + 47, 3, 45, 4, 47, 5, 6, 44, + 7, 8, 9, 43, 10, 11, 12, 42, + 13, 14, 15, 41, 16, 47, 18, 19, + 24, 19, 24, 2, 20, 4, 47, 21, + 22, 23, 22, 23, 2, 4, 47, 26, + 27, 40, 29, 38, 2, 17, 4, 30, + 47, 31, 32, 37, 32, 37, 33, 34, + 35, 36, 35, 36, 2, 17, 4, 47, + 38, 45, 1, 2, 17, 25, 28, 30, + 48, 39, 47, 1, 2, 17, 25, 28, + 30, 39, 47, 2, 17, 25, 28, 30, + 47 }; static const char _deserialize_text_glyphs_trans_actions[] = { - 0, 1, 1, 0, 1, 1, 0, 1, - 2, 2, 3, 2, 2, 2, 0, 0, - 4, 4, 4, 2, 2, 2, 0, 0, - 5, 5, 2, 2, 6, 6, 6, 6, - 2, 2, 2, 0, 0, 7, 2, 2, - 2, 0, 0, 8, 8, 8, 0, 0, - 9, 10, 10, 10, 10, 9, 9, 10, - 12, 13, 13, 13, 13, 12, 13, 14, - 14, 14, 14, 14 + 0, 1, 1, 0, 1, 1, 1, 0, + 1, 2, 2, 3, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 4, 4, 4, 4, 2, + 2, 2, 0, 0, 5, 5, 5, 0, + 0, 0, 2, 2, 6, 6, 6, 6, + 6, 2, 2, 2, 0, 0, 7, 2, + 2, 2, 0, 0, 8, 8, 8, 8, + 0, 0, 9, 10, 10, 10, 10, 10, + 9, 9, 10, 12, 13, 13, 13, 13, + 13, 12, 13, 14, 14, 14, 14, 14, + 14 }; static const char _deserialize_text_glyphs_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 11, 0 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 11, + 0 }; -static const int deserialize_text_glyphs_start = 25; -static const int deserialize_text_glyphs_first_final = 25; +static const int deserialize_text_glyphs_start = 46; +static const int deserialize_text_glyphs_first_final = 46; static const int deserialize_text_glyphs_error = 0; -static const int deserialize_text_glyphs_en_main = 25; +static const int deserialize_text_glyphs_en_main = 46; -#line 99 "hb-buffer-deserialize-text-glyphs.rl" +#line 101 "hb-buffer-deserialize-text-glyphs.rl" static hb_bool_t @@ -294,12 +389,12 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 298 "hb-buffer-deserialize-text-glyphs.hh" +#line 386 "hb-buffer-deserialize-text-glyphs.hh" { cs = deserialize_text_glyphs_start; } -#line 303 "hb-buffer-deserialize-text-glyphs.hh" +#line 389 "hb-buffer-deserialize-text-glyphs.hh" { int _slen; int _trans; @@ -325,13 +420,13 @@ _resume: switch ( _deserialize_text_glyphs_trans_actions[_trans] ) { case 2: -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; case 1: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, @@ -341,27 +436,27 @@ _resume: } break; case 6: -#line 63 "hb-buffer-deserialize-text-glyphs.rl" +#line 62 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; case 7: -#line 64 "hb-buffer-deserialize-text-glyphs.rl" +#line 63 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; case 8: -#line 65 "hb-buffer-deserialize-text-glyphs.rl" +#line 64 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; case 4: -#line 66 "hb-buffer-deserialize-text-glyphs.rl" +#line 65 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; case 5: -#line 67 "hb-buffer-deserialize-text-glyphs.rl" +#line 66 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; case 3: -#line 68 "hb-buffer-deserialize-text-glyphs.rl" +#line 67 "hb-buffer-deserialize-text-glyphs.rl" { if (!parse_uint (tok, p, &info.mask )) return false; } break; case 9: @@ -370,7 +465,7 @@ _resume: hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } @@ -381,11 +476,11 @@ _resume: hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } -#line 55 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, @@ -397,10 +492,9 @@ _resume: case 12: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } #line 38 "hb-buffer-deserialize-text-glyphs.rl" @@ -408,13 +502,13 @@ _resume: hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } break; case 14: -#line 55 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, @@ -427,7 +521,7 @@ _resume: hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } @@ -435,10 +529,9 @@ _resume: case 13: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } #line 38 "hb-buffer-deserialize-text-glyphs.rl" @@ -446,11 +539,11 @@ _resume: hb_memset (&info, 0, sizeof (info)); hb_memset (&pos , 0, sizeof (pos )); } -#line 51 "hb-buffer-deserialize-text-glyphs.rl" +#line 50 "hb-buffer-deserialize-text-glyphs.rl" { tok = p; } -#line 55 "hb-buffer-deserialize-text-glyphs.rl" +#line 54 "hb-buffer-deserialize-text-glyphs.rl" { /* TODO Unescape delimiters. */ if (!hb_font_glyph_from_string (font, @@ -459,7 +552,7 @@ _resume: return false; } break; -#line 463 "hb-buffer-deserialize-text-glyphs.hh" +#line 523 "hb-buffer-deserialize-text-glyphs.hh" } _again: @@ -474,21 +567,20 @@ _again: case 11: #line 43 "hb-buffer-deserialize-text-glyphs.rl" { - buffer->add_info (info); + buffer->add_info_and_pos (info, pos); if (unlikely (!buffer->successful)) return false; - buffer->pos[buffer->len - 1] = pos; *end_ptr = p; } break; -#line 485 "hb-buffer-deserialize-text-glyphs.hh" +#line 542 "hb-buffer-deserialize-text-glyphs.hh" } } _out: {} } -#line 120 "hb-buffer-deserialize-text-glyphs.rl" +#line 122 "hb-buffer-deserialize-text-glyphs.rl" *end_ptr = p; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index 7fb95fe7e19..d2be5216ae5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -370,6 +370,18 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) len++; } +void +hb_buffer_t::add_info_and_pos (const hb_glyph_info_t &glyph_info, + const hb_glyph_position_t &glyph_pos) +{ + if (unlikely (!ensure (len + 1))) return; + + info[len] = glyph_info; + assert (have_positions); + pos[len] = glyph_pos; + + len++; +} void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh index b353b06c7a1..8a520512036 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh @@ -229,6 +229,8 @@ struct hb_buffer_t HB_INTERNAL void add (hb_codepoint_t codepoint, unsigned int cluster); HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info); + HB_INTERNAL void add_info_and_pos (const hb_glyph_info_t &glyph_info, + const hb_glyph_position_t &glyph_pos); void reverse_range (unsigned start, unsigned end) { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cache.hh b/src/3rdparty/harfbuzz-ng/src/hb-cache.hh index 882a71a9daf..f9d1aa08b86 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cache.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cache.hh @@ -30,18 +30,31 @@ #include "hb.hh" -/* Implements a lockfree cache for int->int functions. +/* Implements a lockfree and thread-safe cache for int->int functions, + * using (optionally) _relaxed_ atomic integer operations. * - * The cache is a fixed-size array of 16-bit or 32-bit integers. - * The key is split into two parts: the cache index and the rest. + * The cache is a fixed-size array of 16-bit or 32-bit integers, + * typically 256 elements. * - * The cache index is used to index into the array. The rest is used - * to store the key and the value. + * The key is split into two parts: the cache index (high bits) + * and the rest (low bits). + * + * The cache index is used to index into the array. The array + * member is a 16-bit or 32-bit integer that is used *both* + * to store the low bits of the key, and the value. * * The value is stored in the least significant bits of the integer. - * The key is stored in the most significant bits of the integer. - * The key is shifted by cache_bits to the left to make room for the - * value. + * The low bits of the key are stored in the most significant bits + * of the integer. + * + * A cache hit is detected by comparing the low bits of the key + * with the high bits of the integer at the array position indexed + * by the high bits of the key. If they match, the value is extracted + * from the least significant bits of the integer and returned. + * Otherwise, a cache miss is reported. + * + * Cache operations (storage and retrieval) involve just a few + * arithmetic operations and a single memory access. */ template */ - - /* 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. - * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed - * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. - * - * See this thread for technicalities: - * - * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html - */ - _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ - _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ - -} hb_script_t; - +#include "hb-script-list.h" /* Script functions */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-config.hh b/src/3rdparty/harfbuzz-ng/src/hb-config.hh index 40cc2403c18..3956690da35 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-config.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-config.hh @@ -146,6 +146,7 @@ #ifdef HB_NO_DRAW #define HB_NO_OUTLINE +#define HB_NO_PAINT #endif #ifdef HB_NO_GETENV @@ -191,7 +192,6 @@ #ifdef HB_MINIMIZE_MEMORY_USAGE #define HB_NO_GDEF_CACHE #define HB_NO_OT_LAYOUT_LOOKUP_CACHE -#define HB_NO_OT_FONT_ADVANCE_CACHE #define HB_NO_OT_FONT_CMAP_CACHE #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc index 76c1fa02d3c..9a6bf0bf9c0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext-font.cc @@ -29,6 +29,7 @@ #ifdef HAVE_CORETEXT #include "hb-coretext.hh" +#include "hb-aat-layout-trak-table.hh" #include "hb-draw.hh" #include "hb-font.hh" @@ -209,6 +210,7 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; + hb_position_t tracking = font->face->table.trak->get_tracking (font, HB_DIRECTION_LTR, 0.f); CGGlyph cg_glyph[MAX_GLYPHS]; CGSize advances[MAX_GLYPHS]; @@ -223,7 +225,7 @@ hb_coretext_get_glyph_h_advances (hb_font_t* font, CTFontGetAdvancesForGlyphs (ct_font, kCTFontOrientationHorizontal, cg_glyph, advances, c); for (unsigned j = 0; j < c; j++) { - *first_advance = round (advances[j].width * x_mult); + *first_advance = round (advances[j].width * x_mult) - tracking; first_advance = &StructAtOffset (first_advance, advance_stride); } } @@ -244,6 +246,7 @@ hb_coretext_get_glyph_v_advances (hb_font_t* font, CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat y_mult = (CGFloat) -font->y_scale / ct_font_size; + hb_position_t tracking = font->face->table.trak->get_tracking (font, HB_DIRECTION_TTB, 0.f); CGGlyph cg_glyph[MAX_GLYPHS]; CGSize advances[MAX_GLYPHS]; @@ -258,7 +261,7 @@ hb_coretext_get_glyph_v_advances (hb_font_t* font, CTFontGetAdvancesForGlyphs (ct_font, kCTFontOrientationVertical, cg_glyph, advances, c); for (unsigned j = 0; j < c; j++) { - *first_advance = round (advances[j].width * y_mult); + *first_advance = round (advances[j].width * y_mult) - tracking; first_advance = &StructAtOffset (first_advance, advance_stride); } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 6c0525b3a07..7d7dfc0a8dc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -199,7 +199,7 @@ create_cg_font (hb_blob_t *blob, unsigned int index) if (ttc_index != 0) { - DEBUG_MSG (CORETEXT, blob, "TTC index %d not supported", ttc_index); + DEBUG_MSG (CORETEXT, blob, "TTC index %u not supported", ttc_index); return nullptr; // CoreText does not support TTCs } @@ -414,7 +414,7 @@ hb_coretext_face_create_from_file_or_fail (const char *file_name, if (ttc_index != 0) { - DEBUG_MSG (CORETEXT, nullptr, "TTC index %d not supported", ttc_index); + DEBUG_MSG (CORETEXT, nullptr, "TTC index %u not supported", ttc_index); return nullptr; // CoreText does not support TTCs } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-directwrite-shape.cc index 485075e6464..94440686564 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-directwrite-shape.cc @@ -107,7 +107,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font) void _hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) { - ((IDWriteFontFace *) data)->Release (); + ((IDWriteFontFace *) (const void *) data)->Release (); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.hh b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.hh index f51ab059abd..6c91b2bf5d3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-directwrite.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-directwrite.hh @@ -63,13 +63,13 @@ public: uint64_t RegisterFontFileStream (IDWriteFontFileStream *fontFileStream) { fontFileStream->AddRef (); - auto lock = hb_lock_t (mutex); + hb_lock_t lock {mutex}; mFontStreams.set (mNextFontFileKey, fontFileStream); return mNextFontFileKey++; } void UnregisterFontFileStream (uint64_t fontFileKey) { - auto lock = hb_lock_t (mutex); + hb_lock_t lock {mutex}; IDWriteFontFileStream *stream = mFontStreams.get (fontFileKey); if (stream) { @@ -188,25 +188,8 @@ struct hb_directwrite_global_t { hb_directwrite_global_t () { - dwrite_dll = LoadLibraryW (L"DWrite.dll"); - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" -#endif - - t_DWriteCreateFactory p_DWriteCreateFactory = (t_DWriteCreateFactory) - GetProcAddress (dwrite_dll, "DWriteCreateFactory"); - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif - - if (unlikely (!p_DWriteCreateFactory)) - return; - - HRESULT hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); + HRESULT hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); if (unlikely (hr != S_OK)) return; @@ -222,12 +205,9 @@ struct hb_directwrite_global_t fontFileLoader->Release (); if (dwriteFactory) dwriteFactory->Release (); - if (dwrite_dll) - FreeLibrary (dwrite_dll); } bool success = false; - HMODULE dwrite_dll; IDWriteFactory *dwriteFactory; DWriteFontFileLoader *fontFileLoader; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-draw.h b/src/3rdparty/harfbuzz-ng/src/hb-draw.h index de36901e2a7..02107845582 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-draw.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-draw.h @@ -41,7 +41,7 @@ HB_BEGIN_DECLS * @path_start_y: Y component of the start of current path * @current_x: X component of current point * @current_y: Y component of current point - * @slant_xy: (Since: 11.0.0): Slanting factor for synthetic oblique + * @slant_xy: Slanting factor for synthetic oblique, Since: 11.0.0 * * Current drawing state. * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc index 9051247bc95..431cbaccb1a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc @@ -672,7 +672,7 @@ hb_face_make_immutable (hb_face_t *face) * Since: 0.9.2 **/ hb_bool_t -hb_face_is_immutable (const hb_face_t *face) +hb_face_is_immutable (hb_face_t *face) { return hb_object_is_immutable (face); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h index 5d39a48cc63..b8386f0afb1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h @@ -131,7 +131,7 @@ HB_EXTERN void hb_face_make_immutable (hb_face_t *face); HB_EXTERN hb_bool_t -hb_face_is_immutable (const hb_face_t *face); +hb_face_is_immutable (hb_face_t *face); HB_EXTERN hb_blob_t * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index b73a8704881..4e2adbb788b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -1894,6 +1894,7 @@ _hb_font_adopt_var_coords (hb_font_t *font, font->num_coords = coords_length; font->changed (); + font->serial_coords = font->serial; } /** @@ -2212,6 +2213,7 @@ hb_font_set_face (hb_font_t *font, hb_face_destroy (old); font->changed (); + font->serial_coords = font->serial; } /** diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.hh b/src/3rdparty/harfbuzz-ng/src/hb-font.hh index 5945ec1c2fe..5e23bd04050 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.hh @@ -34,6 +34,7 @@ #include "hb-face.hh" #include "hb-atomic.hh" #include "hb-shaper.hh" +#include "hb-outline.hh" /* @@ -197,10 +198,10 @@ struct hb_font_t float x2 = em_scale_x (extents->x_bearing + extents->width); float y2 = em_scale_y (extents->y_bearing + extents->height); - extents->x_bearing = floorf (x1); - extents->y_bearing = floorf (y1); - extents->width = ceilf (x2) - extents->x_bearing; - extents->height = ceilf (y2) - extents->y_bearing; + extents->x_bearing = roundf (x1); + extents->y_bearing = roundf (y1); + extents->width = roundf (x2) - extents->x_bearing; + extents->height = roundf (y2) - extents->y_bearing; } void synthetic_glyph_extents (hb_glyph_extents_t *extents) @@ -317,16 +318,34 @@ struct hb_font_t hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) { - return klass->get.f.glyph_h_advance (this, user_data, - glyph, - !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); + hb_position_t advance = klass->get.f.glyph_h_advance (this, user_data, + glyph, + !klass->user_data ? nullptr : klass->user_data->glyph_h_advance); + + if (x_strength && !embolden_in_place) + { + /* Emboldening. */ + hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; + advance += advance ? strength : 0; + } + + return advance; } hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) { - return klass->get.f.glyph_v_advance (this, user_data, - glyph, - !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); + hb_position_t advance = klass->get.f.glyph_v_advance (this, user_data, + glyph, + !klass->user_data ? nullptr : klass->user_data->glyph_v_advance); + + if (y_strength && !embolden_in_place) + { + /* Emboldening. */ + hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; + advance += advance ? strength : 0; + } + + return advance; } void get_glyph_h_advances (unsigned int count, @@ -335,11 +354,22 @@ struct hb_font_t hb_position_t *first_advance, unsigned int advance_stride) { - return klass->get.f.glyph_h_advances (this, user_data, - count, - first_glyph, glyph_stride, - first_advance, advance_stride, - !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); + klass->get.f.glyph_h_advances (this, user_data, + count, + first_glyph, glyph_stride, + first_advance, advance_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_h_advances); + + if (x_strength && !embolden_in_place) + { + /* Emboldening. */ + hb_position_t strength = x_scale >= 0 ? x_strength : -x_strength; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } void get_glyph_v_advances (unsigned int count, @@ -348,11 +378,22 @@ struct hb_font_t hb_position_t *first_advance, unsigned int advance_stride) { - return klass->get.f.glyph_v_advances (this, user_data, - count, - first_glyph, glyph_stride, - first_advance, advance_stride, - !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); + klass->get.f.glyph_v_advances (this, user_data, + count, + first_glyph, glyph_stride, + first_advance, advance_stride, + !klass->user_data ? nullptr : klass->user_data->glyph_v_advances); + + if (y_strength && !embolden_in_place) + { + /* Emboldening. */ + hb_position_t strength = y_scale >= 0 ? y_strength : -y_strength; + for (unsigned int i = 0; i < count; i++) + { + *first_advance += *first_advance ? strength : 0; + first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); + } + } } hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, @@ -445,10 +486,37 @@ struct hb_font_t void draw_glyph (hb_codepoint_t glyph, hb_draw_funcs_t *draw_funcs, void *draw_data) { +#ifndef HB_NO_OUTLINE + bool embolden = x_strength || y_strength; +#else + constexpr bool embolden = false; +#endif + + if (!embolden) + { + klass->get.f.draw_glyph (this, user_data, + glyph, + draw_funcs, draw_data, + !klass->user_data ? nullptr : klass->user_data->draw_glyph); + return; + } + +#ifndef HB_NO_OUTLINE + /* Emboldening. */ + hb_outline_t outline; klass->get.f.draw_glyph (this, user_data, glyph, - draw_funcs, draw_data, + hb_outline_recording_pen_get_funcs (), &outline, !klass->user_data ? nullptr : klass->user_data->draw_glyph); + + float x_shift = embolden_in_place ? 0 : (float) x_strength / 2; + float y_shift = (float) y_strength / 2; + if (x_scale < 0) x_shift = -x_shift; + if (y_scale < 0) y_shift = -y_shift; + outline.embolden (x_strength, y_strength, x_shift, y_shift); + + outline.replay (draw_funcs, draw_data); +#endif } void paint_glyph (hb_codepoint_t glyph, @@ -713,8 +781,8 @@ struct hb_font_t bool y_neg = y_scale < 0; y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; - x_strength = fabsf (roundf (x_scale * x_embolden)); - y_strength = fabsf (roundf (y_scale * y_embolden)); + x_strength = roundf (abs (x_scale) * x_embolden); + y_strength = roundf (abs (y_scale) * y_embolden); slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc index 756ba8a54bb..0c0e6938665 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ft.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ft.cc @@ -37,11 +37,7 @@ #include "hb-draw.hh" #include "hb-font.hh" #include "hb-machinery.hh" -#ifndef HB_NO_AAT -#include "hb-aat-layout-trak-table.hh" -#endif #include "hb-ot-os2-table.hh" -#include "hb-ot-stat-table.hh" #include "hb-ot-shaper-arabic-pua.hh" #include "hb-paint.hh" @@ -481,7 +477,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; _hb_ft_hb_font_check_changed (font, ft_font); - hb_position_t *orig_first_advance = first_advance; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; int load_flags = ft_font->load_flags; @@ -522,38 +517,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } - - if (font->x_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? x_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } - -#ifndef HB_NO_AAT - /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ -#ifndef HB_NO_STYLE - bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); -#else - bool apply_trak = false; -#endif - if (apply_trak) - { - hb_position_t tracking = font->face->table.trak->get_h_tracking (font); - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += tracking; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } -#endif } #ifndef HB_NO_VERTICAL @@ -586,26 +549,11 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) return 0; - v = (int) (y_mult * v); - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates * have a Y growing upward. Hence the extra negation. */ + v = ((-v + (1<<9)) >> 10); - hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - v = ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength); - -#ifndef HB_NO_AAT - /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ -#ifndef HB_NO_STYLE - bool apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); -#else - bool apply_trak = false; -#endif - if (apply_trak) - v += font->face->table.trak->get_v_tracking (font); -#endif - - return v; + return (hb_position_t) (y_mult * v); } #endif @@ -719,10 +667,10 @@ hb_ft_get_glyph_extents (hb_font_t *font, float x2 = x1 + x_mult * ft_face->glyph->metrics.width; float y2 = y1 + y_mult * -ft_face->glyph->metrics.height; - extents->x_bearing = floorf (x1); - extents->y_bearing = floorf (y1); - extents->width = ceilf (x2) - extents->x_bearing; - extents->height = ceilf (y2) - extents->y_bearing; + extents->x_bearing = roundf (x1); + extents->y_bearing = roundf (y1); + extents->width = roundf (x2) - extents->x_bearing; + extents->height = roundf (y2) - extents->y_bearing; return true; } @@ -931,38 +879,6 @@ hb_ft_draw_glyph (hb_font_t *font, hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); - /* Embolden */ - if (font->x_strength || font->y_strength) - { - FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_strength, font->y_strength); - - int x_shift = 0; - int y_shift = 0; - if (font->embolden_in_place) - { - /* Undo the FreeType shift. */ - x_shift = -font->x_strength / 2; - y_shift = 0; - if (font->y_scale < 0) y_shift = -font->y_strength; - } - else - { - /* FreeType applied things in the wrong direction for negative scale; fix up. */ - if (font->x_scale < 0) x_shift = -font->x_strength; - if (font->y_scale < 0) y_shift = -font->y_strength; - } - if (x_shift || y_shift) - { - auto &outline = ft_face->glyph->outline; - for (auto &point : hb_iter (outline.points, outline.contours[outline.n_contours - 1] + 1)) - { - point.x += x_shift; - point.y += y_shift; - } - } - } - - FT_Outline_Decompose (&ft_face->glyph->outline, &outline_funcs, &draw_session); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh index e329d9864f1..5942fbea148 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex.hh @@ -99,6 +99,8 @@ struct hb_mutex_t hb_mutex_t () { init (); } ~hb_mutex_t () { fini (); } + hb_mutex_t (const hb_mutex_t &) = delete; + hb_mutex_t &operator= (const hb_mutex_t &) = delete; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" @@ -114,6 +116,10 @@ struct hb_lock_t hb_lock_t (hb_mutex_t &mutex_) : mutex (&mutex_) { mutex->lock (); } hb_lock_t (hb_mutex_t *mutex_) : mutex (mutex_) { if (mutex) mutex->lock (); } ~hb_lock_t () { if (mutex) mutex->unlock (); } + + hb_lock_t (const hb_lock_t &) = delete; + hb_lock_t &operator= (const hb_lock_t &) = delete; + private: hb_mutex_t *mutex; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh index 9d3f4b24953..f6f9ed2c1f7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh @@ -1073,7 +1073,7 @@ struct cff1 this->blob = sc.reference_table (face); - /* setup for run-time santization */ + /* setup for run-time sanitization */ sc.init (this->blob); sc.start_processing (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh index 536c918f0e3..490077a67f0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh @@ -405,7 +405,7 @@ struct cff2 this->blob = sc.reference_table (face); - /* setup for run-time santization */ + /* setup for run-time sanitization */ sc.init (this->blob); sc.start_processing (); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index 7a7a77ad55d..564ef41a96b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -2014,7 +2014,8 @@ struct cmap struct accelerator_t { - using cache_t = hb_cache_t<21, 16, 8, true>; + using cache_t = hb_cache_t<21, 19>; + static_assert (sizeof (cache_t) == 1024, ""); accelerator_t (hb_face_t *face) { @@ -2028,6 +2029,14 @@ struct cmap subtable_uvs = &st->u.format14; } +#ifndef HB_NO_OT_FONT_CMAP_CACHE + cache = (cache_t *) hb_malloc (sizeof (cache_t)); + if (cache) + new (cache) cache_t (); + else + return; // Such that get_glyph_funcZ remains null. +#endif + this->get_glyph_data = subtable; #ifndef HB_NO_CMAP_LEGACY_SUBTABLES if (unlikely (symbol)) @@ -2061,62 +2070,71 @@ struct cmap #endif { switch (subtable->u.format) { - /* Accelerate format 4 and format 12. */ - default: - this->get_glyph_funcZ = get_glyph_from; - break; - case 12: - this->get_glyph_funcZ = get_glyph_from; - break; - case 4: - { - this->format4_accel.init (&subtable->u.format4); - this->get_glyph_data = &this->format4_accel; - this->get_glyph_funcZ = this->format4_accel.get_glyph_func; - break; - } + /* Accelerate format 4 and format 12. */ + default: + this->get_glyph_funcZ = get_glyph_from; + break; + case 12: + this->get_glyph_funcZ = get_glyph_from; + break; + case 4: + { + this->format4_accel.init (&subtable->u.format4); + this->get_glyph_data = &this->format4_accel; + this->get_glyph_funcZ = this->format4_accel.get_glyph_func; + break; + } } } } - ~accelerator_t () { this->table.destroy (); } + ~accelerator_t () + { +#ifndef HB_NO_OT_FONT_CMAP_CACHE + hb_free (cache); +#endif + table.destroy (); + } inline bool _cached_get (hb_codepoint_t unicode, - hb_codepoint_t *glyph, - cache_t *cache) const + hb_codepoint_t *glyph) const { +#ifndef HB_NO_OT_FONT_CMAP_CACHE + // cache is always non-null if we have a get_glyph_funcZ unsigned v; - if (cache && cache->get (unicode, &v)) + if (cache->get (unicode, &v)) { *glyph = v; return true; } +#endif bool ret = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); - if (cache && ret) +#ifndef HB_NO_OT_FONT_CMAP_CACHE + if (ret) cache->set (unicode, *glyph); +#endif + return ret; } bool get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph, - cache_t *cache = nullptr) const + hb_codepoint_t *glyph) const { if (unlikely (!this->get_glyph_funcZ)) return false; - return _cached_get (unicode, glyph, cache); + return _cached_get (unicode, glyph); } unsigned int get_nominal_glyphs (unsigned int count, const hb_codepoint_t *first_unicode, unsigned int unicode_stride, hb_codepoint_t *first_glyph, - unsigned int glyph_stride, - cache_t *cache = nullptr) const + unsigned int glyph_stride) const { if (unlikely (!this->get_glyph_funcZ)) return 0; unsigned int done; for (done = 0; - done < count && _cached_get (*first_unicode, first_glyph, cache); + done < count && _cached_get (*first_unicode, first_glyph); done++) { first_unicode = &StructAtOffsetUnaligned (first_unicode, unicode_stride); @@ -2127,8 +2145,7 @@ struct cmap bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - cache_t *cache = nullptr) const + hb_codepoint_t *glyph) const { switch (this->subtable_uvs->get_glyph_variant (unicode, variation_selector, @@ -2139,7 +2156,7 @@ struct cmap case GLYPH_VARIANT_USE_DEFAULT: break; } - return get_nominal_glyph (unicode, glyph, cache); + return get_nominal_glyph (unicode, glyph); } void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const @@ -2209,11 +2226,15 @@ struct cmap hb_nonnull_ptr_t subtable; hb_nonnull_ptr_t subtable_uvs; - hb_cmap_get_glyph_func_t get_glyph_funcZ; - const void *get_glyph_data; + hb_cmap_get_glyph_func_t get_glyph_funcZ = nullptr; + const void *get_glyph_data = nullptr; CmapSubtableFormat4::accelerator_t format4_accel; +#ifndef HB_NO_OT_FONT_CMAP_CACHE + cache_t *cache = nullptr; +#endif + public: hb_blob_ptr_t table; }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index 9bd0db4b8ac..17e56dbc481 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -34,11 +34,7 @@ #include "hb-font.hh" #include "hb-machinery.hh" #include "hb-ot-face.hh" -#include "hb-outline.hh" -#ifndef HB_NO_AAT -#include "hb-aat-layout-trak-table.hh" -#endif #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-cff2-table.hh" @@ -65,28 +61,111 @@ * never need to call these functions directly. **/ -using hb_ot_font_cmap_cache_t = hb_cache_t<21, 16, 8, true>; -using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>; - -#ifndef HB_NO_OT_FONT_CMAP_CACHE -static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key; -#endif +using hb_ot_font_advance_cache_t = hb_cache_t<24, 16>; +static_assert (sizeof (hb_ot_font_advance_cache_t) == 1024, ""); struct hb_ot_font_t { const hb_ot_face_t *ot_face; -#ifndef HB_NO_AAT - bool apply_trak; -#endif - -#ifndef HB_NO_OT_FONT_CMAP_CACHE - hb_ot_font_cmap_cache_t *cmap_cache; -#endif - /* h_advance caching */ mutable hb_atomic_t cached_coords_serial; - mutable hb_atomic_t advance_cache; + struct advance_cache_t + { + mutable hb_atomic_t advance_cache; + mutable hb_atomic_t varStore_cache; + + ~advance_cache_t () + { + clear (); + } + + hb_ot_font_advance_cache_t *acquire_advance_cache () const + { + retry: + auto *cache = advance_cache.get_acquire (); + if (!cache) + { + cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); + if (!cache) + return nullptr; + new (cache) hb_ot_font_advance_cache_t; + return cache; + } + if (advance_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_advance_cache (hb_ot_font_advance_cache_t *cache) const + { + if (!cache) + return; + if (!advance_cache.cmpexch (nullptr, cache)) + hb_free (cache); + } + void clear_advance_cache () const + { + retry: + auto *cache = advance_cache.get_acquire (); + if (!cache) + return; + if (advance_cache.cmpexch (cache, nullptr)) + hb_free (cache); + else + goto retry; + } + + OT::ItemVariationStore::cache_t *acquire_varStore_cache (const OT::ItemVariationStore &varStore) const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return varStore.create_cache (); + if (varStore_cache.cmpexch (cache, nullptr)) + return cache; + else + goto retry; + } + void release_varStore_cache (OT::ItemVariationStore::cache_t *cache) const + { + if (!cache) + return; + if (!varStore_cache.cmpexch (nullptr, cache)) + OT::ItemVariationStore::destroy_cache (cache); + } + void clear_varStore_cache () const + { + retry: + auto *cache = varStore_cache.get_acquire (); + if (!cache) + return; + if (varStore_cache.cmpexch (cache, nullptr)) + OT::ItemVariationStore::destroy_cache (cache); + else + goto retry; + } + + void clear () const + { + clear_advance_cache (); + clear_varStore_cache (); + } + + } h, v; + + void check_serial (hb_font_t *font) const + { + int font_serial = font->serial_coords.get_acquire (); + + if (cached_coords_serial.get_acquire () == font_serial) + return; + + h.clear (); + v.clear (); + + cached_coords_serial.set_release (font_serial); + } }; static hb_ot_font_t * @@ -98,44 +177,6 @@ _hb_ot_font_create (hb_font_t *font) ot_font->ot_face = &font->face->table; -#ifndef HB_NO_AAT - /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ -#ifndef HB_NO_STYLE - ot_font->apply_trak = font->face->table.STAT->has_data () && font->face->table.trak->has_data (); -#else - ot_font->apply_trak = false; -#endif -#endif - -#ifndef HB_NO_OT_FONT_CMAP_CACHE - // retry: - auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face, - &hb_ot_font_cmap_cache_user_data_key); - if (!cmap_cache) - { - cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t)); - if (unlikely (!cmap_cache)) goto out; - new (cmap_cache) hb_ot_font_cmap_cache_t (); - if (unlikely (!hb_face_set_user_data (font->face, - &hb_ot_font_cmap_cache_user_data_key, - cmap_cache, - hb_free, - false))) - { - hb_free (cmap_cache); - cmap_cache = nullptr; - /* Normally we would retry here, but that would - * infinite-loop if the face is the empty-face. - * Just let it go and this font will be uncached if it - * happened to collide with another thread creating the - * cache at the same time. */ - // goto retry; - } - } - out: - ot_font->cmap_cache = cmap_cache; -#endif - return ot_font; } @@ -144,8 +185,7 @@ _hb_ot_font_destroy (void *font_data) { hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data; - auto *cache = ot_font->advance_cache.get_relaxed (); - hb_free (cache); + ot_font->~hb_ot_font_t (); hb_free (ot_font); } @@ -159,11 +199,7 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif - return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache); + return ot_face->cmap->get_nominal_glyph (unicode, glyph); } static unsigned int @@ -178,14 +214,9 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif return ot_face->cmap->get_nominal_glyphs (count, first_unicode, unicode_stride, - first_glyph, glyph_stride, - cmap_cache); + first_glyph, glyph_stride); } static hb_bool_t @@ -198,13 +229,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; - hb_ot_font_cmap_cache_t *cmap_cache = nullptr; -#ifndef HB_NO_OT_FONT_CMAP_CACHE - cmap_cache = ot_font->cmap_cache; -#endif return ot_face->cmap->get_variation_glyph (unicode, - variation_selector, glyph, - cmap_cache); + variation_selector, glyph); } static void @@ -216,47 +242,25 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; - hb_position_t *orig_first_advance = first_advance; - -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) + ot_font->check_serial (font); const OT::HVAR &HVAR = *hmtx.var_table; const OT::ItemVariationStore &varStore = &HVAR + HVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; + OT::ItemVariationStore::cache_t *varStore_cache = ot_font->h.acquire_varStore_cache (varStore); + + hb_ot_font_advance_cache_t *advance_cache = nullptr; bool use_cache = font->num_coords; -#else - OT::ItemVariationStore::cache_t *varStore_cache = nullptr; - bool use_cache = false; -#endif - - hb_ot_font_advance_cache_t *cache = nullptr; if (use_cache) { - retry: - cache = ot_font->advance_cache.get_acquire (); - if (unlikely (!cache)) - { - cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t)); - if (unlikely (!cache)) - { - use_cache = false; - goto out; - } - new (cache) hb_ot_font_advance_cache_t; - - if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache))) - { - hb_free (cache); - goto retry; - } - ot_font->cached_coords_serial.set_release (font->serial_coords); - } + advance_cache = ot_font->h.acquire_advance_cache (); + if (!advance_cache) + use_cache = false; } - out: if (!use_cache) { @@ -269,58 +273,26 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, } else { /* Use cache. */ - if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords) - { - ot_font->advance_cache->clear (); - ot_font->cached_coords_serial.set_release (font->serial_coords); - } - for (unsigned int i = 0; i < count; i++) { hb_position_t v; unsigned cv; - if (ot_font->advance_cache->get (*first_glyph, &cv)) + if (advance_cache->get (*first_glyph, &cv)) v = cv; else { v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); - ot_font->advance_cache->set (*first_glyph, v); + advance_cache->set (*first_glyph, v); } *first_advance = font->em_scale_x (v); first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } + + ot_font->h.release_advance_cache (advance_cache); } -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::ItemVariationStore::destroy_cache (varStore_cache); -#endif - - if (font->x_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? x_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } - -#ifndef HB_NO_AAT - if (ot_font->apply_trak) - { - hb_position_t tracking = font->face->table.trak->get_h_tracking (font); - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += tracking; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } -#endif + ot_font->h.release_varStore_cache (varStore_cache); } #ifndef HB_NO_VERTICAL @@ -337,17 +309,13 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, const hb_ot_face_t *ot_face = ot_font->ot_face; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - hb_position_t *orig_first_advance = first_advance; - if (vmtx.has_data ()) { -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) + ot_font->check_serial (font); const OT::VVAR &VVAR = *vmtx.var_table; const OT::ItemVariationStore &varStore = &VVAR + VVAR.varStore; - OT::ItemVariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; -#else - OT::ItemVariationStore::cache_t *varStore_cache = nullptr; -#endif + OT::ItemVariationStore::cache_t *varStore_cache = ot_font->v.acquire_varStore_cache (varStore); + // TODO Use advance_cache. for (unsigned int i = 0; i < count; i++) { @@ -356,9 +324,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } -#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE) - OT::ItemVariationStore::destroy_cache (varStore_cache); -#endif + ot_font->v.release_varStore_cache (varStore_cache); } else { @@ -373,32 +339,6 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); } } - - if (font->y_strength && !font->embolden_in_place) - { - /* Emboldening. */ - hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength; - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += *first_advance ? y_strength : 0; - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } - -#ifndef HB_NO_AAT - if (ot_font->apply_trak) - { - hb_position_t tracking = font->face->table.trak->get_v_tracking (font); - first_advance = orig_first_advance; - for (unsigned int i = 0; i < count; i++) - { - *first_advance += tracking; - first_glyph = &StructAtOffsetUnaligned (first_glyph, glyph_stride); - first_advance = &StructAtOffsetUnaligned (first_advance, advance_stride); - } - } -#endif } #endif @@ -435,7 +375,8 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, } hb_glyph_extents_t extents = {0}; - if (ot_face->glyf->get_extents (font, glyph, &extents)) + + if (hb_font_get_glyph_extents (font, glyph, &extents)) { const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; int tsb = 0; @@ -448,7 +389,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, hb_font_extents_t font_extents; font->get_h_extents_with_fallback (&font_extents); hb_position_t advance = font_extents.ascender - font_extents.descender; - int diff = advance - -extents.height; + hb_position_t diff = advance - -extents.height; *y = extents.y_bearing + (diff >> 1); return true; } @@ -564,35 +505,17 @@ hb_ot_draw_glyph (hb_font_t *font, hb_draw_funcs_t *draw_funcs, void *draw_data, void *user_data) { - bool embolden = font->x_strength || font->y_strength; - hb_outline_t outline; - - { // Need draw_session to be destructed before emboldening. - hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs, - embolden ? &outline : draw_data, font->slant_xy); + hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); #ifndef HB_NO_VAR_COMPOSITES - if (!font->face->table.VARC->get_path (font, glyph, draw_session)) + if (!font->face->table.VARC->get_path (font, glyph, draw_session)) #endif - // Keep the following in synch with VARC::get_path_at() - if (!font->face->table.glyf->get_path (font, glyph, draw_session)) + // Keep the following in synch with VARC::get_path_at() + if (!font->face->table.glyf->get_path (font, glyph, draw_session)) #ifndef HB_NO_CFF - if (!font->face->table.cff2->get_path (font, glyph, draw_session)) - if (!font->face->table.cff1->get_path (font, glyph, draw_session)) + if (!font->face->table.cff2->get_path (font, glyph, draw_session)) + if (!font->face->table.cff1->get_path (font, glyph, draw_session)) #endif - {} - } - - if (embolden) - { - float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2; - float y_shift = (float) font->y_strength / 2; - if (font->x_scale < 0) x_shift = -x_shift; - if (font->y_scale < 0) y_shift = -y_shift; - outline.embolden (font->x_strength, font->y_strength, - x_shift, y_shift); - - outline.replay (draw_funcs, draw_data); - } + {} } #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index 8e44f143b9c..a43fdfba312 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -359,7 +359,13 @@ struct hmtxvmtx return true; } - return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb); + // If there's no vmtx data, the phantom points from glyf table are not accurate, + // so we cannot take the next path. + bool is_vertical = T::tableTag == HB_OT_TAG_vmtx; + if (is_vertical && !has_data ()) + return false; + + return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); #else return false; #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh index ad54a1d79c5..085bc3c5cfd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh @@ -1850,7 +1850,7 @@ struct ClassDefFormat2_4 hb_sorted_vector_t glyph_and_klass; hb_set_t orig_klasses; - if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2 + if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) < get_population ()) { for (hb_codepoint_t g : glyph_set) @@ -1931,7 +1931,7 @@ struct ClassDefFormat2_4 bool intersects (const hb_set_t *glyphs) const { - if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2) + if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len)) { for (auto g : *glyphs) if (get_class (g)) @@ -2000,7 +2000,7 @@ struct ClassDefFormat2_4 } unsigned count = rangeRecord.len; - if (count > glyphs->get_population () * hb_bit_storage (count) * 8) + if (count > glyphs->get_population () * hb_bit_storage (count)) { for (auto g : *glyphs) { @@ -2548,11 +2548,13 @@ struct SparseVarRegionAxis DEFINE_SIZE_STATIC (8); }; -#define REGION_CACHE_ITEM_CACHE_INVALID 2.f +#define REGION_CACHE_ITEM_CACHE_INVALID INT_MIN +#define REGION_CACHE_ITEM_MULTIPLIER (float (1 << ((sizeof (int) * 8) - 2))) +#define REGION_CACHE_ITEM_DIVISOR (1.f / float (1 << ((sizeof (int) * 8) - 2))) struct VarRegionList { - using cache_t = float; + using cache_t = hb_atomic_t; float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, @@ -2561,12 +2563,12 @@ struct VarRegionList if (unlikely (region_index >= regionCount)) return 0.; - float *cached_value = nullptr; + cache_t *cached_value = nullptr; if (cache) { cached_value = &(cache[region_index]); if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) - return *cached_value; + return *cached_value * REGION_CACHE_ITEM_DIVISOR; } const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount); @@ -2587,7 +2589,7 @@ struct VarRegionList } if (cache) - *cached_value = v; + *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; return v; } @@ -2730,7 +2732,7 @@ struct SparseVariationRegion : Array16Of struct SparseVarRegionList { - using cache_t = float; + using cache_t = hb_atomic_t; float evaluate (unsigned int region_index, const int *coords, unsigned int coord_len, @@ -2739,12 +2741,12 @@ struct SparseVarRegionList if (unlikely (region_index >= regions.len)) return 0.; - float *cached_value = nullptr; + cache_t *cached_value = nullptr; if (cache) { cached_value = &(cache[region_index]); if (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID) - return *cached_value; + return *cached_value * REGION_CACHE_ITEM_DIVISOR; } const SparseVariationRegion ®ion = this+regions[region_index]; @@ -2752,7 +2754,7 @@ struct SparseVarRegionList float v = region.evaluate (coords, coord_len); if (cache) - *cached_value = v; + *cached_value = v * REGION_CACHE_ITEM_MULTIPLIER; return v; } @@ -2861,8 +2863,13 @@ struct VarData const hb_vector_t*>& rows) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); unsigned row_count = rows.length; + if (!row_count) { + // Nothing to serialize, will be empty. + return false; + } + + if (unlikely (!c->extend_min (this))) return_trace (false); itemCount = row_count; int min_threshold = has_long ? -65536 : -128; @@ -3187,10 +3194,10 @@ struct ItemVariationStore #ifdef HB_NO_VAR return nullptr; #endif - auto &r = this+regions; - unsigned count = r.regionCount; + unsigned count = (this+regions).regionCount; + if (!count) return nullptr; - float *cache = (float *) hb_malloc (sizeof (float) * count); + cache_t *cache = (cache_t *) hb_malloc (sizeof (float) * count); if (unlikely (!cache)) return nullptr; for (unsigned i = 0; i < count; i++) @@ -3440,7 +3447,7 @@ struct MultiItemVariationStore { using cache_t = SparseVarRegionList::cache_t; - cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const + cache_t *create_cache (hb_array_t static_cache = hb_array_t ()) const { #ifdef HB_NO_VAR return nullptr; @@ -3448,12 +3455,12 @@ struct MultiItemVariationStore auto &r = this+regions; unsigned count = r.regions.len; - float *cache; + cache_t *cache; if (count <= static_cache.length) cache = static_cache.arrayZ; else { - cache = (float *) hb_malloc (sizeof (float) * count); + cache = (cache_t *) hb_malloc (sizeof (float) * count); if (unlikely (!cache)) return nullptr; } @@ -3464,7 +3471,7 @@ struct MultiItemVariationStore } static void destroy_cache (cache_t *cache, - hb_array_t static_cache = hb_array_t ()) + hb_array_t static_cache = hb_array_t ()) { if (cache != static_cache.arrayZ) hb_free (cache); @@ -4777,12 +4784,12 @@ struct VariationDevice hb_position_t get_x_delta (hb_font_t *font, const ItemVariationStore &store, ItemVariationStore::cache_t *store_cache = nullptr) const - { return font->em_scalef_x (get_delta (font, store, store_cache)); } + { return !font->num_coords ? 0 : font->em_scalef_x (get_delta (font, store, store_cache)); } hb_position_t get_y_delta (hb_font_t *font, const ItemVariationStore &store, ItemVariationStore::cache_t *store_cache = nullptr) const - { return font->em_scalef_y (get_delta (font, store, store_cache)); } + { return !font->num_coords ? 0 : font->em_scalef_y (get_delta (font, store, store_cache)); } VariationDevice* copy (hb_serialize_context_t *c, const hb_hashmap_t> *layout_variation_idx_delta_map) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh index 7d49710d11e..eab477a8ed0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh @@ -737,7 +737,8 @@ struct hb_ot_apply_context_t : hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_, - hb_blob_t *table_blob_) : + hb_blob_t *table_blob_, + ItemVariationStore::cache_t *var_store_cache_ = nullptr) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), sanitizer (table_blob_), @@ -756,13 +757,7 @@ struct hb_ot_apply_context_t : #endif ), var_store (gdef.get_var_store ()), - var_store_cache ( -#ifndef HB_NO_VAR - table_index == 1 && font->num_coords ? var_store.create_cache () : nullptr -#else - nullptr -#endif - ), + var_store_cache (var_store_cache_), direction (buffer_->props.direction), has_glyph_classes (gdef.has_glyph_classes ()) { @@ -770,13 +765,6 @@ struct hb_ot_apply_context_t : buffer->collect_codepoints (digest); } - ~hb_ot_apply_context_t () - { -#ifndef HB_NO_VAR - ItemVariationStore::destroy_cache (var_store_cache); -#endif - } - void init_iters () { iter_input.init (this, false); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc index 3aca40eb7a9..83e8a5d747f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc @@ -2015,7 +2015,11 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, { const unsigned int table_index = proxy.table_index; unsigned int i = 0; - OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob ()); + + auto *font_data = font->data.ot.get (); + auto *var_store_cache = font_data == HB_SHAPER_DATA_SUCCEEDED ? nullptr : (OT::ItemVariationStore::cache_t *) font_data; + + OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob (), var_store_cache); c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func); for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) @@ -2628,7 +2632,8 @@ struct hb_get_glyph_alternates_dispatch_t : * @alternate_glyphs: (out caller-allocates) (array length=alternate_count): A glyphs buffer. * Alternate glyphs associated with the glyph id. * - * Fetches alternates of a glyph from a given GSUB lookup index. + * Fetches alternates of a glyph from a given GSUB lookup index. Note that for one-to-one GSUB + * glyph substitutions, this function fetches the substituted glyph. * * Return value: Total number of alternates found in the specific lookup index for the given glyph id. * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh index ddec57e068f..a42212f291f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh @@ -431,6 +431,7 @@ _hb_glyph_info_set_aat_deleted (hb_glyph_info_t *info) { _hb_glyph_info_set_general_category (info, HB_UNICODE_GENERAL_CATEGORY_FORMAT); info->unicode_props() |= UPROPS_MASK_Cf_AAT_DELETED; + info->unicode_props() |= UPROPS_MASK_HIDDEN; } /* lig_props: aka lig_id / lig_comp diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh index 5839059fde0..c702e42e2c7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh @@ -1104,6 +1104,24 @@ struct MATH mathVariants.sanitize (c, this)); } + // https://github.com/harfbuzz/harfbuzz/issues/4653 + HB_INTERNAL bool is_bad_cambria (hb_font_t *font) const + { +#ifndef HB_NO_MATH + switch HB_CODEPOINT_ENCODE3 (font->face->table.MATH.get_blob ()->length, + get_constant (HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT, font), + get_constant (HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT, font)) + { + /* sha1sum:ab4a4fe054d23061f3c039493d6f665cfda2ecf5 cambria.ttc + * sha1sum:086855301bff644f9d8827b88491fcf73a6d4cb9 cambria.ttc + * sha1sum:b1e5a3feaca2ea3dfcf79ccb377de749ecf60343 cambria.ttc */ + case HB_CODEPOINT_ENCODE3 (25722, 2500, 3000): + return true; + } +#endif + return false; + } + hb_position_t get_constant (hb_ot_math_constant_t constant, hb_font_t *font) const { return (this+mathConstants).get_value (constant, font); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc index 876ad258e39..719a802d5e5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc @@ -87,6 +87,20 @@ hb_position_t hb_ot_math_get_constant (hb_font_t *font, hb_ot_math_constant_t constant) { + /* https://github.com/harfbuzz/harfbuzz/issues/4653 + * Cambria Math has incorrect value for displayOperatorMinHeight, and + * apparently Microsoft implementation swaps displayOperatorMinHeight and + * delimitedSubFormulaMinHeight, so we do the same if we detect Cambria Math + * with the swapped values. */ + if ((constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT || + constant == HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT) && + font->face->table.MATH->is_bad_cambria (font)) + { + if (constant == HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT) + constant = HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT; + else + constant = HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT; + } return font->face->table.MATH->get_constant(constant, font); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc index b2eedb027bb..6ddf7982b5b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc @@ -427,8 +427,13 @@ position_cluster (const hb_ot_shape_plan_t *plan, /* Find mark glyphs */ unsigned int j; for (j = i + 1; j < end; j++) + { + if (_hb_glyph_info_is_hidden (&info[j]) || + _hb_glyph_info_is_default_ignorable (&info[j])) + continue; if (!_hb_glyph_info_is_unicode_mark (&info[j])) break; + } position_around_base (plan, font, buffer, i, j, adjust_offsets_when_zeroing); @@ -455,7 +460,9 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]))) { + if (likely (!_hb_glyph_info_is_unicode_mark (&info[i]) && + !_hb_glyph_info_is_hidden (&info[i]) && + !_hb_glyph_info_is_default_ignorable (&info[i]))) { position_cluster (plan, font, buffer, start, i, adjust_offsets_when_zeroing); start = i; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc index dfc6be0fbd6..a2d2edee9cc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc @@ -46,6 +46,7 @@ #include "hb-set.hh" #include "hb-aat-layout.hh" +#include "hb-ot-layout-gdef-table.hh" #include "hb-ot-stat-table.hh" @@ -210,6 +211,14 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, https://github.com/harfbuzz/harfbuzz/issues/2967. */ if (plan.apply_morx) plan.adjust_mark_positioning_when_zeroing = false; + + /* According to Ned, trak is applied by default for "modern fonts", as detected by presence of STAT table. */ +#ifndef HB_NO_STYLE + plan.apply_trak = hb_aat_layout_has_tracking (face) && face->table.STAT->has_data (); +#else + plan.apply_trak = false; +#endif + #endif } @@ -274,6 +283,11 @@ hb_ot_shape_plan_t::position (hb_font_t *font, #endif else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); + +#ifndef HB_NO_AAT_SHAPE + if (this->apply_trak) + hb_aat_layout_track (this, font, buffer); +#endif } @@ -410,17 +424,26 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) * shaper font data */ -struct hb_ot_font_data_t {}; +struct hb_ot_font_data_t { + OT::ItemVariationStore::cache_t unused; // Just for alignment +}; hb_ot_font_data_t * -_hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED) +_hb_ot_shaper_font_data_create (hb_font_t *font) { - return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; + if (!font->num_coords) + return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; + + const OT::ItemVariationStore &var_store = font->face->table.GDEF->table->get_var_store (); + auto *cache = (hb_ot_font_data_t *) var_store.create_cache (); + return cache ? cache : (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; } void -_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED) +_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data) { + if (data == HB_SHAPER_DATA_SUCCEEDED) return; + OT::ItemVariationStore::destroy_cache ((OT::ItemVariationStore::cache_t *) data); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh index 49398818539..af71fb45b00 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.hh @@ -109,9 +109,11 @@ struct hb_ot_shape_plan_t #ifndef HB_NO_AAT_SHAPE bool apply_kerx : 1; bool apply_morx : 1; + bool apply_trak : 1; #else static constexpr bool apply_kerx = false; static constexpr bool apply_morx = false; + static constexpr bool apply_trak = false; #endif void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh index b32720be7ca..8523683b974 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh @@ -590,9 +590,9 @@ struct gvar_GVAR /* If sanitize failed, set glyphCount to 0. */ glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0; - /* For shared tuples that only have one axis active, shared the index of - * that axis as a cache. This will speed up caclulate_scalar() a lot - * for fonts with lots of axes and many "monovar" tuples. */ + /* For shared tuples that only have one or two axes active, shared the index + * of that axis as a cache. This will speed up caclulate_scalar() a lot + * for fonts with lots of axes and many "monovar" or "duovar" tuples. */ hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount); unsigned count = table->sharedTupleCount; if (unlikely (!shared_tuple_active_idx.resize (count, false))) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-script-list.h b/src/3rdparty/harfbuzz-ng/src/hb-script-list.h new file mode 100644 index 00000000000..88e270d3479 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-script-list.h @@ -0,0 +1,484 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * 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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#if !defined(HB_H_IN) && !defined(HB_NO_SINGLE_HEADER_ERROR) +#error "Include instead." +#endif + +#ifndef HB_SCRIPT_LIST_H +#define HB_SCRIPT_LIST_H + +/* This file belongs to the middle of hb-common.h. + * The reason it has been surgically extracted is because + * FreeType imports types and enums from hb-common.h, + * and since this enum is large and growing, we want to + * make it easy to just copy the file over to FreeType. + * https://github.com/harfbuzz/harfbuzz/issues/5271 + */ + +/* Dummy lines to make our checks happy. */ +#if 0 +#include "hb-common.h" +HB_BEGIN_DECLS +HB_END_DECLS +#endif + + +/** + * hb_script_t: + * @HB_SCRIPT_COMMON: `Zyyy` + * @HB_SCRIPT_INHERITED: `Zinh` + * @HB_SCRIPT_UNKNOWN: `Zzzz` + * @HB_SCRIPT_ARABIC: `Arab` + * @HB_SCRIPT_ARMENIAN: `Armn` + * @HB_SCRIPT_BENGALI: `Beng` + * @HB_SCRIPT_CYRILLIC: `Cyrl` + * @HB_SCRIPT_DEVANAGARI: `Deva` + * @HB_SCRIPT_GEORGIAN: `Geor` + * @HB_SCRIPT_GREEK: `Grek` + * @HB_SCRIPT_GUJARATI: `Gujr` + * @HB_SCRIPT_GURMUKHI: `Guru` + * @HB_SCRIPT_HANGUL: `Hang` + * @HB_SCRIPT_HAN: `Hani` + * @HB_SCRIPT_HEBREW: `Hebr` + * @HB_SCRIPT_HIRAGANA: `Hira` + * @HB_SCRIPT_KANNADA: `Knda` + * @HB_SCRIPT_KATAKANA: `Kana` + * @HB_SCRIPT_LAO: `Laoo` + * @HB_SCRIPT_LATIN: `Latn` + * @HB_SCRIPT_MALAYALAM: `Mlym` + * @HB_SCRIPT_ORIYA: `Orya` + * @HB_SCRIPT_TAMIL: `Taml` + * @HB_SCRIPT_TELUGU: `Telu` + * @HB_SCRIPT_THAI: `Thai` + * @HB_SCRIPT_TIBETAN: `Tibt` + * @HB_SCRIPT_BOPOMOFO: `Bopo` + * @HB_SCRIPT_BRAILLE: `Brai` + * @HB_SCRIPT_CANADIAN_SYLLABICS: `Cans` + * @HB_SCRIPT_CHEROKEE: `Cher` + * @HB_SCRIPT_ETHIOPIC: `Ethi` + * @HB_SCRIPT_KHMER: `Khmr` + * @HB_SCRIPT_MONGOLIAN: `Mong` + * @HB_SCRIPT_MYANMAR: `Mymr` + * @HB_SCRIPT_OGHAM: `Ogam` + * @HB_SCRIPT_RUNIC: `Runr` + * @HB_SCRIPT_SINHALA: `Sinh` + * @HB_SCRIPT_SYRIAC: `Syrc` + * @HB_SCRIPT_THAANA: `Thaa` + * @HB_SCRIPT_YI: `Yiii` + * @HB_SCRIPT_DESERET: `Dsrt` + * @HB_SCRIPT_GOTHIC: `Goth` + * @HB_SCRIPT_OLD_ITALIC: `Ital` + * @HB_SCRIPT_BUHID: `Buhd` + * @HB_SCRIPT_HANUNOO: `Hano` + * @HB_SCRIPT_TAGALOG: `Tglg` + * @HB_SCRIPT_TAGBANWA: `Tagb` + * @HB_SCRIPT_CYPRIOT: `Cprt` + * @HB_SCRIPT_LIMBU: `Limb` + * @HB_SCRIPT_LINEAR_B: `Linb` + * @HB_SCRIPT_OSMANYA: `Osma` + * @HB_SCRIPT_SHAVIAN: `Shaw` + * @HB_SCRIPT_TAI_LE: `Tale` + * @HB_SCRIPT_UGARITIC: `Ugar` + * @HB_SCRIPT_BUGINESE: `Bugi` + * @HB_SCRIPT_COPTIC: `Copt` + * @HB_SCRIPT_GLAGOLITIC: `Glag` + * @HB_SCRIPT_KHAROSHTHI: `Khar` + * @HB_SCRIPT_NEW_TAI_LUE: `Talu` + * @HB_SCRIPT_OLD_PERSIAN: `Xpeo` + * @HB_SCRIPT_SYLOTI_NAGRI: `Sylo` + * @HB_SCRIPT_TIFINAGH: `Tfng` + * @HB_SCRIPT_BALINESE: `Bali` + * @HB_SCRIPT_CUNEIFORM: `Xsux` + * @HB_SCRIPT_NKO: `Nkoo` + * @HB_SCRIPT_PHAGS_PA: `Phag` + * @HB_SCRIPT_PHOENICIAN: `Phnx` + * @HB_SCRIPT_CARIAN: `Cari` + * @HB_SCRIPT_CHAM: `Cham` + * @HB_SCRIPT_KAYAH_LI: `Kali` + * @HB_SCRIPT_LEPCHA: `Lepc` + * @HB_SCRIPT_LYCIAN: `Lyci` + * @HB_SCRIPT_LYDIAN: `Lydi` + * @HB_SCRIPT_OL_CHIKI: `Olck` + * @HB_SCRIPT_REJANG: `Rjng` + * @HB_SCRIPT_SAURASHTRA: `Saur` + * @HB_SCRIPT_SUNDANESE: `Sund` + * @HB_SCRIPT_VAI: `Vaii` + * @HB_SCRIPT_AVESTAN: `Avst` + * @HB_SCRIPT_BAMUM: `Bamu` + * @HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: `Egyp` + * @HB_SCRIPT_IMPERIAL_ARAMAIC: `Armi` + * @HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: `Phli` + * @HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: `Prti` + * @HB_SCRIPT_JAVANESE: `Java` + * @HB_SCRIPT_KAITHI: `Kthi` + * @HB_SCRIPT_LISU: `Lisu` + * @HB_SCRIPT_MEETEI_MAYEK: `Mtei` + * @HB_SCRIPT_OLD_SOUTH_ARABIAN: `Sarb` + * @HB_SCRIPT_OLD_TURKIC: `Orkh` + * @HB_SCRIPT_SAMARITAN: `Samr` + * @HB_SCRIPT_TAI_THAM: `Lana` + * @HB_SCRIPT_TAI_VIET: `Tavt` + * @HB_SCRIPT_BATAK: `Batk` + * @HB_SCRIPT_BRAHMI: `Brah` + * @HB_SCRIPT_MANDAIC: `Mand` + * @HB_SCRIPT_CHAKMA: `Cakm` + * @HB_SCRIPT_MEROITIC_CURSIVE: `Merc` + * @HB_SCRIPT_MEROITIC_HIEROGLYPHS: `Mero` + * @HB_SCRIPT_MIAO: `Plrd` + * @HB_SCRIPT_SHARADA: `Shrd` + * @HB_SCRIPT_SORA_SOMPENG: `Sora` + * @HB_SCRIPT_TAKRI: `Takr` + * @HB_SCRIPT_BASSA_VAH: `Bass`, Since: 0.9.30 + * @HB_SCRIPT_CAUCASIAN_ALBANIAN: `Aghb`, Since: 0.9.30 + * @HB_SCRIPT_DUPLOYAN: `Dupl`, Since: 0.9.30 + * @HB_SCRIPT_ELBASAN: `Elba`, Since: 0.9.30 + * @HB_SCRIPT_GRANTHA: `Gran`, Since: 0.9.30 + * @HB_SCRIPT_KHOJKI: `Khoj`, Since: 0.9.30 + * @HB_SCRIPT_KHUDAWADI: `Sind`, Since: 0.9.30 + * @HB_SCRIPT_LINEAR_A: `Lina`, Since: 0.9.30 + * @HB_SCRIPT_MAHAJANI: `Mahj`, Since: 0.9.30 + * @HB_SCRIPT_MANICHAEAN: `Mani`, Since: 0.9.30 + * @HB_SCRIPT_MENDE_KIKAKUI: `Mend`, Since: 0.9.30 + * @HB_SCRIPT_MODI: `Modi`, Since: 0.9.30 + * @HB_SCRIPT_MRO: `Mroo`, Since: 0.9.30 + * @HB_SCRIPT_NABATAEAN: `Nbat`, Since: 0.9.30 + * @HB_SCRIPT_OLD_NORTH_ARABIAN: `Narb`, Since: 0.9.30 + * @HB_SCRIPT_OLD_PERMIC: `Perm`, Since: 0.9.30 + * @HB_SCRIPT_PAHAWH_HMONG: `Hmng`, Since: 0.9.30 + * @HB_SCRIPT_PALMYRENE: `Palm`, Since: 0.9.30 + * @HB_SCRIPT_PAU_CIN_HAU: `Pauc`, Since: 0.9.30 + * @HB_SCRIPT_PSALTER_PAHLAVI: `Phlp`, Since: 0.9.30 + * @HB_SCRIPT_SIDDHAM: `Sidd`, Since: 0.9.30 + * @HB_SCRIPT_TIRHUTA: `Tirh`, Since: 0.9.30 + * @HB_SCRIPT_WARANG_CITI: `Wara`, Since: 0.9.30 + * @HB_SCRIPT_AHOM: `Ahom`, Since: 0.9.30 + * @HB_SCRIPT_ANATOLIAN_HIEROGLYPHS: `Hluw`, Since: 0.9.30 + * @HB_SCRIPT_HATRAN: `Hatr`, Since: 0.9.30 + * @HB_SCRIPT_MULTANI: `Mult`, Since: 0.9.30 + * @HB_SCRIPT_OLD_HUNGARIAN: `Hung`, Since: 0.9.30 + * @HB_SCRIPT_SIGNWRITING: `Sgnw`, Since: 0.9.30 + * @HB_SCRIPT_ADLAM: `Adlm`, Since: 1.3.0 + * @HB_SCRIPT_BHAIKSUKI: `Bhks`, Since: 1.3.0 + * @HB_SCRIPT_MARCHEN: `Marc`, Since: 1.3.0 + * @HB_SCRIPT_OSAGE: `Osge`, Since: 1.3.0 + * @HB_SCRIPT_TANGUT: `Tang`, Since: 1.3.0 + * @HB_SCRIPT_NEWA: `Newa`, Since: 1.3.0 + * @HB_SCRIPT_MASARAM_GONDI: `Gonm`, Since: 1.6.0 + * @HB_SCRIPT_NUSHU: `Nshu`, Since: 1.6.0 + * @HB_SCRIPT_SOYOMBO: `Soyo`, Since: 1.6.0 + * @HB_SCRIPT_ZANABAZAR_SQUARE: `Zanb`, Since: 1.6.0 + * @HB_SCRIPT_DOGRA: `Dogr`, Since: 1.8.0 + * @HB_SCRIPT_GUNJALA_GONDI: `Gong`, Since: 1.8.0 + * @HB_SCRIPT_HANIFI_ROHINGYA: `Rohg`, Since: 1.8.0 + * @HB_SCRIPT_MAKASAR: `Maka`, Since: 1.8.0 + * @HB_SCRIPT_MEDEFAIDRIN: `Medf`, Since: 1.8.0 + * @HB_SCRIPT_OLD_SOGDIAN: `Sogo`, Since: 1.8.0 + * @HB_SCRIPT_SOGDIAN: `Sogd`, Since: 1.8.0 + * @HB_SCRIPT_ELYMAIC: `Elym`, Since: 2.4.0 + * @HB_SCRIPT_NANDINAGARI: `Nand`, Since: 2.4.0 + * @HB_SCRIPT_NYIAKENG_PUACHUE_HMONG: `Hmnp`, Since: 2.4.0 + * @HB_SCRIPT_WANCHO: `Wcho`, Since: 2.4.0 + * @HB_SCRIPT_CHORASMIAN: `Chrs`, Since: 2.6.7 + * @HB_SCRIPT_DIVES_AKURU: `Diak`, Since: 2.6.7 + * @HB_SCRIPT_KHITAN_SMALL_SCRIPT: `Kits`, Since: 2.6.7 + * @HB_SCRIPT_YEZIDI: `Yezi`, Since: 2.6.7 + * @HB_SCRIPT_CYPRO_MINOAN: `Cpmn`, Since: 3.0.0 + * @HB_SCRIPT_OLD_UYGHUR: `Ougr`, Since: 3.0.0 + * @HB_SCRIPT_TANGSA: `Tnsa`, Since: 3.0.0 + * @HB_SCRIPT_TOTO: `Toto`, Since: 3.0.0 + * @HB_SCRIPT_VITHKUQI: `Vith`, Since: 3.0.0 + * @HB_SCRIPT_MATH: `Zmth`, Since: 3.4.0 + * @HB_SCRIPT_KAWI: `Kawi`, Since: 5.2.0 + * @HB_SCRIPT_NAG_MUNDARI: `Nagm`, Since: 5.2.0 + * @HB_SCRIPT_GARAY: `Gara`, Since: 10.0.0 + * @HB_SCRIPT_GURUNG_KHEMA: `Gukh`, Since: 10.0.0 + * @HB_SCRIPT_KIRAT_RAI: `Krai`, Since: 10.0.0 + * @HB_SCRIPT_OL_ONAL: `Onao`, Since: 10.0.0 + * @HB_SCRIPT_SUNUWAR: `Sunu`, Since: 10.0.0 + * @HB_SCRIPT_TODHRI: `Todr`, Since: 10.0.0 + * @HB_SCRIPT_TULU_TIGALARI: `Tutg`, Since: 10.0.0 + * @HB_SCRIPT_INVALID: No script set + * + * Data type for scripts. Each #hb_script_t's value is an #hb_tag_t corresponding + * to the four-letter values defined by [ISO 15924](https://unicode.org/iso15924/). + * + * See also the Script (sc) property of the Unicode Character Database. + * + **/ + +/* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ +typedef enum +{ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + HB_SCRIPT_CHORASMIAN = HB_TAG ('C','h','r','s'), /*13.0*/ + HB_SCRIPT_DIVES_AKURU = HB_TAG ('D','i','a','k'), /*13.0*/ + HB_SCRIPT_KHITAN_SMALL_SCRIPT = HB_TAG ('K','i','t','s'), /*13.0*/ + HB_SCRIPT_YEZIDI = HB_TAG ('Y','e','z','i'), /*13.0*/ + + /* + * Since 3.0.0 + */ + HB_SCRIPT_CYPRO_MINOAN = HB_TAG ('C','p','m','n'), /*14.0*/ + HB_SCRIPT_OLD_UYGHUR = HB_TAG ('O','u','g','r'), /*14.0*/ + HB_SCRIPT_TANGSA = HB_TAG ('T','n','s','a'), /*14.0*/ + HB_SCRIPT_TOTO = HB_TAG ('T','o','t','o'), /*14.0*/ + HB_SCRIPT_VITHKUQI = HB_TAG ('V','i','t','h'), /*14.0*/ + + /* + * Since 3.4.0 + */ + HB_SCRIPT_MATH = HB_TAG ('Z','m','t','h'), + + /* + * Since 5.2.0 + */ + HB_SCRIPT_KAWI = HB_TAG ('K','a','w','i'), /*15.0*/ + HB_SCRIPT_NAG_MUNDARI = HB_TAG ('N','a','g','m'), /*15.0*/ + + /* + * Since 10.0.0 + */ + HB_SCRIPT_GARAY = HB_TAG ('G','a','r','a'), /*16.0*/ + HB_SCRIPT_GURUNG_KHEMA = HB_TAG ('G','u','k','h'), /*16.0*/ + HB_SCRIPT_KIRAT_RAI = HB_TAG ('K','r','a','i'), /*16.0*/ + HB_SCRIPT_OL_ONAL = HB_TAG ('O','n','a','o'), /*16.0*/ + HB_SCRIPT_SUNUWAR = HB_TAG ('S','u','n','u'), /*16.0*/ + HB_SCRIPT_TODHRI = HB_TAG ('T','o','d','r'), /*16.0*/ + HB_SCRIPT_TULU_TIGALARI = HB_TAG ('T','u','t','g'), /*16.0*/ + + /* No script set. */ + 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. + * HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed + * to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well. + * + * See this thread for technicalities: + * + * https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html + */ + _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/ + _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/ + +} hb_script_t; + + +#endif /* HB_SCRIPT_LIST_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh index 0d05e72c1cd..d696f1b654b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh @@ -31,11 +31,10 @@ #include "hb-machinery.hh" /* - * The set-digests here implement various "filters" that support - * "approximate member query". Conceptually these are like Bloom - * Filter and Quotient Filter, however, much smaller, faster, and - * designed to fit the requirements of our uses for glyph coverage - * queries. + * The set-digests implement "filters" that support "approximate + * member query". Conceptually these are like Bloom Filter and + * Quotient Filter, however, much smaller, faster, and designed + * to fit the requirements of our uses for glyph coverage queries. * * Our filters are highly accurate if the lookup covers fairly local * set of glyphs, but fully flooded and ineffective if coverage is diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc index 2f0b54f474b..a3c3b929562 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc @@ -868,7 +868,7 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, src = hb_utf8_t::next (src, src_end, &unicode, replacement); if (unicode >= 0x0080u) { - printf ("Non-ascii character detected, ignored...This API supports ascii characters only for mac platform\n"); + // Non-ascii character detected, ignored... return false; } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-layout.cc new file mode 100644 index 00000000000..aa2807b6979 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-layout.cc @@ -0,0 +1,382 @@ +/* + * Copyright © 2023 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Qunxin Liu, Roderick Sheeter + */ + +#include "hb-subset-plan.hh" + +#include "hb-ot-layout-gdef-table.hh" +#include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-layout-gsub-table.hh" + +using OT::Layout::GSUB; +using OT::Layout::GPOS; + +#ifndef HB_NO_SUBSET_LAYOUT + +void +remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map) +{ + hb_blob_ptr_t gdef = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) + { + gdef.destroy (); + return; + } + + hb_set_t used_mark_sets; + gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); + gdef.destroy (); + + remap_indexes (&used_mark_sets, &used_mark_sets_map); +} + +/* + * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates. + * Returns true if anything was removed (not including duplicates). + */ +static bool _filter_tag_list(hb_vector_t* tags, /* IN/OUT */ + const hb_set_t* filter) +{ + hb_vector_t out; + out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator. + + bool removed = false; + hb_set_t visited; + + for (hb_tag_t tag : *tags) + { + if (!tag) continue; + if (visited.has (tag)) continue; + + if (!filter->has (tag)) + { + removed = true; + continue; + } + + visited.add (tag); + out.push (tag); + } + + // The collect function needs a null element to signal end of the array. + out.push (HB_TAG_NONE); + + hb_swap (out, *tags); + return removed; +} + +template +static void _collect_layout_indices (hb_subset_plan_t *plan, + const T& table, + hb_set_t *lookup_indices, /* OUT */ + hb_set_t *feature_indices, /* OUT */ + hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ + hb_hashmap_t *feature_substitutes_map, /* OUT */ + hb_set_t& catch_all_record_feature_idxes, /* OUT */ + hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) +{ + unsigned num_features = table.get_feature_count (); + hb_vector_t features; + if (!plan->check_success (features.resize (num_features))) return; + table.get_feature_tags (0, &num_features, features.arrayZ); + bool retain_all_features = !_filter_tag_list (&features, &plan->layout_features); + + unsigned num_scripts = table.get_script_count (); + hb_vector_t scripts; + if (!plan->check_success (scripts.resize (num_scripts))) return; + table.get_script_tags (0, &num_scripts, scripts.arrayZ); + bool retain_all_scripts = !_filter_tag_list (&scripts, &plan->layout_scripts); + + if (!plan->check_success (!features.in_error ()) || !features + || !plan->check_success (!scripts.in_error ()) || !scripts) + return; + + hb_ot_layout_collect_features (plan->source, + T::tableTag, + retain_all_scripts ? nullptr : scripts.arrayZ, + nullptr, + retain_all_features ? nullptr : features.arrayZ, + feature_indices); + +#ifndef HB_NO_VAR + // collect feature substitutes with variations + if (!plan->user_axes_location.is_empty ()) + { + hb_hashmap_t, unsigned> conditionset_map; + OT::hb_collect_feature_substitutes_with_var_context_t c = + { + &plan->axes_old_index_tag_map, + &plan->axes_location, + feature_record_cond_idx_map, + feature_substitutes_map, + catch_all_record_feature_idxes, + feature_indices, + false, + false, + false, + 0, + &conditionset_map + }; + table.collect_feature_substitutes_with_variations (&c); + } +#endif + + for (unsigned feature_index : *feature_indices) + { + const OT::Feature* f = &(table.get_feature (feature_index)); + const OT::Feature **p = nullptr; + if (feature_substitutes_map->has (feature_index, &p)) + f = *p; + + f->add_lookup_indexes_to (lookup_indices); + } + +#ifndef HB_NO_VAR + if (catch_all_record_feature_idxes) + { + for (unsigned feature_index : catch_all_record_feature_idxes) + { + const OT::Feature& f = table.get_feature (feature_index); + f.add_lookup_indexes_to (lookup_indices); + const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); + catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); + } + } + + // If all axes are pinned then all feature variations will be dropped so there's no need + // to collect lookups from them. + if (!plan->all_axes_pinned) + table.feature_variation_collect_lookups (feature_indices, + plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, + lookup_indices); +#endif +} + + +static inline void +_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, + const hb_map_t *lookup_indices, + const hb_set_t *feature_indices, + const hb_hashmap_t *feature_substitutes_map, + hb_map_t *duplicate_feature_map /* OUT */) +{ + if (feature_indices->is_empty ()) return; + hb_hashmap_t> unique_features; + //find out duplicate features after subset + for (unsigned i : feature_indices->iter ()) + { + hb_tag_t t = g.get_feature_tag (i); + if (t == HB_MAP_VALUE_INVALID) continue; + if (!unique_features.has (t)) + { + if (unlikely (!unique_features.set (t, hb::unique_ptr {hb_set_create ()}))) + return; + if (unique_features.has (t)) + unique_features.get (t)->add (i); + duplicate_feature_map->set (i, i); + continue; + } + + bool found = false; + + hb_set_t* same_tag_features = unique_features.get (t); + for (unsigned other_f_index : same_tag_features->iter ()) + { + const OT::Feature* f = &(g.get_feature (i)); + const OT::Feature **p = nullptr; + if (feature_substitutes_map->has (i, &p)) + f = *p; + + const OT::Feature* other_f = &(g.get_feature (other_f_index)); + if (feature_substitutes_map->has (other_f_index, &p)) + other_f = *p; + + auto f_iter = + + hb_iter (f->lookupIndex) + | hb_filter (lookup_indices) + ; + + auto other_f_iter = + + hb_iter (other_f->lookupIndex) + | hb_filter (lookup_indices) + ; + + bool is_equal = true; + for (; f_iter && other_f_iter; f_iter++, other_f_iter++) + { + unsigned a = *f_iter; + unsigned b = *other_f_iter; + if (a != b) { is_equal = false; break; } + } + + if (is_equal == false || f_iter || other_f_iter) continue; + + found = true; + duplicate_feature_map->set (i, other_f_index); + break; + } + + if (found == false) + { + same_tag_features->add (i); + duplicate_feature_map->set (i, i); + } + } +} + +template +static void +_closure_glyphs_lookups_features (hb_subset_plan_t *plan, + hb_set_t *gids_to_retain, + hb_map_t *lookups, + hb_map_t *features, + script_langsys_map *langsys_map, + hb_hashmap_t> *feature_record_cond_idx_map, + hb_hashmap_t *feature_substitutes_map, + hb_set_t &catch_all_record_feature_idxes, + hb_hashmap_t>& catch_all_record_idx_feature_map) +{ + hb_blob_ptr_t table = plan->source_table (); + hb_tag_t table_tag = table->tableTag; + hb_set_t lookup_indices, feature_indices; + _collect_layout_indices (plan, + *table, + &lookup_indices, + &feature_indices, + feature_record_cond_idx_map, + feature_substitutes_map, + catch_all_record_feature_idxes, + catch_all_record_idx_feature_map); + + if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) + hb_ot_layout_lookups_substitute_closure (plan->source, + &lookup_indices, + gids_to_retain); + table->closure_lookups (plan->source, + gids_to_retain, + &lookup_indices); + remap_indexes (&lookup_indices, lookups); + + // prune features + table->prune_features (lookups, + plan->user_axes_location.is_empty () ? nullptr : feature_record_cond_idx_map, + feature_substitutes_map, + &feature_indices); + hb_map_t duplicate_feature_map; + _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map); + + feature_indices.clear (); + table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices); + remap_indexes (&feature_indices, features); + + table.destroy (); +} + +void layout_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables) +{ + if (!drop_tables->has (HB_OT_TAG_GPOS)) + { + hb_blob_ptr_t gpos = plan->source_table (); + gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); + gpos.destroy (); + } + if (!drop_tables->has (HB_OT_TAG_GSUB)) + { + hb_blob_ptr_t gsub = plan->source_table (); + gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); + gsub.destroy (); + } +} + +void +layout_populate_gids_to_retain (hb_subset_plan_t* plan, + hb_set_t* drop_tables) { + if (!drop_tables->has (HB_OT_TAG_GSUB)) + // closure all glyphs/lookups/features needed for GSUB substitutions. + _closure_glyphs_lookups_features ( + plan, + &plan->_glyphset_gsub, + &plan->gsub_lookups, + &plan->gsub_features, + &plan->gsub_langsys, + &plan->gsub_feature_record_cond_idx_map, + &plan->gsub_feature_substitutes_map, + plan->gsub_old_features, + plan->gsub_old_feature_idx_tag_map); + + if (!drop_tables->has (HB_OT_TAG_GPOS)) + _closure_glyphs_lookups_features ( + plan, + &plan->_glyphset_gsub, + &plan->gpos_lookups, + &plan->gpos_features, + &plan->gpos_langsys, + &plan->gpos_feature_record_cond_idx_map, + &plan->gpos_feature_substitutes_map, + plan->gpos_old_features, + plan->gpos_old_feature_idx_tag_map); +} + +#ifndef HB_NO_VAR +void +collect_layout_variation_indices (hb_subset_plan_t* plan) +{ + hb_blob_ptr_t gdef = plan->source_table (); + hb_blob_ptr_t gpos = plan->source_table (); + + if (!gdef->has_data () || !gdef->has_var_store ()) + { + gdef.destroy (); + gpos.destroy (); + return; + } + + hb_set_t varidx_set; + OT::hb_collect_variation_indices_context_t c (&varidx_set, + &plan->_glyphset_gsub, + &plan->gpos_lookups); + gdef->collect_variation_indices (&c); + + if (hb_ot_layout_has_positioning (plan->source)) + gpos->collect_variation_indices (&c); + + remap_variation_indices (gdef->get_var_store (), + varidx_set, plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->layout_variation_idx_delta_map); + + unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); + generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); + + gdef.destroy (); + gpos.destroy (); +} +#endif + +#endif \ No newline at end of file diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-var.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-var.cc new file mode 100644 index 00000000000..0515b42b2e0 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-var.cc @@ -0,0 +1,388 @@ +/* + * Copyright © 2023 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Qunxin Liu, Roderick Sheeter + */ + + #include "hb-ot-layout-common.hh" +#include "hb-subset-plan.hh" + + #include "hb-ot-var-common.hh" + #include "hb-ot-layout-base-table.hh" + #include "hb-ot-glyf-table.hh" + #include "hb-ot-var-fvar-table.hh" + #include "hb-ot-var-avar-table.hh" + #include "hb-ot-cff2-table.hh" + + #ifndef HB_NO_VAR + + void + generate_varstore_inner_maps (const hb_set_t& varidx_set, + unsigned subtable_count, + hb_vector_t &inner_maps /* OUT */) + { + if (varidx_set.is_empty () || subtable_count == 0) return; + + if (unlikely (!inner_maps.resize (subtable_count))) return; + for (unsigned idx : varidx_set) + { + uint16_t major = idx >> 16; + uint16_t minor = idx & 0xFFFF; + + if (major >= subtable_count) + continue; + inner_maps[major].add (minor); + } + } + + static inline hb_font_t* + _get_hb_font_with_variations (const hb_subset_plan_t *plan) + { + hb_font_t *font = hb_font_create (plan->source); + + hb_vector_t vars; + if (!vars.alloc (plan->user_axes_location.get_population ())) { + hb_font_destroy (font); + return nullptr; + } + + for (auto _ : plan->user_axes_location) + { + hb_variation_t var; + var.tag = _.first; + var.value = _.second.middle; + vars.push (var); + } + + hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); + return font; + } + + template + void + remap_variation_indices (const ItemVarStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */) + { + if (&var_store == &Null (OT::ItemVariationStore)) return; + unsigned subtable_count = var_store.get_sub_table_count (); + auto *store_cache = var_store.create_cache (); + + unsigned new_major = 0, new_minor = 0; + unsigned last_major = (variation_indices.get_min ()) >> 16; + for (unsigned idx : variation_indices) + { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + + uint16_t major = idx >> 16; + if (major >= subtable_count) break; + if (major != last_major) + { + new_minor = 0; + ++new_major; + } + + unsigned new_idx = (new_major << 16) + new_minor; + variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); + ++new_minor; + last_major = major; + } + var_store.destroy_cache (store_cache); + } + + template + void + remap_variation_indices (const OT::ItemVariationStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */); + + #ifndef HB_NO_BASE + void + collect_base_variation_indices (hb_subset_plan_t* plan) + { + hb_blob_ptr_t base = plan->source_table (); + if (!base->has_var_store ()) + { + base.destroy (); + return; + } + + hb_set_t varidx_set; + base->collect_variation_indices (plan, varidx_set); + const OT::ItemVariationStore &var_store = base->get_var_store (); + unsigned subtable_count = var_store.get_sub_table_count (); + + + remap_variation_indices (var_store, varidx_set, + plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + plan->base_variation_idx_map); + generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); + + base.destroy (); + } + + #endif + +void +normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) +{ + if (plan->user_axes_location.is_empty ()) + return; + + hb_array_t axes = face->table.fvar->get_axes (); + plan->normalized_coords.resize (axes.length); + + bool has_avar = face->table.avar->has_data (); + const OT::SegmentMaps *seg_maps = nullptr; + unsigned avar_axis_count = 0; + if (has_avar) + { + seg_maps = face->table.avar->get_segment_maps (); + avar_axis_count = face->table.avar->get_axis_count(); + } + + bool axis_not_pinned = false; + unsigned old_axis_idx = 0, new_axis_idx = 0; + for (const auto& axis : axes) + { + hb_tag_t axis_tag = axis.get_axis_tag (); + plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag); + + if (!plan->user_axes_location.has (axis_tag) || + !plan->user_axes_location.get (axis_tag).is_point ()) + { + axis_not_pinned = true; + plan->axes_index_map.set (old_axis_idx, new_axis_idx); + plan->axis_tags.push (axis_tag); + new_axis_idx++; + } + + Triple *axis_range; + if (plan->user_axes_location.has (axis_tag, &axis_range)) + { + plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ()); + + int normalized_min = axis.normalize_axis_value (axis_range->minimum); + int normalized_default = axis.normalize_axis_value (axis_range->middle); + int normalized_max = axis.normalize_axis_value (axis_range->maximum); + + if (has_avar && old_axis_idx < avar_axis_count) + { + normalized_min = seg_maps->map (normalized_min); + normalized_default = seg_maps->map (normalized_default); + normalized_max = seg_maps->map (normalized_max); + } + plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.0), + static_cast (normalized_default / 16384.0), + static_cast (normalized_max / 16384.0))); + + if (normalized_default != 0) + plan->pinned_at_default = false; + + plan->normalized_coords[old_axis_idx] = normalized_default; + } + + old_axis_idx++; + + if (has_avar && old_axis_idx < avar_axis_count) + seg_maps = &StructAfter (*seg_maps); + } + plan->all_axes_pinned = !axis_not_pinned; +} + +void +update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) +{ + if (!plan->normalized_coords) return; + OT::cff2::accelerator_t cff2 (plan->source); + if (!cff2.is_valid ()) return; + + hb_font_t *font = _get_hb_font_with_variations (plan); + if (unlikely (!plan->check_success (font != nullptr))) + { + hb_font_destroy (font); + return; + } + + hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; + OT::hmtx_accelerator_t _hmtx (plan->source); + OT::ItemVariationStore::cache_t *hvar_store_cache = nullptr; + if (_hmtx.has_data () && _hmtx.var_table.get_length ()) + hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); + + OT::vmtx_accelerator_t _vmtx (plan->source); + OT::ItemVariationStore::cache_t *vvar_store_cache = nullptr; + if (_vmtx.has_data () && _vmtx.var_table.get_length ()) + vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); + + for (auto p : *plan->glyph_map) + { + hb_codepoint_t old_gid = p.first; + hb_codepoint_t new_gid = p.second; + if (!cff2.get_extents (font, old_gid, &extents)) continue; + bool has_bounds_info = true; + if (extents.x_bearing == 0 && extents.width == 0 && + extents.height == 0 && extents.y_bearing == 0) + has_bounds_info = false; + + if (has_bounds_info) + { + plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing); + plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width); + plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing); + plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height); + } + + if (_hmtx.has_data ()) + { + int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid); + if (_hmtx.var_table.get_length ()) + hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, + hvar_store_cache)); + int lsb = extents.x_bearing; + if (!has_bounds_info) + { + if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) + continue; + } + plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); + plan->bounds_width_vec[new_gid] = extents.width; + } + + if (_vmtx.has_data ()) + { + int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid); + if (_vmtx.var_table.get_length ()) + vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, + vvar_store_cache)); + + int tsb = extents.y_bearing; + if (!has_bounds_info) + { + if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb)) + continue; + } + plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); + plan->bounds_height_vec[new_gid] = extents.height; + } + } + hb_font_destroy (font); + if (hvar_store_cache) + _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache); + if (vvar_store_cache) + _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); +} + +bool +get_instance_glyphs_contour_points (hb_subset_plan_t *plan) +{ + /* contour_points vector only needed for updating gvar table (infer delta and + * iup delta optimization) during partial instancing */ + if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) + return true; + + OT::glyf_accelerator_t glyf (plan->source); + + for (auto &_ : plan->new_to_old_gid_list) + { + hb_codepoint_t new_gid = _.first; + contour_point_vector_t all_points; + if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + continue; + } + + hb_codepoint_t old_gid = _.second; + auto glyph = glyf.glyph_for_gid (old_gid); + if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) + return false; + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + + /* composite new gids are only needed by iup delta optimization */ + if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) + plan->composite_new_gids.add (new_gid); + } + return true; +} + +template +void +remap_colrv1_delta_set_index_indices (const DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */) +{ + if (!index_map.get_map_count ()) + return; + + hb_hashmap_t> delta_set_idx_delta_map; + unsigned new_delta_set_idx = 0; + for (unsigned delta_set_idx : delta_set_idxes) + { + unsigned var_idx = index_map.map (delta_set_idx); + unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + int delta = 0; + + if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) + { + hb_pair_t *new_varidx_delta; + if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; + + new_varidx = hb_first (*new_varidx_delta); + delta = hb_second (*new_varidx_delta); + } + + new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); + delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); + new_delta_set_idx++; + } + variation_idx_delta_map = std::move (delta_set_idx_delta_map); +} + +template void +remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */); + + #endif \ No newline at end of file diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc index c88fd75a543..a56965246ce 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc @@ -29,27 +29,21 @@ #include "hb-map.hh" #include "hb-multimap.hh" #include "hb-set.hh" +#include "hb-subset.h" +#include "hb-unicode.h" #include "hb-ot-cmap-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-layout-base-table.hh" -#include "hb-ot-layout-gdef-table.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-layout-gsub-table.hh" #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "OT/Color/COLR/COLR.hh" #include "OT/Color/COLR/colrv1-closure.hh" #include "OT/Color/CPAL/CPAL.hh" #include "hb-ot-var-fvar-table.hh" -#include "hb-ot-var-avar-table.hh" #include "hb-ot-stat-table.hh" #include "hb-ot-math-table.hh" -using OT::Layout::GSUB; -using OT::Layout::GPOS; - - hb_subset_accelerator_t::~hb_subset_accelerator_t () { if (cmap_cache && destroy_cmap_cache) @@ -63,7 +57,6 @@ hb_subset_accelerator_t::~hb_subset_accelerator_t () } -typedef hb_hashmap_t> script_langsys_map; #ifndef HB_NO_SUBSET_CFF static inline bool _add_cff_seac_components (const OT::cff1::accelerator_subset_t &cff, @@ -98,414 +91,14 @@ _remap_palette_indexes (const hb_set_t *palette_indexes, } } -static void -_remap_indexes (const hb_set_t *indexes, - hb_map_t *mapping /* OUT */) +void +remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */) { for (auto _ : + hb_enumerate (indexes->iter ())) mapping->set (_.second, _.first); - } -#ifndef HB_NO_SUBSET_LAYOUT - -/* - * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates. - * Returns true if anything was removed (not including duplicates). - */ -static bool _filter_tag_list(hb_vector_t* tags, /* IN/OUT */ - const hb_set_t* filter) -{ - hb_vector_t out; - out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator. - - bool removed = false; - hb_set_t visited; - - for (hb_tag_t tag : *tags) - { - if (!tag) continue; - if (visited.has (tag)) continue; - - if (!filter->has (tag)) - { - removed = true; - continue; - } - - visited.add (tag); - out.push (tag); - } - - // The collect function needs a null element to signal end of the array. - out.push (HB_TAG_NONE); - - hb_swap (out, *tags); - return removed; -} - -template -static void _collect_layout_indices (hb_subset_plan_t *plan, - const T& table, - hb_set_t *lookup_indices, /* OUT */ - hb_set_t *feature_indices, /* OUT */ - hb_hashmap_t> *feature_record_cond_idx_map, /* OUT */ - hb_hashmap_t *feature_substitutes_map, /* OUT */ - hb_set_t& catch_all_record_feature_idxes, /* OUT */ - hb_hashmap_t>& catch_all_record_idx_feature_map /* OUT */) -{ - unsigned num_features = table.get_feature_count (); - hb_vector_t features; - if (!plan->check_success (features.resize (num_features))) return; - table.get_feature_tags (0, &num_features, features.arrayZ); - bool retain_all_features = !_filter_tag_list (&features, &plan->layout_features); - - unsigned num_scripts = table.get_script_count (); - hb_vector_t scripts; - if (!plan->check_success (scripts.resize (num_scripts))) return; - table.get_script_tags (0, &num_scripts, scripts.arrayZ); - bool retain_all_scripts = !_filter_tag_list (&scripts, &plan->layout_scripts); - - if (!plan->check_success (!features.in_error ()) || !features - || !plan->check_success (!scripts.in_error ()) || !scripts) - return; - - hb_ot_layout_collect_features (plan->source, - T::tableTag, - retain_all_scripts ? nullptr : scripts.arrayZ, - nullptr, - retain_all_features ? nullptr : features.arrayZ, - feature_indices); - -#ifndef HB_NO_VAR - // collect feature substitutes with variations - if (!plan->user_axes_location.is_empty ()) - { - hb_hashmap_t, unsigned> conditionset_map; - OT::hb_collect_feature_substitutes_with_var_context_t c = - { - &plan->axes_old_index_tag_map, - &plan->axes_location, - feature_record_cond_idx_map, - feature_substitutes_map, - catch_all_record_feature_idxes, - feature_indices, - false, - false, - false, - 0, - &conditionset_map - }; - table.collect_feature_substitutes_with_variations (&c); - } -#endif - - for (unsigned feature_index : *feature_indices) - { - const OT::Feature* f = &(table.get_feature (feature_index)); - const OT::Feature **p = nullptr; - if (feature_substitutes_map->has (feature_index, &p)) - f = *p; - - f->add_lookup_indexes_to (lookup_indices); - } - -#ifndef HB_NO_VAR - if (catch_all_record_feature_idxes) - { - for (unsigned feature_index : catch_all_record_feature_idxes) - { - const OT::Feature& f = table.get_feature (feature_index); - f.add_lookup_indexes_to (lookup_indices); - const void *tag = reinterpret_cast (&(table.get_feature_list ().get_tag (feature_index))); - catch_all_record_idx_feature_map.set (feature_index, hb_pair (&f, tag)); - } - } - - // If all axes are pinned then all feature variations will be dropped so there's no need - // to collect lookups from them. - if (!plan->all_axes_pinned) - table.feature_variation_collect_lookups (feature_indices, - plan->user_axes_location.is_empty () ? nullptr: feature_record_cond_idx_map, - lookup_indices); -#endif -} - - -static inline void -_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, - const hb_map_t *lookup_indices, - const hb_set_t *feature_indices, - const hb_hashmap_t *feature_substitutes_map, - hb_map_t *duplicate_feature_map /* OUT */) -{ - if (feature_indices->is_empty ()) return; - hb_hashmap_t> unique_features; - //find out duplicate features after subset - for (unsigned i : feature_indices->iter ()) - { - hb_tag_t t = g.get_feature_tag (i); - if (t == HB_MAP_VALUE_INVALID) continue; - if (!unique_features.has (t)) - { - if (unlikely (!unique_features.set (t, hb::unique_ptr {hb_set_create ()}))) - return; - if (unique_features.has (t)) - unique_features.get (t)->add (i); - duplicate_feature_map->set (i, i); - continue; - } - - bool found = false; - - hb_set_t* same_tag_features = unique_features.get (t); - for (unsigned other_f_index : same_tag_features->iter ()) - { - const OT::Feature* f = &(g.get_feature (i)); - const OT::Feature **p = nullptr; - if (feature_substitutes_map->has (i, &p)) - f = *p; - - const OT::Feature* other_f = &(g.get_feature (other_f_index)); - if (feature_substitutes_map->has (other_f_index, &p)) - other_f = *p; - - auto f_iter = - + hb_iter (f->lookupIndex) - | hb_filter (lookup_indices) - ; - - auto other_f_iter = - + hb_iter (other_f->lookupIndex) - | hb_filter (lookup_indices) - ; - - bool is_equal = true; - for (; f_iter && other_f_iter; f_iter++, other_f_iter++) - { - unsigned a = *f_iter; - unsigned b = *other_f_iter; - if (a != b) { is_equal = false; break; } - } - - if (is_equal == false || f_iter || other_f_iter) continue; - - found = true; - duplicate_feature_map->set (i, other_f_index); - break; - } - - if (found == false) - { - same_tag_features->add (i); - duplicate_feature_map->set (i, i); - } - } -} - -template -static inline void -_closure_glyphs_lookups_features (hb_subset_plan_t *plan, - hb_set_t *gids_to_retain, - hb_map_t *lookups, - hb_map_t *features, - script_langsys_map *langsys_map, - hb_hashmap_t> *feature_record_cond_idx_map, - hb_hashmap_t *feature_substitutes_map, - hb_set_t &catch_all_record_feature_idxes, - hb_hashmap_t>& catch_all_record_idx_feature_map) -{ - hb_blob_ptr_t table = plan->source_table (); - hb_tag_t table_tag = table->tableTag; - hb_set_t lookup_indices, feature_indices; - _collect_layout_indices (plan, - *table, - &lookup_indices, - &feature_indices, - feature_record_cond_idx_map, - feature_substitutes_map, - catch_all_record_feature_idxes, - catch_all_record_idx_feature_map); - - if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE)) - hb_ot_layout_lookups_substitute_closure (plan->source, - &lookup_indices, - gids_to_retain); - table->closure_lookups (plan->source, - gids_to_retain, - &lookup_indices); - _remap_indexes (&lookup_indices, lookups); - - // prune features - table->prune_features (lookups, - plan->user_axes_location.is_empty () ? nullptr : feature_record_cond_idx_map, - feature_substitutes_map, - &feature_indices); - hb_map_t duplicate_feature_map; - _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map); - - feature_indices.clear (); - table->prune_langsys (&duplicate_feature_map, &plan->layout_scripts, langsys_map, &feature_indices); - _remap_indexes (&feature_indices, features); - - table.destroy (); -} - -#endif - -#ifndef HB_NO_VAR -static inline void -_generate_varstore_inner_maps (const hb_set_t& varidx_set, - unsigned subtable_count, - hb_vector_t &inner_maps /* OUT */) -{ - if (varidx_set.is_empty () || subtable_count == 0) return; - - if (unlikely (!inner_maps.resize (subtable_count))) return; - for (unsigned idx : varidx_set) - { - uint16_t major = idx >> 16; - uint16_t minor = idx & 0xFFFF; - - if (major >= subtable_count) - continue; - inner_maps[major].add (minor); - } -} - -static inline hb_font_t* -_get_hb_font_with_variations (const hb_subset_plan_t *plan) -{ - hb_font_t *font = hb_font_create (plan->source); - - hb_vector_t vars; - if (!vars.alloc (plan->user_axes_location.get_population ())) { - hb_font_destroy (font); - return nullptr; - } - - for (auto _ : plan->user_axes_location) - { - hb_variation_t var; - var.tag = _.first; - var.value = _.second.middle; - vars.push (var); - } - -#ifndef HB_NO_VAR - hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ()); -#endif - return font; -} - -static inline void -_remap_variation_indices (const OT::ItemVariationStore &var_store, - const hb_set_t &variation_indices, - const hb_vector_t& normalized_coords, - bool calculate_delta, /* not pinned at default */ - bool no_variations, /* all axes pinned */ - hb_hashmap_t> &variation_idx_delta_map /* OUT */) -{ - if (&var_store == &Null (OT::ItemVariationStore)) return; - unsigned subtable_count = var_store.get_sub_table_count (); - float *store_cache = var_store.create_cache (); - - unsigned new_major = 0, new_minor = 0; - unsigned last_major = (variation_indices.get_min ()) >> 16; - for (unsigned idx : variation_indices) - { - int delta = 0; - if (calculate_delta) - delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, - normalized_coords.length, store_cache)); - - if (no_variations) - { - variation_idx_delta_map.set (idx, hb_pair_t (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - continue; - } - - uint16_t major = idx >> 16; - if (major >= subtable_count) break; - if (major != last_major) - { - new_minor = 0; - ++new_major; - } - - unsigned new_idx = (new_major << 16) + new_minor; - variation_idx_delta_map.set (idx, hb_pair_t (new_idx, delta)); - ++new_minor; - last_major = major; - } - var_store.destroy_cache (store_cache); -} - -static inline void -_collect_layout_variation_indices (hb_subset_plan_t* plan) -{ - hb_blob_ptr_t gdef = plan->source_table (); - hb_blob_ptr_t gpos = plan->source_table (); - - if (!gdef->has_data () || !gdef->has_var_store ()) - { - gdef.destroy (); - gpos.destroy (); - return; - } - - hb_set_t varidx_set; - OT::hb_collect_variation_indices_context_t c (&varidx_set, - &plan->_glyphset_gsub, - &plan->gpos_lookups); - gdef->collect_variation_indices (&c); - - if (hb_ot_layout_has_positioning (plan->source)) - gpos->collect_variation_indices (&c); - - _remap_variation_indices (gdef->get_var_store (), - varidx_set, plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - plan->layout_variation_idx_delta_map); - - unsigned subtable_count = gdef->get_var_store ().get_sub_table_count (); - _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); - - gdef.destroy (); - gpos.destroy (); -} - -#ifndef HB_NO_BASE -static inline void -_collect_base_variation_indices (hb_subset_plan_t* plan) -{ - hb_blob_ptr_t base = plan->source_table (); - if (!base->has_var_store ()) - { - base.destroy (); - return; - } - - hb_set_t varidx_set; - base->collect_variation_indices (plan, varidx_set); - const OT::ItemVariationStore &var_store = base->get_var_store (); - unsigned subtable_count = var_store.get_sub_table_count (); - - - _remap_variation_indices (var_store, varidx_set, - plan->normalized_coords, - !plan->pinned_at_default, - plan->all_axes_pinned, - plan->base_variation_idx_map); - _generate_varstore_inner_maps (varidx_set, subtable_count, plan->base_varstore_inner_maps); - - base.destroy (); -} - -#endif -#endif - static inline void _cmap_closure (hb_face_t *face, const hb_set_t *unicodes, @@ -515,41 +108,6 @@ _cmap_closure (hb_face_t *face, cmap.table->closure_glyphs (unicodes, glyphset); } -#ifndef HB_NO_VAR -static void -_remap_colrv1_delta_set_index_indices (const OT::DeltaSetIndexMap &index_map, - const hb_set_t &delta_set_idxes, - hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ - hb_map_t &new_deltaset_idx_varidx_map /* OUT */) -{ - if (!index_map.get_map_count ()) - return; - - hb_hashmap_t> delta_set_idx_delta_map; - unsigned new_delta_set_idx = 0; - for (unsigned delta_set_idx : delta_set_idxes) - { - unsigned var_idx = index_map.map (delta_set_idx); - unsigned new_varidx = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - int delta = 0; - - if (var_idx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) - { - hb_pair_t *new_varidx_delta; - if (!variation_idx_delta_map.has (var_idx, &new_varidx_delta)) continue; - - new_varidx = hb_first (*new_varidx_delta); - delta = hb_second (*new_varidx_delta); - } - - new_deltaset_idx_varidx_map.set (new_delta_set_idx, new_varidx); - delta_set_idx_delta_map.set (delta_set_idx, hb_pair_t (new_delta_set_idx, delta)); - new_delta_set_idx++; - } - variation_idx_delta_map = std::move (delta_set_idx_delta_map); -} -#endif - static void _colr_closure (hb_subset_plan_t* plan, hb_set_t *glyphs_colred) { @@ -569,7 +127,7 @@ static void _colr_closure (hb_subset_plan_t* plan, colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices, &variation_indices, &delta_set_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); - _remap_indexes (&layer_indices, &plan->colrv1_layers); + remap_indexes (&layer_indices, &plan->colrv1_layers); _remap_palette_indexes (&palette_indices, &plan->colr_palettes); #ifndef HB_NO_VAR @@ -578,7 +136,7 @@ static void _colr_closure (hb_subset_plan_t* plan, const OT::ItemVariationStore &var_store = colr.get_var_store (); // generated inner_maps is used by ItemVariationStore serialize(), which is subset only unsigned subtable_count = var_store.get_sub_table_count (); - _generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); + generate_varstore_inner_maps (variation_indices, subtable_count, plan->colrv1_varstore_inner_maps); /* colr variation indices mapping during planning phase: * generate colrv1_variation_idx_delta_map. When delta set index map is not @@ -590,7 +148,7 @@ static void _colr_closure (hb_subset_plan_t* plan, * instancing. */ if (!plan->all_axes_pinned) { - _remap_variation_indices (var_store, + remap_variation_indices (var_store, variation_indices, plan->normalized_coords, false, /* no need to calculate delta for COLR during planning */ @@ -598,7 +156,7 @@ static void _colr_closure (hb_subset_plan_t* plan, plan->colrv1_variation_idx_delta_map); if (colr.has_delta_set_index_map ()) - _remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), + remap_colrv1_delta_set_index_indices (colr.get_delta_set_index_map (), delta_set_indices, plan->colrv1_variation_idx_delta_map, plan->colrv1_new_deltaset_idx_varidx_map); @@ -616,25 +174,6 @@ _math_closure (hb_subset_plan_t *plan, math.destroy (); } -static inline void -_remap_used_mark_sets (hb_subset_plan_t *plan, - hb_map_t& used_mark_sets_map) -{ - hb_blob_ptr_t gdef = plan->source_table (); - - if (!gdef->has_data () || !gdef->has_mark_glyph_sets ()) - { - gdef.destroy (); - return; - } - - hb_set_t used_mark_sets; - gdef->get_mark_glyph_sets ().collect_used_mark_sets (plan->_glyphset_gsub, used_mark_sets); - gdef.destroy (); - - _remap_indexes (&used_mark_sets, &used_mark_sets_map); -} - static inline void _remove_invalid_gids (hb_set_t *glyphs, unsigned int num_glyphs) @@ -672,15 +211,46 @@ _fill_unicode_and_glyph_map(hb_subset_plan_t *plan, _fill_unicode_and_glyph_map(plan, unicode_iterator, unicode_to_gid_for_iterator, unicode_to_gid_for_iterator); } +/* + * Finds additional unicode codepoints which are reachable from the input unicode set. + * Currently this adds in mirrored variants (needed for bidi) of any input unicodes. + */ +static hb_set_t +_unicode_closure (const hb_set_t* unicodes, bool bidi_closure) { + // TODO: we may want to also consider pulling in reachable unicode composition and decompositions. + // see: https://github.com/harfbuzz/harfbuzz/issues/2283 + hb_set_t out = *unicodes; + if (!bidi_closure) return out; + + if (out.is_inverted()) { + // don't closure inverted sets, they are asking to specifically exclude certain codepoints. + // otherwise everything is already included. + return out; + } + + auto unicode_funcs = hb_unicode_funcs_get_default (); + for (hb_codepoint_t cp : *unicodes) { + hb_codepoint_t mirror = hb_unicode_mirroring(unicode_funcs, cp); + if (unlikely (mirror != cp)) { + out.add(mirror); + } + } + + return out; +} + static void -_populate_unicodes_to_retain (const hb_set_t *unicodes, +_populate_unicodes_to_retain (const hb_set_t *unicodes_in, const hb_set_t *glyphs, hb_subset_plan_t *plan) { + hb_set_t unicodes = _unicode_closure(unicodes_in, + !(plan->flags & HB_SUBSET_FLAGS_NO_BIDI_CLOSURE)); + OT::cmap::accelerator_t cmap (plan->source); unsigned size_threshold = plan->source->get_num_glyphs (); - if (glyphs->is_empty () && unicodes->get_population () < size_threshold) + if (glyphs->is_empty () && unicodes.get_population () < size_threshold) { const hb_map_t* unicode_to_gid = nullptr; @@ -690,9 +260,9 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // This is approach to collection is faster, but can only be used if glyphs // are not being explicitly added to the subset and the input unicodes set is // not excessively large (eg. an inverted set). - plan->unicode_to_new_gid_list.alloc (unicodes->get_population ()); + plan->unicode_to_new_gid_list.alloc (unicodes.get_population ()); if (!unicode_to_gid) { - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { hb_codepoint_t gid; if (!cmap.get_nominal_glyph (cp, &gid)) { return HB_MAP_VALUE_INVALID; @@ -704,7 +274,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, // the map. This code is mostly duplicated from above to avoid doing // conditionals on the presence of the unicode_to_gid map each // iteration. - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { return unicode_to_gid->get (cp); }); } @@ -721,7 +291,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, if (!plan->accelerator) { cmap.collect_mapping (&cmap_unicodes_storage, &unicode_glyphid_map_storage); - plan->unicode_to_new_gid_list.alloc (hb_min(unicodes->get_population () + plan->unicode_to_new_gid_list.alloc (hb_min(unicodes.get_population () + glyphs->get_population (), cmap_unicodes->get_population ())); } else { @@ -730,10 +300,10 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, } if (plan->accelerator && - unicodes->get_population () < cmap_unicodes->get_population () && + unicodes.get_population () < cmap_unicodes->get_population () && glyphs->get_population () < cmap_unicodes->get_population ()) { - plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ()); + plan->codepoint_to_glyph->alloc (unicodes.get_population () + glyphs->get_population ()); auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes; @@ -748,7 +318,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, }); } - _fill_unicode_and_glyph_map(plan, unicodes->iter(), [&] (hb_codepoint_t cp) { + _fill_unicode_and_glyph_map(plan, unicodes.iter(), [&] (hb_codepoint_t cp) { /* Don't double-add entry. */ if (plan->codepoint_to_glyph->has (cp)) return HB_MAP_VALUE_INVALID; @@ -769,7 +339,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes, { _fill_unicode_and_glyph_map(plan, hb_range(first, last + 1), [&] (hb_codepoint_t cp) { hb_codepoint_t gid = (*unicode_glyphid_map)[cp]; - if (!unicodes->has (cp) && !glyphs->has (gid)) + if (!unicodes.has (cp) && !glyphs->has (gid)) return HB_MAP_VALUE_INVALID; return gid; }, @@ -860,18 +430,7 @@ _nameid_closure (hb_subset_plan_t* plan, #endif #ifndef HB_NO_SUBSET_LAYOUT - if (!drop_tables->has (HB_OT_TAG_GPOS)) - { - hb_blob_ptr_t gpos = plan->source_table (); - gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids); - gpos.destroy (); - } - if (!drop_tables->has (HB_OT_TAG_GSUB)) - { - hb_blob_ptr_t gsub = plan->source_table (); - gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids); - gsub.destroy (); - } + layout_nameid_closure(plan, drop_tables); #endif } @@ -893,31 +452,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _cmap_closure (plan->source, &plan->unicodes, &plan->_glyphset_gsub); #ifndef HB_NO_SUBSET_LAYOUT - if (!drop_tables->has (HB_OT_TAG_GSUB)) - // closure all glyphs/lookups/features needed for GSUB substitutions. - _closure_glyphs_lookups_features ( - plan, - &plan->_glyphset_gsub, - &plan->gsub_lookups, - &plan->gsub_features, - &plan->gsub_langsys, - &plan->gsub_feature_record_cond_idx_map, - &plan->gsub_feature_substitutes_map, - plan->gsub_old_features, - plan->gsub_old_feature_idx_tag_map); - - if (!drop_tables->has (HB_OT_TAG_GPOS)) - _closure_glyphs_lookups_features ( - plan, - &plan->_glyphset_gsub, - &plan->gpos_lookups, - &plan->gpos_features, - &plan->gpos_langsys, - &plan->gpos_feature_record_cond_idx_map, - &plan->gpos_feature_substitutes_map, - plan->gpos_old_features, - plan->gpos_old_feature_idx_tag_map); + layout_populate_gids_to_retain(plan, drop_tables); #endif + _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ()); plan->_glyphset_mathed = plan->_glyphset_gsub; @@ -962,8 +499,10 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ()); #ifndef HB_NO_VAR +#ifndef HB_NO_SUBSET_LAYOUT if (!drop_tables->has (HB_OT_TAG_GDEF)) - _collect_layout_variation_indices (plan); + collect_layout_variation_indices (plan); +#endif #endif } @@ -1077,193 +616,6 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, return true; } -#ifndef HB_NO_VAR -static void -_normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) -{ - if (plan->user_axes_location.is_empty ()) - return; - - hb_array_t axes = face->table.fvar->get_axes (); - plan->normalized_coords.resize (axes.length); - - bool has_avar = face->table.avar->has_data (); - const OT::SegmentMaps *seg_maps = nullptr; - unsigned avar_axis_count = 0; - if (has_avar) - { - seg_maps = face->table.avar->get_segment_maps (); - avar_axis_count = face->table.avar->get_axis_count(); - } - - bool axis_not_pinned = false; - unsigned old_axis_idx = 0, new_axis_idx = 0; - for (const auto& axis : axes) - { - hb_tag_t axis_tag = axis.get_axis_tag (); - plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag); - - if (!plan->user_axes_location.has (axis_tag) || - !plan->user_axes_location.get (axis_tag).is_point ()) - { - axis_not_pinned = true; - plan->axes_index_map.set (old_axis_idx, new_axis_idx); - plan->axis_tags.push (axis_tag); - new_axis_idx++; - } - - Triple *axis_range; - if (plan->user_axes_location.has (axis_tag, &axis_range)) - { - plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ()); - - int normalized_min = axis.normalize_axis_value (axis_range->minimum); - int normalized_default = axis.normalize_axis_value (axis_range->middle); - int normalized_max = axis.normalize_axis_value (axis_range->maximum); - - if (has_avar && old_axis_idx < avar_axis_count) - { - normalized_min = seg_maps->map (normalized_min); - normalized_default = seg_maps->map (normalized_default); - normalized_max = seg_maps->map (normalized_max); - } - plan->axes_location.set (axis_tag, Triple (static_cast (normalized_min / 16384.0), - static_cast (normalized_default / 16384.0), - static_cast (normalized_max / 16384.0))); - - if (normalized_default != 0) - plan->pinned_at_default = false; - - plan->normalized_coords[old_axis_idx] = normalized_default; - } - - old_axis_idx++; - - if (has_avar && old_axis_idx < avar_axis_count) - seg_maps = &StructAfter (*seg_maps); - } - plan->all_axes_pinned = !axis_not_pinned; -} - -static void -_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) -{ - if (!plan->normalized_coords) return; - OT::cff2::accelerator_t cff2 (plan->source); - if (!cff2.is_valid ()) return; - - hb_font_t *font = _get_hb_font_with_variations (plan); - if (unlikely (!plan->check_success (font != nullptr))) - { - hb_font_destroy (font); - return; - } - - hb_glyph_extents_t extents = {0x7FFF, -0x7FFF}; - OT::hmtx_accelerator_t _hmtx (plan->source); - float *hvar_store_cache = nullptr; - if (_hmtx.has_data () && _hmtx.var_table.get_length ()) - hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache (); - - OT::vmtx_accelerator_t _vmtx (plan->source); - float *vvar_store_cache = nullptr; - if (_vmtx.has_data () && _vmtx.var_table.get_length ()) - vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache (); - - for (auto p : *plan->glyph_map) - { - hb_codepoint_t old_gid = p.first; - hb_codepoint_t new_gid = p.second; - if (!cff2.get_extents (font, old_gid, &extents)) continue; - bool has_bounds_info = true; - if (extents.x_bearing == 0 && extents.width == 0 && - extents.height == 0 && extents.y_bearing == 0) - has_bounds_info = false; - - if (has_bounds_info) - { - plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing); - plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width); - plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing); - plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height); - } - - if (_hmtx.has_data ()) - { - int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid); - if (_hmtx.var_table.get_length ()) - hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, - hvar_store_cache)); - int lsb = extents.x_bearing; - if (!has_bounds_info) - { - if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb)) - continue; - } - plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb)); - plan->bounds_width_vec[new_gid] = extents.width; - } - - if (_vmtx.has_data ()) - { - int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid); - if (_vmtx.var_table.get_length ()) - vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords, - vvar_store_cache)); - - int tsb = extents.y_bearing; - if (!has_bounds_info) - { - if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb)) - continue; - } - plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb)); - plan->bounds_height_vec[new_gid] = extents.height; - } - } - hb_font_destroy (font); - if (hvar_store_cache) - _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache); - if (vvar_store_cache) - _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); -} - -static bool -_get_instance_glyphs_contour_points (hb_subset_plan_t *plan) -{ - /* contour_points vector only needed for updating gvar table (infer delta and - * iup delta optimization) during partial instancing */ - if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) - return true; - - OT::glyf_accelerator_t glyf (plan->source); - - for (auto &_ : plan->new_to_old_gid_list) - { - hb_codepoint_t new_gid = _.first; - contour_point_vector_t all_points; - if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) - { - if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) - return false; - continue; - } - - hb_codepoint_t old_gid = _.second; - auto glyph = glyf.glyph_for_gid (old_gid); - if (unlikely (!glyph.get_all_points_without_var (plan->source, all_points))) - return false; - if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) - return false; - - /* composite new gids are only needed by iup delta optimization */ - if ((plan->flags & HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS) && glyph.is_composite ()) - plan->composite_new_gids.add (new_gid); - } - return true; -} -#endif - hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, const hb_subset_input_t *input) { @@ -1324,7 +676,7 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - _normalize_axes_location (face, this); + normalize_axes_location (face, this); #endif _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this); @@ -1365,13 +717,15 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, for (auto &v : bounds_height_vec) v = 0xFFFFFFFF; +#ifndef HB_NO_SUBSET_LAYOUT if (!drop_tables.has (HB_OT_TAG_GDEF)) - _remap_used_mark_sets (this, used_mark_sets_map); + remap_used_mark_sets (this, used_mark_sets_map); +#endif #ifndef HB_NO_VAR #ifndef HB_NO_BASE if (!drop_tables.has (HB_OT_TAG_BASE)) - _collect_base_variation_indices (this); + collect_base_variation_indices (this); #endif #endif @@ -1379,8 +733,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, return; #ifndef HB_NO_VAR - _update_instance_metrics_map_from_cff2 (this); - if (!check_success (_get_instance_glyphs_contour_points (this))) + update_instance_metrics_map_from_cff2 (this); + if (!check_success (get_instance_glyphs_contour_points (this))) return; #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh index 214ea934191..335b750da35 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh @@ -296,5 +296,75 @@ struct hb_subset_plan_t } }; +// hb-subset-plan implementation is split into multiple files to keep +// compile times more reasonable: +// - hb-subset-plan.cc +// - hb-subset-plan-layout.cc +// +// The functions below are those needed to connect the split files +// above together. +HB_INTERNAL void +remap_indexes (const hb_set_t *indexes, + hb_map_t *mapping /* OUT */); + + +#ifndef HB_NO_VAR +template +HB_INTERNAL void +remap_variation_indices (const ItemVarStore &var_store, + const hb_set_t &variation_indices, + const hb_vector_t& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ + hb_hashmap_t> &variation_idx_delta_map /* OUT */); + + +template +HB_INTERNAL void +remap_colrv1_delta_set_index_indices (const DeltaSetIndexMap &index_map, + const hb_set_t &delta_set_idxes, + hb_hashmap_t> &variation_idx_delta_map, /* IN/OUT */ + hb_map_t &new_deltaset_idx_varidx_map /* OUT */); + + +HB_INTERNAL void +generate_varstore_inner_maps (const hb_set_t& varidx_set, + unsigned subtable_count, + hb_vector_t &inner_maps /* OUT */); + +HB_INTERNAL void +normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan); + +HB_INTERNAL void +update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan); + +HB_INTERNAL bool +get_instance_glyphs_contour_points (hb_subset_plan_t *plan); + +#ifndef HB_NO_BASE +HB_INTERNAL void +collect_base_variation_indices (hb_subset_plan_t* plan); +#endif +#endif + +#ifndef HB_NO_SUBSET_LAYOUT +typedef hb_hashmap_t> script_langsys_map; + +HB_INTERNAL void +remap_used_mark_sets (hb_subset_plan_t *plan, + hb_map_t& used_mark_sets_map); + +HB_INTERNAL void +layout_nameid_closure (hb_subset_plan_t* plan, + hb_set_t* drop_tables); + +HB_INTERNAL void +layout_populate_gids_to_retain (hb_subset_plan_t* plan, + hb_set_t* drop_tables); + +HB_INTERNAL void +collect_layout_variation_indices (hb_subset_plan_t* plan); +#endif + #endif /* HB_SUBSET_PLAN_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc index fbdf1b4f92d..7f9dc34ded8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc @@ -708,3 +708,107 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan) end: return success ? hb_face_reference (plan->dest) : nullptr; } + + +#ifdef HB_EXPERIMENTAL_API + +#include "hb-ot-cff1-table.hh" + +template +static hb_blob_t* get_charstrings_data(accel_t& accel, hb_codepoint_t glyph_index) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + hb_ubytes_t bytes = (*accel.charStrings)[glyph_index]; + if (!bytes) { + return hb_blob_get_empty (); + } + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = (const char*) bytes.arrayZ - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, bytes.length); +} + +template +static hb_blob_t* get_charstrings_index(accel_t& accel) { + if (!accel.is_valid()) { + return hb_blob_get_empty (); + } + + const char* charstrings_start = (const char*) accel.charStrings; + unsigned charstrings_length = accel.charStrings->get_size(); + + hb_blob_t* cff_blob = accel.get_blob(); + uint32_t length; + const char* cff_data = hb_blob_get_data(cff_blob, &length) ; + + long int offset = charstrings_start - cff_data; + if (offset < 0 || offset > INT32_MAX) { + return hb_blob_get_empty (); + } + + return hb_blob_create_sub_blob(cff_blob, (uint32_t) offset, charstrings_length); +} + +/** + * hb_subset_cff_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff1, glyph_index); +} + +/** + * hb_subset_cff_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF CharStrings INDEX from the CFF table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff1); +} + +/** + * hb_subset_cff2_get_charstring_data: + * @face: A face object + * @glyph_index: Glyph index to get data for. + * + * Returns the raw outline data from the CFF/CFF2 table associated with the given glyph index. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data(hb_face_t* face, hb_codepoint_t glyph_index) { + return get_charstrings_data(*face->table.cff2, glyph_index); +} + +/** + * hb_subset_cff2_get_charstrings_index: + * @face: A face object + * + * Returns the raw CFF2 CharStrings INDEX from the CFF2 table. + * + * XSince: EXPERIMENTAL + **/ +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face) { + return get_charstrings_index (*face->table.cff2); +} +#endif \ No newline at end of file diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.h b/src/3rdparty/harfbuzz-ng/src/hb-subset.h index 71276c7a6d1..374035df3ee 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-subset.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.h @@ -71,10 +71,12 @@ typedef struct hb_subset_plan_t hb_subset_plan_t; * in the final subset. * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in * OS/2 will not be recalculated. - * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set don't perform glyph closure on layout + * @HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE: If set do not perform glyph closure on layout * substitution rules (GSUB). Since: 7.2.0. * @HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS: If set perform IUP delta optimization on the * remaining gvar table's deltas. Since: 8.5.0 + * @HB_SUBSET_FLAGS_NO_BIDI_CLOSURE: If set do not pull mirrored versions of input + * codepoints into the subset. Since: 11.1.0 * @HB_SUBSET_FLAGS_IFTB_REQUIREMENTS: If set enforce requirements on the output subset * to allow it to be used with incremental font transfer IFTB patches. Primarily, * this forces all outline data to use long (32 bit) offsets. Since: EXPERIMENTAL @@ -96,8 +98,9 @@ typedef enum { /*< flags >*/ HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u, HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE = 0x00000200u, HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS = 0x00000400u, + HB_SUBSET_FLAGS_NO_BIDI_CLOSURE = 0x00000800u, #ifdef HB_EXPERIMENTAL_API - HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00000800u, + HB_SUBSET_FLAGS_IFTB_REQUIREMENTS = 0x00001000u, #endif } hb_subset_flags_t; @@ -224,6 +227,23 @@ hb_subset_input_override_name_table (hb_subset_input_t *input, unsigned language_id, const char *name_str, int str_len); + + +/* +* Raw outline data access +*/ + +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstring_data (hb_face_t* face, hb_codepoint_t glyph_index); + +HB_EXTERN hb_blob_t* +hb_subset_cff_get_charstrings_index (hb_face_t* face); + +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstring_data (hb_face_t* face, hb_codepoint_t glyph_index); + +HB_EXTERN hb_blob_t* +hb_subset_cff2_get_charstrings_index (hb_face_t* face); #endif HB_EXTERN hb_face_t * diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index 59601fe102c..885434adc91 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -47,7 +47,7 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 0 +#define HB_VERSION_MINOR 1 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "11.0.0" +#define HB_VERSION_STRING "11.1.0" /** * HB_VERSION_ATLEAST: diff --git a/src/3rdparty/harfbuzz-ng/src/hb.hh b/src/3rdparty/harfbuzz-ng/src/hb.hh index ffbfef099fb..ce8d075cd4d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb.hh @@ -89,6 +89,7 @@ #pragma GCC diagnostic error "-Wstring-conversion" #pragma GCC diagnostic error "-Wswitch-enum" #pragma GCC diagnostic error "-Wtautological-overlap-compare" +#pragma GCC diagnostic error "-Wuninitialized" #pragma GCC diagnostic error "-Wunneeded-internal-declaration" #pragma GCC diagnostic error "-Wunused" #pragma GCC diagnostic error "-Wunused-local-typedefs" @@ -464,7 +465,7 @@ static int HB_UNUSED _hb_errno = 0; # define hb_atexit atexit # else template struct hb_atexit_t { ~hb_atexit_t () { function (); } }; -# define hb_atexit(f) static hb_atexit_t _hb_atexit_##__LINE__; +# define hb_atexit(f) static hb_atexit_t _hb_atexit_##__LINE__ # endif #endif #endif