summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtConfigDependencies.cmake.in4
-rw-r--r--cmake/QtToolchainHelpers.cmake21
-rw-r--r--coin/instructions/cmake_build_tests_in_test_stage.yaml22
-rw-r--r--coin/instructions/prepare_building_env.yaml10
-rw-r--r--src/3rdparty/harfbuzz-ng/CMakeLists.txt5
-rw-r--r--src/3rdparty/harfbuzz-ng/README.md6
-rw-r--r--src/3rdparty/harfbuzz-ng/qt_attribution.json4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh11
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh11
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh7
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh19
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh31
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh30
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh26
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh28
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh26
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh9
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/graph.hh50
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/ligature-graph.hh53
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc66
-rw-r--r--src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc5
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cache.hh8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-config.hh11
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-debug.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.cc3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-harfrust.cc43
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-iter.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-kbts.cc259
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-machinery.hh15
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh782
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc23
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh13
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh295
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc23
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh516
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc12
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-serialize.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.cc3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-string-array.hh12
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-table-cff.cc143
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-table-color.cc21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-table-layout.cc22
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-table-other.cc31
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-table-var.cc45
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-table.hh217
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.cc578
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb.hh12
-rw-r--r--src/corelib/kernel/qpermissions.cpp4
-rw-r--r--src/corelib/kernel/qproperty.cpp2
-rw-r--r--src/corelib/serialization/qxmlstream.cpp1
-rw-r--r--src/corelib/text/qvsnprintf.cpp4
-rw-r--r--src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_metering.cpp78
-rw-r--r--src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_reachability.cpp66
-rw-r--r--src/network/kernel/qnetworkinformation.cpp38
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm1
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h2
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp7
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp2
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp18
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm145
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p_p.h1
-rw-r--r--src/widgets/doc/snippets/itemselection/main.cpp24
-rw-r--r--src/widgets/doc/snippets/reading-selections/window.cpp20
-rw-r--r--src/widgets/doc/snippets/sharedtablemodel/main.cpp20
-rw-r--r--src/widgets/doc/snippets/updating-selections/window.cpp21
-rw-r--r--src/widgets/kernel/qwindowcontainer_p.h2
98 files changed, 2527 insertions, 1672 deletions
diff --git a/cmake/QtConfigDependencies.cmake.in b/cmake/QtConfigDependencies.cmake.in
index e68e2954f9d..b006f052f7f 100644
--- a/cmake/QtConfigDependencies.cmake.in
+++ b/cmake/QtConfigDependencies.cmake.in
@@ -7,8 +7,10 @@ if(DEFINED QT_REQUIRE_HOST_PATH_CHECK)
set(__qt_platform_requires_host_info_package "${QT_REQUIRE_HOST_PATH_CHECK}")
elseif(DEFINED ENV{QT_REQUIRE_HOST_PATH_CHECK})
set(__qt_platform_requires_host_info_package "$ENV{QT_REQUIRE_HOST_PATH_CHECK}")
-else()
+elseif(CMAKE_CROSSCOMPILING OR DEFINED QT_HOST_PATH)
set(__qt_platform_requires_host_info_package "@platform_requires_host_info_package@")
+else()
+ set(__qt_platform_requires_host_info_package FALSE)
endif()
set(__qt_platform_initial_qt_host_path "@qt_host_path_absolute@")
set(__qt_platform_initial_qt_host_path_cmake_dir "@qt_host_path_cmake_dir_absolute@")
diff --git a/cmake/QtToolchainHelpers.cmake b/cmake/QtToolchainHelpers.cmake
index c006f1b677a..9407fd0ebe5 100644
--- a/cmake/QtToolchainHelpers.cmake
+++ b/cmake/QtToolchainHelpers.cmake
@@ -34,10 +34,23 @@ set(__qt_chainload_toolchain_file \"\${__qt_initially_configured_toolchain_file}
set(init_vcpkg "")
endif()
- if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND CMAKE_SYSTEM_VERSION STREQUAL "10")
- list(APPEND init_platform "set(CMAKE_SYSTEM_NAME Windows CACHE STRING \"\")")
- list(APPEND init_platform "set(CMAKE_SYSTEM_VERSION 10 CACHE STRING \"\")")
- list(APPEND init_platform "set(CMAKE_SYSTEM_PROCESSOR arm64 CACHE STRING \"\")")
+ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_CROSSCOMPILING)
+ list(APPEND init_platform
+ "string(TOUPPER \"${CMAKE_SYSTEM_PROCESSOR}\" _qt_orig_target_system_processor_upper)"
+ "string(TOUPPER \"\${CMAKE_HOST_SYSTEM_PROCESSOR}\" _qt_host_system_processor_upper)"
+ "if(NOT _qt_orig_target_system_processor_upper STREQUAL _qt_host_system_processor_upper"
+ " OR NOT CMAKE_HOST_SYSTEM_VERSION MATCHES \"^${CMAKE_SYSTEM_VERSION}(\\\\..+|$)\""
+ " OR QT_FORCE_CROSSCOMPILING)"
+ ""
+ " set(CMAKE_SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\" CACHE STRING \"\")"
+ " set(CMAKE_SYSTEM_VERSION \"${CMAKE_SYSTEM_VERSION}\" CACHE STRING \"\")"
+ " set(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\" CACHE STRING \"\")"
+ "else()"
+ " set(QT_REQUIRE_HOST_PATH_CHECK FALSE)"
+ "endif()"
+ "unset(_qt_host_system_processor_upper)"
+ "unset(_qt_orig_host_system_processor_upper)"
+ )
endif()
if(QT_QMAKE_TARGET_MKSPEC)
diff --git a/coin/instructions/cmake_build_tests_in_test_stage.yaml b/coin/instructions/cmake_build_tests_in_test_stage.yaml
index 420b4331f57..2f4e62b989e 100644
--- a/coin/instructions/cmake_build_tests_in_test_stage.yaml
+++ b/coin/instructions/cmake_build_tests_in_test_stage.yaml
@@ -8,16 +8,26 @@ instructions:
instructions:
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts_host.yaml"
disable_if:
- condition: property
- property: target.osVersion
- in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
+ condition: or
+ conditions:
+ - condition: property
+ property: target.osVersion
+ in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
+ - condition: property
+ property: features
+ contains_value: UseToolchainFromTargetDir
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts_target.yaml"
enable_if:
- condition: property
- property: target.osVersion
- in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
+ condition: or
+ conditions:
+ - condition: property
+ property: target.osVersion
+ in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
+ - condition: property
+ property: features
+ contains_value: UseToolchainFromTargetDir
enable_if:
condition: property
property: features
diff --git a/coin/instructions/prepare_building_env.yaml b/coin/instructions/prepare_building_env.yaml
index 03b05ddf7ea..cda46145e01 100644
--- a/coin/instructions/prepare_building_env.yaml
+++ b/coin/instructions/prepare_building_env.yaml
@@ -202,8 +202,8 @@ instructions:
property: target.arch
in_values: ["AARCH64", "ARM64"]
- condition: property
- property: host
- equals_property: target
+ property: host.arch
+ in_values: ["AARCH64", "ARM64"]
- type: EnvironmentVariable
# HACK. Overwrite TARGET_ARCHITECTURE as we do not use standard MSVC cross
# compilation targets here. The target architecture will be detected by Qt.
@@ -398,11 +398,11 @@ instructions:
condition: and
conditions:
- condition: property
- property: target.os
+ property: host.os
equals_value: Windows
- condition: property
- property: target.arch
- not_equals_property: host.arch
+ property: host.compiler
+ contains_value: MSVC
instructions:
- type: EnvironmentVariable
variableName: TARGET_ENV_PREFIX
diff --git a/src/3rdparty/harfbuzz-ng/CMakeLists.txt b/src/3rdparty/harfbuzz-ng/CMakeLists.txt
index 6db3ce881bb..8c299a3daac 100644
--- a/src/3rdparty/harfbuzz-ng/CMakeLists.txt
+++ b/src/3rdparty/harfbuzz-ng/CMakeLists.txt
@@ -69,6 +69,11 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz
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-table-cff.cc
+ src/hb-subset-table-color.cc
+ src/hb-subset-table-layout.cc
+ src/hb-subset-table-other.cc
+ src/hb-subset-table-var.cc src/hb-subset-table.hh
src/hb-subset-plan-var.cc
src/hb-unicode.cc src/hb-unicode.h src/hb-unicode.hh
src/hb-utf.hh
diff --git a/src/3rdparty/harfbuzz-ng/README.md b/src/3rdparty/harfbuzz-ng/README.md
index 0cbdf00be31..7646565fb02 100644
--- a/src/3rdparty/harfbuzz-ng/README.md
+++ b/src/3rdparty/harfbuzz-ng/README.md
@@ -78,7 +78,7 @@ Internationalization and Unicode Conference over the years:
More presentations and papers are available on [behdad][11]'s website.
In particular, the following _studies_ are relevant to HarfBuzz development:
-- 2025 - [Introducing HarfRust][22]
+- 2025 – [Introducing HarfRust][22]
- 2025 – [Subsetting][21]
- 2025 – [Caching][12]
- 2025 – [`hb-decycler`][13]
@@ -119,10 +119,10 @@ 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
-[6]: http://behdad.org/text2024
+[6]: https://behdad.org/text2024
[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
+[9]: https://behdad.org/doc/harfbuzz2009-slides.pdf
[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
diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json
index 8bb94c14423..9c286cb13b1 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.3.3",
- "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/11.3.3",
+ "Version": "11.4.1",
+ "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/11.4.1",
"PURL": "pkg:github/harfbuzz/harfbuzz@$<VERSION>",
"CPE": "cpe:2.3:a:harfbuzz_project:harfbuzz:$<VERSION>:*:*:*:*:*:*:*",
"License": "MIT License",
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
index 896b0fb1034..7d72a11a42c 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
@@ -178,7 +178,10 @@ struct hb_colrv1_closure_context_t :
{ glyphs->add (glyph_id); }
void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
- { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
+ {
+ if (num_of_layers == 0) return;
+ layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1);
+ }
void add_palette_index (unsigned palette_index)
{ palette_indices->add (palette_index); }
@@ -650,10 +653,10 @@ struct PaintColrLayers
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
- return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex),
- HB_SERIALIZE_ERROR_INT_OVERFLOW));
- return_trace (true);
+ uint32_t first_layer_index = numLayers ? c->plan->colrv1_layers.get (firstLayerIndex) : 0;
+ return_trace (c->serializer->check_assign (out->firstLayerIndex, first_layer_index,
+ HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
bool sanitize (hb_sanitize_context_t *c) const
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh
index 940126a86c5..2b8b69b6009 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/CPAL/CPAL.hh
@@ -307,6 +307,7 @@ struct CPAL
if (first_color_to_layer_index.has (first_color_record_idx)) continue;
first_color_index_for_layer.push (first_color_record_idx);
+ if (unlikely (!c->serializer->propagate_error (first_color_index_for_layer))) return_trace (false);
first_color_to_layer_index.set (first_color_record_idx,
first_color_index_for_layer.length - 1);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
index daa1979544c..797a8d2448a 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
@@ -97,12 +97,17 @@ struct Coverage
}
}
unsigned int get_coverage (hb_codepoint_t glyph_id,
- hb_ot_lookup_cache_t *cache) const
+ hb_ot_layout_mapping_cache_t *cache) const
{
unsigned coverage;
- if (cache && cache->get (glyph_id, &coverage)) return coverage;
+ if (cache && cache->get (glyph_id, &coverage)) return coverage < cache->MAX_VALUE ? coverage : NOT_COVERED;
coverage = get_coverage (glyph_id);
- if (cache) cache->set (glyph_id, coverage);
+ if (cache) {
+ if (coverage == NOT_COVERED)
+ cache->set_unchecked (glyph_id, cache->MAX_VALUE);
+ else if (likely (coverage < cache->MAX_VALUE))
+ cache->set_unchecked (glyph_id, coverage);
+ }
return coverage;
}
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 79de21e5919..ed397b75088 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
@@ -977,7 +977,7 @@ struct GDEF
}
#ifndef HB_NO_GDEF_CACHE
- table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests);
+ table->get_mark_glyph_sets ().collect_coverage (mark_glyph_sets);
#endif
}
~accelerator_t () { table.destroy (); }
@@ -1006,14 +1006,16 @@ struct GDEF
{
return
#ifndef HB_NO_GDEF_CACHE
- mark_glyph_set_digests[set_index].may_have (glyph_id) &&
+ mark_glyph_sets[set_index].may_have (glyph_id)
+#else
+ table->mark_set_covers (set_index, glyph_id)
#endif
- table->mark_set_covers (set_index, glyph_id);
+ ;
}
hb_blob_ptr_t<GDEF> table;
#ifndef HB_NO_GDEF_CACHE
- hb_vector_t<hb_set_digest_t> mark_glyph_set_digests;
+ hb_vector_t<hb_bit_set_t> mark_glyph_sets;
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/AnchorMatrix.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh
index 2557e9a7231..7e676371f7b 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/AnchorMatrix.hh
@@ -77,6 +77,13 @@ struct AnchorMatrix
return_trace (true);
}
+
+ bool offset_is_null (unsigned row, unsigned col, unsigned num_cols) const
+ {
+ if (unlikely (row >= rows || col >= num_cols)) return true;
+ auto &offset = matrixZ[row * num_cols + col];
+ return offset.is_null ();
+ }
};
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh
index 59cca40aadc..fd131224630 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/LigatureArray.hh
@@ -19,22 +19,30 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach>
bool subset (hb_subset_context_t *c,
Iterator coverage,
unsigned class_count,
- const hb_map_t *klass_mapping) const
+ const hb_map_t *klass_mapping,
+ hb_sorted_vector_t<hb_codepoint_t> &new_coverage /* OUT */) const
{
TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
auto *out = c->serializer->start_embed (this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
bool ret = false;
for (const auto _ : + hb_zip (coverage, *this)
- | hb_filter (glyphset, hb_first))
+ | hb_filter (glyph_map, hb_first))
{
+ const LigatureAttach& src = (this + _.second);
+ bool non_empty = + hb_range (src.rows * class_count)
+ | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
+ | hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); })
+ | hb_any;
+
+ if (!non_empty) continue;
+
auto *matrix = out->serialize_append (c->serializer);
if (unlikely (!matrix)) return_trace (false);
- const LigatureAttach& src = (this + _.second);
auto indexes =
+ hb_range (src.rows * class_count)
| hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
@@ -44,6 +52,9 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach>
this,
src.rows,
indexes);
+
+ hb_codepoint_t new_gid = glyph_map.get (_.first);
+ new_coverage.push (new_gid);
}
return_trace (ret);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
index ab1378e615c..c13dc65d439 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
@@ -209,19 +209,22 @@ struct MarkBasePosFormat1_2
;
new_coverage.reset ();
- + base_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
hb_sorted_vector_t<unsigned> base_indexes;
- for (const unsigned row : + base_iter
- | hb_map (hb_second))
+ auto &base_array = (this+baseArray);
+ for (const auto _ : + base_iter)
{
+ unsigned row = _.second;
+ bool non_empty = + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return !base_array.offset_is_null (row, col, (unsigned) classCount); })
+ | hb_any
+ ;
+
+ if (!non_empty) continue;
+
+ hb_codepoint_t new_g = glyph_map.get ( _.first);
+ new_coverage.push (new_g);
+
+ hb_range ((unsigned) classCount)
| hb_filter (klass_mapping)
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
@@ -229,8 +232,12 @@ struct MarkBasePosFormat1_2
;
}
+ if (!new_coverage) return_trace (false);
+ if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+ return_trace (false);
+
return_trace (out->baseArray.serialize_subset (c, baseArray, this,
- base_iter.len (),
+ new_coverage.length,
base_indexes.iter ()));
}
};
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
index 46013c613b0..57dae77a9d0 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
@@ -200,19 +200,13 @@ struct MarkLigPosFormat1_2
&klass_mapping)))
return_trace (false);
- auto new_ligature_coverage =
- + hb_iter (this + ligatureCoverage)
- | hb_take ((this + ligatureArray).len)
- | hb_map_retains_sorting (glyph_map)
- | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
- ;
-
- if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
+ hb_sorted_vector_t<hb_codepoint_t> new_lig_coverage;
+ if (!out->ligatureArray.serialize_subset (c, ligatureArray, this,
+ hb_iter (this+ligatureCoverage),
+ classCount, &klass_mapping, new_lig_coverage))
return_trace (false);
- return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this,
- hb_iter (this+ligatureCoverage),
- classCount, &klass_mapping));
+ return_trace (out->ligatureCoverage.serialize_serialize (c->serializer, new_lig_coverage.iter ()));
}
};
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index c4d129f2cb0..3221704caec 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -196,19 +196,23 @@ struct MarkMarkPosFormat1_2
;
new_coverage.reset ();
- + mark2_iter
- | hb_map (hb_first)
- | hb_map (glyph_map)
- | hb_sink (new_coverage)
- ;
-
- if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
- return_trace (false);
-
hb_sorted_vector_t<unsigned> mark2_indexes;
- for (const unsigned row : + mark2_iter
- | hb_map (hb_second))
+ auto &mark2_array = (this+mark2Array);
+ for (const auto _ : + mark2_iter)
{
+ unsigned row = _.second;
+
+ bool non_empty = + hb_range ((unsigned) classCount)
+ | hb_filter (klass_mapping)
+ | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); })
+ | hb_any
+ ;
+
+ if (!non_empty) continue;
+
+ hb_codepoint_t new_g = glyph_map.get ( _.first);
+ new_coverage.push (new_g);
+
+ hb_range ((unsigned) classCount)
| hb_filter (klass_mapping)
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
@@ -216,6 +220,10 @@ struct MarkMarkPosFormat1_2
;
}
+ if (!new_coverage) return_trace (false);
+ if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+ return_trace (false);
+
return_trace (out->mark2Array.serialize_subset (c, mark2Array, this,
mark2_iter.len (),
mark2_indexes.iter ()));
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 a8ea5f96c05..6e366a2a090 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -103,28 +103,24 @@ struct PairPosFormat1_3
const Coverage &get_coverage () const { return this+coverage; }
- unsigned cache_cost () const
- {
- return (this+coverage).cost ();
- }
- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
+ static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
{
switch (op)
{
- case hb_ot_lookup_cache_op_t::CREATE:
+ case hb_ot_subtable_cache_op_t::CREATE:
{
- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t));
+ hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) hb_malloc (sizeof (hb_ot_layout_mapping_cache_t));
if (likely (cache))
cache->clear ();
return cache;
}
- case hb_ot_lookup_cache_op_t::ENTER:
- return (void *) true;
- case hb_ot_lookup_cache_op_t::LEAVE:
+ case hb_ot_subtable_cache_op_t::ENTER:
+ return nullptr;
+ case hb_ot_subtable_cache_op_t::LEAVE:
return nullptr;
- case hb_ot_lookup_cache_op_t::DESTROY:
+ case hb_ot_subtable_cache_op_t::DESTROY:
{
- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p;
+ hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) p;
hb_free (cache);
return nullptr;
}
@@ -132,16 +128,14 @@ struct PairPosFormat1_3
return nullptr;
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
- bool _apply (hb_ot_apply_context_t *c, bool cached) const
+ bool apply (hb_ot_apply_context_t *c, void *external_cache) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr;
+ hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) external_cache;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache);
#else
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
index 59c018b9276..d251b1ff641 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -125,20 +125,16 @@ struct PairPosFormat2_4 : ValueBase
struct pair_pos_cache_t
{
- hb_ot_lookup_cache_t coverage;
- hb_ot_lookup_cache_t first;
- hb_ot_lookup_cache_t second;
+ hb_ot_layout_mapping_cache_t coverage;
+ hb_ot_layout_mapping_cache_t first;
+ hb_ot_layout_mapping_cache_t second;
};
- unsigned cache_cost () const
- {
- return (this+coverage).cost () + (this+classDef1).cost () + (this+classDef2).cost ();
- }
- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
+ static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
{
switch (op)
{
- case hb_ot_lookup_cache_op_t::CREATE:
+ case hb_ot_subtable_cache_op_t::CREATE:
{
pair_pos_cache_t *cache = (pair_pos_cache_t *) hb_malloc (sizeof (pair_pos_cache_t));
if (likely (cache))
@@ -149,11 +145,11 @@ struct PairPosFormat2_4 : ValueBase
}
return cache;
}
- case hb_ot_lookup_cache_op_t::ENTER:
- return (void *) true;
- case hb_ot_lookup_cache_op_t::LEAVE:
+ case hb_ot_subtable_cache_op_t::ENTER:
+ return nullptr;
+ case hb_ot_subtable_cache_op_t::LEAVE:
return nullptr;
- case hb_ot_lookup_cache_op_t::DESTROY:
+ case hb_ot_subtable_cache_op_t::DESTROY:
{
pair_pos_cache_t *cache = (pair_pos_cache_t *) p;
hb_free (cache);
@@ -163,16 +159,14 @@ struct PairPosFormat2_4 : ValueBase
return nullptr;
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
- bool _apply (hb_ot_apply_context_t *c, bool cached) const
+ bool apply (hb_ot_apply_context_t *c, void *external_cache) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- pair_pos_cache_t *cache = cached ? (pair_pos_cache_t *) c->lookup_accel->cache : nullptr;
+ pair_pos_cache_t *cache = (pair_pos_cache_t *) external_cache;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache ? &cache->coverage : nullptr);
#else
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
index 2ef46145e98..95d282228c2 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
@@ -78,28 +78,24 @@ struct LigatureSubstFormat1_2
return lig_set.would_apply (c);
}
- unsigned cache_cost () const
- {
- return (this+coverage).cost ();
- }
- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
+ static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
{
switch (op)
{
- case hb_ot_lookup_cache_op_t::CREATE:
+ case hb_ot_subtable_cache_op_t::CREATE:
{
- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) hb_malloc (sizeof (hb_ot_lookup_cache_t));
+ hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) hb_malloc (sizeof (hb_ot_layout_mapping_cache_t));
if (likely (cache))
cache->clear ();
return cache;
}
- case hb_ot_lookup_cache_op_t::ENTER:
- return (void *) true;
- case hb_ot_lookup_cache_op_t::LEAVE:
+ case hb_ot_subtable_cache_op_t::ENTER:
+ return nullptr;
+ case hb_ot_subtable_cache_op_t::LEAVE:
return nullptr;
- case hb_ot_lookup_cache_op_t::DESTROY:
+ case hb_ot_subtable_cache_op_t::DESTROY:
{
- hb_ot_lookup_cache_t *cache = (hb_ot_lookup_cache_t *) p;
+ hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) p;
hb_free (cache);
return nullptr;
}
@@ -107,15 +103,13 @@ struct LigatureSubstFormat1_2
return nullptr;
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
- bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
- bool _apply (hb_ot_apply_context_t *c, bool cached) const
+ bool apply (hb_ot_apply_context_t *c, void *external_cache) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- hb_ot_lookup_cache_t *cache = cached ? (hb_ot_lookup_cache_t *) c->lookup_accel->cache : nullptr;
+ hb_ot_layout_mapping_cache_t *cache = (hb_ot_layout_mapping_cache_t *) external_cache;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint, cache);
#else
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh
index 527f64114b4..6e412e5fe92 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/types.hh
@@ -29,8 +29,8 @@
#ifndef OT_LAYOUT_TYPES_HH
#define OT_LAYOUT_TYPES_HH
-using hb_ot_lookup_cache_t = hb_cache_t<15, 8, 7>;
-static_assert (sizeof (hb_ot_lookup_cache_t) == 256, "");
+using hb_ot_layout_mapping_cache_t = hb_cache_t<15, 8, 7>;
+static_assert (sizeof (hb_ot_layout_mapping_cache_t) == 256, "");
namespace OT {
namespace Layout {
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 9e4fa3c2440..1a22f1d8124 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.cc
@@ -11,6 +11,8 @@ namespace OT {
//namespace Var {
+#ifndef HB_NO_DRAW
+
struct hb_transforming_pen_context_t
{
hb_transform_t<> transform;
@@ -411,6 +413,8 @@ VARC::get_path_at (const hb_varc_context_t &c,
return true;
}
+#endif
+
//} // namespace Var
} // namespace OT
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh
index a372701cde9..719302c93e4 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Var/VARC/VARC.hh
@@ -194,6 +194,7 @@ struct VARC
hb_codepoint_t gid,
hb_glyph_extents_t *extents) const
{
+#ifndef HB_NO_DRAW
if (!table->has_data ()) return false;
hb_extents_t<> f_extents;
@@ -207,6 +208,9 @@ struct VARC
*extents = f_extents.to_glyph_extents (font->x_scale < 0, font->y_scale < 0);
return ret;
+#else
+ return false;
+#endif
}
private:
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
index f8a396bf9bd..a3ec885e64c 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
@@ -533,7 +533,11 @@ struct Glyph
bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
hb_glyph_extents_t *extents) const
{
- if (type == EMPTY) return true; /* Empty glyph; zero extents. */
+ if (type == EMPTY)
+ {
+ *extents = {0, 0, 0, 0};
+ return true; /* Empty glyph; zero extents. */
+ }
return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh
index b821dd32258..71989d8df4a 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/glyf.hh
@@ -445,8 +445,7 @@ struct glyf_accelerator_t
if (coords)
{
hb_glyf_scratch_t *scratch = acquire_scratch ();
- if (unlikely (!scratch))
- return false;
+ if (unlikely (!scratch)) return false;
bool ret = get_points (font,
gid,
points_aggregator_t (font, extents, nullptr, true),
@@ -493,8 +492,7 @@ struct glyf_accelerator_t
if (!has_data ()) return false;
hb_glyf_scratch_t *scratch = acquire_scratch ();
- if (unlikely (!scratch))
- return true;
+ if (unlikely (!scratch)) return true;
bool ret = get_points (font, gid, glyf_impl::path_builder_t (font, draw_session),
hb_array (font->coords,
@@ -523,6 +521,7 @@ struct glyf_accelerator_t
hb_glyf_scratch_t *acquire_scratch () const
{
+ if (!has_data ()) return nullptr;
hb_glyf_scratch_t *scratch = cached_scratch.get_acquire ();
if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr)))
{
@@ -534,6 +533,8 @@ struct glyf_accelerator_t
}
void release_scratch (hb_glyf_scratch_t *scratch) const
{
+ if (!scratch)
+ return;
if (!cached_scratch.cmpexch (nullptr, scratch))
{
scratch->~hb_glyf_scratch_t ();
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
index 332f27169df..0b538c3d2e3 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
@@ -965,9 +965,9 @@ struct graph_t
*/
template<typename O>
unsigned move_child (unsigned old_parent_idx,
- const O* old_offset,
- unsigned new_parent_idx,
- const O* new_offset)
+ const O* old_offset,
+ unsigned new_parent_idx,
+ const O* new_offset)
{
distance_invalid = true;
positions_invalid = true;
@@ -993,6 +993,50 @@ struct graph_t
}
/*
+ * Moves all outgoing links in old parent that have
+ * a link position between [old_post_start, old_pos_end)
+ * to the new parent. Links are placed serially in the new
+ * parent starting at new_pos_start.
+ */
+ template<typename O>
+ void move_children (unsigned old_parent_idx,
+ unsigned old_pos_start,
+ unsigned old_pos_end,
+ unsigned new_parent_idx,
+ unsigned new_pos_start)
+ {
+ distance_invalid = true;
+ positions_invalid = true;
+
+ auto& old_v = vertices_[old_parent_idx];
+ auto& new_v = vertices_[new_parent_idx];
+
+ hb_vector_t<hb_serialize_context_t::object_t::link_t> old_links;
+ for (const auto& l : old_v.obj.real_links)
+ {
+ if (l.position < old_pos_start || l.position >= old_pos_end)
+ {
+ old_links.push(l);
+ continue;
+ }
+
+ unsigned array_pos = l.position - old_pos_start;
+
+ unsigned child_id = l.objidx;
+ auto* new_link = new_v.obj.real_links.push ();
+ new_link->width = O::static_size;
+ new_link->objidx = child_id;
+ new_link->position = new_pos_start + array_pos;
+
+ auto& child = vertices_[child_id];
+ child.add_parent (new_parent_idx, false);
+ child.remove_parent (old_parent_idx);
+ }
+
+ old_v.obj.real_links = std::move (old_links);
+ }
+
+ /*
* duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign
* links. index_map is updated with mappings from old id to new id. If a duplication has already
* been performed for a given index, then it will be skipped.
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/ligature-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/ligature-graph.hh
index 611ab686e9b..fd170bd9ccb 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/ligature-graph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/graph/ligature-graph.hh
@@ -105,6 +105,23 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1
return result;
}
+ hb_vector_t<unsigned> ligature_index_to_object_id(const graph_t::vertex_and_table_t<LigatureSet>& liga_set) const {
+ hb_vector_t<unsigned> map;
+ map.resize_exact(liga_set.table->ligature.len);
+ if (map.in_error()) return map;
+
+ for (unsigned i = 0; i < map.length; i++) {
+ map[i] = (unsigned) -1;
+ }
+
+ for (const auto& l : liga_set.vertex->obj.real_links) {
+ if (l.position < 2) continue;
+ unsigned array_index = (l.position - 2) / 2;
+ map[array_index] = l.objidx;
+ }
+ return map;
+ }
+
hb_vector_t<unsigned> compute_split_points(gsubgpos_graph_context_t& c,
unsigned parent_index,
unsigned this_index) const
@@ -128,9 +145,16 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1
return hb_vector_t<unsigned> {};
}
+ // Finding the object id associated with an array index is O(n)
+ // so to avoid O(n^2), precompute the mapping by scanning through
+ // all links
+ auto index_to_id = ligature_index_to_object_id(liga_set);
+ if (index_to_id.in_error()) return hb_vector_t<unsigned>();
+
for (unsigned j = 0; j < liga_set.table->ligature.len; j++)
{
- const unsigned liga_id = c.graph.index_for_offset (liga_set.index, &liga_set.table->ligature[j]);
+ const unsigned liga_id = index_to_id[j];
+ if (liga_id == (unsigned) -1) continue; // no outgoing link, ignore
const unsigned liga_size = c.graph.vertices_[liga_id].table_size ();
accumulated += OT::HBUINT16::static_size; // for ligature offset
@@ -154,7 +178,6 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1
return split_points;
}
-
struct split_context_t
{
gsubgpos_graph_context_t& c;
@@ -323,19 +346,19 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1
{
// This liga set partially overlaps [start, end). We'll need to create
// a new liga set sub table and move the intersecting ligas to it.
- unsigned liga_count = hb_min(end, current_end) - hb_max(start, current_start);
+ unsigned start_index = hb_max(start, current_start) - count;
+ unsigned end_index = hb_min(end, current_end) - count;
+ unsigned liga_count = end_index - start_index;
auto result = new_liga_set(c, liga_count);
liga_set_prime_id = result.first;
- LigatureSet* prime = result.second;
if (liga_set_prime_id == (unsigned) -1) return -1;
- unsigned new_index = 0;
- for (unsigned j = hb_max(start, current_start) - count; j < hb_min(end, current_end) - count; j++) {
- c.graph.move_child<> (liga_set_index,
- &liga_set.table->ligature[j],
- liga_set_prime_id,
- &prime->ligature[new_index++]);
- }
+ c.graph.move_children<OT::Offset16>(
+ liga_set_index,
+ 2 + start_index * 2,
+ 2 + end_index * 2,
+ liga_set_prime_id,
+ 2);
liga_set_end = i;
if (i < liga_set_start) liga_set_start = i;
@@ -392,8 +415,12 @@ struct LigatureSubstFormat1 : public OT::Layout::GSUB_impl::LigatureSubstFormat1
// duplicated. Code later on will re-add the virtual links as needed (via retained_indices).
clear_virtual_links(c, liga_set.index);
retained_indices.add(liga_set.index);
- for (const auto& liga_offset : liga_set.table->ligature) {
- unsigned liga_index = c.graph.index_for_offset(liga_set.index, &liga_offset);
+
+ auto index_to_id = ligature_index_to_object_id(liga_set);
+ if (index_to_id.in_error()) return false;
+
+ for (unsigned i = 0; i < liga_set.table->ligature.len; i++) {
+ unsigned liga_index = index_to_id[i];
if (liga_index != (unsigned) -1) {
clear_virtual_links(c, liga_index);
retained_indices.add(liga_index);
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc b/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
index 2da93481115..d3e8d892b7b 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
+++ b/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
@@ -38,7 +38,7 @@ static unsigned actual_class_def_size(It glyph_and_class) {
hb_serialize_context_t serializer(buffer, 100);
OT::ClassDef_serialize (&serializer, glyph_and_class);
serializer.end_serialize ();
- assert(!serializer.in_error());
+ hb_always_assert(!serializer.in_error());
hb_blob_t* blob = serializer.copy_blob();
unsigned size = hb_blob_get_length(blob);
@@ -66,7 +66,7 @@ static unsigned actual_coverage_size(It glyphs) {
hb_serialize_context_t serializer(buffer, 100);
OT::Layout::Common::Coverage_serialize (&serializer, glyphs);
serializer.end_serialize ();
- assert(!serializer.in_error());
+ hb_always_assert(!serializer.in_error());
hb_blob_t* blob = serializer.copy_blob();
unsigned size = hb_blob_get_length(blob);
@@ -101,9 +101,9 @@ static bool check_coverage_size(graph::class_def_size_estimator_t& estimator,
return true;
}
-static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator,
- const gid_and_class_list_t& map,
- unsigned klass, hb_vector_t<unsigned> klasses)
+static HB_UNUSED bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator,
+ const gid_and_class_list_t& map,
+ unsigned klass, hb_vector_t<unsigned> klasses)
{
unsigned result = estimator.add_class_def_size(klass);
unsigned expected = actual_class_def_size(map, klasses);
@@ -115,7 +115,7 @@ static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimato
return check_coverage_size(estimator, map, klasses);
}
-static bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass)
+static HB_UNUSED bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass)
{
graph::class_def_size_estimator_t estimator (list.iter ());
@@ -149,13 +149,13 @@ static void test_class_and_coverage_size_estimates ()
{
gid_and_class_list_t empty = {
};
- assert (check_add_class_def_size (empty, 0));
- assert (check_add_class_def_size (empty, 1));
+ hb_always_assert (check_add_class_def_size (empty, 0));
+ hb_always_assert (check_add_class_def_size (empty, 1));
gid_and_class_list_t class_zero = {
{5, 0},
};
- assert (check_add_class_def_size (class_zero, 0));
+ hb_always_assert (check_add_class_def_size (class_zero, 0));
gid_and_class_list_t consecutive = {
{4, 0},
@@ -169,9 +169,9 @@ static void test_class_and_coverage_size_estimates ()
{10, 2},
{11, 2},
};
- assert (check_add_class_def_size (consecutive, 0));
- assert (check_add_class_def_size (consecutive, 1));
- assert (check_add_class_def_size (consecutive, 2));
+ hb_always_assert (check_add_class_def_size (consecutive, 0));
+ hb_always_assert (check_add_class_def_size (consecutive, 1));
+ hb_always_assert (check_add_class_def_size (consecutive, 2));
gid_and_class_list_t non_consecutive = {
{4, 0},
@@ -185,9 +185,9 @@ static void test_class_and_coverage_size_estimates ()
{11, 2},
{13, 2},
};
- assert (check_add_class_def_size (non_consecutive, 0));
- assert (check_add_class_def_size (non_consecutive, 1));
- assert (check_add_class_def_size (non_consecutive, 2));
+ hb_always_assert (check_add_class_def_size (non_consecutive, 0));
+ hb_always_assert (check_add_class_def_size (non_consecutive, 1));
+ hb_always_assert (check_add_class_def_size (non_consecutive, 2));
gid_and_class_list_t multiple_ranges = {
{4, 0},
@@ -202,8 +202,8 @@ static void test_class_and_coverage_size_estimates ()
{12, 1},
{13, 1},
};
- assert (check_add_class_def_size (multiple_ranges, 0));
- assert (check_add_class_def_size (multiple_ranges, 1));
+ hb_always_assert (check_add_class_def_size (multiple_ranges, 0));
+ hb_always_assert (check_add_class_def_size (multiple_ranges, 1));
}
static void test_running_class_and_coverage_size_estimates () {
@@ -229,14 +229,14 @@ static void test_running_class_and_coverage_size_estimates () {
};
graph::class_def_size_estimator_t estimator1(consecutive_map.iter());
- assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1}));
- assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2}));
- assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works
- assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3}));
+ hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1}));
+ hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2}));
+ hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works
+ hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3}));
estimator1.reset();
- assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2}));
- assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3}));
+ hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2}));
+ hb_always_assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3}));
// #### With non-consecutive gids: always uses format 2 ###
gid_and_class_list_t non_consecutive_map = {
@@ -261,13 +261,13 @@ static void test_running_class_and_coverage_size_estimates () {
};
graph::class_def_size_estimator_t estimator2(non_consecutive_map.iter());
- assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1}));
- assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2}));
- assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3}));
+ hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1}));
+ hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2}));
+ hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3}));
estimator2.reset();
- assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2}));
- assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3}));
+ hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2}));
+ hb_always_assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3}));
}
static void test_running_class_size_estimates_with_locally_consecutive_glyphs () {
@@ -278,13 +278,13 @@ static void test_running_class_size_estimates_with_locally_consecutive_glyphs ()
};
graph::class_def_size_estimator_t estimator(map.iter());
- assert(check_add_class_def_size(estimator, map, 1, {1}));
- assert(check_add_class_def_size(estimator, map, 2, {1, 2}));
- assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3}));
+ hb_always_assert(check_add_class_def_size(estimator, map, 1, {1}));
+ hb_always_assert(check_add_class_def_size(estimator, map, 2, {1, 2}));
+ hb_always_assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3}));
estimator.reset();
- assert(check_add_class_def_size(estimator, map, 2, {2}));
- assert(check_add_class_def_size(estimator, map, 3, {2, 3}));
+ hb_always_assert(check_add_class_def_size(estimator, map, 2, {2}));
+ hb_always_assert(check_add_class_def_size(estimator, map, 3, {2, 3}));
}
int
diff --git a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc
index 79fac9e62d5..f6a5a319c97 100644
--- a/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc
+++ b/src/3rdparty/harfbuzz-ng/src/harfbuzz-subset.cc
@@ -62,6 +62,11 @@
#include "hb-subset-plan-var.cc"
#include "hb-subset-plan.cc"
#include "hb-subset-serialize.cc"
+#include "hb-subset-table-cff.cc"
+#include "hb-subset-table-color.cc"
+#include "hb-subset-table-layout.cc"
+#include "hb-subset-table-other.cc"
+#include "hb-subset-table-var.cc"
#include "hb-subset.cc"
#include "hb-ucd.cc"
#include "hb-unicode.cc"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh
index 1941009f800..e84557984a7 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-bit-page.hh
@@ -290,7 +290,7 @@ struct hb_bit_page_t
unsigned int j = m & ELT_MASK;
const elt_t vv = v[i] & ~((elt_t (1) << j) - 1);
- for (const elt_t *p = &vv; i < len (); p = &v[++i])
+ for (const elt_t *p = &vv; i < len (); p = ((const elt_t *) &v[0]) + (++i))
if (*p)
{
*codepoint = i * ELT_BITS + elt_get_min (*p);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh
index 26ec0b42257..0bb00c4c2e5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text-unicode.hh
@@ -32,7 +32,7 @@
#include "hb.hh"
-#line 36 "hb-buffer-deserialize-text-unicode.hh"
+#line 33 "hb-buffer-deserialize-text-unicode.hh"
static const unsigned char _deserialize_text_unicode_trans_keys[] = {
0u, 0u, 43u, 102u, 48u, 102u, 48u, 124u, 48u, 57u, 62u, 124u, 48u, 124u, 60u, 117u,
85u, 117u, 85u, 117u, 0
@@ -150,12 +150,12 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer,
hb_glyph_info_t info = {0};
const hb_glyph_position_t pos = {0};
-#line 154 "hb-buffer-deserialize-text-unicode.hh"
+#line 147 "hb-buffer-deserialize-text-unicode.hh"
{
cs = deserialize_text_unicode_start;
}
-#line 159 "hb-buffer-deserialize-text-unicode.hh"
+#line 150 "hb-buffer-deserialize-text-unicode.hh"
{
int _slen;
int _trans;
@@ -215,7 +215,7 @@ _resume:
hb_memset (&info, 0, sizeof (info));
}
break;
-#line 219 "hb-buffer-deserialize-text-unicode.hh"
+#line 203 "hb-buffer-deserialize-text-unicode.hh"
}
_again:
@@ -238,7 +238,7 @@ _again:
*end_ptr = p;
}
break;
-#line 242 "hb-buffer-deserialize-text-unicode.hh"
+#line 224 "hb-buffer-deserialize-text-unicode.hh"
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cache.hh b/src/3rdparty/harfbuzz-ng/src/hb-cache.hh
index ac76deb725e..b1a6ebf06b9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-cache.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-cache.hh
@@ -75,6 +75,8 @@ struct hb_cache_t
static_assert ((key_bits >= cache_bits), "");
static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
+ static constexpr unsigned MAX_VALUE = (1u << value_bits) - 1;
+
hb_cache_t () { clear (); }
void clear ()
@@ -100,6 +102,12 @@ struct hb_cache_t
{
if (unlikely ((key >> key_bits) || (value >> value_bits)))
return; /* Overflows */
+ set_unchecked (key, value);
+ }
+
+ HB_HOT
+ void set_unchecked (unsigned int key, unsigned int value)
+ {
unsigned int k = key & ((1u<<cache_bits)-1);
unsigned int v = ((key>>cache_bits)<<value_bits) | value;
values[k] = v;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh
index 22871e30c90..27a0c8cf920 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-cff2-interp-cs.hh
@@ -72,7 +72,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<ELEM, CFF2Subrs>
cff2_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd,
const int *coords_=nullptr, unsigned int num_coords_=0)
: SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs),
- cached_scalars_vector (&acc.cached_scalars_vector)
+ region_count (0), cached_scalars_vector (&acc.cached_scalars_vector)
{
coords = coords_;
num_coords = num_coords_;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-config.hh b/src/3rdparty/harfbuzz-ng/src/hb-config.hh
index 3956690da35..68bc7a1a57f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-config.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-config.hh
@@ -91,7 +91,10 @@
#ifdef HB_MINI
#define HB_NO_AAT
#define HB_NO_LEGACY
-#define HB_NO_BORING_EXPANSION
+#define HB_NO_BEYOND_64K
+#define HB_NO_CUBIC_GLYF
+#define HB_NO_VAR_COMPOSITES
+#define HB_NO_VAR_HVF
#endif
#ifdef __OPTIMIZE_SIZE__
@@ -109,12 +112,6 @@
/* Closure of options. */
-#ifdef HB_NO_BORING_EXPANSION
-#define HB_NO_BEYOND_64K
-#define HB_NO_CUBIC_GLYF
-#define HB_NO_VAR_COMPOSITES
-#endif
-
#ifdef HB_NO_VAR
#define HB_NO_VAR_COMPOSITES
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
index f79b42bc4b3..1f7a7f925a2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
@@ -394,6 +394,10 @@ struct hb_no_trace_t {
#define HB_DEBUG_WASM (HB_DEBUG+0)
#endif
+#ifndef HB_DEBUG_KBTS
+#define HB_DEBUG_KBTS (HB_DEBUG+0)
+#endif
+
/*
* With tracing.
*/
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
index 3a504510921..b0cc787d0d1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
@@ -84,8 +84,7 @@ hb_face_count (hb_blob_t *blob)
hb_sanitize_context_t c (blob);
- const char *start = hb_blob_get_data (blob, nullptr);
- auto *ot = reinterpret_cast<OT::OpenTypeFontFile *> (const_cast<char *> (start));
+ auto *ot = blob->as<OT::OpenTypeFontFile> ();
if (unlikely (!ot->sanitize (&c)))
return 0;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc
index c547134d5f3..e2acdffb1db 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-graphite2.cc
@@ -266,7 +266,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
gr_segment *seg = nullptr;
const gr_slot *is;
unsigned int ci = 0, ic = 0;
- unsigned int curradvx = 0, curradvy = 0;
+ int curradvx = 0, curradvy = 0;
unsigned int scratch_size;
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-harfrust.cc b/src/3rdparty/harfbuzz-ng/src/hb-harfrust.cc
index 2f3eb259612..38c9c89d81d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-harfrust.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-harfrust.cc
@@ -30,6 +30,16 @@
/*
+ * buffer
+ */
+extern "C" void *
+_hb_harfrust_buffer_create_rs (void);
+
+extern "C" void
+_hb_harfrust_buffer_destroy_rs (void *data);
+
+
+/*
* shaper face data
*/
@@ -75,6 +85,7 @@ _hb_harfrust_shaper_font_data_destroy (hb_harfrust_font_data_t *data)
_hb_harfrust_shaper_font_data_destroy_rs (data);
}
+
/*
* shape plan
*/
@@ -98,12 +109,13 @@ extern "C" hb_bool_t
_hb_harfrust_shape_rs (const void *font_data,
const void *face_data,
const void *rs_shape_plan,
+ const void *rs_buffer,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features);
-static hb_user_data_key_t hr_shape_plan_key = {0};
+static hb_user_data_key_t hb_object_key = {0};
hb_bool_t
_hb_harfrust_shape (hb_shape_plan_t *shape_plan,
@@ -115,13 +127,31 @@ _hb_harfrust_shape (hb_shape_plan_t *shape_plan,
const hb_harfrust_font_data_t *font_data = font->data.harfrust;
const hb_harfrust_face_data_t *face_data = font->face->data.harfrust;
+retry_buffer:
+ void *hr_buffer = hb_buffer_get_user_data (buffer, &hb_object_key);
+ if (unlikely (!hr_buffer))
+ {
+ hr_buffer = _hb_harfrust_buffer_create_rs ();
+ if (unlikely (!hr_buffer))
+ return false;
+
+ if (!hb_buffer_set_user_data (buffer,
+ &hb_object_key,
+ hr_buffer,
+ _hb_harfrust_buffer_destroy_rs,
+ false))
+ {
+ _hb_harfrust_buffer_destroy_rs (hr_buffer);
+ goto retry_buffer;
+ }
+ }
+
void *hr_shape_plan = nullptr;
if (!num_features)
{
- retry:
- hr_shape_plan = hb_shape_plan_get_user_data (shape_plan,
- &hr_shape_plan_key);
+ retry_shape_plan:
+ hr_shape_plan = hb_shape_plan_get_user_data (shape_plan, &hb_object_key);
if (unlikely (!hr_shape_plan))
{
hr_shape_plan = _hb_harfrust_shape_plan_create_rs (font_data, face_data,
@@ -130,13 +160,13 @@ _hb_harfrust_shape (hb_shape_plan_t *shape_plan,
shape_plan->key.props.direction);
if (hr_shape_plan &&
!hb_shape_plan_set_user_data (shape_plan,
- &hr_shape_plan_key,
+ &hb_object_key,
hr_shape_plan,
_hb_harfrust_shape_plan_destroy_rs,
false))
{
_hb_harfrust_shape_plan_destroy_rs (hr_shape_plan);
- goto retry;
+ goto retry_shape_plan;
}
}
}
@@ -144,6 +174,7 @@ _hb_harfrust_shape (hb_shape_plan_t *shape_plan,
return _hb_harfrust_shape_rs (font_data,
face_data,
hr_shape_plan,
+ hr_buffer,
font,
buffer,
features,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-iter.hh b/src/3rdparty/harfbuzz-ng/src/hb-iter.hh
index 04d09940aef..a9541597eb9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-iter.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-iter.hh
@@ -972,7 +972,7 @@ struct
Proj&& f = hb_identity) const
{
for (auto it = hb_iter (c); it; ++it)
- if (!hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
+ if (!hb_match (p, hb_get (f, *it)))
return false;
return true;
}
@@ -989,7 +989,7 @@ struct
Proj&& f = hb_identity) const
{
for (auto it = hb_iter (c); it; ++it)
- if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
+ if (hb_match (p, hb_get (f, *it)))
return true;
return false;
}
@@ -1006,7 +1006,7 @@ struct
Proj&& f = hb_identity) const
{
for (auto it = hb_iter (c); it; ++it)
- if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
+ if (hb_match (p, hb_get (f, *it)))
return false;
return true;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-kbts.cc b/src/3rdparty/harfbuzz-ng/src/hb-kbts.cc
new file mode 100644
index 00000000000..eb3bfc22576
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-kbts.cc
@@ -0,0 +1,259 @@
+/*
+ * 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.
+ *
+ * Author(s): Khaled Hosny
+ */
+
+#include "hb.hh"
+
+#if HAVE_KBTS
+
+#include "hb-shaper-impl.hh"
+
+#define KB_TEXT_SHAPE_IMPLEMENTATION
+#define KB_TEXT_SHAPE_STATIC
+#define KB_TEXT_SHAPE_NO_CRT
+#define KBTS_MEMSET hb_memset
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#include "kb_text_shape.h"
+#pragma GCC diagnostic pop
+
+
+hb_kbts_face_data_t *
+_hb_kbts_shaper_face_data_create (hb_face_t *face)
+{
+ hb_blob_t *blob = hb_face_reference_blob (face);
+
+ unsigned int blob_length;
+ const char *blob_data = hb_blob_get_data (blob, &blob_length);
+ if (unlikely (!blob_length))
+ {
+ DEBUG_MSG (KBTS, blob, "Empty blob");
+ hb_blob_destroy (blob);
+ return nullptr;
+ }
+
+ void *data = hb_malloc (blob_length);
+ if (likely (data))
+ hb_memcpy (data, blob_data, blob_length);
+
+ hb_blob_destroy (blob);
+ blob = nullptr;
+
+ if (unlikely (!data))
+ {
+ DEBUG_MSG (KBTS, face, "Failed to allocate memory for font data");
+ return nullptr;
+ }
+
+ kbts_font *kb_font = (kbts_font *) hb_calloc (1, sizeof (kbts_font));
+ if (unlikely (!kb_font))
+ {
+ hb_free (data);
+ return nullptr;
+ }
+
+ size_t memory_size;
+ {
+ unsigned scratch_size = kbts_ReadFontHeader (kb_font, data, blob_length);
+ void *scratch = hb_malloc (scratch_size);
+ memory_size = kbts_ReadFontData (kb_font, scratch, scratch_size);
+ hb_free (scratch);
+ }
+
+ void *memory = hb_malloc (memory_size);
+ if (unlikely (!kbts_PostReadFontInitialize (kb_font, memory, memory_size)))
+ {
+ DEBUG_MSG (KBTS, face, "kbts_PostReadFontInitialize failed");
+ hb_free (memory);
+ hb_free (data);
+ hb_free (kb_font);
+ return nullptr;
+ }
+
+ return (hb_kbts_face_data_t *) kb_font;
+}
+
+void
+_hb_kbts_shaper_face_data_destroy (hb_kbts_face_data_t *data)
+{
+ kbts_font *font = (kbts_font *) data;
+
+ assert (kbts_FontIsValid (font));
+
+ hb_free (font->FileBase);
+ hb_free (font->GlyphLookupMatrix);
+ hb_free (font);
+}
+
+hb_kbts_font_data_t *
+_hb_kbts_shaper_font_data_create (hb_font_t *font)
+{
+ return (hb_kbts_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_kbts_shaper_font_data_destroy (hb_kbts_font_data_t *data)
+{
+}
+
+hb_bool_t
+_hb_kbts_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ hb_face_t *face = font->face;
+ kbts_font *kb_font = (kbts_font *) (const void *) face->data.kbts;
+
+ kbts_direction kb_direction;
+ switch (buffer->props.direction)
+ {
+ case HB_DIRECTION_LTR: kb_direction = KBTS_DIRECTION_LTR; break;
+ case HB_DIRECTION_RTL: kb_direction = KBTS_DIRECTION_RTL; break;
+ case HB_DIRECTION_TTB:
+ case HB_DIRECTION_BTT:
+ DEBUG_MSG (KBTS, face, "Vertical direction is not supported");
+ return false;
+ default:
+ case HB_DIRECTION_INVALID:
+ DEBUG_MSG (KBTS, face, "Invalid direction");
+ return false;
+ }
+
+ kbts_script kb_script = KBTS_SCRIPT_DONT_KNOW;
+ kbts_language kb_language = KBTS_LANGUAGE_DEFAULT;
+ {
+ hb_tag_t scripts[HB_OT_MAX_TAGS_PER_SCRIPT];
+ hb_tag_t language;
+ unsigned int script_count = ARRAY_LENGTH (scripts);
+ unsigned int language_count = 1;
+
+ hb_ot_tags_from_script_and_language (buffer->props.script, buffer->props.language,
+ &script_count, scripts,
+ &language_count, &language);
+
+ for (unsigned int i = 0; i < script_count && scripts[i] != HB_TAG_NONE; ++i)
+ {
+ kb_script = kbts_ScriptTagToScript (hb_uint32_swap (scripts[i]));
+ if (kb_script != KBTS_SCRIPT_DONT_KNOW)
+ break;
+ }
+
+ if (language_count)
+ kb_language = (kbts_language) hb_uint32_swap (language);
+ }
+
+ hb_vector_t<kbts_glyph> kb_glyphs;
+ if (unlikely (!kb_glyphs.resize_exact (buffer->len, false)))
+ return false;
+
+ for (size_t i = 0; i < buffer->len; ++i)
+ kb_glyphs.arrayZ[i] = kbts_CodepointToGlyph (kb_font, buffer->info[i].codepoint);
+
+ if (num_features)
+ {
+ for (unsigned int i = 0; i < num_features; ++i)
+ {
+ hb_feature_t feature = features[i];
+ for (unsigned int j = 0; j < buffer->len; ++j)
+ {
+ kbts_glyph *kb_glyph = &kb_glyphs.arrayZ[j];
+ if (hb_in_range (j, feature.start, feature.end))
+ {
+ if (!kb_glyph->Config)
+ kb_glyph->Config = (kbts_glyph_config *) hb_calloc (1, sizeof (kbts_glyph_config));
+ kbts_glyph_config *config = kb_glyph->Config;
+ while (!kbts_GlyphConfigOverrideFeatureFromTag (config, hb_uint32_swap (feature.tag),
+ feature.value > 1, feature.value))
+ {
+ config->FeatureOverrides = (kbts_feature_override *) hb_realloc (config->FeatureOverrides,
+ config->RequiredFeatureOverrideCapacity);
+ config->FeatureOverrideCapacity += 1;
+ }
+ }
+ }
+ }
+ }
+
+ kbts_shape_state *kb_shape_state;
+ {
+ size_t kb_shape_state_size = kbts_SizeOfShapeState (kb_font);
+ void *kb_shape_state_buffer = hb_malloc (kb_shape_state_size);
+ if (unlikely (!kb_shape_state_buffer))
+ {
+ DEBUG_MSG (KBTS, face, "Failed to allocate memory for shape state");
+ return false;
+ }
+ kb_shape_state = kbts_PlaceShapeState (kb_shape_state_buffer, kb_shape_state_size);
+ }
+ kbts_shape_config kb_shape_config = kbts_ShapeConfig (kb_font, kb_script, kb_language);
+ uint32_t glyph_count = buffer->len;
+ uint32_t glyph_capacity = kb_glyphs.length;
+ while (kbts_Shape (kb_shape_state, &kb_shape_config, KBTS_DIRECTION_LTR, kb_direction,
+ kb_glyphs.arrayZ, &glyph_count, glyph_capacity))
+ {
+ glyph_capacity = kb_shape_state->RequiredGlyphCapacity;
+ /* kb increases capacity by a fixed number only. We increase it by 50% to
+ * avoid O(n^2) behavior in case of expanding text.
+ *
+ * https://github.com/JimmyLefevre/kb/issues/32
+ */
+ glyph_capacity += glyph_capacity / 2;
+ if (unlikely (!kb_glyphs.resize_exact (glyph_capacity, false)))
+ return false;
+ }
+
+ hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
+ hb_buffer_set_length (buffer, glyph_count);
+
+ hb_glyph_info_t *info = buffer->info;
+ hb_glyph_position_t *pos = buffer->pos;
+
+ buffer->clear_positions ();
+ for (size_t i = 0; i < glyph_count; ++i)
+ {
+ kbts_glyph kb_glyph = kb_glyphs.arrayZ[i];
+ info[i].codepoint = kb_glyph.Id;
+ info[i].cluster = 0; // FIXME
+ pos[i].x_advance = font->em_scalef_x (kb_glyph.AdvanceX);
+ pos[i].y_advance = font->em_scalef_y (kb_glyph.AdvanceY);
+ pos[i].x_offset = font->em_scalef_x (kb_glyph.OffsetX);
+ pos[i].y_offset = font->em_scalef_y (kb_glyph.OffsetY);
+
+ if (kb_glyph.Config)
+ hb_free (kb_glyph.Config->FeatureOverrides);
+ }
+
+ hb_free (kb_shape_state);
+
+ buffer->clear_glyph_flags ();
+ buffer->unsafe_to_break ();
+
+ return true;
+}
+
+#endif \ No newline at end of file
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh
index 4916765e8fd..869fdba0ffc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh
@@ -70,11 +70,18 @@ static inline Type& StructAtOffsetUnaligned(void *P, unsigned int offset)
* Any extra arguments are forwarded to get_size, so for example
* it can work with UnsizedArrayOf<> as well. */
template <typename Type, typename TObject, typename ...Ts>
-static inline const Type& StructAfter(const TObject &X, Ts... args)
-{ return StructAtOffset<Type>(&X, X.get_size(args...)); }
+static inline auto StructAfter(const TObject &X, Ts... args) HB_AUTO_RETURN((
+ StructAtOffset<Type>(&X, X.get_size(std::forward<Ts> (args)...))
+))
+/* The is_const shenanigans is to avoid ambiguous overload with gcc-8.
+ * It disables this path when TObject is const.
+ * See: https://github.com/harfbuzz/harfbuzz/issues/5429 */
template <typename Type, typename TObject, typename ...Ts>
-static inline Type& StructAfter(TObject &X, Ts... args)
-{ return StructAtOffset<Type>(&X, X.get_size(args...)); }
+static inline auto StructAfter(TObject &X, Ts... args) HB_AUTO_RETURN((
+ sizeof(int[std::is_const<TObject>::value ? -1 : +1]) > 0 ?
+ StructAtOffset<Type>(&X, X.get_size(std::forward<Ts> (args)...))
+ : *reinterpret_cast<Type*> (0)
+))
/*
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh b/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh
index 1a9dbba6dd3..ec68c3a7281 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-number-parser.hh
@@ -31,7 +31,7 @@
#include "hb.hh"
-#line 35 "hb-number-parser.hh"
+#line 32 "hb-number-parser.hh"
static const unsigned char _double_parser_trans_keys[] = {
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
46u, 101u, 0
@@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */)
int cs;
-#line 139 "hb-number-parser.hh"
+#line 132 "hb-number-parser.hh"
{
cs = double_parser_start;
}
-#line 144 "hb-number-parser.hh"
+#line 135 "hb-number-parser.hh"
{
int _slen;
int _trans;
@@ -198,7 +198,7 @@ _resume:
exp_overflow = true;
}
break;
-#line 202 "hb-number-parser.hh"
+#line 187 "hb-number-parser.hh"
}
_again:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh
index b49c0be5171..4308a73442b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff-common.hh
@@ -79,7 +79,7 @@ struct Dict : UnsizedByteStr
{
TRACE_SERIALIZE (this);
for (unsigned int i = 0; i < dictval.get_count (); i++)
- if (unlikely (!opszr.serialize (c, dictval[i], std::forward<Ts> (ds)...)))
+ if (unlikely (!opszr.serialize (c, dictval[i], ds...)))
return_trace (false);
return_trace (true);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh
index 65d56ae18b5..bf56abb975c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-std-str.hh
@@ -30,396 +30,396 @@
#include "hb.hh"
#endif
-_S(".notdef")
-_S("space")
-_S("exclam")
-_S("quotedbl")
-_S("numbersign")
-_S("dollar")
-_S("percent")
-_S("ampersand")
-_S("quoteright")
-_S("parenleft")
-_S("parenright")
-_S("asterisk")
-_S("plus")
-_S("comma")
-_S("hyphen")
-_S("period")
-_S("slash")
-_S("zero")
-_S("one")
-_S("two")
-_S("three")
-_S("four")
-_S("five")
-_S("six")
-_S("seven")
-_S("eight")
-_S("nine")
-_S("colon")
-_S("semicolon")
-_S("less")
-_S("equal")
-_S("greater")
-_S("question")
-_S("at")
-_S("A")
-_S("B")
-_S("C")
-_S("D")
-_S("E")
-_S("F")
-_S("G")
-_S("H")
-_S("I")
-_S("J")
-_S("K")
-_S("L")
-_S("M")
-_S("N")
-_S("O")
-_S("P")
-_S("Q")
-_S("R")
-_S("S")
-_S("T")
-_S("U")
-_S("V")
-_S("W")
-_S("X")
-_S("Y")
-_S("Z")
-_S("bracketleft")
-_S("backslash")
-_S("bracketright")
-_S("asciicircum")
-_S("underscore")
-_S("quoteleft")
-_S("a")
-_S("b")
-_S("c")
-_S("d")
-_S("e")
-_S("f")
-_S("g")
-_S("h")
-_S("i")
-_S("j")
-_S("k")
-_S("l")
-_S("m")
-_S("n")
-_S("o")
-_S("p")
-_S("q")
-_S("r")
-_S("s")
-_S("t")
-_S("u")
-_S("v")
-_S("w")
-_S("x")
-_S("y")
-_S("z")
-_S("braceleft")
-_S("bar")
-_S("braceright")
-_S("asciitilde")
-_S("exclamdown")
-_S("cent")
-_S("sterling")
-_S("fraction")
-_S("yen")
-_S("florin")
-_S("section")
-_S("currency")
-_S("quotesingle")
-_S("quotedblleft")
-_S("guillemotleft")
-_S("guilsinglleft")
-_S("guilsinglright")
-_S("fi")
-_S("fl")
-_S("endash")
-_S("dagger")
-_S("daggerdbl")
-_S("periodcentered")
-_S("paragraph")
-_S("bullet")
-_S("quotesinglbase")
-_S("quotedblbase")
-_S("quotedblright")
-_S("guillemotright")
-_S("ellipsis")
-_S("perthousand")
-_S("questiondown")
-_S("grave")
-_S("acute")
-_S("circumflex")
-_S("tilde")
-_S("macron")
-_S("breve")
-_S("dotaccent")
-_S("dieresis")
-_S("ring")
-_S("cedilla")
-_S("hungarumlaut")
-_S("ogonek")
-_S("caron")
-_S("emdash")
-_S("AE")
-_S("ordfeminine")
-_S("Lslash")
-_S("Oslash")
-_S("OE")
-_S("ordmasculine")
-_S("ae")
-_S("dotlessi")
-_S("lslash")
-_S("oslash")
-_S("oe")
-_S("germandbls")
-_S("onesuperior")
-_S("logicalnot")
-_S("mu")
-_S("trademark")
-_S("Eth")
-_S("onehalf")
-_S("plusminus")
-_S("Thorn")
-_S("onequarter")
-_S("divide")
-_S("brokenbar")
-_S("degree")
-_S("thorn")
-_S("threequarters")
-_S("twosuperior")
-_S("registered")
-_S("minus")
-_S("eth")
-_S("multiply")
-_S("threesuperior")
-_S("copyright")
-_S("Aacute")
-_S("Acircumflex")
-_S("Adieresis")
-_S("Agrave")
-_S("Aring")
-_S("Atilde")
-_S("Ccedilla")
-_S("Eacute")
-_S("Ecircumflex")
-_S("Edieresis")
-_S("Egrave")
-_S("Iacute")
-_S("Icircumflex")
-_S("Idieresis")
-_S("Igrave")
-_S("Ntilde")
-_S("Oacute")
-_S("Ocircumflex")
-_S("Odieresis")
-_S("Ograve")
-_S("Otilde")
-_S("Scaron")
-_S("Uacute")
-_S("Ucircumflex")
-_S("Udieresis")
-_S("Ugrave")
-_S("Yacute")
-_S("Ydieresis")
-_S("Zcaron")
-_S("aacute")
-_S("acircumflex")
-_S("adieresis")
-_S("agrave")
-_S("aring")
-_S("atilde")
-_S("ccedilla")
-_S("eacute")
-_S("ecircumflex")
-_S("edieresis")
-_S("egrave")
-_S("iacute")
-_S("icircumflex")
-_S("idieresis")
-_S("igrave")
-_S("ntilde")
-_S("oacute")
-_S("ocircumflex")
-_S("odieresis")
-_S("ograve")
-_S("otilde")
-_S("scaron")
-_S("uacute")
-_S("ucircumflex")
-_S("udieresis")
-_S("ugrave")
-_S("yacute")
-_S("ydieresis")
-_S("zcaron")
-_S("exclamsmall")
-_S("Hungarumlautsmall")
-_S("dollaroldstyle")
-_S("dollarsuperior")
-_S("ampersandsmall")
-_S("Acutesmall")
-_S("parenleftsuperior")
-_S("parenrightsuperior")
-_S("twodotenleader")
-_S("onedotenleader")
-_S("zerooldstyle")
-_S("oneoldstyle")
-_S("twooldstyle")
-_S("threeoldstyle")
-_S("fouroldstyle")
-_S("fiveoldstyle")
-_S("sixoldstyle")
-_S("sevenoldstyle")
-_S("eightoldstyle")
-_S("nineoldstyle")
-_S("commasuperior")
-_S("threequartersemdash")
-_S("periodsuperior")
-_S("questionsmall")
-_S("asuperior")
-_S("bsuperior")
-_S("centsuperior")
-_S("dsuperior")
-_S("esuperior")
-_S("isuperior")
-_S("lsuperior")
-_S("msuperior")
-_S("nsuperior")
-_S("osuperior")
-_S("rsuperior")
-_S("ssuperior")
-_S("tsuperior")
-_S("ff")
-_S("ffi")
-_S("ffl")
-_S("parenleftinferior")
-_S("parenrightinferior")
-_S("Circumflexsmall")
-_S("hyphensuperior")
-_S("Gravesmall")
-_S("Asmall")
-_S("Bsmall")
-_S("Csmall")
-_S("Dsmall")
-_S("Esmall")
-_S("Fsmall")
-_S("Gsmall")
-_S("Hsmall")
-_S("Ismall")
-_S("Jsmall")
-_S("Ksmall")
-_S("Lsmall")
-_S("Msmall")
-_S("Nsmall")
-_S("Osmall")
-_S("Psmall")
-_S("Qsmall")
-_S("Rsmall")
-_S("Ssmall")
-_S("Tsmall")
-_S("Usmall")
-_S("Vsmall")
-_S("Wsmall")
-_S("Xsmall")
-_S("Ysmall")
-_S("Zsmall")
-_S("colonmonetary")
-_S("onefitted")
-_S("rupiah")
-_S("Tildesmall")
-_S("exclamdownsmall")
-_S("centoldstyle")
-_S("Lslashsmall")
-_S("Scaronsmall")
-_S("Zcaronsmall")
-_S("Dieresissmall")
-_S("Brevesmall")
-_S("Caronsmall")
-_S("Dotaccentsmall")
-_S("Macronsmall")
-_S("figuredash")
-_S("hypheninferior")
-_S("Ogoneksmall")
-_S("Ringsmall")
-_S("Cedillasmall")
-_S("questiondownsmall")
-_S("oneeighth")
-_S("threeeighths")
-_S("fiveeighths")
-_S("seveneighths")
-_S("onethird")
-_S("twothirds")
-_S("zerosuperior")
-_S("foursuperior")
-_S("fivesuperior")
-_S("sixsuperior")
-_S("sevensuperior")
-_S("eightsuperior")
-_S("ninesuperior")
-_S("zeroinferior")
-_S("oneinferior")
-_S("twoinferior")
-_S("threeinferior")
-_S("fourinferior")
-_S("fiveinferior")
-_S("sixinferior")
-_S("seveninferior")
-_S("eightinferior")
-_S("nineinferior")
-_S("centinferior")
-_S("dollarinferior")
-_S("periodinferior")
-_S("commainferior")
-_S("Agravesmall")
-_S("Aacutesmall")
-_S("Acircumflexsmall")
-_S("Atildesmall")
-_S("Adieresissmall")
-_S("Aringsmall")
-_S("AEsmall")
-_S("Ccedillasmall")
-_S("Egravesmall")
-_S("Eacutesmall")
-_S("Ecircumflexsmall")
-_S("Edieresissmall")
-_S("Igravesmall")
-_S("Iacutesmall")
-_S("Icircumflexsmall")
-_S("Idieresissmall")
-_S("Ethsmall")
-_S("Ntildesmall")
-_S("Ogravesmall")
-_S("Oacutesmall")
-_S("Ocircumflexsmall")
-_S("Otildesmall")
-_S("Odieresissmall")
-_S("OEsmall")
-_S("Oslashsmall")
-_S("Ugravesmall")
-_S("Uacutesmall")
-_S("Ucircumflexsmall")
-_S("Udieresissmall")
-_S("Yacutesmall")
-_S("Thornsmall")
-_S("Ydieresissmall")
-_S("001.000")
-_S("001.001")
-_S("001.002")
-_S("001.003")
-_S("Black")
-_S("Bold")
-_S("Book")
-_S("Light")
-_S("Medium")
-_S("Regular")
-_S("Roman")
-_S("Semibold")
+HB_STR(".notdef")
+HB_STR("space")
+HB_STR("exclam")
+HB_STR("quotedbl")
+HB_STR("numbersign")
+HB_STR("dollar")
+HB_STR("percent")
+HB_STR("ampersand")
+HB_STR("quoteright")
+HB_STR("parenleft")
+HB_STR("parenright")
+HB_STR("asterisk")
+HB_STR("plus")
+HB_STR("comma")
+HB_STR("hyphen")
+HB_STR("period")
+HB_STR("slash")
+HB_STR("zero")
+HB_STR("one")
+HB_STR("two")
+HB_STR("three")
+HB_STR("four")
+HB_STR("five")
+HB_STR("six")
+HB_STR("seven")
+HB_STR("eight")
+HB_STR("nine")
+HB_STR("colon")
+HB_STR("semicolon")
+HB_STR("less")
+HB_STR("equal")
+HB_STR("greater")
+HB_STR("question")
+HB_STR("at")
+HB_STR("A")
+HB_STR("B")
+HB_STR("C")
+HB_STR("D")
+HB_STR("E")
+HB_STR("F")
+HB_STR("G")
+HB_STR("H")
+HB_STR("I")
+HB_STR("J")
+HB_STR("K")
+HB_STR("L")
+HB_STR("M")
+HB_STR("N")
+HB_STR("O")
+HB_STR("P")
+HB_STR("Q")
+HB_STR("R")
+HB_STR("S")
+HB_STR("T")
+HB_STR("U")
+HB_STR("V")
+HB_STR("W")
+HB_STR("X")
+HB_STR("Y")
+HB_STR("Z")
+HB_STR("bracketleft")
+HB_STR("backslash")
+HB_STR("bracketright")
+HB_STR("asciicircum")
+HB_STR("underscore")
+HB_STR("quoteleft")
+HB_STR("a")
+HB_STR("b")
+HB_STR("c")
+HB_STR("d")
+HB_STR("e")
+HB_STR("f")
+HB_STR("g")
+HB_STR("h")
+HB_STR("i")
+HB_STR("j")
+HB_STR("k")
+HB_STR("l")
+HB_STR("m")
+HB_STR("n")
+HB_STR("o")
+HB_STR("p")
+HB_STR("q")
+HB_STR("r")
+HB_STR("s")
+HB_STR("t")
+HB_STR("u")
+HB_STR("v")
+HB_STR("w")
+HB_STR("x")
+HB_STR("y")
+HB_STR("z")
+HB_STR("braceleft")
+HB_STR("bar")
+HB_STR("braceright")
+HB_STR("asciitilde")
+HB_STR("exclamdown")
+HB_STR("cent")
+HB_STR("sterling")
+HB_STR("fraction")
+HB_STR("yen")
+HB_STR("florin")
+HB_STR("section")
+HB_STR("currency")
+HB_STR("quotesingle")
+HB_STR("quotedblleft")
+HB_STR("guillemotleft")
+HB_STR("guilsinglleft")
+HB_STR("guilsinglright")
+HB_STR("fi")
+HB_STR("fl")
+HB_STR("endash")
+HB_STR("dagger")
+HB_STR("daggerdbl")
+HB_STR("periodcentered")
+HB_STR("paragraph")
+HB_STR("bullet")
+HB_STR("quotesinglbase")
+HB_STR("quotedblbase")
+HB_STR("quotedblright")
+HB_STR("guillemotright")
+HB_STR("ellipsis")
+HB_STR("perthousand")
+HB_STR("questiondown")
+HB_STR("grave")
+HB_STR("acute")
+HB_STR("circumflex")
+HB_STR("tilde")
+HB_STR("macron")
+HB_STR("breve")
+HB_STR("dotaccent")
+HB_STR("dieresis")
+HB_STR("ring")
+HB_STR("cedilla")
+HB_STR("hungarumlaut")
+HB_STR("ogonek")
+HB_STR("caron")
+HB_STR("emdash")
+HB_STR("AE")
+HB_STR("ordfeminine")
+HB_STR("Lslash")
+HB_STR("Oslash")
+HB_STR("OE")
+HB_STR("ordmasculine")
+HB_STR("ae")
+HB_STR("dotlessi")
+HB_STR("lslash")
+HB_STR("oslash")
+HB_STR("oe")
+HB_STR("germandbls")
+HB_STR("onesuperior")
+HB_STR("logicalnot")
+HB_STR("mu")
+HB_STR("trademark")
+HB_STR("Eth")
+HB_STR("onehalf")
+HB_STR("plusminus")
+HB_STR("Thorn")
+HB_STR("onequarter")
+HB_STR("divide")
+HB_STR("brokenbar")
+HB_STR("degree")
+HB_STR("thorn")
+HB_STR("threequarters")
+HB_STR("twosuperior")
+HB_STR("registered")
+HB_STR("minus")
+HB_STR("eth")
+HB_STR("multiply")
+HB_STR("threesuperior")
+HB_STR("copyright")
+HB_STR("Aacute")
+HB_STR("Acircumflex")
+HB_STR("Adieresis")
+HB_STR("Agrave")
+HB_STR("Aring")
+HB_STR("Atilde")
+HB_STR("Ccedilla")
+HB_STR("Eacute")
+HB_STR("Ecircumflex")
+HB_STR("Edieresis")
+HB_STR("Egrave")
+HB_STR("Iacute")
+HB_STR("Icircumflex")
+HB_STR("Idieresis")
+HB_STR("Igrave")
+HB_STR("Ntilde")
+HB_STR("Oacute")
+HB_STR("Ocircumflex")
+HB_STR("Odieresis")
+HB_STR("Ograve")
+HB_STR("Otilde")
+HB_STR("Scaron")
+HB_STR("Uacute")
+HB_STR("Ucircumflex")
+HB_STR("Udieresis")
+HB_STR("Ugrave")
+HB_STR("Yacute")
+HB_STR("Ydieresis")
+HB_STR("Zcaron")
+HB_STR("aacute")
+HB_STR("acircumflex")
+HB_STR("adieresis")
+HB_STR("agrave")
+HB_STR("aring")
+HB_STR("atilde")
+HB_STR("ccedilla")
+HB_STR("eacute")
+HB_STR("ecircumflex")
+HB_STR("edieresis")
+HB_STR("egrave")
+HB_STR("iacute")
+HB_STR("icircumflex")
+HB_STR("idieresis")
+HB_STR("igrave")
+HB_STR("ntilde")
+HB_STR("oacute")
+HB_STR("ocircumflex")
+HB_STR("odieresis")
+HB_STR("ograve")
+HB_STR("otilde")
+HB_STR("scaron")
+HB_STR("uacute")
+HB_STR("ucircumflex")
+HB_STR("udieresis")
+HB_STR("ugrave")
+HB_STR("yacute")
+HB_STR("ydieresis")
+HB_STR("zcaron")
+HB_STR("exclamsmall")
+HB_STR("Hungarumlautsmall")
+HB_STR("dollaroldstyle")
+HB_STR("dollarsuperior")
+HB_STR("ampersandsmall")
+HB_STR("Acutesmall")
+HB_STR("parenleftsuperior")
+HB_STR("parenrightsuperior")
+HB_STR("twodotenleader")
+HB_STR("onedotenleader")
+HB_STR("zerooldstyle")
+HB_STR("oneoldstyle")
+HB_STR("twooldstyle")
+HB_STR("threeoldstyle")
+HB_STR("fouroldstyle")
+HB_STR("fiveoldstyle")
+HB_STR("sixoldstyle")
+HB_STR("sevenoldstyle")
+HB_STR("eightoldstyle")
+HB_STR("nineoldstyle")
+HB_STR("commasuperior")
+HB_STR("threequartersemdash")
+HB_STR("periodsuperior")
+HB_STR("questionsmall")
+HB_STR("asuperior")
+HB_STR("bsuperior")
+HB_STR("centsuperior")
+HB_STR("dsuperior")
+HB_STR("esuperior")
+HB_STR("isuperior")
+HB_STR("lsuperior")
+HB_STR("msuperior")
+HB_STR("nsuperior")
+HB_STR("osuperior")
+HB_STR("rsuperior")
+HB_STR("ssuperior")
+HB_STR("tsuperior")
+HB_STR("ff")
+HB_STR("ffi")
+HB_STR("ffl")
+HB_STR("parenleftinferior")
+HB_STR("parenrightinferior")
+HB_STR("Circumflexsmall")
+HB_STR("hyphensuperior")
+HB_STR("Gravesmall")
+HB_STR("Asmall")
+HB_STR("Bsmall")
+HB_STR("Csmall")
+HB_STR("Dsmall")
+HB_STR("Esmall")
+HB_STR("Fsmall")
+HB_STR("Gsmall")
+HB_STR("Hsmall")
+HB_STR("Ismall")
+HB_STR("Jsmall")
+HB_STR("Ksmall")
+HB_STR("Lsmall")
+HB_STR("Msmall")
+HB_STR("Nsmall")
+HB_STR("Osmall")
+HB_STR("Psmall")
+HB_STR("Qsmall")
+HB_STR("Rsmall")
+HB_STR("Ssmall")
+HB_STR("Tsmall")
+HB_STR("Usmall")
+HB_STR("Vsmall")
+HB_STR("Wsmall")
+HB_STR("Xsmall")
+HB_STR("Ysmall")
+HB_STR("Zsmall")
+HB_STR("colonmonetary")
+HB_STR("onefitted")
+HB_STR("rupiah")
+HB_STR("Tildesmall")
+HB_STR("exclamdownsmall")
+HB_STR("centoldstyle")
+HB_STR("Lslashsmall")
+HB_STR("Scaronsmall")
+HB_STR("Zcaronsmall")
+HB_STR("Dieresissmall")
+HB_STR("Brevesmall")
+HB_STR("Caronsmall")
+HB_STR("Dotaccentsmall")
+HB_STR("Macronsmall")
+HB_STR("figuredash")
+HB_STR("hypheninferior")
+HB_STR("Ogoneksmall")
+HB_STR("Ringsmall")
+HB_STR("Cedillasmall")
+HB_STR("questiondownsmall")
+HB_STR("oneeighth")
+HB_STR("threeeighths")
+HB_STR("fiveeighths")
+HB_STR("seveneighths")
+HB_STR("onethird")
+HB_STR("twothirds")
+HB_STR("zerosuperior")
+HB_STR("foursuperior")
+HB_STR("fivesuperior")
+HB_STR("sixsuperior")
+HB_STR("sevensuperior")
+HB_STR("eightsuperior")
+HB_STR("ninesuperior")
+HB_STR("zeroinferior")
+HB_STR("oneinferior")
+HB_STR("twoinferior")
+HB_STR("threeinferior")
+HB_STR("fourinferior")
+HB_STR("fiveinferior")
+HB_STR("sixinferior")
+HB_STR("seveninferior")
+HB_STR("eightinferior")
+HB_STR("nineinferior")
+HB_STR("centinferior")
+HB_STR("dollarinferior")
+HB_STR("periodinferior")
+HB_STR("commainferior")
+HB_STR("Agravesmall")
+HB_STR("Aacutesmall")
+HB_STR("Acircumflexsmall")
+HB_STR("Atildesmall")
+HB_STR("Adieresissmall")
+HB_STR("Aringsmall")
+HB_STR("AEsmall")
+HB_STR("Ccedillasmall")
+HB_STR("Egravesmall")
+HB_STR("Eacutesmall")
+HB_STR("Ecircumflexsmall")
+HB_STR("Edieresissmall")
+HB_STR("Igravesmall")
+HB_STR("Iacutesmall")
+HB_STR("Icircumflexsmall")
+HB_STR("Idieresissmall")
+HB_STR("Ethsmall")
+HB_STR("Ntildesmall")
+HB_STR("Ogravesmall")
+HB_STR("Oacutesmall")
+HB_STR("Ocircumflexsmall")
+HB_STR("Otildesmall")
+HB_STR("Odieresissmall")
+HB_STR("OEsmall")
+HB_STR("Oslashsmall")
+HB_STR("Ugravesmall")
+HB_STR("Uacutesmall")
+HB_STR("Ucircumflexsmall")
+HB_STR("Udieresissmall")
+HB_STR("Yacutesmall")
+HB_STR("Thornsmall")
+HB_STR("Ydieresissmall")
+HB_STR("001.000")
+HB_STR("001.001")
+HB_STR("001.002")
+HB_STR("001.003")
+HB_STR("Black")
+HB_STR("Bold")
+HB_STR("Book")
+HB_STR("Light")
+HB_STR("Medium")
+HB_STR("Regular")
+HB_STR("Roman")
+HB_STR("Semibold")
#endif /* HB_OT_CFF1_STD_STR_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
index 0f19b55614f..76c4bf28d9b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
@@ -466,6 +466,11 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
{
const auto &glyf = *ot_face->glyf;
auto *scratch = glyf.acquire_scratch ();
+ if (unlikely (!scratch))
+ {
+ ot_font->h.release_advance_cache (advance_cache);
+ goto fallback;
+ }
OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar);
for (unsigned int i = 0; i < count; i++)
@@ -586,6 +591,11 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
{
const auto &glyf = *ot_face->glyf;
auto *scratch = glyf.acquire_scratch ();
+ if (unlikely (!scratch))
+ {
+ ot_font->v.release_advance_cache (advance_cache);
+ goto fallback;
+ }
OT::hb_scalar_cache_t *gvar_cache = ot_font->draw.acquire_gvar_cache (gvar);
for (unsigned int i = 0; i < count; i++)
@@ -664,7 +674,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font,
hb_position_t origin;
unsigned cv;
if (origin_cache->get (*first_glyph, &cv))
- origin = font->y_scale < 0 ? -cv : cv;
+ origin = font->y_scale < 0 ? -static_cast<hb_position_t>(cv) : static_cast<hb_position_t>(cv);
else
{
origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph));
@@ -688,7 +698,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font,
hb_position_t origin;
unsigned cv;
if (origin_cache->get (*first_glyph, &cv))
- origin = font->y_scale < 0 ? -cv : cv;
+ origin = font->y_scale < 0 ? -static_cast<hb_position_t>(cv) : static_cast<hb_position_t>(cv);
else
{
origin = font->em_scalef_y (VORG.get_y_origin (*first_glyph) +
@@ -717,6 +727,11 @@ hb_ot_get_glyph_v_origins (hb_font_t *font,
if (origin_cache && vmtx.has_data() && glyf.has_data ())
{
auto *scratch = glyf.acquire_scratch ();
+ if (unlikely (!scratch))
+ {
+ ot_font->v_origin.release_origin_cache (origin_cache);
+ return false;
+ }
OT::hb_scalar_cache_t *gvar_cache = font->has_nonzero_coords ?
ot_font->draw.acquire_gvar_cache (*ot_face->gvar) :
nullptr;
@@ -726,7 +741,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font,
hb_position_t origin;
unsigned cv;
if (origin_cache->get (*first_glyph, &cv))
- origin = font->y_scale < 0 ? -cv : cv;
+ origin = font->y_scale < 0 ? -static_cast<hb_position_t>(cv) : static_cast<hb_position_t>(cv);
else
{
origin = font->em_scalef_y (glyf.get_v_origin_with_var_unscaled (*first_glyph, font, *scratch, gvar_cache));
@@ -760,7 +775,7 @@ hb_ot_get_glyph_v_origins (hb_font_t *font,
unsigned cv;
if (origin_cache->get (*first_glyph, &cv))
- origin = font->y_scale < 0 ? -cv : cv;
+ origin = font->y_scale < 0 ? -static_cast<hb_position_t>(cv) : static_cast<hb_position_t>(cv);
else
{
hb_glyph_extents_t extents = {0};
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 43a2d9cf76a..99ea3804263 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -371,9 +371,9 @@ struct hmtxvmtx
hb_scalar_cache_t *store_cache = nullptr) const
{
unsigned int advance = get_advance_without_var_unscaled (glyph);
- return advance + roundf (var_table->get_advance_delta_unscaled (glyph,
+ return hb_max(0.0f, advance + roundf (var_table->get_advance_delta_unscaled (glyph,
font->coords, font->num_coords,
- store_cache));
+ store_cache)));
}
#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 06c3c0ee976..53c186f5c2e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
@@ -1337,7 +1337,7 @@ struct Lookup
TRACE_DISPATCH (this, lookup_type);
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
- typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
+ typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, ds...);
if (c->stop_sublookup_iteration (r))
return_trace (r);
}
@@ -2078,7 +2078,7 @@ struct ClassDef
}
}
unsigned int get_class (hb_codepoint_t glyph_id,
- hb_ot_lookup_cache_t *cache) const
+ hb_ot_layout_mapping_cache_t *cache) const
{
unsigned klass;
if (cache && cache->get (glyph_id, &klass)) return klass;
@@ -2575,7 +2575,7 @@ struct hb_scalar_cache_t
return scratch_cache;
}
- auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (values) + sizeof (values[0]) * count);
+ auto *cache = (hb_scalar_cache_t *) hb_malloc (sizeof (hb_scalar_cache_t) - sizeof (static_values) + sizeof (static_values[0]) * count);
if (unlikely (!cache)) return (hb_scalar_cache_t *) &Null(hb_scalar_cache_t);
cache->length = count;
@@ -2593,6 +2593,7 @@ struct hb_scalar_cache_t
void clear ()
{
+ auto *values = &static_values[0];
for (unsigned i = 0; i < length; i++)
values[i] = INVALID;
}
@@ -2605,6 +2606,7 @@ struct hb_scalar_cache_t
*value = 0.f;
return true;
}
+ auto *values = &static_values[0];
auto *cached_value = &values[i];
if (*cached_value != INVALID)
{
@@ -2618,13 +2620,14 @@ struct hb_scalar_cache_t
void set (unsigned i, float value)
{
if (unlikely (i >= length)) return;
+ auto *values = &static_values[0];
auto *cached_value = &values[i];
*cached_value = roundf(value * MULTIPLIER);
}
private:
unsigned length;
- mutable hb_atomic_t<int> values[STATIC_LENGTH];
+ mutable hb_atomic_t<int> static_values[STATIC_LENGTH];
};
struct VarRegionList
@@ -3439,7 +3442,7 @@ struct ItemVariationStore
for (unsigned i = 0; i < count; i++)
{
hb_inc_bimap_t *map = inner_maps.push ();
- if (!c->propagate_error(inner_maps))
+ if (unlikely (!c->propagate_error(inner_maps)))
return_trace(nullptr);
auto &data = this+dataSets[i];
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 83325548ded..6f9bb18cd27 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
@@ -455,7 +455,7 @@ struct matcher_t
HB_ALWAYS_INLINE
#endif
may_skip_t may_skip (const context_t *c,
- const hb_glyph_info_t &info) const
+ const hb_glyph_info_t &info) const
{
if (!c->check_glyph_property (&info, lookup_props))
return SKIP_YES;
@@ -470,7 +470,7 @@ struct matcher_t
}
public:
- unsigned int lookup_props = 0;
+ unsigned int lookup_props = (unsigned) -1;
hb_mask_t mask = -1;
bool ignore_zwnj = false;
bool ignore_zwj = false;
@@ -670,8 +670,14 @@ struct hb_ot_apply_context_t :
{
const char *get_name () { return "APPLY"; }
typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index);
+
+ template <typename T>
+ static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (return_t, obj.apply (c, nullptr) )
+ template <typename T>
+ static inline auto apply_ (const T &obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (return_t, obj.apply (c) )
template <typename T>
- return_t dispatch (const T &obj) { return obj.apply (this); }
+ return_t dispatch (const T &obj) { return apply_(obj, this, hb_prioritize); }
+
static return_t default_return_value () { return false; }
bool stop_sublookup_iteration (return_t r) const { return r; }
return_t recurse (unsigned int sub_lookup_index)
@@ -706,7 +712,8 @@ struct hb_ot_apply_context_t :
hb_direction_t direction;
hb_mask_t lookup_mask = 1;
unsigned int lookup_index = (unsigned) -1;
- unsigned int lookup_props = 0;
+ unsigned int lookup_props = (unsigned) -1;
+ unsigned int cached_props = (unsigned) -1; /* Cached glyph properties for the current lookup. */
unsigned int nesting_level_left = HB_MAX_NESTING_LEVEL;
bool has_glyph_classes;
@@ -772,15 +779,22 @@ struct hb_ot_apply_context_t :
return buffer->random_state;
}
- bool match_properties_mark (hb_codepoint_t glyph,
+ HB_ALWAYS_INLINE
+ HB_HOT
+ bool match_properties_mark (const hb_glyph_info_t *info,
unsigned int glyph_props,
- unsigned int match_props) const
+ unsigned int match_props,
+ bool cached) const
{
/* If using mark filtering sets, the high short of
* match_props has the set index.
*/
if (match_props & LookupFlag::UseMarkFilteringSet)
- return gdef_accel.mark_set_covers (match_props >> 16, glyph);
+ {
+ if (cached && match_props == cached_props)
+ return _hb_glyph_info_matches (info);
+ return gdef_accel.mark_set_covers (match_props >> 16, info->codepoint);
+ }
/* The second byte of match_props has the meaning
* "ignore marks of attachment type different than
@@ -796,7 +810,8 @@ struct hb_ot_apply_context_t :
HB_ALWAYS_INLINE
#endif
bool check_glyph_property (const hb_glyph_info_t *info,
- unsigned int match_props) const
+ unsigned match_props,
+ bool cached = true) const
{
unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
@@ -807,7 +822,7 @@ struct hb_ot_apply_context_t :
return false;
if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
- return match_properties_mark (info->codepoint, glyph_props, match_props);
+ return match_properties_mark (info, glyph_props, match_props, cached);
return true;
}
@@ -849,6 +864,10 @@ struct hb_ot_apply_context_t :
}
else
_hb_glyph_info_set_glyph_props (&buffer->cur(), props);
+
+ if (cached_props != (unsigned) -1)
+ _hb_glyph_info_set_match (&buffer->cur(),
+ check_glyph_property (&buffer->cur(), cached_props, false));
}
void replace_glyph (hb_codepoint_t glyph_index)
@@ -875,7 +894,7 @@ struct hb_ot_apply_context_t :
}
};
-enum class hb_ot_lookup_cache_op_t
+enum class hb_ot_subtable_cache_op_t
{
CREATE,
ENTER,
@@ -886,43 +905,49 @@ enum class hb_ot_lookup_cache_op_t
struct hb_accelerate_subtables_context_t :
hb_dispatch_context_t<hb_accelerate_subtables_context_t>
{
- template <typename Type>
- static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c)
+ template <typename T>
+ static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) )
+ template <typename T>
+ static inline auto apply_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
+ template <typename T>
+ static inline bool apply_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache)
{
- const Type *typed_obj = (const Type *) obj;
- return typed_obj->apply (c);
+ const T *typed_obj = (const T *) obj;
+ return apply_ (typed_obj, c, external_cache, hb_prioritize);
}
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) )
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<2>) HB_RETURN (bool, obj->apply_cached (c, external_cache) )
template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
- template <typename Type>
- static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c)
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<1>) HB_RETURN (bool, obj->apply (c, external_cache) )
+ template <typename T>
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, void *external_cache, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
+ template <typename T>
+ static inline bool apply_cached_to (const void *obj, hb_ot_apply_context_t *c, void *external_cache)
{
- const Type *typed_obj = (const Type *) obj;
- return apply_cached_ (typed_obj, c, hb_prioritize);
+ const T *typed_obj = (const T *) obj;
+ return apply_cached_ (typed_obj, c, external_cache, hb_prioritize);
}
template <typename T>
static inline auto cache_func_ (void *p,
- hb_ot_lookup_cache_op_t op,
+ hb_ot_subtable_cache_op_t op,
hb_priority<1>) HB_RETURN (void *, T::cache_func (p, op) )
template <typename T=void>
static inline void * cache_func_ (void *p,
- hb_ot_lookup_cache_op_t op HB_UNUSED,
- hb_priority<0>) { return (void *) false; }
+ hb_ot_subtable_cache_op_t op HB_UNUSED,
+ hb_priority<0>) { return nullptr; }
template <typename Type>
static inline void * cache_func_to (void *p,
- hb_ot_lookup_cache_op_t op)
+ hb_ot_subtable_cache_op_t op)
{
return cache_func_<Type> (p, op, hb_prioritize);
}
#endif
- typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c);
- typedef void * (*hb_cache_func_t) (void *p, hb_ot_lookup_cache_op_t op);
+ typedef bool (*hb_apply_func_t) (const void *obj, hb_ot_apply_context_t *c, void *external_cache);
+ typedef void * (*hb_cache_func_t) (void *p, hb_ot_subtable_cache_op_t op);
struct hb_applicable_t
{
@@ -943,27 +968,37 @@ struct hb_accelerate_subtables_context_t :
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
apply_cached_func = apply_cached_func_;
cache_func = cache_func_;
+ external_cache = cache_create ();
#endif
digest.init ();
obj_.get_coverage ().collect_coverage (&digest);
}
+#ifdef HB_NO_OT_LAYOUT_LOOKUP_CACHE
bool apply (hb_ot_apply_context_t *c) const
{
- return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c);
+ return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, nullptr);
+ }
+#else
+ bool apply (hb_ot_apply_context_t *c) const
+ {
+ return digest.may_have (c->buffer->cur().codepoint) && apply_func (obj, c, external_cache);
}
-#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
bool apply_cached (hb_ot_apply_context_t *c) const
{
- return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c);
+ return digest.may_have (c->buffer->cur().codepoint) && apply_cached_func (obj, c, external_cache);
+ }
+ void *cache_create () const
+ {
+ return cache_func (nullptr, hb_ot_subtable_cache_op_t::CREATE);
}
bool cache_enter (hb_ot_apply_context_t *c) const
{
- return (bool) cache_func (c, hb_ot_lookup_cache_op_t::ENTER);
+ return (bool) cache_func (c, hb_ot_subtable_cache_op_t::ENTER);
}
void cache_leave (hb_ot_apply_context_t *c) const
{
- cache_func (c, hb_ot_lookup_cache_op_t::LEAVE);
+ cache_func (c, hb_ot_subtable_cache_op_t::LEAVE);
}
#endif
@@ -973,6 +1008,7 @@ struct hb_accelerate_subtables_context_t :
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
hb_apply_func_t apply_cached_func;
hb_cache_func_t cache_func;
+ void *external_cache;
#endif
hb_set_digest_t digest;
};
@@ -1008,10 +1044,10 @@ struct hb_accelerate_subtables_context_t :
* and we allocate the cache opportunity to the costliest subtable.
*/
unsigned cost = cache_cost (obj, hb_prioritize);
- if (cost > cache_user_cost)
+ if (cost > subtable_cache_user_cost)
{
- cache_user_idx = i - 1;
- cache_user_cost = cost;
+ subtable_cache_user_idx = i - 1;
+ subtable_cache_user_cost = cost;
}
#endif
@@ -1026,8 +1062,8 @@ struct hb_accelerate_subtables_context_t :
unsigned i = 0;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- unsigned cache_user_idx = (unsigned) -1;
- unsigned cache_user_cost = 0;
+ unsigned subtable_cache_user_idx = (unsigned) -1;
+ unsigned subtable_cache_user_cost = 0;
#endif
};
@@ -1176,38 +1212,50 @@ static inline bool match_class (hb_glyph_info_t &info, unsigned value, const voi
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.get_class (info.codepoint) == value;
}
-static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data)
+static inline unsigned get_class_cached (const ClassDef &class_def, hb_glyph_info_t &info)
{
unsigned klass = info.syllable();
if (klass < 255)
- return klass == value;
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return klass;
klass = class_def.get_class (info.codepoint);
if (likely (klass < 255))
info.syllable() = klass;
- return klass == value;
+ return klass;
}
-static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data)
+static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return get_class_cached (class_def, info) == value;
+}
+static inline unsigned get_class_cached1 (const ClassDef &class_def, hb_glyph_info_t &info)
{
unsigned klass = info.syllable() & 0x0F;
if (klass < 15)
- return klass == value;
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return klass;
klass = class_def.get_class (info.codepoint);
if (likely (klass < 15))
info.syllable() = (info.syllable() & 0xF0) | klass;
- return klass == value;
+ return klass;
}
-static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data)
+static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return get_class_cached1 (class_def, info) == value;
+}
+static inline unsigned get_class_cached2 (const ClassDef &class_def, hb_glyph_info_t &info)
{
unsigned klass = (info.syllable() & 0xF0) >> 4;
if (klass < 15)
- return klass == value;
- const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return klass;
klass = class_def.get_class (info.codepoint);
if (likely (klass < 15))
info.syllable() = (info.syllable() & 0x0F) | (klass << 4);
- return klass == value;
+ return klass;
+}
+static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return get_class_cached2 (class_def, info) == value;
}
static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data)
{
@@ -1321,7 +1369,7 @@ static bool match_input (hb_ot_apply_context_t *c,
if (ligbase == LIGBASE_NOT_CHECKED)
{
bool found = false;
- const auto *out = buffer->out_info;
+ auto *out = buffer->out_info;
unsigned int j = buffer->out_len;
while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
{
@@ -1979,6 +2027,37 @@ static bool context_apply_lookup (hb_ot_apply_context_t *c,
return ret;
}
+static inline void * context_cache_func (void *p, hb_ot_subtable_cache_op_t op)
+{
+ switch (op)
+ {
+ case hb_ot_subtable_cache_op_t::CREATE:
+ return nullptr;
+ case hb_ot_subtable_cache_op_t::ENTER:
+ {
+ hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
+ if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
+ return (void *) false;
+ auto &info = c->buffer->info;
+ unsigned count = c->buffer->len;
+ for (unsigned i = 0; i < count; i++)
+ info[i].syllable() = 255;
+ c->new_syllables = 255;
+ return (void *) true;
+ }
+ case hb_ot_subtable_cache_op_t::LEAVE:
+ {
+ hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
+ c->new_syllables = (unsigned) -1;
+ HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
+ return nullptr;
+ }
+ case hb_ot_subtable_cache_op_t::DESTROY:
+ return nullptr;
+ }
+ return nullptr;
+}
+
template <typename Types>
struct Rule
{
@@ -2607,41 +2686,14 @@ struct ContextFormat2_5
unsigned cache_cost () const
{
- unsigned c = (this+classDef).cost () * ruleSet.len;
- return c >= 4 ? c : 0;
+ return (this+classDef).cost ();
}
- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
+ static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
{
- switch (op)
- {
- case hb_ot_lookup_cache_op_t::CREATE:
- return (void *) true;
- case hb_ot_lookup_cache_op_t::ENTER:
- {
- hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
- if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
- return (void *) false;
- auto &info = c->buffer->info;
- unsigned count = c->buffer->len;
- for (unsigned i = 0; i < count; i++)
- info[i].syllable() = 255;
- c->new_syllables = 255;
- return (void *) true;
- }
- case hb_ot_lookup_cache_op_t::LEAVE:
- {
- hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
- c->new_syllables = (unsigned) -1;
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
- return nullptr;
- }
- case hb_ot_lookup_cache_op_t::DESTROY:
- return nullptr;
- }
- return nullptr;
+ return context_cache_func (p, op);
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+ bool apply_cached (hb_ot_apply_context_t *c, void *external_cache HB_UNUSED) const { return _apply (c, true); }
bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
@@ -2656,10 +2708,7 @@ struct ContextFormat2_5
&class_def
};
- if (cached && c->buffer->cur().syllable() < 255)
- index = c->buffer->cur().syllable ();
- else
- index = class_def.get_class (c->buffer->cur().codepoint);
+ index = cached ? get_class_cached (class_def, c->buffer->cur()) : class_def.get_class (c->buffer->cur().codepoint);
const RuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -3858,40 +3907,14 @@ struct ChainContextFormat2_5
unsigned cache_cost () const
{
- return (this+lookaheadClassDef).cost () * ruleSet.len;
+ return (this+inputClassDef).cost () + (this+lookaheadClassDef).cost ();
}
- static void * cache_func (void *p, hb_ot_lookup_cache_op_t op)
+ static void * cache_func (void *p, hb_ot_subtable_cache_op_t op)
{
- switch (op)
- {
- case hb_ot_lookup_cache_op_t::CREATE:
- return (void *) true;
- case hb_ot_lookup_cache_op_t::ENTER:
- {
- hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
- if (!HB_BUFFER_TRY_ALLOCATE_VAR (c->buffer, syllable))
- return (void *) false;
- auto &info = c->buffer->info;
- unsigned count = c->buffer->len;
- for (unsigned i = 0; i < count; i++)
- info[i].syllable() = 255;
- c->new_syllables = 255;
- return (void *) true;
- }
- case hb_ot_lookup_cache_op_t::LEAVE:
- {
- hb_ot_apply_context_t *c = (hb_ot_apply_context_t *) p;
- c->new_syllables = (unsigned) -1;
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, syllable);
- return nullptr;
- }
- case hb_ot_lookup_cache_op_t::DESTROY:
- return nullptr;
- }
- return nullptr;
+ return context_cache_func (p, op);
}
- bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+ bool apply_cached (hb_ot_apply_context_t *c, void *external_cache HB_UNUSED) const { return _apply (c, true); }
bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
@@ -3914,11 +3937,9 @@ struct ChainContextFormat2_5
&lookahead_class_def}
};
- // Note: Corresponds to match_class_cached2
- if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15)
- index = (c->buffer->cur().syllable () & 0xF0) >> 4;
- else
- index = input_class_def.get_class (c->buffer->cur().codepoint);
+ index = cached
+ ? get_class_cached2 (input_class_def, c->buffer->cur())
+ : input_class_def.get_class (c->buffer->cur().codepoint);
const ChainRuleSet &rule_set = this+ruleSet[index];
return_trace (rule_set.apply (c, lookup_context));
}
@@ -4414,21 +4435,12 @@ struct hb_ot_layout_lookup_accelerator_t
thiz->digest.union_ (subtable.digest);
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- if (c_accelerate_subtables.cache_user_cost < 4)
- c_accelerate_subtables.cache_user_idx = (unsigned) -1;
-
- thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx;
-
- if (thiz->cache_user_idx != (unsigned) -1)
- {
- thiz->cache = thiz->subtables[thiz->cache_user_idx].cache_func (nullptr, hb_ot_lookup_cache_op_t::CREATE);
- if (!thiz->cache)
- thiz->cache_user_idx = (unsigned) -1;
- }
+ thiz->count = count;
+ thiz->subtable_cache_user_idx = c_accelerate_subtables.subtable_cache_user_idx;
for (unsigned i = 0; i < count; i++)
- if (i != thiz->cache_user_idx)
- thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func;
+ if (i != thiz->subtable_cache_user_idx)
+ thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func;
#endif
return thiz;
@@ -4437,11 +4449,9 @@ struct hb_ot_layout_lookup_accelerator_t
void fini ()
{
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- if (cache)
- {
- assert (cache_user_idx != (unsigned) -1);
- subtables[cache_user_idx].cache_func (cache, hb_ot_lookup_cache_op_t::DESTROY);
- }
+ for (unsigned i = 0; i < count; i++)
+ if (subtables[i].external_cache)
+ subtables[i].cache_func (subtables[i].external_cache, hb_ot_subtable_cache_op_t::DESTROY);
#endif
}
@@ -4478,8 +4488,8 @@ struct hb_ot_layout_lookup_accelerator_t
bool cache_enter (hb_ot_apply_context_t *c) const
{
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- return cache_user_idx != (unsigned) -1 &&
- subtables[cache_user_idx].cache_enter (c);
+ return subtable_cache_user_idx != (unsigned) -1 &&
+ subtables[subtable_cache_user_idx].cache_enter (c);
#else
return false;
#endif
@@ -4487,17 +4497,16 @@ struct hb_ot_layout_lookup_accelerator_t
void cache_leave (hb_ot_apply_context_t *c) const
{
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- subtables[cache_user_idx].cache_leave (c);
+ subtables[subtable_cache_user_idx].cache_leave (c);
#endif
}
hb_set_digest_t digest;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
- public:
- void *cache = nullptr;
private:
- unsigned cache_user_idx = (unsigned) -1;
+ unsigned count = 0; /* Number of subtables in the array. */
+ unsigned subtable_cache_user_idx = (unsigned) -1;
#endif
private:
hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY];
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
index 51572ce4b03..bc6ba54833b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -1918,7 +1918,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
const OT::hb_ot_layout_lookup_accelerator_t &accel,
unsigned subtable_count)
{
- bool use_cache = accel.cache_enter (c);
+ bool use_hot_subtable_cache = accel.cache_enter (c);
bool ret = false;
hb_buffer_t *buffer = c->buffer;
@@ -1930,7 +1930,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
(cur.mask & c->lookup_mask) &&
c->check_glyph_property (&cur, c->lookup_props))
{
- applied = accel.apply (c, subtable_count, use_cache);
+ applied = accel.apply (c, subtable_count, use_hot_subtable_cache);
}
if (applied)
@@ -1939,7 +1939,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
(void) buffer->next_glyph ();
}
- if (use_cache)
+ if (use_hot_subtable_cache)
accel.cache_leave (c);
return ret;
@@ -1982,7 +1982,22 @@ apply_string (OT::hb_ot_apply_context_t *c,
bool ret = false;
- c->set_lookup_props (lookup.get_props ());
+ unsigned lookup_props = lookup.get_props ();
+ if (lookup_props != c->cached_props)
+ {
+ bool cache_it = subtable_count > 1 && (lookup_props & OT::LookupFlag::UseMarkFilteringSet);
+ if (cache_it)
+ {
+ auto &info = buffer->info;
+ for (unsigned int i = 0; i < buffer->len; i++)
+ _hb_glyph_info_set_match (&info[i],
+ c->check_glyph_property (&info[i], lookup_props, false));
+ c->cached_props = lookup_props;
+ }
+ else
+ c->cached_props = (unsigned) -1;
+ }
+ c->set_lookup_props (lookup_props);
if (likely (!lookup.is_reverse ()))
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh
index a42212f291f..72de36bbb3e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.hh
@@ -81,9 +81,10 @@ enum hb_ot_layout_glyph_props_flags_t
HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u,
/* The following are used internally; not derived from GDEF. */
- HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
- HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
- HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u,
+ HB_OT_LAYOUT_GLYPH_PROPS_MATCHES = 0x10u,
+ HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x20u,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x40u,
+ HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x80u,
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
@@ -610,6 +611,20 @@ _hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
return false;
}
+static inline bool
+_hb_glyph_info_matches (const hb_glyph_info_t *info)
+{
+ return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MATCHES;
+}
+static inline void
+_hb_glyph_info_set_match (hb_glyph_info_t *info, bool match)
+{
+ if (match)
+ info->glyph_props() |= HB_OT_LAYOUT_GLYPH_PROPS_MATCHES;
+ else
+ info->glyph_props() &= ~HB_OT_LAYOUT_GLYPH_PROPS_MATCHES;
+}
+
/* Allocation / deallocation. */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
index b4df8aaeeab..269b4d3fe45 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
@@ -31,264 +31,264 @@
#endif
-_S(".notdef")
-_S(".null")
-_S("nonmarkingreturn")
-_S("space")
-_S("exclam")
-_S("quotedbl")
-_S("numbersign")
-_S("dollar")
-_S("percent")
-_S("ampersand")
-_S("quotesingle")
-_S("parenleft")
-_S("parenright")
-_S("asterisk")
-_S("plus")
-_S("comma")
-_S("hyphen")
-_S("period")
-_S("slash")
-_S("zero")
-_S("one")
-_S("two")
-_S("three")
-_S("four")
-_S("five")
-_S("six")
-_S("seven")
-_S("eight")
-_S("nine")
-_S("colon")
-_S("semicolon")
-_S("less")
-_S("equal")
-_S("greater")
-_S("question")
-_S("at")
-_S("A")
-_S("B")
-_S("C")
-_S("D")
-_S("E")
-_S("F")
-_S("G")
-_S("H")
-_S("I")
-_S("J")
-_S("K")
-_S("L")
-_S("M")
-_S("N")
-_S("O")
-_S("P")
-_S("Q")
-_S("R")
-_S("S")
-_S("T")
-_S("U")
-_S("V")
-_S("W")
-_S("X")
-_S("Y")
-_S("Z")
-_S("bracketleft")
-_S("backslash")
-_S("bracketright")
-_S("asciicircum")
-_S("underscore")
-_S("grave")
-_S("a")
-_S("b")
-_S("c")
-_S("d")
-_S("e")
-_S("f")
-_S("g")
-_S("h")
-_S("i")
-_S("j")
-_S("k")
-_S("l")
-_S("m")
-_S("n")
-_S("o")
-_S("p")
-_S("q")
-_S("r")
-_S("s")
-_S("t")
-_S("u")
-_S("v")
-_S("w")
-_S("x")
-_S("y")
-_S("z")
-_S("braceleft")
-_S("bar")
-_S("braceright")
-_S("asciitilde")
-_S("Adieresis")
-_S("Aring")
-_S("Ccedilla")
-_S("Eacute")
-_S("Ntilde")
-_S("Odieresis")
-_S("Udieresis")
-_S("aacute")
-_S("agrave")
-_S("acircumflex")
-_S("adieresis")
-_S("atilde")
-_S("aring")
-_S("ccedilla")
-_S("eacute")
-_S("egrave")
-_S("ecircumflex")
-_S("edieresis")
-_S("iacute")
-_S("igrave")
-_S("icircumflex")
-_S("idieresis")
-_S("ntilde")
-_S("oacute")
-_S("ograve")
-_S("ocircumflex")
-_S("odieresis")
-_S("otilde")
-_S("uacute")
-_S("ugrave")
-_S("ucircumflex")
-_S("udieresis")
-_S("dagger")
-_S("degree")
-_S("cent")
-_S("sterling")
-_S("section")
-_S("bullet")
-_S("paragraph")
-_S("germandbls")
-_S("registered")
-_S("copyright")
-_S("trademark")
-_S("acute")
-_S("dieresis")
-_S("notequal")
-_S("AE")
-_S("Oslash")
-_S("infinity")
-_S("plusminus")
-_S("lessequal")
-_S("greaterequal")
-_S("yen")
-_S("mu")
-_S("partialdiff")
-_S("summation")
-_S("product")
-_S("pi")
-_S("integral")
-_S("ordfeminine")
-_S("ordmasculine")
-_S("Omega")
-_S("ae")
-_S("oslash")
-_S("questiondown")
-_S("exclamdown")
-_S("logicalnot")
-_S("radical")
-_S("florin")
-_S("approxequal")
-_S("Delta")
-_S("guillemotleft")
-_S("guillemotright")
-_S("ellipsis")
-_S("nonbreakingspace")
-_S("Agrave")
-_S("Atilde")
-_S("Otilde")
-_S("OE")
-_S("oe")
-_S("endash")
-_S("emdash")
-_S("quotedblleft")
-_S("quotedblright")
-_S("quoteleft")
-_S("quoteright")
-_S("divide")
-_S("lozenge")
-_S("ydieresis")
-_S("Ydieresis")
-_S("fraction")
-_S("currency")
-_S("guilsinglleft")
-_S("guilsinglright")
-_S("fi")
-_S("fl")
-_S("daggerdbl")
-_S("periodcentered")
-_S("quotesinglbase")
-_S("quotedblbase")
-_S("perthousand")
-_S("Acircumflex")
-_S("Ecircumflex")
-_S("Aacute")
-_S("Edieresis")
-_S("Egrave")
-_S("Iacute")
-_S("Icircumflex")
-_S("Idieresis")
-_S("Igrave")
-_S("Oacute")
-_S("Ocircumflex")
-_S("apple")
-_S("Ograve")
-_S("Uacute")
-_S("Ucircumflex")
-_S("Ugrave")
-_S("dotlessi")
-_S("circumflex")
-_S("tilde")
-_S("macron")
-_S("breve")
-_S("dotaccent")
-_S("ring")
-_S("cedilla")
-_S("hungarumlaut")
-_S("ogonek")
-_S("caron")
-_S("Lslash")
-_S("lslash")
-_S("Scaron")
-_S("scaron")
-_S("Zcaron")
-_S("zcaron")
-_S("brokenbar")
-_S("Eth")
-_S("eth")
-_S("Yacute")
-_S("yacute")
-_S("Thorn")
-_S("thorn")
-_S("minus")
-_S("multiply")
-_S("onesuperior")
-_S("twosuperior")
-_S("threesuperior")
-_S("onehalf")
-_S("onequarter")
-_S("threequarters")
-_S("franc")
-_S("Gbreve")
-_S("gbreve")
-_S("Idotaccent")
-_S("Scedilla")
-_S("scedilla")
-_S("Cacute")
-_S("cacute")
-_S("Ccaron")
-_S("ccaron")
-_S("dcroat")
+HB_STR(".notdef")
+HB_STR(".null")
+HB_STR("nonmarkingreturn")
+HB_STR("space")
+HB_STR("exclam")
+HB_STR("quotedbl")
+HB_STR("numbersign")
+HB_STR("dollar")
+HB_STR("percent")
+HB_STR("ampersand")
+HB_STR("quotesingle")
+HB_STR("parenleft")
+HB_STR("parenright")
+HB_STR("asterisk")
+HB_STR("plus")
+HB_STR("comma")
+HB_STR("hyphen")
+HB_STR("period")
+HB_STR("slash")
+HB_STR("zero")
+HB_STR("one")
+HB_STR("two")
+HB_STR("three")
+HB_STR("four")
+HB_STR("five")
+HB_STR("six")
+HB_STR("seven")
+HB_STR("eight")
+HB_STR("nine")
+HB_STR("colon")
+HB_STR("semicolon")
+HB_STR("less")
+HB_STR("equal")
+HB_STR("greater")
+HB_STR("question")
+HB_STR("at")
+HB_STR("A")
+HB_STR("B")
+HB_STR("C")
+HB_STR("D")
+HB_STR("E")
+HB_STR("F")
+HB_STR("G")
+HB_STR("H")
+HB_STR("I")
+HB_STR("J")
+HB_STR("K")
+HB_STR("L")
+HB_STR("M")
+HB_STR("N")
+HB_STR("O")
+HB_STR("P")
+HB_STR("Q")
+HB_STR("R")
+HB_STR("S")
+HB_STR("T")
+HB_STR("U")
+HB_STR("V")
+HB_STR("W")
+HB_STR("X")
+HB_STR("Y")
+HB_STR("Z")
+HB_STR("bracketleft")
+HB_STR("backslash")
+HB_STR("bracketright")
+HB_STR("asciicircum")
+HB_STR("underscore")
+HB_STR("grave")
+HB_STR("a")
+HB_STR("b")
+HB_STR("c")
+HB_STR("d")
+HB_STR("e")
+HB_STR("f")
+HB_STR("g")
+HB_STR("h")
+HB_STR("i")
+HB_STR("j")
+HB_STR("k")
+HB_STR("l")
+HB_STR("m")
+HB_STR("n")
+HB_STR("o")
+HB_STR("p")
+HB_STR("q")
+HB_STR("r")
+HB_STR("s")
+HB_STR("t")
+HB_STR("u")
+HB_STR("v")
+HB_STR("w")
+HB_STR("x")
+HB_STR("y")
+HB_STR("z")
+HB_STR("braceleft")
+HB_STR("bar")
+HB_STR("braceright")
+HB_STR("asciitilde")
+HB_STR("Adieresis")
+HB_STR("Aring")
+HB_STR("Ccedilla")
+HB_STR("Eacute")
+HB_STR("Ntilde")
+HB_STR("Odieresis")
+HB_STR("Udieresis")
+HB_STR("aacute")
+HB_STR("agrave")
+HB_STR("acircumflex")
+HB_STR("adieresis")
+HB_STR("atilde")
+HB_STR("aring")
+HB_STR("ccedilla")
+HB_STR("eacute")
+HB_STR("egrave")
+HB_STR("ecircumflex")
+HB_STR("edieresis")
+HB_STR("iacute")
+HB_STR("igrave")
+HB_STR("icircumflex")
+HB_STR("idieresis")
+HB_STR("ntilde")
+HB_STR("oacute")
+HB_STR("ograve")
+HB_STR("ocircumflex")
+HB_STR("odieresis")
+HB_STR("otilde")
+HB_STR("uacute")
+HB_STR("ugrave")
+HB_STR("ucircumflex")
+HB_STR("udieresis")
+HB_STR("dagger")
+HB_STR("degree")
+HB_STR("cent")
+HB_STR("sterling")
+HB_STR("section")
+HB_STR("bullet")
+HB_STR("paragraph")
+HB_STR("germandbls")
+HB_STR("registered")
+HB_STR("copyright")
+HB_STR("trademark")
+HB_STR("acute")
+HB_STR("dieresis")
+HB_STR("notequal")
+HB_STR("AE")
+HB_STR("Oslash")
+HB_STR("infinity")
+HB_STR("plusminus")
+HB_STR("lessequal")
+HB_STR("greaterequal")
+HB_STR("yen")
+HB_STR("mu")
+HB_STR("partialdiff")
+HB_STR("summation")
+HB_STR("product")
+HB_STR("pi")
+HB_STR("integral")
+HB_STR("ordfeminine")
+HB_STR("ordmasculine")
+HB_STR("Omega")
+HB_STR("ae")
+HB_STR("oslash")
+HB_STR("questiondown")
+HB_STR("exclamdown")
+HB_STR("logicalnot")
+HB_STR("radical")
+HB_STR("florin")
+HB_STR("approxequal")
+HB_STR("Delta")
+HB_STR("guillemotleft")
+HB_STR("guillemotright")
+HB_STR("ellipsis")
+HB_STR("nonbreakingspace")
+HB_STR("Agrave")
+HB_STR("Atilde")
+HB_STR("Otilde")
+HB_STR("OE")
+HB_STR("oe")
+HB_STR("endash")
+HB_STR("emdash")
+HB_STR("quotedblleft")
+HB_STR("quotedblright")
+HB_STR("quoteleft")
+HB_STR("quoteright")
+HB_STR("divide")
+HB_STR("lozenge")
+HB_STR("ydieresis")
+HB_STR("Ydieresis")
+HB_STR("fraction")
+HB_STR("currency")
+HB_STR("guilsinglleft")
+HB_STR("guilsinglright")
+HB_STR("fi")
+HB_STR("fl")
+HB_STR("daggerdbl")
+HB_STR("periodcentered")
+HB_STR("quotesinglbase")
+HB_STR("quotedblbase")
+HB_STR("perthousand")
+HB_STR("Acircumflex")
+HB_STR("Ecircumflex")
+HB_STR("Aacute")
+HB_STR("Edieresis")
+HB_STR("Egrave")
+HB_STR("Iacute")
+HB_STR("Icircumflex")
+HB_STR("Idieresis")
+HB_STR("Igrave")
+HB_STR("Oacute")
+HB_STR("Ocircumflex")
+HB_STR("apple")
+HB_STR("Ograve")
+HB_STR("Uacute")
+HB_STR("Ucircumflex")
+HB_STR("Ugrave")
+HB_STR("dotlessi")
+HB_STR("circumflex")
+HB_STR("tilde")
+HB_STR("macron")
+HB_STR("breve")
+HB_STR("dotaccent")
+HB_STR("ring")
+HB_STR("cedilla")
+HB_STR("hungarumlaut")
+HB_STR("ogonek")
+HB_STR("caron")
+HB_STR("Lslash")
+HB_STR("lslash")
+HB_STR("Scaron")
+HB_STR("scaron")
+HB_STR("Zcaron")
+HB_STR("zcaron")
+HB_STR("brokenbar")
+HB_STR("Eth")
+HB_STR("eth")
+HB_STR("Yacute")
+HB_STR("yacute")
+HB_STR("Thorn")
+HB_STR("thorn")
+HB_STR("minus")
+HB_STR("multiply")
+HB_STR("onesuperior")
+HB_STR("twosuperior")
+HB_STR("threesuperior")
+HB_STR("onehalf")
+HB_STR("onequarter")
+HB_STR("threequarters")
+HB_STR("franc")
+HB_STR("Gbreve")
+HB_STR("gbreve")
+HB_STR("Idotaccent")
+HB_STR("Scedilla")
+HB_STR("scedilla")
+HB_STR("Cacute")
+HB_STR("cacute")
+HB_STR("Ccaron")
+HB_STR("ccaron")
+HB_STR("dcroat")
#endif /* HB_OT_POST_MACROMAN_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 2d093f78b33..e9dbcd77aea 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -78,14 +78,14 @@
static inline void
set_glyph (hb_glyph_info_t &info, hb_font_t *font)
{
- (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index());
+ (void) font->get_nominal_glyph (info.codepoint, &info.normalizer_glyph_index());
}
static inline void
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
{
/* This is very confusing indeed. */
- buffer->cur().glyph_index() = glyph;
+ buffer->cur().normalizer_glyph_index() = glyph;
(void) buffer->output_glyph (unichar);
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
}
@@ -93,7 +93,7 @@ output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
static inline void
next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
{
- buffer->cur().glyph_index() = glyph;
+ buffer->cur().normalizer_glyph_index() = glyph;
(void) buffer->next_glyph ();
}
@@ -210,7 +210,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
hb_font_t * const font = c->font;
for (; buffer->idx < end - 1 && buffer->successful;) {
if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
- if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
+ if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().normalizer_glyph_index()))
{
hb_codepoint_t unicode = buffer->cur().codepoint;
(void) buffer->replace_glyphs (2, 1, &unicode);
@@ -342,7 +342,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
&buffer->cur().codepoint,
sizeof (buffer->info[0]),
- &buffer->cur().glyph_index(),
+ &buffer->cur().normalizer_glyph_index(),
sizeof (buffer->info[0]));
if (unlikely (!buffer->next_glyphs (done))) break;
}
@@ -456,7 +456,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->out_len--; /* Remove the second composable. */
/* Modify starter and carry on. */
buffer->out_info[starter].codepoint = composed;
- buffer->out_info[starter].glyph_index() = glyph;
+ buffer->out_info[starter].normalizer_glyph_index() = glyph;
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
continue;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh
index f12cb35c0fe..2f282f34754 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.hh
@@ -32,7 +32,7 @@
/* buffer var allocations, used during the normalization process */
-#define glyph_index() var1.u32
+#define normalizer_glyph_index() var1.u32
struct hb_ot_shape_plan_t;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
index 6ee0e2b7f9d..dd2c576fd04 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -614,14 +614,14 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
for (unsigned i = 0; i < count; i++)
{
auto gc = _hb_glyph_info_get_general_category (&info[i]);
- if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
- found_number = true;
- else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc))
+ if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc))
{
found_letter = true;
break;
}
- else if (_hb_codepoint_is_regional_indicator (info[i].codepoint))
+ else if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
+ found_number = true;
+ else if (unlikely (_hb_codepoint_is_regional_indicator (info[i].codepoint)))
found_ri = true;
}
if ((found_number || found_ri) && !found_letter)
@@ -843,11 +843,11 @@ hb_ot_hide_default_ignorables (hb_buffer_t *buffer,
static inline void
hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
{
- /* Normalization process sets up glyph_index(), we just copy it. */
+ /* Normalization process sets up normalizer_glyph_index(), we just copy it. */
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
- info[i].codepoint = info[i].glyph_index();
+ info[i].codepoint = info[i].normalizer_glyph_index();
buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
}
@@ -885,7 +885,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c)
hb_ot_rotate_chars (c);
- HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
+ HB_BUFFER_ALLOCATE_VAR (buffer, normalizer_glyph_index);
_hb_ot_shape_normalize (c->plan, buffer, c->font);
@@ -897,7 +897,7 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c)
hb_ot_map_glyphs_fast (buffer);
- HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, normalizer_glyph_index);
}
static inline void
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
index 6ff65c30a33..92fb64ad07e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
@@ -53,7 +53,7 @@ enum indic_syllable_type_t {
};
-#line 57 "hb-ot-shaper-indic-machine.hh"
+#line 54 "hb-ot-shaper-indic-machine.hh"
#define indic_syllable_machine_ex_A 9u
#define indic_syllable_machine_ex_C 1u
#define indic_syllable_machine_ex_CM 16u
@@ -77,7 +77,7 @@ enum indic_syllable_type_t {
#define indic_syllable_machine_ex_ZWNJ 5u
-#line 81 "hb-ot-shaper-indic-machine.hh"
+#line 76 "hb-ot-shaper-indic-machine.hh"
static const unsigned char _indic_syllable_machine_trans_keys[] = {
8u, 57u, 4u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u,
8u, 57u, 5u, 57u, 5u, 57u, 13u, 13u, 4u, 57u, 4u, 57u, 4u, 57u, 4u, 57u,
@@ -1126,7 +1126,7 @@ find_syllables_indic (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 1130 "hb-ot-shaper-indic-machine.hh"
+#line 1119 "hb-ot-shaper-indic-machine.hh"
{
cs = indic_syllable_machine_start;
ts = 0;
@@ -1142,7 +1142,7 @@ find_syllables_indic (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
-#line 1146 "hb-ot-shaper-indic-machine.hh"
+#line 1131 "hb-ot-shaper-indic-machine.hh"
{
int _slen;
int _trans;
@@ -1156,7 +1156,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 1160 "hb-ot-shaper-indic-machine.hh"
+#line 1143 "hb-ot-shaper-indic-machine.hh"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1268,7 +1268,7 @@ _eof_trans:
#line 117 "hb-ot-shaper-indic-machine.rl"
{act = 7;}
break;
-#line 1272 "hb-ot-shaper-indic-machine.hh"
+#line 1232 "hb-ot-shaper-indic-machine.hh"
}
_again:
@@ -1277,7 +1277,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 1281 "hb-ot-shaper-indic-machine.hh"
+#line 1239 "hb-ot-shaper-indic-machine.hh"
}
if ( ++p != pe )
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh
index f1e7a91f050..848ed231f71 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-khmer-machine.hh
@@ -48,7 +48,7 @@ enum khmer_syllable_type_t {
};
-#line 52 "hb-ot-shaper-khmer-machine.hh"
+#line 49 "hb-ot-shaper-khmer-machine.hh"
#define khmer_syllable_machine_ex_C 1u
#define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
#define khmer_syllable_machine_ex_H 4u
@@ -66,7 +66,7 @@ enum khmer_syllable_type_t {
#define khmer_syllable_machine_ex_ZWNJ 5u
-#line 70 "hb-ot-shaper-khmer-machine.hh"
+#line 65 "hb-ot-shaper-khmer-machine.hh"
static const unsigned char _khmer_syllable_machine_trans_keys[] = {
5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u,
5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u,
@@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 298 "hb-ot-shaper-khmer-machine.hh"
+#line 287 "hb-ot-shaper-khmer-machine.hh"
{
cs = khmer_syllable_machine_start;
ts = 0;
@@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
-#line 314 "hb-ot-shaper-khmer-machine.hh"
+#line 299 "hb-ot-shaper-khmer-machine.hh"
{
int _slen;
int _trans;
@@ -324,7 +324,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 328 "hb-ot-shaper-khmer-machine.hh"
+#line 311 "hb-ot-shaper-khmer-machine.hh"
}
_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
@@ -394,7 +394,7 @@ _eof_trans:
#line 98 "hb-ot-shaper-khmer-machine.rl"
{act = 3;}
break;
-#line 398 "hb-ot-shaper-khmer-machine.hh"
+#line 368 "hb-ot-shaper-khmer-machine.hh"
}
_again:
@@ -403,7 +403,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 407 "hb-ot-shaper-khmer-machine.hh"
+#line 375 "hb-ot-shaper-khmer-machine.hh"
}
if ( ++p != pe )
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh
index 4b8da586d37..292bc9f3dfc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-myanmar-machine.hh
@@ -50,7 +50,7 @@ enum myanmar_syllable_type_t {
};
-#line 54 "hb-ot-shaper-myanmar-machine.hh"
+#line 51 "hb-ot-shaper-myanmar-machine.hh"
#define myanmar_syllable_machine_ex_A 9u
#define myanmar_syllable_machine_ex_As 32u
#define myanmar_syllable_machine_ex_C 1u
@@ -78,7 +78,7 @@ enum myanmar_syllable_type_t {
#define myanmar_syllable_machine_ex_ZWNJ 5u
-#line 82 "hb-ot-shaper-myanmar-machine.hh"
+#line 77 "hb-ot-shaper-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 57u, 3u, 57u, 5u, 57u, 5u, 57u, 3u, 57u, 5u, 57u, 3u, 57u, 3u, 57u,
3u, 57u, 3u, 57u, 3u, 57u, 5u, 57u, 1u, 15u, 3u, 57u, 3u, 57u, 3u, 57u,
@@ -549,7 +549,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 553 "hb-ot-shaper-myanmar-machine.hh"
+#line 542 "hb-ot-shaper-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@@ -565,7 +565,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
-#line 569 "hb-ot-shaper-myanmar-machine.hh"
+#line 554 "hb-ot-shaper-myanmar-machine.hh"
{
int _slen;
int _trans;
@@ -579,7 +579,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 583 "hb-ot-shaper-myanmar-machine.hh"
+#line 566 "hb-ot-shaper-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -649,7 +649,7 @@ _eof_trans:
#line 113 "hb-ot-shaper-myanmar-machine.rl"
{act = 3;}
break;
-#line 653 "hb-ot-shaper-myanmar-machine.hh"
+#line 623 "hb-ot-shaper-myanmar-machine.hh"
}
_again:
@@ -658,7 +658,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 662 "hb-ot-shaper-myanmar-machine.hh"
+#line 630 "hb-ot-shaper-myanmar-machine.hh"
}
if ( ++p != pe )
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc
index 6d293b5c489..90ef8e39b74 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-thai.cc
@@ -191,7 +191,7 @@ static const struct thai_above_state_machine_edge_t {
};
-static enum thai_below_state_t
+static const enum thai_below_state_t
{
B0, /* No descender */
B1, /* Removable descender */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh
index 65b6adc36d9..5072e4d38ee 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-use-machine.hh
@@ -53,7 +53,7 @@ enum use_syllable_type_t {
};
-#line 57 "hb-ot-shaper-use-machine.hh"
+#line 54 "hb-ot-shaper-use-machine.hh"
#define use_syllable_machine_ex_B 1u
#define use_syllable_machine_ex_CGJ 6u
#define use_syllable_machine_ex_CMAbv 31u
@@ -100,7 +100,7 @@ enum use_syllable_type_t {
#define use_syllable_machine_ex_ZWNJ 14u
-#line 104 "hb-ot-shaper-use-machine.hh"
+#line 99 "hb-ot-shaper-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
49u, 51u, 0u, 56u, 11u, 56u, 11u, 56u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u,
14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u,
@@ -929,7 +929,7 @@ find_syllables_use (hb_buffer_t *buffer)
unsigned int act HB_UNUSED;
int cs;
-#line 933 "hb-ot-shaper-use-machine.hh"
+#line 922 "hb-ot-shaper-use-machine.hh"
{
cs = use_syllable_machine_start;
ts = 0;
@@ -942,7 +942,7 @@ find_syllables_use (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
-#line 946 "hb-ot-shaper-use-machine.hh"
+#line 931 "hb-ot-shaper-use-machine.hh"
{
int _slen;
int _trans;
@@ -956,7 +956,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 960 "hb-ot-shaper-use-machine.hh"
+#line 943 "hb-ot-shaper-use-machine.hh"
}
_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -1078,7 +1078,7 @@ _eof_trans:
#line 181 "hb-ot-shaper-use-machine.rl"
{act = 9;}
break;
-#line 1082 "hb-ot-shaper-use-machine.hh"
+#line 1039 "hb-ot-shaper-use-machine.hh"
}
_again:
@@ -1087,7 +1087,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 1091 "hb-ot-shaper-use-machine.hh"
+#line 1046 "hb-ot-shaper-use-machine.hh"
}
if ( ++p != pe )
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh
index c6dbf8db91c..cfc40924506 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-serialize.hh
@@ -724,7 +724,7 @@ struct hb_serialize_context_t
hb_requires (hb_is_iterator (Iterator)),
typename ...Ts>
void copy_all (Iterator it, Ts&&... ds)
- { for (decltype (*it) _ : it) copy (_, std::forward<Ts> (ds)...); }
+ { for (decltype (*it) _ : it) copy (_, ds...); }
template <typename Type>
hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
index c62f8c6bcdd..db46e110ca5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
@@ -199,6 +199,7 @@ hb_shape (hb_font_t *font,
#ifdef HB_EXPERIMENTAL_API
+#ifndef HB_NO_VAR
static float
buffer_advance (hb_buffer_t *buffer)
@@ -440,7 +441,7 @@ hb_shape_justify (hb_font_t *font,
return true;
}
-
+#endif
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
index 41673a38441..cb386f26827 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
@@ -61,6 +61,10 @@ HB_SHAPER_IMPLEMENT (coretext)
HB_SHAPER_IMPLEMENT (harfrust)
#endif
+#ifdef HAVE_KBTS
+HB_SHAPER_IMPLEMENT (kbts)
+#endif
+
#ifndef HB_NO_FALLBACK_SHAPE
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
index e7ac1192324..3a714889c20 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
@@ -45,25 +45,25 @@ static const union HB_STRING_ARRAY_TYPE_NAME {
* but C++ does not allow that.
* https://stackoverflow.com/q/28433862
*/
-#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)];
+#define HB_STR(s) char HB_PASTE (str, __LINE__)[sizeof (s)];
#include HB_STRING_ARRAY_LIST
-#undef _S
+#undef HB_STR
} st;
char str[HB_VAR_ARRAY];
}
HB_STRING_ARRAY_POOL_NAME =
{
{
-#define _S(s) s,
+#define HB_STR(s) s,
#include HB_STRING_ARRAY_LIST
-#undef _S
+#undef HB_STR
}
};
static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] =
{
-#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)),
+#define HB_STR(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)),
#include HB_STRING_ARRAY_LIST
-#undef _S
+#undef HB_STR
sizeof (HB_STRING_ARRAY_TYPE_NAME)
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
index 335b750da35..30e8e639b90 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
@@ -300,6 +300,7 @@ struct hb_subset_plan_t
// compile times more reasonable:
// - hb-subset-plan.cc
// - hb-subset-plan-layout.cc
+// - hb-subset-plan-var.cc
//
// The functions below are those needed to connect the split files
// above together.
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-table-cff.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-cff.cc
new file mode 100644
index 00000000000..3984cfb8660
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-cff.cc
@@ -0,0 +1,143 @@
+#include "hb-subset-table.hh"
+
+#include "hb-ot-cff1-table.hh"
+#include "hb-ot-cff2-table.hh"
+#include "hb-ot-vorg-table.hh"
+
+
+#ifndef HB_NO_SUBSET_CFF
+template<>
+struct hb_subset_plan_t::source_table_loader<const OT::cff1>
+{
+ auto operator () (hb_subset_plan_t *plan)
+ HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel :
+ plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel :
+ plan->cff1_accel)
+};
+template<>
+struct hb_subset_plan_t::source_table_loader<const OT::cff2>
+{
+ auto operator () (hb_subset_plan_t *plan)
+ HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel :
+ plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel :
+ plan->cff2_accel)
+};
+#endif
+
+
+bool _hb_subset_table_cff (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success)
+{
+#ifndef HB_NO_SUBSET_CFF
+ switch (tag)
+ {
+ case HB_TAG('C','F','F',' '): *success = _hb_subset_table<const OT::cff1> (plan, buf); return true;
+ case HB_TAG('C','F','F','2'): *success = _hb_subset_table<const OT::cff2> (plan, buf); return true;
+ case HB_TAG('V','O','R','G'): *success = _hb_subset_table<const OT::VORG> (plan, buf); return true;
+ }
+#endif
+ return false;
+}
+
+
+#ifdef HB_EXPERIMENTAL_API
+#ifndef HB_NO_CFF
+
+template<typename accel_t>
+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<typename accel_t>
+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
+#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-table-color.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-color.cc
new file mode 100644
index 00000000000..e44305e7dd7
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-color.cc
@@ -0,0 +1,21 @@
+#include "hb-subset-table.hh"
+
+#include "OT/Color/sbix/sbix.hh"
+#include "OT/Color/CPAL/CPAL.hh"
+#include "OT/Color/COLR/COLR.hh"
+#include "OT/Color/CBDT/CBDT.hh"
+
+bool _hb_subset_table_color (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success)
+{
+#ifndef HB_NO_COLOR
+ switch (tag)
+ {
+ case HB_TAG('s','b','i','x'): *success = _hb_subset_table<const OT::sbix> (plan, buf); return true;
+ case HB_TAG('C','O','L','R'): *success = _hb_subset_table<const OT::COLR> (plan, buf); return true;
+ case HB_TAG('C','P','A','L'): *success = _hb_subset_table<const OT::CPAL> (plan, buf); return true;
+ case HB_TAG('C','B','L','C'): *success = _hb_subset_table<const OT::CBLC> (plan, buf); return true;
+ case HB_TAG('C','B','D','T'): *success = true; return true; /* skip CBDT, handled by CBLC */
+ }
+#endif
+ return false;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-table-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-layout.cc
new file mode 100644
index 00000000000..765422e365b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-layout.cc
@@ -0,0 +1,22 @@
+#include "hb-subset-table.hh"
+
+#include "hb-ot-layout-gdef-table.hh"
+#include "hb-ot-layout-gsub-table.hh"
+#include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-layout-base-table.hh"
+#include "hb-ot-math-table.hh"
+
+bool _hb_subset_table_layout (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success)
+{
+#ifndef HB_NO_SUBSET_LAYOUT
+ switch (tag)
+ {
+ case HB_TAG('G','D','E','F'): *success = _hb_subset_table<const OT::GDEF> (plan, buf); return true;
+ case HB_TAG('G','S','U','B'): *success = _hb_subset_table<const OT::Layout::GSUB> (plan, buf); return true;
+ case HB_TAG('G','P','O','S'): *success = _hb_subset_table<const OT::Layout::GPOS> (plan, buf); return true;
+ case HB_TAG('B','A','S','E'): *success = _hb_subset_table<const OT::BASE> (plan, buf); return true;
+ case HB_TAG('M','A','T','H'): *success = _hb_subset_table<const OT::MATH> (plan, buf); return true;
+ }
+#endif
+ return false;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-table-other.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-other.cc
new file mode 100644
index 00000000000..3b7ff4b3264
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-other.cc
@@ -0,0 +1,31 @@
+#include "hb-subset-table.hh"
+
+#include "hb-ot-cmap-table.hh"
+#include "hb-ot-glyf-table.hh"
+#include "hb-ot-hdmx-table.hh"
+#include "hb-ot-hhea-table.hh"
+#include "hb-ot-hmtx-table.hh"
+#include "hb-ot-maxp-table.hh"
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-name-table.hh"
+#include "hb-ot-post-table.hh"
+
+bool _hb_subset_table_other (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success)
+{
+ switch (tag)
+ {
+ case HB_TAG('g','l','y','f'): *success = _hb_subset_table<const OT::glyf> (plan, buf); return true;
+ case HB_TAG('h','d','m','x'): *success = _hb_subset_table<const OT::hdmx> (plan, buf); return true;
+ case HB_TAG('n','a','m','e'): *success = _hb_subset_table<const OT::name> (plan, buf); return true;
+ case HB_TAG('h','h','e','a'): *success = true; return true; /* skip hhea, handled by hmtx */
+ case HB_TAG('h','m','t','x'): *success = _hb_subset_table<const OT::hmtx> (plan, buf); return true;
+ case HB_TAG('v','h','e','a'): *success = true; return true; /* skip vhea, handled by vmtx */
+ case HB_TAG('v','m','t','x'): *success = _hb_subset_table<const OT::vmtx> (plan, buf); return true;
+ case HB_TAG('m','a','x','p'): *success = _hb_subset_table<const OT::maxp> (plan, buf); return true;
+ case HB_TAG('l','o','c','a'): *success = true; return true; /* skip loca, handled by glyf */
+ case HB_TAG('c','m','a','p'): *success = _hb_subset_table<const OT::cmap> (plan, buf); return true;
+ case HB_TAG('O','S','/','2'): *success = _hb_subset_table<const OT::OS2 > (plan, buf); return true;
+ case HB_TAG('p','o','s','t'): *success = _hb_subset_table<const OT::post> (plan, buf); return true;
+ }
+ return false;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-table-var.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-var.cc
new file mode 100644
index 00000000000..b569b08a008
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-table-var.cc
@@ -0,0 +1,45 @@
+#include "hb-subset-table.hh"
+
+#include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-var-gvar-table.hh"
+#include "hb-ot-var-fvar-table.hh"
+#include "hb-ot-var-avar-table.hh"
+#include "hb-ot-var-cvar-table.hh"
+#include "hb-ot-var-mvar-table.hh"
+
+bool _hb_subset_table_var (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success)
+{
+#ifndef HB_NO_VAR
+ switch (tag)
+ {
+ case HB_TAG('H','V','A','R'): *success = _hb_subset_table<const OT::HVAR> (plan, buf); return true;
+ case HB_TAG('V','V','A','R'): *success = _hb_subset_table<const OT::VVAR> (plan, buf); return true;
+ case HB_TAG('g','v','a','r'): *success = _hb_subset_table<const OT::gvar> (plan, buf); return true;
+ case HB_TAG('f','v','a','r'):
+ if (plan->user_axes_location.is_empty ())
+ *success = _hb_subset_table_passthrough (plan, tag);
+ else
+ *success = _hb_subset_table<const OT::fvar> (plan, buf);
+ return true;
+ case HB_TAG('a','v','a','r'):
+ if (plan->user_axes_location.is_empty ())
+ *success = _hb_subset_table_passthrough (plan, tag);
+ else
+ *success = _hb_subset_table<const OT::avar> (plan, buf);
+ return true;
+ case HB_TAG('c','v','a','r'):
+ if (plan->user_axes_location.is_empty ())
+ *success = _hb_subset_table_passthrough (plan, tag);
+ else
+ *success = _hb_subset_table<const OT::cvar> (plan, buf);
+ return true;
+ case HB_TAG('M','V','A','R'):
+ if (plan->user_axes_location.is_empty ())
+ *success = _hb_subset_table_passthrough (plan, tag);
+ else
+ *success = _hb_subset_table<const OT::MVAR> (plan, buf);
+ return true;
+ }
+#endif
+ return false;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-table.hh
new file mode 100644
index 00000000000..66588ec6f8f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-table.hh
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2018 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, Roderick Sheeter
+ */
+
+#ifndef HB_SUBSET_TABLE_HH
+#define HB_SUBSET_TABLE_HH
+
+
+#include "hb.hh"
+
+#include "hb-subset.hh"
+#include "hb-repacker.hh"
+
+
+template<typename TableType>
+static bool
+_hb_subset_table_try (const TableType *table,
+ hb_vector_t<char>* buf,
+ hb_subset_context_t* c /* OUT */)
+{
+ c->serializer->start_serialize ();
+ if (c->serializer->in_error ()) return false;
+
+ bool needed = table->subset (c);
+ if (!c->serializer->ran_out_of_room ())
+ {
+ c->serializer->end_serialize ();
+ return needed;
+ }
+
+ unsigned buf_size = buf->allocated;
+ buf_size = buf_size * 2 + 16;
+
+
+
+
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.",
+ HB_UNTAG (c->table_tag), buf_size);
+
+ if (unlikely (buf_size > c->source_blob->length * 256 ||
+ !buf->alloc_exact (buf_size)))
+ {
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.",
+ HB_UNTAG (c->table_tag), buf_size);
+ return needed;
+ }
+
+ c->serializer->reset (buf->arrayZ, buf->allocated);
+ return _hb_subset_table_try (table, buf, c);
+}
+
+static HB_UNUSED unsigned
+_hb_subset_estimate_table_size (hb_subset_plan_t *plan,
+ unsigned table_len,
+ hb_tag_t table_tag)
+{
+ unsigned src_glyphs = plan->source->get_num_glyphs ();
+ unsigned dst_glyphs = plan->glyphset ()->get_population ();
+
+ unsigned bulk = 8192;
+ /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
+ * because those are expensive to subset, so giving them more room is fine. */
+ bool same_size = table_tag == HB_TAG('G','S','U','B') ||
+ table_tag == HB_TAG('G','P','O','S') ||
+ table_tag == HB_TAG('G','D','E','F') ||
+ table_tag == HB_TAG('n','a','m','e');
+
+ if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS)
+ {
+ if (table_tag == HB_TAG('C','F','F',' '))
+ {
+ /* Add some extra room for the CFF charset. */
+ bulk += src_glyphs * 16;
+ }
+ else if (table_tag == HB_TAG('C','F','F','2'))
+ {
+ /* Just extra CharString offsets. */
+ bulk += src_glyphs * 4;
+ }
+ }
+
+ if (unlikely (!src_glyphs) || same_size)
+ return bulk + table_len;
+
+ return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
+}
+
+/*
+ * Repack the serialization buffer if any offset overflows exist.
+ */
+static HB_UNUSED hb_blob_t*
+_hb_subset_repack (hb_tag_t tag, const hb_serialize_context_t& c)
+{
+ if (!c.offset_overflow ())
+ return c.copy_blob ();
+
+ hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag);
+
+ if (unlikely (!result))
+ {
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.",
+ HB_UNTAG (tag));
+ return nullptr;
+ }
+
+ return result;
+}
+
+template <typename T>
+static HB_UNUSED auto _hb_do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ())
+
+template <typename T>
+static HB_UNUSED void _hb_do_destroy (T &t, hb_priority<0>) {}
+
+template<typename TableType>
+static bool
+_hb_subset_table (hb_subset_plan_t *plan, hb_vector_t<char> &buf)
+{
+ auto &&source_blob = plan->source_table<TableType> ();
+ auto *table = source_blob.get ();
+
+ hb_tag_t tag = TableType::tableTag;
+ hb_blob_t *blob = source_blob.get_blob();
+ if (unlikely (!blob || !blob->data))
+ {
+ DEBUG_MSG (SUBSET, nullptr,
+ "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
+ _hb_do_destroy (source_blob, hb_prioritize);
+ return false;
+ }
+
+ unsigned buf_size = _hb_subset_estimate_table_size (plan, blob->length, TableType::tableTag);
+ DEBUG_MSG (SUBSET, nullptr,
+ "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
+ if (unlikely (!buf.alloc (buf_size)))
+ {
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
+ _hb_do_destroy (source_blob, hb_prioritize);
+ return false;
+ }
+
+ bool needed = false;
+ hb_serialize_context_t serializer (buf.arrayZ, buf.allocated);
+ {
+ hb_subset_context_t c (blob, plan, &serializer, tag);
+ needed = _hb_subset_table_try (table, &buf, &c);
+ }
+ _hb_do_destroy (source_blob, hb_prioritize);
+
+ if (serializer.in_error () && !serializer.only_offset_overflow ())
+ {
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag));
+ return false;
+ }
+
+ if (!needed)
+ {
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
+ return true;
+ }
+
+ bool result = false;
+ hb_blob_t *dest_blob = _hb_subset_repack (tag, serializer);
+ if (dest_blob)
+ {
+ DEBUG_MSG (SUBSET, nullptr,
+ "OT::%c%c%c%c final subset table size: %u bytes.",
+ HB_UNTAG (tag), dest_blob->length);
+ result = plan->add_table (tag, dest_blob);
+ hb_blob_destroy (dest_blob);
+ }
+
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s",
+ HB_UNTAG (tag), result ? "success" : "FAILED!");
+ return result;
+}
+
+static HB_UNUSED bool
+_hb_subset_table_passthrough (hb_subset_plan_t *plan, hb_tag_t tag)
+{
+ hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
+ bool result = plan->add_table (tag, source_table);
+ hb_blob_destroy (source_table);
+ return result;
+}
+
+
+HB_INTERNAL bool _hb_subset_table_layout (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success);
+HB_INTERNAL bool _hb_subset_table_var (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success);
+HB_INTERNAL bool _hb_subset_table_cff (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success);
+HB_INTERNAL bool _hb_subset_table_color (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success);
+HB_INTERNAL bool _hb_subset_table_other (hb_subset_plan_t *plan, hb_vector_t<char> &buf, hb_tag_t tag, bool *success);
+
+
+#endif /* HB_SUBSET_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
index 7f9dc34ded8..d1ca60e63e5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
@@ -25,65 +25,19 @@
*/
#include "hb.hh"
+
#include "hb-open-type.hh"
+#include "hb-open-file.hh"
#include "hb-subset.hh"
+#include "hb-subset-table.hh"
+#include "hb-subset-accelerator.hh"
-#include "hb-open-file.hh"
#include "hb-ot-cmap-table.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-ot-hdmx-table.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-hhea-table.hh"
-#include "hb-ot-hmtx-table.hh"
-#include "hb-ot-maxp-table.hh"
-#include "OT/Color/CBDT/CBDT.hh"
-#include "OT/Color/COLR/COLR.hh"
-#include "OT/Color/CPAL/CPAL.hh"
-#include "OT/Color/sbix/sbix.hh"
-#include "hb-ot-os2-table.hh"
-#include "hb-ot-post-table.hh"
-#include "hb-ot-post-table-v2subset.hh"
-#include "hb-ot-cff1-table.hh"
-#include "hb-ot-cff2-table.hh"
-#include "hb-ot-vorg-table.hh"
-#include "hb-ot-name-table.hh"
-#include "hb-ot-layout-base-table.hh"
-#include "hb-ot-layout-gsub-table.hh"
-#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-var-avar-table.hh"
#include "hb-ot-var-cvar-table.hh"
-#include "hb-ot-var-fvar-table.hh"
-#include "hb-ot-var-gvar-table.hh"
-#include "hb-ot-var-hvar-table.hh"
-#include "hb-ot-var-mvar-table.hh"
-#include "hb-ot-math-table.hh"
+#include "hb-ot-head-table.hh"
#include "hb-ot-stat-table.hh"
-#include "hb-repacker.hh"
-#include "hb-subset-accelerator.hh"
-
-using OT::Layout::GSUB;
-using OT::Layout::GPOS;
-
-
-#ifndef HB_NO_SUBSET_CFF
-template<>
-struct hb_subset_plan_t::source_table_loader<const OT::cff1>
-{
- auto operator () (hb_subset_plan_t *plan)
- HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel :
- plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel :
- plan->cff1_accel)
-};
-template<>
-struct hb_subset_plan_t::source_table_loader<const OT::cff2>
-{
- auto operator () (hb_subset_plan_t *plan)
- HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel :
- plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel :
- plan->cff2_accel)
-};
-#endif
+#include "hb-ot-post-table-v2subset.hh"
/**
@@ -116,56 +70,56 @@ hb_user_data_key_t _hb_subset_accelerator_user_data_key = {};
* if we are unable to list the tables in a face.
*/
static hb_tag_t known_tables[] {
- HB_TAG ('a', 'v', 'a', 'r'),
- HB_OT_TAG_BASE,
- HB_OT_TAG_CBDT,
- HB_OT_TAG_CBLC,
- HB_OT_TAG_CFF1,
- HB_OT_TAG_CFF2,
- HB_OT_TAG_cmap,
- HB_OT_TAG_COLR,
- HB_OT_TAG_CPAL,
- HB_TAG ('c', 'v', 'a', 'r'),
- HB_TAG ('c', 'v', 't', ' '),
- HB_TAG ('D', 'S', 'I', 'G'),
- HB_TAG ('E', 'B', 'D', 'T'),
- HB_TAG ('E', 'B', 'L', 'C'),
- HB_TAG ('E', 'B', 'S', 'C'),
- HB_TAG ('f', 'p', 'g', 'm'),
- HB_TAG ('f', 'v', 'a', 'r'),
- HB_TAG ('g', 'a', 's', 'p'),
- HB_OT_TAG_GDEF,
- HB_OT_TAG_glyf,
- HB_OT_TAG_GPOS,
- HB_OT_TAG_GSUB,
- HB_OT_TAG_gvar,
- HB_OT_TAG_hdmx,
- HB_OT_TAG_head,
- HB_OT_TAG_hhea,
- HB_OT_TAG_hmtx,
- HB_OT_TAG_HVAR,
- HB_OT_TAG_JSTF,
- HB_TAG ('k', 'e', 'r', 'n'),
- HB_OT_TAG_loca,
- HB_TAG ('L', 'T', 'S', 'H'),
- HB_OT_TAG_MATH,
- HB_OT_TAG_maxp,
- HB_TAG ('M', 'E', 'R', 'G'),
- HB_TAG ('m', 'e', 't', 'a'),
- HB_TAG ('M', 'V', 'A', 'R'),
- HB_TAG ('P', 'C', 'L', 'T'),
- HB_OT_TAG_post,
- HB_TAG ('p', 'r', 'e', 'p'),
- HB_OT_TAG_sbix,
- HB_TAG ('S', 'T', 'A', 'T'),
- HB_TAG ('S', 'V', 'G', ' '),
- HB_TAG ('V', 'D', 'M', 'X'),
- HB_OT_TAG_vhea,
- HB_OT_TAG_vmtx,
- HB_OT_TAG_VORG,
- HB_OT_TAG_VVAR,
- HB_OT_TAG_name,
- HB_OT_TAG_OS2
+ HB_TAG('a','v','a','r'),
+ HB_TAG('B','A','S','E'),
+ HB_TAG('C','B','D','T'),
+ HB_TAG('C','B','L','C'),
+ HB_TAG('C','F','F',' '),
+ HB_TAG('C','F','F','2'),
+ HB_TAG('c','m','a','p'),
+ HB_TAG('C','O','L','R'),
+ HB_TAG('C','P','A','L'),
+ HB_TAG('c','v','a','r'),
+ HB_TAG('c','v','t',' '),
+ HB_TAG('D','S','I','G'),
+ HB_TAG('E','B','D','T'),
+ HB_TAG('E','B','L','C'),
+ HB_TAG('E','B','S','C'),
+ HB_TAG('f','p','g','m'),
+ HB_TAG('f','v','a','r'),
+ HB_TAG('g','a','s','p'),
+ HB_TAG('G','D','E','F'),
+ HB_TAG('g','l','y','f'),
+ HB_TAG('G','P','O','S'),
+ HB_TAG('G','S','U','B'),
+ HB_TAG('g','v','a','r'),
+ HB_TAG('h','d','m','x'),
+ HB_TAG('h','e','a','d'),
+ HB_TAG('h','h','e','a'),
+ HB_TAG('h','m','t','x'),
+ HB_TAG('H','V','A','R'),
+ HB_TAG('J','S','T','F'),
+ HB_TAG('k','e','r','n'),
+ HB_TAG('l','o','c','a'),
+ HB_TAG('L','T','S','H'),
+ HB_TAG('M','A','T','H'),
+ HB_TAG('m','a','x','p'),
+ HB_TAG('M','E','R','G'),
+ HB_TAG('m','e','t','a'),
+ HB_TAG('M','V','A','R'),
+ HB_TAG('P','C','L','T'),
+ HB_TAG('p','o','s','t'),
+ HB_TAG('p','r','e','p'),
+ HB_TAG('s','b','i','x'),
+ HB_TAG('S','T','A','T'),
+ HB_TAG('S','V','G',' '),
+ HB_TAG('V','D','M','X'),
+ HB_TAG('v','h','e','a'),
+ HB_TAG('v','m','t','x'),
+ HB_TAG('V','O','R','G'),
+ HB_TAG('V','V','A','R'),
+ HB_TAG('n','a','m','e'),
+ HB_TAG('O','S','/','2')
};
static bool _table_is_empty (const hb_face_t *face, hb_tag_t tag)
@@ -213,169 +167,6 @@ _get_table_tags (const hb_subset_plan_t* plan,
}
-static unsigned
-_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
- unsigned table_len,
- hb_tag_t table_tag)
-{
- unsigned src_glyphs = plan->source->get_num_glyphs ();
- unsigned dst_glyphs = plan->glyphset ()->get_population ();
-
- unsigned bulk = 8192;
- /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
- * because those are expensive to subset, so giving them more room is fine. */
- bool same_size = table_tag == HB_OT_TAG_GSUB ||
- table_tag == HB_OT_TAG_GPOS ||
- table_tag == HB_OT_TAG_name;
-
- if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS)
- {
- if (table_tag == HB_OT_TAG_CFF1)
- {
- /* Add some extra room for the CFF charset. */
- bulk += src_glyphs * 16;
- }
- else if (table_tag == HB_OT_TAG_CFF2)
- {
- /* Just extra CharString offsets. */
- bulk += src_glyphs * 4;
- }
- }
-
- if (unlikely (!src_glyphs) || same_size)
- return bulk + table_len;
-
- return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
-}
-
-/*
- * Repack the serialization buffer if any offset overflows exist.
- */
-static hb_blob_t*
-_repack (hb_tag_t tag, const hb_serialize_context_t& c)
-{
- if (!c.offset_overflow ())
- return c.copy_blob ();
-
- hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag);
-
- if (unlikely (!result))
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.",
- HB_UNTAG (tag));
- return nullptr;
- }
-
- return result;
-}
-
-template<typename TableType>
-static
-bool
-_try_subset (const TableType *table,
- hb_vector_t<char>* buf,
- hb_subset_context_t* c /* OUT */)
-{
- c->serializer->start_serialize ();
- if (c->serializer->in_error ()) return false;
-
- bool needed = table->subset (c);
- if (!c->serializer->ran_out_of_room ())
- {
- c->serializer->end_serialize ();
- return needed;
- }
-
- unsigned buf_size = buf->allocated;
- buf_size = buf_size * 2 + 16;
-
-
-
-
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.",
- HB_UNTAG (c->table_tag), buf_size);
-
- if (unlikely (buf_size > c->source_blob->length * 256 ||
- !buf->alloc_exact (buf_size)))
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.",
- HB_UNTAG (c->table_tag), buf_size);
- return needed;
- }
-
- c->serializer->reset (buf->arrayZ, buf->allocated);
- return _try_subset (table, buf, c);
-}
-
-template <typename T>
-static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ())
-
-template <typename T>
-static void _do_destroy (T &t, hb_priority<0>) {}
-
-template<typename TableType>
-static bool
-_subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf)
-{
- auto &&source_blob = plan->source_table<TableType> ();
- auto *table = source_blob.get ();
-
- hb_tag_t tag = TableType::tableTag;
- hb_blob_t *blob = source_blob.get_blob();
- if (unlikely (!blob || !blob->data))
- {
- DEBUG_MSG (SUBSET, nullptr,
- "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
- _do_destroy (source_blob, hb_prioritize);
- return false;
- }
-
- unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag);
- DEBUG_MSG (SUBSET, nullptr,
- "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
- if (unlikely (!buf.alloc (buf_size)))
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
- _do_destroy (source_blob, hb_prioritize);
- return false;
- }
-
- bool needed = false;
- hb_serialize_context_t serializer (buf.arrayZ, buf.allocated);
- {
- hb_subset_context_t c (blob, plan, &serializer, tag);
- needed = _try_subset (table, &buf, &c);
- }
- _do_destroy (source_blob, hb_prioritize);
-
- if (serializer.in_error () && !serializer.only_offset_overflow ())
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset FAILED!", HB_UNTAG (tag));
- return false;
- }
-
- if (!needed)
- {
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
- return true;
- }
-
- bool result = false;
- hb_blob_t *dest_blob = _repack (tag, serializer);
- if (dest_blob)
- {
- DEBUG_MSG (SUBSET, nullptr,
- "OT::%c%c%c%c final subset table size: %u bytes.",
- HB_UNTAG (tag), dest_blob->length);
- result = plan->add_table (tag, dest_blob);
- hb_blob_destroy (dest_blob);
- }
-
- DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset %s",
- HB_UNTAG (tag), result ? "success" : "FAILED!");
- return result;
-}
-
static bool
_is_table_present (hb_face_t *source, hb_tag_t tag)
{
@@ -407,34 +198,34 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
switch (tag)
{
- case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */
+ case HB_TAG('c','v','a','r'): /* hint table, fallthrough */
return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
- case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */
- case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */
- case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */
- case HB_TAG ('h','d','m','x'): /* hint table, fallthrough */
- case HB_TAG ('V','D','M','X'): /* hint table, fallthrough */
+ case HB_TAG('c','v','t',' '): /* hint table, fallthrough */
+ case HB_TAG('f','p','g','m'): /* hint table, fallthrough */
+ case HB_TAG('p','r','e','p'): /* hint table, fallthrough */
+ case HB_TAG('h','d','m','x'): /* hint table, fallthrough */
+ case HB_TAG('V','D','M','X'): /* hint table, fallthrough */
return plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
#ifdef HB_NO_SUBSET_LAYOUT
// Drop Layout Tables if requested.
- case HB_OT_TAG_GDEF:
- case HB_OT_TAG_GPOS:
- case HB_OT_TAG_GSUB:
- case HB_TAG ('m','o','r','x'):
- case HB_TAG ('m','o','r','t'):
- case HB_TAG ('k','e','r','x'):
- case HB_TAG ('k','e','r','n'):
+ case HB_TAG('G','D','E','F'):
+ case HB_TAG('G','P','O','S'):
+ case HB_TAG('G','S','U','B'):
+ case HB_TAG('m','o','r','x'):
+ case HB_TAG('m','o','r','t'):
+ case HB_TAG('k','e','r','x'):
+ case HB_TAG('k','e','r','n'):
return true;
#endif
- case HB_TAG ('a','v','a','r'):
- case HB_TAG ('f','v','a','r'):
- case HB_TAG ('g','v','a','r'):
- case HB_OT_TAG_HVAR:
- case HB_OT_TAG_VVAR:
- case HB_TAG ('M','V','A','R'):
+ case HB_TAG('a','v','a','r'):
+ case HB_TAG('f','v','a','r'):
+ case HB_TAG('g','v','a','r'):
+ case HB_TAG('H','V','A','R'):
+ case HB_TAG('V','V','A','R'):
+ case HB_TAG('M','V','A','R'):
return plan->all_axes_pinned;
default:
@@ -443,28 +234,19 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
}
static bool
-_passthrough (hb_subset_plan_t *plan, hb_tag_t tag)
-{
- hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
- bool result = plan->add_table (tag, source_table);
- hb_blob_destroy (source_table);
- return result;
-}
-
-static bool
_dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag,
const hb_set_t &subsetted_tags,
const hb_set_t &pending_subset_tags)
{
switch (tag)
{
- case HB_OT_TAG_hmtx:
- case HB_OT_TAG_vmtx:
- case HB_OT_TAG_maxp:
- case HB_OT_TAG_OS2:
- return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf);
- case HB_OT_TAG_GPOS:
- return plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF);
+ case HB_TAG('h','m','t','x'):
+ case HB_TAG('v','m','t','x'):
+ case HB_TAG('m','a','x','p'):
+ case HB_TAG('O','S','/','2'):
+ return !plan->normalized_coords || !pending_subset_tags.has (HB_TAG('g','l','y','f'));
+ case HB_TAG('G','P','O','S'):
+ return plan->all_axes_pinned || !pending_subset_tags.has (HB_TAG('G','D','E','F'));
default:
return true;
}
@@ -476,88 +258,48 @@ _subset_table (hb_subset_plan_t *plan,
hb_tag_t tag)
{
if (plan->no_subset_tables.has (tag)) {
- return _passthrough (plan, tag);
+ return _hb_subset_table_passthrough (plan, tag);
}
DEBUG_MSG (SUBSET, nullptr, "subset %c%c%c%c", HB_UNTAG (tag));
+
+ bool success;
+ if (_hb_subset_table_layout (plan, buf, tag, &success) ||
+ _hb_subset_table_var (plan, buf, tag, &success) ||
+ _hb_subset_table_cff (plan, buf, tag, &success) ||
+ _hb_subset_table_color (plan, buf, tag, &success) ||
+ _hb_subset_table_other (plan, buf, tag, &success))
+ return success;
+
+
switch (tag)
{
- case HB_OT_TAG_glyf: return _subset<const OT::glyf> (plan, buf);
- case HB_OT_TAG_hdmx: return _subset<const OT::hdmx> (plan, buf);
- case HB_OT_TAG_name: return _subset<const OT::name> (plan, buf);
- case HB_OT_TAG_head:
- if (_is_table_present (plan->source, HB_OT_TAG_glyf) && !_should_drop_table (plan, HB_OT_TAG_glyf))
+ case HB_TAG('h','e','a','d'):
+ if (_is_table_present (plan->source, HB_TAG('g','l','y','f')) && !_should_drop_table (plan, HB_TAG('g','l','y','f')))
return true; /* skip head, handled by glyf */
- return _subset<const OT::head> (plan, buf);
- case HB_OT_TAG_hhea: return true; /* skip hhea, handled by hmtx */
- case HB_OT_TAG_hmtx: return _subset<const OT::hmtx> (plan, buf);
- case HB_OT_TAG_vhea: return true; /* skip vhea, handled by vmtx */
- case HB_OT_TAG_vmtx: return _subset<const OT::vmtx> (plan, buf);
- case HB_OT_TAG_maxp: return _subset<const OT::maxp> (plan, buf);
- case HB_OT_TAG_sbix: return _subset<const OT::sbix> (plan, buf);
- case HB_OT_TAG_loca: return true; /* skip loca, handled by glyf */
- case HB_OT_TAG_cmap: return _subset<const OT::cmap> (plan, buf);
- case HB_OT_TAG_OS2 : return _subset<const OT::OS2 > (plan, buf);
- case HB_OT_TAG_post: return _subset<const OT::post> (plan, buf);
- case HB_OT_TAG_COLR: return _subset<const OT::COLR> (plan, buf);
- case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan, buf);
- case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan, buf);
- case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
- case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan, buf);
- case HB_OT_TAG_BASE: return _subset<const OT::BASE> (plan, buf);
-
-#ifndef HB_NO_SUBSET_CFF
- case HB_OT_TAG_CFF1: return _subset<const OT::cff1> (plan, buf);
- case HB_OT_TAG_CFF2: return _subset<const OT::cff2> (plan, buf);
- case HB_OT_TAG_VORG: return _subset<const OT::VORG> (plan, buf);
-#endif
+ return _hb_subset_table<const OT::head> (plan, buf);
-#ifndef HB_NO_SUBSET_LAYOUT
- case HB_OT_TAG_GDEF: return _subset<const OT::GDEF> (plan, buf);
- case HB_OT_TAG_GSUB: return _subset<const GSUB> (plan, buf);
- case HB_OT_TAG_GPOS: return _subset<const GPOS> (plan, buf);
- case HB_OT_TAG_gvar: return _subset<const OT::gvar> (plan, buf);
- case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
- case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
-#endif
+ case HB_TAG('S','T','A','T'):
+ if (!plan->user_axes_location.is_empty ()) return _hb_subset_table<const OT::STAT> (plan, buf);
+ else return _hb_subset_table_passthrough (plan, tag);
+ case HB_TAG('c','v','t',' '):
#ifndef HB_NO_VAR
- case HB_OT_TAG_fvar:
- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
- return _subset<const OT::fvar> (plan, buf);
- case HB_OT_TAG_avar:
- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
- return _subset<const OT::avar> (plan, buf);
- case HB_OT_TAG_cvar:
- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
- return _subset<const OT::cvar> (plan, buf);
- case HB_OT_TAG_MVAR:
- if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
- return _subset<const OT::MVAR> (plan, buf);
-#endif
-
- case HB_OT_TAG_STAT:
- if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf);
- else return _passthrough (plan, tag);
-
- case HB_TAG ('c', 'v', 't', ' '):
-#ifndef HB_NO_VAR
- if (_is_table_present (plan->source, HB_OT_TAG_cvar) &&
+ if (_is_table_present (plan->source, HB_TAG('c','v','a','r')) &&
plan->normalized_coords && !plan->pinned_at_default)
{
auto &cvar = *plan->source->table.cvar;
return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar);
}
#endif
- return _passthrough (plan, tag);
+ return _hb_subset_table_passthrough (plan, tag);
+ }
- default:
- if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED)
- return _passthrough (plan, tag);
+ if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED)
+ return _hb_subset_table_passthrough (plan, tag);
- // Drop table
- return true;
- }
+ // Drop table
+ return true;
}
static void _attach_accelerator_data (hb_subset_plan_t* plan,
@@ -707,108 +449,4 @@ 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<typename accel_t>
-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<typename accel_t>
-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
+} \ No newline at end of file
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset.hh
index 4f192aae406..fca378de173 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.hh
@@ -70,5 +70,4 @@ struct hb_subset_context_t :
table_tag (table_tag_) {}
};
-
#endif /* HB_SUBSET_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
index aaf0b01d412..2d2dab45aba 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-version.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -47,20 +47,20 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 3
+#define HB_VERSION_MINOR 4
/**
* HB_VERSION_MICRO:
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 3
+#define HB_VERSION_MICRO 1
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "11.3.3"
+#define HB_VERSION_STRING "11.4.1"
/**
* HB_VERSION_ATLEAST:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb.hh b/src/3rdparty/harfbuzz-ng/src/hb.hh
index 47b710e6740..ba18e36b9f9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb.hh
@@ -136,6 +136,7 @@
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang
#pragma GCC diagnostic ignored "-Wrange-loop-analysis" // https://github.com/harfbuzz/harfbuzz/issues/2834
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
@@ -239,6 +240,8 @@
// clang defines it so no need.
#ifdef __has_builtin
#define hb_has_builtin __has_builtin
+#elif defined(_MSC_VER)
+#define hb_has_builtin(x) 0
#else
#define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5))
#endif
@@ -557,4 +560,13 @@ extern "C" void hb_free_impl(void *ptr);
#include "hb-vector.hh" // Requires: hb-array hb-null
#include "hb-object.hh" // Requires: hb-atomic hb-mutex hb-vector
+
+/* Our src/test-*.cc use hb_assert(), such that it's not compiled out under NDEBUG.
+ * https://github.com/harfbuzz/harfbuzz/issues/5418 */
+#define hb_always_assert(x) \
+ HB_STMT_START { \
+ if (!(x)) { fprintf(stderr, "Assertion failed: %s, at %s:%d\n", #x, __FILE__, __LINE__); abort(); } \
+ } HB_STMT_END
+
+
#endif /* HB_HH */
diff --git a/src/corelib/kernel/qpermissions.cpp b/src/corelib/kernel/qpermissions.cpp
index c5062860ea1..8c95431d01f 100644
--- a/src/corelib/kernel/qpermissions.cpp
+++ b/src/corelib/kernel/qpermissions.cpp
@@ -102,7 +102,7 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg);
application, please \l{Information Property List Files}
{point the build system to your custom \c Info.plist}.
- \sa {Information Property List Files}.
+ \sa {Information Property List Files}
\section3 Android
\target android-uses-permission
@@ -124,7 +124,7 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg);
The relevant permission names are described in the documentation
for each permission type.
- \sa {Qt Creator: Editing Manifest Files}.
+ \sa {Qt Creator: Editing Manifest Files}
\section1 Available Permissions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp
index 4238400b358..1da1704619f 100644
--- a/src/corelib/kernel/qproperty.cpp
+++ b/src/corelib/kernel/qproperty.cpp
@@ -1080,7 +1080,7 @@ QString QPropertyBindingError::description() const
long as the returned \c QPropertyChangeHandler and the property are kept alive.
On each value change, the handler is either called immediately, or deferred, depending on the context.
- \sa onValueChanged(), subscribe()
+ \sa QProperty::onValueChanged(), subscribe()
*/
/*!
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index 3b68ba4b71b..edaf73fbe57 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -3518,7 +3518,6 @@ QXmlStreamWriter::QXmlStreamWriter(QByteArray *array)
/*! Constructs a stream writer that writes into \a string.
- *
*/
QXmlStreamWriter::QXmlStreamWriter(QString *string)
: d_ptr(new QXmlStreamWriterPrivate(this))
diff --git a/src/corelib/text/qvsnprintf.cpp b/src/corelib/text/qvsnprintf.cpp
index 522c56fb800..abe3dd6772d 100644
--- a/src/corelib/text/qvsnprintf.cpp
+++ b/src/corelib/text/qvsnprintf.cpp
@@ -5,10 +5,10 @@
#include "qplatformdefs.h"
#include "qbytearray.h"
-#include <QtCore/private/qnumeric_p.h>
#include "qstring.h"
#include <cerrno>
+#include <QtCore/q26numeric.h>
#include "string.h"
@@ -68,7 +68,7 @@ int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
const auto realSize = ba.size();
int result;
if constexpr (sizeof(int) != sizeof(realSize)) {
- result = qt_saturate<int>(realSize);
+ result = q26::saturate_cast<int>(realSize);
if (result != realSize) {
errno = EOVERFLOW;
return -1;
diff --git a/src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_metering.cpp b/src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_metering.cpp
new file mode 100644
index 00000000000..edbe0e063d7
--- /dev/null
+++ b/src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_metering.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//![file]
+#include <QCoreApplication>
+#include <QNetworkInformation>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QFile>
+#include <QDebug>
+#include <QTimer>
+
+//! [0]
+void uploadLogFile()
+{
+//! [0]
+ // Hardcoded log file path (can be replaced with config or env variable)
+ QString logFilePath = QCoreApplication::applicationDirPath() + "/log.txt";
+
+ QFile *file = new QFile(logFilePath);
+ if (!file->exists()) {
+ qWarning() << "Log file does not exist:" << logFilePath;
+ return;
+ }
+
+ if (!file->open(QIODevice::ReadOnly)) {
+ qWarning() << "Could not open log file for reading:" << logFilePath;
+ return;
+ }
+
+ QNetworkRequest request(QUrl("http://localhost:8080/upload")); // Replace it with an actual upload URL
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
+
+ QNetworkAccessManager *manager = new QNetworkAccessManager(file);
+ QNetworkReply *reply = manager->post(request, file);
+
+ QObject::connect(reply, &QNetworkReply::finished, [=]() {
+ if (reply->error() == QNetworkReply::NoError)
+ qDebug() << "Log file upload successful.";
+ else
+ qWarning() << "Log file upload failed:" << reply->errorString();
+
+ file->deleteLater();
+ reply->deleteLater();
+ QCoreApplication::quit();
+ });
+//! [1]
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+//! [1]
+
+ if (!QNetworkInformation::loadDefaultBackend()) {
+ qWarning() << "Failed to load QNetworkInformation backend. Exiting.";
+ return 1;
+ }
+
+ QNetworkInformation *netInfo = QNetworkInformation::instance();
+
+ QTimer::singleShot(0, [&]() {
+//! [2]
+ if (netInfo->isMetered()) {
+ qWarning() << "Log upload skipped: Current network is metered.";
+ app.quit();
+ } else {
+ uploadLogFile();
+ }
+//! [2]
+ });
+
+ return app.exec();
+//! [3]
+}
+//! [3]
+//![file]
diff --git a/src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_reachability.cpp b/src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_reachability.cpp
new file mode 100644
index 00000000000..2c736f40c9a
--- /dev/null
+++ b/src/network/doc/snippets/code/src_network_kernel_qnetworkinformation_reachability.cpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+//![file]
+#include <QCoreApplication>
+#include <QNetworkInformation>
+#include <QHostAddress>
+#include <QDebug>
+
+//! [0]
+// Simple helper to decide whether an IP address is "local"
+bool isLocalAddress(const QHostAddress &address)
+{
+ return address.isInSubnet(QHostAddress("192.168.0.0"), 16) ||
+ address.isInSubnet(QHostAddress("10.0.0.0"), 8) ||
+ address.isInSubnet(QHostAddress("172.16.0.0"), 12) ||
+ address.isLoopback();
+}
+
+
+int main(int argc, char *argv[])
+{
+//! [0]
+ QCoreApplication app(argc, argv);
+
+ // Load the default backend for QNetworkInformation
+ if (!QNetworkInformation::loadDefaultBackend()) {
+ qWarning() << "Failed to load QNetworkInformation backend. Exiting.";
+ return 1;
+ }
+
+ QNetworkInformation *networkInfo = QNetworkInformation::instance();
+//! [1]
+ // Target IP address (default: Google DNS)
+ QString targetIpStr = argc > 1 ? argv[1] : "8.8.8.8";
+ QHostAddress targetIp(targetIpStr);
+
+ if (targetIp.isNull()) {
+ qWarning() << "Invalid IP address:" << targetIpStr;
+ return 1;
+ }
+
+ // Decide what level of reachability is needed for the target
+ QNetworkInformation::Reachability requiredReachability =
+ isLocalAddress(targetIp)
+ ? QNetworkInformation::Reachability::Local
+ : QNetworkInformation::Reachability::Online;
+
+ // Fetch the current system-reported reachability
+ QNetworkInformation::Reachability currentReachability = networkInfo->reachability();
+
+ qDebug() << "Target IP:" << targetIp.toString();
+ qDebug() << "Target is considered"
+ << (isLocalAddress(targetIp) ? "local/site." : "external/online.");
+ qDebug() << "Required reachability level:" << requiredReachability;
+ qDebug() << "Current reachability:" << currentReachability;
+
+ if (currentReachability < requiredReachability) {
+ qWarning() << "Current network state may not allow reaching the target address.";
+ } else {
+ qDebug() << "Target may be reachable based on current network state.";
+ }
+//! [1]
+ return 0;
+}
+//![file]
diff --git a/src/network/kernel/qnetworkinformation.cpp b/src/network/kernel/qnetworkinformation.cpp
index a156dd08ece..66be77c383a 100644
--- a/src/network/kernel/qnetworkinformation.cpp
+++ b/src/network/kernel/qnetworkinformation.cpp
@@ -440,6 +440,36 @@ QNetworkInformationBackendFactory::~QNetworkInformationBackendFactory()
object will also be destroyed in this thread, and various backend-specific
components may rely on being destroyed in the same thread as it is created.
+ One possible use case for QNetworkInformation is to monitor network
+ connectivity status. reachability() provides an indication of whether the
+ system is considered online, based on information reported by the
+ underlying operating system or plugin. However, this information may not
+ always be accurate. For example, on Windows, the online check may rely on
+ connectivity to a Microsoft-owned server; if that server is unreachable
+ (e.g., due to firewall rules), the system may incorrectly report that it is
+ offline. As such, reachability() should not be used as a definitive
+ pre-check before attempting a network connection, but rather as a general
+ signal of connectivity state.
+
+ To use reachability() effectively, the application must also understand
+ what kind of destination it is trying to reach. For example, if the target
+ is a local IP address, then Reachability::Local or Reachability::Site may
+ be sufficient. If the destination is on the public internet, then
+ Reachability::Online is required. Without this context, interpretring the
+ reported reachability may lead to incorrect assumptions about actual
+ network access.
+
+ \warning Only Linux and Windows provide support for the finer-grained
+ Reachability::Site and Reachability::Local options. On Android and Apple
+ platforms reachability() is limited to reporting only Online, Offline or
+ Unknown. Therefore, any logic that relies on detecting Local or Site level
+ connectivity must include appropriate platform checks or fallbacks.
+
+ \snippet code/src_network_kernel_qnetworkinformation_reachability.cpp 0
+ \dots
+ \snippet code/src_network_kernel_qnetworkinformation_reachability.cpp 1
+ \dots
+
\sa QNetworkInformation::Feature
*/
@@ -612,6 +642,14 @@ QNetworkInformation::TransportMedium QNetworkInformation::transportMedium() cons
application should perform certain network requests or uploads.
For instance, you may not want to upload logs or diagnostics while this
property is \c true.
+
+ \snippet code/src_network_kernel_qnetworkinformation_metering.cpp 0
+ \dots
+ \snippet code/src_network_kernel_qnetworkinformation_metering.cpp 1
+ \dots
+ \snippet code/src_network_kernel_qnetworkinformation_metering.cpp 2
+ \dots
+ \snippet code/src_network_kernel_qnetworkinformation_metering.cpp 3
*/
bool QNetworkInformation::isMetered() const
{
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
index b120e8bc6d1..60d2ac12644 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
@@ -11,6 +11,8 @@
#include <QtCore/private/qcore_mac_p.h>
#include <QtGui/qaccessible.h>
+#import <AppKit/NSAccessibilityElement.h>
+
QT_DECLARE_NAMESPACED_OBJC_INTERFACE(QMacAccessibilityElement, NSObject <NSAccessibilityElement>
- (instancetype)initWithId:(QAccessible::Id)anId;
- (instancetype)initWithId:(QAccessible::Id)anId role:(NSAccessibilityRole)role;
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
index 5a5fdfe664e..65257399eec 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -22,6 +22,8 @@
#include "qcocoansmenu.h"
+#import <AppKit/NSApplication.h>
+
QT_DECLARE_NAMESPACED_OBJC_INTERFACE(QCocoaApplicationDelegate, NSObject <NSApplicationDelegate>
@property (nonatomic, retain) NSMenu *dockMenu;
+ (instancetype)sharedDelegate;
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 6a54a826c0a..e2b517f20a5 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -26,6 +26,10 @@
#if defined(__OBJC__)
+#import <AppKit/NSDragging.h>
+#import <AppKit/NSEvent.h>
+#import <AppKit/NSButton.h>
+
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSView));
struct mach_header;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index 9c2fc842395..afcb6756ed9 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -17,6 +17,8 @@
#include <QtCore/private/qcore_mac_p.h>
+#import <AppKit/NSMenu.h>
+
QT_FORWARD_DECLARE_CLASS(QCocoaMenuItem);
QT_DECLARE_NAMESPACED_OBJC_INTERFACE(QCocoaMenuLoader, NSObject
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.h b/src/plugins/platforms/cocoa/qcocoansmenu.h
index 533aba1a21d..467115359b1 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.h
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.h
@@ -17,6 +17,8 @@
#include <QtCore/private/qcore_mac_p.h>
+#import <AppKit/NSMenu.h>
+
QT_FORWARD_DECLARE_CLASS(QCocoaMenu);
QT_FORWARD_DECLARE_CLASS(QCocoaMenuItem);
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h
index 4898255e022..273d2c942eb 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.h
+++ b/src/plugins/platforms/cocoa/qcocoascreen.h
@@ -12,8 +12,8 @@
#include <CoreGraphics/CoreGraphics.h>
#include <CoreVideo/CoreVideo.h>
-Q_FORWARD_DECLARE_OBJC_CLASS(NSScreen);
-Q_FORWARD_DECLARE_OBJC_CLASS(NSArray);
+#import <AppKit/NSScreen.h>
+#import <Foundation/NSArray.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 12ca6106732..7c55b38886b 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -196,6 +196,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMenuHelper);
- (void)removeFromSuperview
{
+ qCDebug(lcQpaWindow) << "Removing" << self << "from" << self.superview;
QMacAutoReleasePool pool;
[super removeFromSuperview];
}
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index e5b3c4b3a98..76fd3f13c90 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -6,6 +6,8 @@
#include <QtCore/private/qcore_mac_p.h>
+#import <AppKit/NSWindow.h>
+
QT_BEGIN_NAMESPACE
class QCocoaWindow;
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
index c96ac2855b4..03d8d330578 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
@@ -333,7 +333,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *s
if (type == Qt::ToolTip)
setPopup(transientParent);
- else if (type == Qt::Popup || type == Qt::Tool)
+ else if (type == Qt::Popup)
setGrabPopup(transientParent, display->lastInputDevice(), display->lastInputSerial());
else
setToplevel();
@@ -599,10 +599,11 @@ bool QWaylandXdgSurface::requestActivate()
bool QWaylandXdgSurface::requestActivateOnShow()
{
- const Qt::WindowFlags flags = m_window->window()->flags();
- if (flags.testFlag(Qt::Popup))
+ const Qt::WindowType type = m_window->window()->type();
+ if (type == Qt::ToolTip || type == Qt::Popup || type == Qt::SplashScreen)
return false;
+ const Qt::WindowFlags flags = m_window->window()->flags();
if (flags & Qt::WindowDoesNotAcceptFocus)
return false;
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
index 47fdf0e1ffc..90a5965bba6 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgshellintegration.cpp
@@ -55,7 +55,7 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
return new QWaylandShellSurface(window);
}
- if ((type == Qt::Popup || type == Qt::Tool) && (!transientParent || !display->lastInputDevice())) {
+ if (type == Qt::Popup && (!transientParent || !display->lastInputDevice())) {
qCWarning(lcQpaWayland) << "Failed to create grabbing popup. Ensure popup " << window->window() << "has a transientParent set and that parent window has received input.";
QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(window->window());
return new QWaylandShellSurface(window);
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index ba98e579e39..cc32eb4d1e9 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -121,7 +121,7 @@ void QWaylandWindow::initWindow()
Q_ASSERT(mShellIntegration);
mTransientParent = guessTransientParent();
if (mTransientParent) {
- if (window()->type() == Qt::Popup || window()->type() == Qt::Tool) {
+ if (window()->type() == Qt::Popup) {
if (mTopPopup && mTopPopup != mTransientParent) {
qCWarning(lcQpaWayland) << "Creating a popup with a parent," << mTransientParent->window()
<< "which does not match the current topmost grabbing popup,"
@@ -346,9 +346,7 @@ void QWaylandWindow::resetSurfaceRole()
closeChildPopups();
if (mTopPopup == this)
- mTopPopup = mTransientParent &&
- (mTransientParent->window()->type() == Qt::Popup || mTransientParent->window()->type() == Qt::Tool)
- ? mTransientParent : nullptr;
+ mTopPopup = mTransientParent && (mTransientParent->window()->type() == Qt::Popup) ? mTransientParent : nullptr;
if (mTransientParent)
mTransientParent->removeChildPopup(this);
mTransientParent = nullptr;
@@ -479,7 +477,8 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect)
void QWaylandWindow::setGeometry(const QRect &r)
{
auto rect = r;
- if (fixedToplevelPositions && !QPlatformWindow::parent() && !window()->flags().testFlag(Qt::Popup)) {
+ if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
+ && window()->type() != Qt::ToolTip && window()->type() != Qt::Tool) {
rect.moveTo(screen()->geometry().topLeft());
}
setGeometry_helper(rect);
@@ -1219,12 +1218,12 @@ QWaylandWindow *QWaylandWindow::guessTransientParent() const
if (auto transientParent = closestShellSurfaceWindow(window()->transientParent()))
return transientParent;
- if (window()->type() == Qt::Popup || window()->type() == Qt::Tool) {
+ if (window()->type() == Qt::Popup) {
if (mTopPopup)
return mTopPopup;
}
- if (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup || window()->type() == Qt::Tool) {
+ if (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup) {
if (auto lastInputWindow = display()->lastInputWindow())
return closestShellSurfaceWindow(lastInputWindow->window());
}
@@ -1499,7 +1498,8 @@ void QWaylandWindow::handleScreensChanged()
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->QPlatformScreen::screen());
- if (fixedToplevelPositions && !QPlatformWindow::parent() && !window()->flags().testFlag(Qt::Popup)
+ if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
+ && window()->type() != Qt::ToolTip && window()->type() != Qt::Tool
&& geometry().topLeft() != newScreen->geometry().topLeft()) {
auto geometry = this->geometry();
geometry.moveTo(newScreen->geometry().topLeft());
@@ -1649,7 +1649,7 @@ qreal QWaylandWindow::devicePixelRatio() const
bool QWaylandWindow::setMouseGrabEnabled(bool grab)
{
- if (window()->type() != Qt::Popup && window()->type() != Qt::Tool) {
+ if (window()->type() != Qt::Popup) {
qWarning("This plugin supports grabbing the mouse only for popup windows");
return false;
}
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 83b2d284e86..2c07f4e387c 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -1963,6 +1963,95 @@ void QMacStylePrivate::resolveCurrentNSView(QWindow *window) const
backingStoreNSView = window ? (NSView *)window->winId() : nil;
}
+void QMacStylePrivate::drawProgressBar(QPainter* p, const QStyleOptionProgressBar *pb) const
+{
+ const qreal progress = pb->progress / double(pb->maximum - pb->minimum);
+ const bool indeterminate = (pb->minimum == 0 && pb->maximum == 0);
+ const bool vertical = !(pb->state & QStyle::State_Horizontal);
+ const bool inverted = pb->invertedAppearance || (!vertical && (pb->direction == Qt::RightToLeft));
+ QRect rect = pb->rect;
+
+ // The height of a (horizontal) progressbar is fixed, and is found to have
+ // a value of 8 (from eyeballing an NSProgressIndicator in XCode 26)
+ const qreal fixedSize = 8;
+ const qreal radius = fixedSize / 2.;
+
+ QRectF groove;
+ QRectF track;
+
+ if (vertical)
+ groove = QRectF((rect.width() - fixedSize) / 2, rect.y(), fixedSize, rect.height());
+ else
+ groove = QRectF(rect.x(), (rect.height() - fixedSize) / 2, rect.width(), fixedSize);
+
+ if (indeterminate) {
+ const qreal velocity = 100;
+ const qreal minBlockSize = 15;
+ const qreal maxBlockFraction = 0.25;
+
+ // We use a static timer to dermine the progress position, since
+ // all indeterminate progressbars should animate in sync.
+ static QElapsedTimer timer;
+ if (!timer.isValid())
+ timer.start();
+
+ const qreal time = (timer.elapsed() / (1000.0 / 60.0));
+ const qreal normalizedPos = 0.5 - (0.5 * std::cos(time / velocity * 2 * M_PI)); // 0 -> 1
+
+ if (vertical) {
+ const qreal maxBlockSize = rect.height() * maxBlockFraction;
+ const qreal margin = (maxBlockSize - minBlockSize) / (2 * rect.height());
+ const qreal pos = -margin + (normalizedPos * (1 + (margin * 2)));
+ const qreal pixelPos = pos * rect.height();
+ const qreal top = pixelPos > (maxBlockSize / 2) ? pixelPos - (maxBlockSize / 2) : 0;
+ const qreal bottom = pixelPos > rect.height() - (maxBlockSize / 2)
+ ? rect.height() : pixelPos + (maxBlockSize / 2);
+ track = QRectF((rect.width() - fixedSize) / 2, top, fixedSize, bottom - top);
+ } else {
+ const qreal maxBlockSize = rect.width() * maxBlockFraction;
+ const qreal margin = (maxBlockSize - minBlockSize) / (2 * rect.width());
+ const qreal pos = -margin + (normalizedPos * (1 + (margin * 2)));
+ const qreal pixelPos = pos * rect.width();
+ const qreal left = pixelPos > (maxBlockSize / 2) ? pixelPos - (maxBlockSize / 2) : 0;
+ const qreal right = pixelPos > rect.width() - (maxBlockSize / 2)
+ ? rect.width() : pixelPos + (maxBlockSize / 2);
+ track = QRectF(left, (rect.height() - fixedSize) / 2, right - left, fixedSize);
+ }
+ } else {
+ if (vertical) {
+ const qreal trackSize = rect.height() * progress;
+ if (inverted)
+ track = QRectF((rect.width() - fixedSize) / 2, rect.y(), fixedSize, trackSize);
+ else
+ track = QRectF((rect.width() - fixedSize) / 2, rect.height() - trackSize, fixedSize, trackSize);
+ } else {
+ const qreal trackSize = rect.width() * progress;
+ if (inverted)
+ track = QRectF(rect.width() - trackSize, (rect.height() - fixedSize) / 2, trackSize, fixedSize);
+ else
+ track = QRectF(rect.x(), (rect.height() - fixedSize) / 2, trackSize, fixedSize);
+ }
+ }
+
+ // Draw groove
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing, true);
+ if (@available(macOS 14.0, *)) { // silence compiler
+ p->setPen(qt_mac_toQBrush([NSColor secondarySystemFillColor]).color());
+ p->setBrush(qt_mac_toQBrush([NSColor tertiarySystemFillColor]).color());
+ } else {
+ p->setPen(Qt::NoPen);
+ p->setBrush(qt_mac_toQBrush([NSColor controlColor]).color());
+ }
+ p->drawRoundedRect(groove, radius, radius);
+
+ // Draw track / progress
+ p->setPen(Qt::NoPen);
+ p->setBrush(pb->state & QStyle::State_Active ? pb->palette.accent().color() : Qt::lightGray);
+ p->drawRoundedRect(track, radius, radius);
+ p->restore();
+}
+
QMacStyle *QMacStyle::create()
{
return new QMacApperanceStyle<QMacStyle>;
@@ -4312,17 +4401,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
bool reverse = (!vertical && (pb->direction == Qt::RightToLeft));
if (inverted)
reverse = !reverse;
-
QRect rect = pb->rect;
- if (vertical)
- rect = rect.transposed();
- const CGRect cgRect = rect.toCGRect();
const auto aquaSize = d->effectiveAquaSizeConstrain(opt, w);
const QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject));
- QIndeterminateProgressIndicator *ipi = nil;
- if (isIndeterminate || animation)
- ipi = static_cast<QIndeterminateProgressIndicator *>(d->cocoaControl({ QMacStylePrivate::ProgressIndicator_Indeterminate, aquaSize }));
if (isIndeterminate) {
// QIndeterminateProgressIndicator derives from NSProgressIndicator. We use a single
// instance that we start animating as soon as one of the progress bars is indeterminate.
@@ -4336,28 +4418,45 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
// NSProgressIndicator is heavier to draw than the HITheme API, so we reduce the frame rate a couple notches.
animation->setFrameRate(QStyleAnimation::FifteenFps);
d->startAnimation(animation);
- [ipi startAnimation];
}
- d->setupNSGraphicsContext(cg, NO);
- d->setupVerticalInvertedXform(cg, reverse, vertical, cgRect);
- [ipi drawWithFrame:cgRect inView:d->backingStoreNSView];
- d->restoreNSGraphicsContext(cg);
+ if (qt_apple_runningWithLiquidGlass()) {
+ d->drawProgressBar(p, pb);
+ } else {
+ if (vertical)
+ rect = rect.transposed();
+ d->setupNSGraphicsContext(cg, NO);
+ d->setupVerticalInvertedXform(cg, reverse, vertical, rect.toCGRect());
+ if (auto *ipi
+ = static_cast<QIndeterminateProgressIndicator *>(
+ d->cocoaControl({ QMacStylePrivate::ProgressIndicator_Indeterminate, aquaSize }))) {
+ [ipi startAnimation];
+ [ipi drawWithFrame:rect.toCGRect() inView:d->backingStoreNSView];
+ }
+ d->restoreNSGraphicsContext(cg);
+ }
} else {
if (animation) {
d->stopAnimation(opt->styleObject);
- [ipi stopAnimation];
+ if (auto *ipi
+ = static_cast<QIndeterminateProgressIndicator *>(
+ d->cocoaControl({ QMacStylePrivate::ProgressIndicator_Indeterminate, aquaSize })))
+ [ipi stopAnimation];
+ }
+ if (qt_apple_runningWithLiquidGlass()) {
+ d->drawProgressBar(p, pb);
+ } else {
+ if (vertical)
+ rect = rect.transposed();
+ const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::ProgressIndicator_Determinate, aquaSize);
+ auto *pi = static_cast<NSProgressIndicator *>(d->cocoaControl(cw));
+ d->drawNSViewInRect(pi, rect, p, ^(CGContextRef ctx, const CGRect &cgrect) {
+ d->setupVerticalInvertedXform(ctx, reverse, vertical, cgrect);
+ pi.minValue = pb->minimum;
+ pi.maxValue = pb->maximum;
+ pi.doubleValue = pb->progress;
+ [pi drawRect:cgrect]; });
}
-
- const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::ProgressIndicator_Determinate, aquaSize);
- auto *pi = static_cast<NSProgressIndicator *>(d->cocoaControl(cw));
- d->drawNSViewInRect(pi, rect, p, ^(CGContextRef ctx, const CGRect &rect) {
- d->setupVerticalInvertedXform(ctx, reverse, vertical, rect);
- pi.minValue = pb->minimum;
- pi.maxValue = pb->maximum;
- pi.doubleValue = pb->progress;
- [pi drawRect:rect];
- });
}
}
break;
diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
index 3ad91df33fe..d702b9e30df 100644
--- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h
+++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
@@ -237,6 +237,7 @@ public:
void drawNSViewInRect(NSView *view, const QRectF &rect, QPainter *p, __attribute__((noescape)) DrawRectBlock drawRectBlock = nil) const;
void resolveCurrentNSView(QWindow *window) const;
+ void drawProgressBar(QPainter *p, const QStyleOptionProgressBar *pb) const;
void drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const;
void drawToolbarButtonArrow(const QStyleOption *opt, QPainter *p) const;
diff --git a/src/widgets/doc/snippets/itemselection/main.cpp b/src/widgets/doc/snippets/itemselection/main.cpp
index 31908076055..ce277432100 100644
--- a/src/widgets/doc/snippets/itemselection/main.cpp
+++ b/src/widgets/doc/snippets/itemselection/main.cpp
@@ -13,29 +13,7 @@
#include <QItemSelectionModel>
#include <QTableView>
-class TableModel : public QAbstractTableModel
-{
- Q_OBJECT
-public:
- TableModel(int rows, int columns, QObject *parent = nullptr)
- : QAbstractTableModel(parent), m_rows(rows), m_columns(columns) {}
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override {
- return m_rows;
- }
-
- int columnCount(const QModelIndex &parent = QModelIndex()) const override {
- return m_columns;
- }
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
- return QVariant();
- }
-
-private:
- int m_rows, m_columns;
-
-};
+#include "../common-table-model/model.h"
int main(int argc, char *argv[])
{
diff --git a/src/widgets/doc/snippets/reading-selections/window.cpp b/src/widgets/doc/snippets/reading-selections/window.cpp
index c0c3bcbe6f4..1f219c861e1 100644
--- a/src/widgets/doc/snippets/reading-selections/window.cpp
+++ b/src/widgets/doc/snippets/reading-selections/window.cpp
@@ -17,25 +17,7 @@
#include <QTableView>
#include "../include/mainwindow.h"
-
-class TableModel : public QAbstractTableModel
-{
- Q_OBJECT
-public:
- TableModel(int rows, int columns, QObject *parent = nullptr) {}
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override {
- return 0;
- }
-
- int columnCount(const QModelIndex &parent = QModelIndex()) const override {
- return 0;
- }
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
- return QVariant();
- }
-};
+#include "../common-table-model/model.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
diff --git a/src/widgets/doc/snippets/sharedtablemodel/main.cpp b/src/widgets/doc/snippets/sharedtablemodel/main.cpp
index ab02094595d..76a4ebc6670 100644
--- a/src/widgets/doc/snippets/sharedtablemodel/main.cpp
+++ b/src/widgets/doc/snippets/sharedtablemodel/main.cpp
@@ -13,25 +13,7 @@
#include <QItemSelectionModel>
#include <QTableView>
-class TableModel : public QAbstractTableModel
-{
- Q_OBJECT
-public:
- TableModel(int rows, int columns, QObject *parent = nullptr)
- : QAbstractTableModel(parent), rowCount(rows), columnCount(columns) {}
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override {
- return rowCount;
- }
-
- int columnCount(const QModelIndex &parent = QModelIndex()) const override {
- return columnCount;
- }
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
- return QVariant();
- }
-};
+#include "../common-table-model/model.h"
int main(int argc, char *argv[])
{
diff --git a/src/widgets/doc/snippets/updating-selections/window.cpp b/src/widgets/doc/snippets/updating-selections/window.cpp
index d03a36d5fc3..a2dc44d1088 100644
--- a/src/widgets/doc/snippets/updating-selections/window.cpp
+++ b/src/widgets/doc/snippets/updating-selections/window.cpp
@@ -15,26 +15,7 @@
#include <QTableView>
#include "../include/mainwindow.h"
-
-class TableModel : public QAbstractTableModel
-{
- Q_OBJECT
-public:
- TableModel(int rows, int columns, QObject *parent = nullptr)
- : QAbstractTableModel(parent) {}
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override {
- return 0;
- }
-
- int columnCount(const QModelIndex &parent = QModelIndex()) const override {
- return 0;
- }
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
- return QVariant();
- }
-};
+#include "../common-table-model/model.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h
index 0cbcc5321d4..262207f40c8 100644
--- a/src/widgets/kernel/qwindowcontainer_p.h
+++ b/src/widgets/kernel/qwindowcontainer_p.h
@@ -30,7 +30,7 @@ class Q_WIDGETS_EXPORT QWindowContainer : public QWidget
public:
explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = nullptr, Qt::WindowFlags f = { });
~QWindowContainer();
- QWindow *containedWindow() const;
+ Q_INVOKABLE QWindow *containedWindow() const;
QSize minimumSizeHint() const override;
static void toplevelAboutToBeDestroyed(QWidget *parent);