summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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/doc/snippets/CMakeLists.txt36
-rw-r--r--src/corelib/doc/snippets/code/CMakeLists.txt48
-rw-r--r--src/corelib/doc/snippets/eventfilters/CMakeLists.txt20
-rw-r--r--src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt10
-rw-r--r--src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt10
-rw-r--r--src/corelib/io/qdebug.h3
-rw-r--r--src/corelib/itemmodels/qrangemodel.cpp64
-rw-r--r--src/corelib/itemmodels/qrangemodel_impl.h557
-rw-r--r--src/corelib/kernel/qdeadlinetimer.cpp4
-rw-r--r--src/corelib/kernel/qmetacontainer.cpp2
-rw-r--r--src/corelib/kernel/qmetatype.cpp4
-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/corelib/thread/qfutureinterface.h6
-rw-r--r--src/gui/doc/snippets/CMakeLists.txt45
-rw-r--r--src/gui/doc/snippets/code/CMakeLists.txt24
-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.cpp23
-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/testlib/doc/snippets/code/CMakeLists.txt20
-rw-r--r--src/widgets/doc/snippets/CMakeLists.txt54
-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
110 files changed, 3047 insertions, 2007 deletions
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/doc/snippets/CMakeLists.txt b/src/corelib/doc/snippets/CMakeLists.txt
index 90f80ee6575..5521bf1f651 100644
--- a/src/corelib/doc/snippets/CMakeLists.txt
+++ b/src/corelib/doc/snippets/CMakeLists.txt
@@ -29,22 +29,23 @@ target_link_libraries(corelib_snippets PRIVATE
Qt::Core
)
-qt_internal_extend_target(corelib_snippets CONDITION QT_FEATURE_process
- SOURCES
+if(QT_FEATURE_process)
+ target_sources(corelib_snippets PRIVATE
process/process.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets
- CONDITION
- QT_FEATURE_process AND QT_FEATURE_processenvironment
- SOURCES
+if(QT_FEATURE_process AND QT_FEATURE_processenvironment)
+ target_sources(corelib_snippets PRIVATE
qprocess-environment/main.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(corelib_snippets PRIVATE
Qt::Widgets
- SOURCES
+ )
+ target_sources(corelib_snippets PRIVATE
events/events.cpp
hellotrmain.cpp
fileinfo/main.cpp
@@ -54,15 +55,18 @@ qt_internal_extend_target(corelib_snippets CONDITION QT_FEATURE_widgets
qstring/main.cpp
qtcast/qtcast.cpp
settings/settings.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets CONDITION QT_FEATURE_gui
- LIBRARIES
+if(QT_FEATURE_gui)
+ target_link_libraries(corelib_snippets PRIVATE
Qt::Gui
- SOURCES
+ )
+ target_sources(corelib_snippets PRIVATE
buffer/buffer.cpp
qdebug/qdebugsnippet.cpp
-)
+ )
+endif()
set_target_properties(corelib_snippets PROPERTIES COMPILE_OPTIONS "-w")
diff --git a/src/corelib/doc/snippets/code/CMakeLists.txt b/src/corelib/doc/snippets/code/CMakeLists.txt
index 64abd1def67..402d20cfe7b 100644
--- a/src/corelib/doc/snippets/code/CMakeLists.txt
+++ b/src/corelib/doc/snippets/code/CMakeLists.txt
@@ -102,47 +102,55 @@ target_link_libraries(corelib_snippets_code PRIVATE
Qt::Core
)
-qt_internal_extend_target(corelib_snippets_code CONDITION APPLE
- SOURCES
+if(APPLE)
+ target_sources(corelib_snippets_code PRIVATE
src_corelib_kernel_qabstractnativeeventfilter.mm
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets_code CONDITION QT_FEATURE_process
- SOURCES
+if(QT_FEATURE_process)
+ target_sources(corelib_snippets_code PRIVATE
src_corelib_io_qiodevice.cpp
src_corelib_io_qprocess.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets_code CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(corelib_snippets_code PRIVATE
Qt::Widgets
- SOURCES
+ )
+ target_sources(corelib_snippets_code PRIVATE
doc_src_objecttrees.cpp
src_corelib_animation_qpropertyanimation.cpp
src_corelib_global_qglobal_widgets.cpp
src_corelib_kernel_qobject.cpp
src_corelib_kernel_qtimer.cpp
src_corelib_tools_qtimeline.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets_code CONDITION QT_FEATURE_gui
- LIBRARIES
+if(QT_FEATURE_gui)
+ target_link_libraries(corelib_snippets_code PRIVATE
Qt::Gui
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets_code CONDITION QT_FEATURE_concurrent
- LIBRARIES
+if(QT_FEATURE_concurrent)
+ target_link_libraries(corelib_snippets_code PRIVATE
Qt::Concurrent
- SOURCES
+ )
+ target_sources(corelib_snippets_code PRIVATE
src_corelib_thread_qexception.cpp
src_corelib_thread_qfuture.cpp
src_corelib_thread_qfuturesynchronizer.cpp
src_corelib_thread_qfuturewatcher.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets_code CONDITION QT_FEATURE_network
- LIBRARIES
+if(QT_FEATURE_network)
+ target_link_libraries(corelib_snippets_code PRIVATE
Qt::Network
-)
+ )
+endif()
set_target_properties(corelib_snippets_code PROPERTIES COMPILE_OPTIONS "-w")
diff --git a/src/corelib/doc/snippets/eventfilters/CMakeLists.txt b/src/corelib/doc/snippets/eventfilters/CMakeLists.txt
index 7da83cbdf6e..d9941a5ec96 100644
--- a/src/corelib/doc/snippets/eventfilters/CMakeLists.txt
+++ b/src/corelib/doc/snippets/eventfilters/CMakeLists.txt
@@ -6,16 +6,20 @@ target_link_libraries(corelib_snippets_eventfilters PRIVATE
Qt::Core
)
-qt_internal_extend_target(corelib_snippets_eventfilters CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(corelib_snippets_eventfilters PRIVATE
Qt::Widgets
- SOURCE
+ )
+ target_sources(corelib_snippets_eventfilters PRIVATE
main.cpp
-)
+ )
+endif()
-qt_internal_extend_target(corelib_snippets_eventfilters CONDITION QT_FEATURE_gui
- LIBRARIES
+if(QT_FEATURE_gui)
+ target_link_libraries(corelib_snippets_eventfilters PRIVATE
Qt::Gui
- SOURCES
+ )
+ target_sources(corelib_snippets_eventfilters PRIVATE
filterobject.cpp
-)
+ )
+endif()
diff --git a/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt b/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt
index 972bf43d9b1..80fff7820ca 100644
--- a/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt
+++ b/src/corelib/doc/snippets/qmetaobject-invokable/CMakeLists.txt
@@ -10,10 +10,12 @@ target_link_libraries(corelib_snippets_qmetaobject-invokable PRIVATE
Qt::Core
)
-qt_internal_extend_target(corelib_snippets_qmetaobject-invokable CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(corelib_snippets_qmetaobject-invokable PRIVATE
Qt::Widgets
- SOURCES
+ )
+ target_sources(corelib_snippets_qmetaobject-invokable PRIVATE
main.cpp
window.cpp
-)
+ )
+endif()
diff --git a/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt b/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt
index 369b2e15315..72b0201447d 100644
--- a/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt
+++ b/src/corelib/doc/snippets/qmetaobject-revision/CMakeLists.txt
@@ -10,10 +10,12 @@ target_link_libraries(corelib_snippets_qmetaobject-revision PRIVATE
Qt::Core
)
-qt_internal_extend_target(corelib_snippets_qmetaobject-revision CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(corelib_snippets_qmetaobject-revision PRIVATE
Qt::Widgets
- SOURCES
+ )
+ target_sources(corelib_snippets_qmetaobject-revision PRIVATE
main.cpp
window.cpp
-)
+ )
+endif()
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index b04051f3597..f59f3e2aed2 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -351,7 +351,8 @@ public:
template<typename T>
inline QNoDebug &operator<<(const T &) { return *this; }
};
-inline QNoDebug QMessageLogger::noDebug(...) const noexcept
+
+QNoDebug QMessageLogger::noDebug(...) const noexcept
{ return {}; }
inline QDebug &QDebug::operator=(const QDebug &other)
diff --git a/src/corelib/itemmodels/qrangemodel.cpp b/src/corelib/itemmodels/qrangemodel.cpp
index 01f6de6fe9d..27db73c4021 100644
--- a/src/corelib/itemmodels/qrangemodel.cpp
+++ b/src/corelib/itemmodels/qrangemodel.cpp
@@ -13,33 +13,13 @@ class QRangeModelPrivate : QAbstractItemModelPrivate
{
Q_DECLARE_PUBLIC(QRangeModel)
- struct Deleter { void operator()(QRangeModelImplBase *that) { that->destroy(); } };
-
public:
- explicit QRangeModelPrivate(std::unique_ptr<QRangeModelImplBase, Deleter> impl)
+ explicit QRangeModelPrivate(std::unique_ptr<QRangeModelImplBase, QRangeModelImplBase::Deleter> impl)
: impl(std::move(impl))
{}
- template <typename Ret, typename ...Args>
- Ret call(QRangeModelImplBase::ConstOp op, const Args &...args) const
- {
- Ret ret = {};
- const auto tuple = std::tie(args...);
- impl->callConst_fn(op, impl.get(), &ret, &tuple);
- return ret;
- }
-
- template <typename Ret, typename ...Args>
- Ret call(QRangeModelImplBase::Op op, const Args &...args)
- {
- Ret ret = {};
- const auto tuple = std::tie(args...);
- impl->call_fn(op, impl.get(), &ret, &tuple);
- return ret;
- }
-
private:
- std::unique_ptr<QRangeModelImplBase, Deleter> impl;
+ std::unique_ptr<QRangeModelImplBase, QRangeModelImplBase::Deleter> impl;
mutable QHash<int, QByteArray> m_roleNames;
};
@@ -552,7 +532,7 @@ QRangeModel::~QRangeModel() = default;
QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent) const
{
Q_D(const QRangeModel);
- return d->call<QModelIndex>(QRangeModelImplBase::Index, row, column, parent);
+ return d->impl->call<QRangeModelImplBase::Index>(row, column, parent);
}
/*!
@@ -570,7 +550,7 @@ QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent) c
QModelIndex QRangeModel::parent(const QModelIndex &child) const
{
Q_D(const QRangeModel);
- return d->call<QModelIndex>(QRangeModelImplBase::Parent, child);
+ return d->impl->call<QRangeModelImplBase::Parent>(child);
}
/*!
@@ -587,7 +567,7 @@ QModelIndex QRangeModel::parent(const QModelIndex &child) const
QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index) const
{
Q_D(const QRangeModel);
- return d->call<QModelIndex>(QRangeModelImplBase::Sibling, row, column, index);
+ return d->impl->call<QRangeModelImplBase::Sibling>(row, column, index);
}
/*!
@@ -606,7 +586,7 @@ QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index)
int QRangeModel::rowCount(const QModelIndex &parent) const
{
Q_D(const QRangeModel);
- return d->call<int>(QRangeModelImplBase::RowCount, parent);
+ return d->impl->call<QRangeModelImplBase::RowCount>(parent);
}
/*!
@@ -625,7 +605,7 @@ int QRangeModel::rowCount(const QModelIndex &parent) const
int QRangeModel::columnCount(const QModelIndex &parent) const
{
Q_D(const QRangeModel);
- return d->call<int>(QRangeModelImplBase::ColumnCount, parent);
+ return d->impl->call<QRangeModelImplBase::ColumnCount>(parent);
}
/*!
@@ -643,7 +623,7 @@ int QRangeModel::columnCount(const QModelIndex &parent) const
Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const
{
Q_D(const QRangeModel);
- return d->call<Qt::ItemFlags>(QRangeModelImplBase::Flags, index);
+ return d->impl->call<QRangeModelImplBase::Flags>(index);
}
/*!
@@ -661,7 +641,7 @@ Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const
QVariant QRangeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_D(const QRangeModel);
- return d->call<QVariant>(QRangeModelImplBase::HeaderData, section, orientation, role);
+ return d->impl->call<QRangeModelImplBase::HeaderData>(section, orientation, role);
}
/*!
@@ -697,7 +677,7 @@ bool QRangeModel::setHeaderData(int section, Qt::Orientation orientation, const
QVariant QRangeModel::data(const QModelIndex &index, int role) const
{
Q_D(const QRangeModel);
- return d->call<QVariant>(QRangeModelImplBase::Data, index, role);
+ return d->impl->call<QRangeModelImplBase::Data>(index, role);
}
/*!
@@ -729,7 +709,7 @@ QVariant QRangeModel::data(const QModelIndex &index, int role) const
bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int role)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::SetData, index, data, role);
+ return d->impl->call<QRangeModelImplBase::SetData>(index, data, role);
}
/*!
@@ -753,7 +733,7 @@ bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int ro
QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const
{
Q_D(const QRangeModel);
- return d->call<QMap<int, QVariant>>(QRangeModelImplBase::ItemData, index);
+ return d->impl->call<QRangeModelImplBase::ItemData>(index);
}
/*!
@@ -785,7 +765,7 @@ QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const
bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &data)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::SetItemData, index, data);
+ return d->impl->call<QRangeModelImplBase::SetItemData>(index, data);
}
/*!
@@ -799,7 +779,7 @@ bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant
bool QRangeModel::clearItemData(const QModelIndex &index)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::ClearItemData, index);
+ return d->impl->call<QRangeModelImplBase::ClearItemData>(index);
}
/*
@@ -825,7 +805,7 @@ bool QRangeModel::clearItemData(const QModelIndex &index)
bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::InsertColumns, column, count, parent);
+ return d->impl->call<QRangeModelImplBase::InsertColumns>(column, count, parent);
}
/*!
@@ -840,7 +820,7 @@ bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent
bool QRangeModel::removeColumns(int column, int count, const QModelIndex &parent)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::RemoveColumns, column, count, parent);
+ return d->impl->call<QRangeModelImplBase::RemoveColumns>(column, count, parent);
}
/*!
@@ -856,7 +836,7 @@ bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn,
const QModelIndex &destinationParent, int destinationColumn)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::MoveColumns,
+ return d->impl->call<QRangeModelImplBase::MoveColumns>(
sourceParent, sourceColumn, count,
destinationParent, destinationColumn);
}
@@ -886,7 +866,7 @@ bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn,
bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::InsertRows, row, count, parent);
+ return d->impl->call<QRangeModelImplBase::InsertRows>(row, count, parent);
}
/*!
@@ -900,7 +880,7 @@ bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent)
bool QRangeModel::removeRows(int row, int count, const QModelIndex &parent)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::RemoveRows, row, count, parent);
+ return d->impl->call<QRangeModelImplBase::RemoveRows>(row, count, parent);
}
/*!
@@ -916,7 +896,7 @@ bool QRangeModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int c
const QModelIndex &destinationParent, int destinationRow)
{
Q_D(QRangeModel);
- return d->call<bool>(QRangeModelImplBase::MoveRows,
+ return d->impl->call<QRangeModelImplBase::MoveRows>(
sourceParent, sourceRow, count,
destinationParent, destinationRow);
}
@@ -1058,7 +1038,7 @@ QHash<int, QByteArray> QRangeModel::roleNames() const
{
Q_D(const QRangeModel);
if (d->m_roleNames.isEmpty())
- d->m_roleNames = d->call<QHash<int, QByteArray>>(QRangeModelImplBase::RoleNames);
+ d->m_roleNames = d->impl->call<QRangeModelImplBase::RoleNames>();
return d->m_roleNames;
}
@@ -1069,7 +1049,7 @@ void QRangeModel::setRoleNames(const QHash<int, QByteArray> &names)
if (d->m_roleNames == names)
return;
beginResetModel();
- d->impl->invalidateCaches();
+ d->impl->call<QRangeModelImplBase::InvalidateCaches>();
d->m_roleNames = names;
endResetModel();
Q_EMIT roleNamesChanged();
diff --git a/src/corelib/itemmodels/qrangemodel_impl.h b/src/corelib/itemmodels/qrangemodel_impl.h
index 4dfc07be37d..af1a8fc3e04 100644
--- a/src/corelib/itemmodels/qrangemodel_impl.h
+++ b/src/corelib/itemmodels/qrangemodel_impl.h
@@ -31,6 +31,202 @@
QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+
+// TODO: move to a separate header in Qt 6.11
+template <typename Interface>
+class QQuasiVirtualInterface
+{
+private:
+ template <typename Arg>
+ static constexpr bool passArgAsValue = sizeof(Arg) <= sizeof(size_t)
+ && std::is_trivially_destructible_v<Arg>;
+
+ template <typename ...>
+ struct MethodImpl;
+
+ template <typename M, typename R, typename I, typename... Args>
+ struct MethodImpl<M, R, I, Args...>
+ {
+ static_assert(std::is_base_of_v<I, Interface>, "The method must belong to the interface");
+ using return_type = R;
+ using call_args = std::tuple<std::conditional_t<passArgAsValue<Args>, Args, Args&&>...>;
+
+ static constexpr size_t index()
+ {
+ return index(std::make_index_sequence<std::tuple_size_v<Methods<>>>());
+ }
+
+ private:
+ template <size_t Ix>
+ static constexpr bool matchesAt()
+ {
+ return std::is_base_of_v<std::tuple_element_t<Ix, Methods<>>, M>;
+ }
+
+ template <size_t... Is>
+ static constexpr size_t index(std::index_sequence<Is...>)
+ {
+ constexpr size_t matchesCount = (size_t(matchesAt<Is>()) + ...);
+ static_assert(matchesCount == 1, "Expected exactly one match");
+ return ((size_t(matchesAt<Is>()) * Is) + ...);
+ }
+
+ static R invoke(I &intf /*const validation*/, Args... args)
+ {
+ Q_ASSERT(intf.m_callFN);
+
+ auto& baseIntf = static_cast<base_interface&>(const_cast<std::remove_const_t<I>&>(intf));
+ call_args callArgs(std::forward<Args>(args)...);
+ if constexpr (std::is_void_v<R>) {
+ intf.m_callFN(index(), baseIntf, nullptr, &callArgs);
+ } else {
+ alignas(R) std::byte buf[sizeof(R)];
+ intf.m_callFN(index(), baseIntf, buf, &callArgs);
+
+ R* result = std::launder(reinterpret_cast<R*>(buf));
+ QScopeGuard destroyBuffer([result]() { std::destroy_at(result); });
+ return std::forward<R>(*result);
+ }
+ }
+
+ friend class QQuasiVirtualInterface<Interface>;
+ };
+
+ template <typename M, typename R, typename I, typename... Args>
+ struct MethodImpl<M, R(I::*)(Args...)> : MethodImpl<M, R, I, Args...> {
+ template <typename Subclass>
+ using Overridden = R(Subclass::*)(Args...);
+ };
+
+ template <typename M, typename R, typename I, typename... Args>
+ struct MethodImpl<M, R(I::*)(Args...) const> : MethodImpl<M, R, const I, Args...> {
+ template <typename Subclass>
+ using Overridden = R(Subclass::*)(Args...) const;
+ };
+
+ template <typename C = Interface> using Methods = typename C::template MethodTemplates<C>;
+
+public:
+ template <typename Signature, Signature s = nullptr /*disambiguates Signature*/>
+ struct Method : MethodImpl<Method<Signature, s>, Signature> {};
+
+ template <typename Method, typename... Args>
+ auto call(Args &&... args) const
+ {
+ return Method::invoke(static_cast<const Interface &>(*this), std::forward<Args>(args)...);
+ }
+
+ template <typename Method, typename... Args>
+ auto call(Args &&... args)
+ {
+ return Method::invoke(static_cast<Interface &>(*this), std::forward<Args>(args)...);
+ }
+
+ void destroy(); // quasi-virtual pure destructor
+ using Destroy = Method<decltype(&QQuasiVirtualInterface::destroy)>;
+
+ struct Deleter
+ {
+ void operator () (QQuasiVirtualInterface* self) const { self->call<Destroy>(); }
+ };
+
+protected:
+ using base_interface = QQuasiVirtualInterface<Interface>;
+ using CallFN = void (*)(size_t index, base_interface &intf, void *ret, void *args);
+ void initCallFN(CallFN func) { m_callFN = func; }
+
+ QQuasiVirtualInterface() = default;
+ ~QQuasiVirtualInterface() = default;
+
+private:
+ Q_DISABLE_COPY_MOVE(QQuasiVirtualInterface)
+ CallFN m_callFN = nullptr;
+};
+
+template <typename Subclass, typename Interface>
+class QQuasiVirtualSubclass : public Interface
+{
+private:
+ template <typename C = Subclass> using Methods = typename C::template MethodTemplates<C>;
+
+ template <size_t OverriddenIndex>
+ static constexpr size_t interfaceMethodIndex() {
+ return std::tuple_element_t<OverriddenIndex, Methods<>>::index();
+ }
+
+ template <size_t... Is>
+ static void callImpl(size_t index, Subclass &subclass, void *ret, void *args, std::index_sequence<Is...>)
+ {
+ // TODO: come up with more sophisticated check if methods count becomes more than 64
+ static constexpr std::uint64_t methodIndexMask = ((uint64_t(1)
+ << interfaceMethodIndex<Is>()) | ...);
+ static_assert(sizeof...(Is) == std::tuple_size_v<Methods<Interface>>,
+ "Base and overridden methods count are different");
+ static_assert(methodIndexMask == (uint64_t(1) << sizeof...(Is)) - 1,
+ "Mapping between base and overridden methods is not unique");
+
+ // TODO: check if it's optimized properly on gcc
+ ((interfaceMethodIndex<Is>() == index
+ ? std::tuple_element_t<Is, Methods<>>::doInvoke(subclass, ret, args)
+ : static_cast<void>(0))
+ , ...);
+ }
+
+ static void callImpl(size_t index, typename Interface::base_interface &intf, void *ret, void *args)
+ {
+ constexpr auto seq = std::make_index_sequence<std::tuple_size_v<Methods<>>>();
+ callImpl(index, static_cast<Subclass&>(intf), ret, args, seq);
+ }
+
+ template <typename BaseMethod>
+ using OverridenSignature = typename BaseMethod::template Overridden<Subclass>;
+
+protected:
+ template <typename... Args>
+ QQuasiVirtualSubclass(Args &&... args)
+ : Interface(std::forward<Args>(args)...)
+ {
+ Interface::initCallFN(&QQuasiVirtualSubclass::callImpl);
+ }
+
+public:
+ template <typename BaseMethod, OverridenSignature<BaseMethod> overridden>
+ struct Override : BaseMethod
+ {
+ private:
+ static constexpr void doInvoke(Subclass &subclass, void *ret, void *args)
+ {
+ using Return = typename BaseMethod::return_type;
+ using PackedArgs = typename BaseMethod::call_args;
+
+ Q_ASSERT(args);
+ Q_ASSERT(std::is_void_v<Return> == !ret);
+
+ auto invoke = [&subclass](auto &&...params)
+ {
+ return std::invoke(overridden, &subclass, std::forward<decltype(params)>(params)...);
+ };
+
+ if constexpr (std::is_void_v<Return>) {
+ std::apply(invoke, std::move(*static_cast<PackedArgs *>(args)));
+ } else {
+ // Note, that ::new Return(...) fails on Integrity.
+ // TODO: use std::construct_at for c++20
+ using Alloc = std::allocator<Return>;
+ Alloc alloc;
+ std::allocator_traits<Alloc>::construct(alloc, static_cast<Return *>(ret),
+ std::apply(invoke, std::move(*static_cast<PackedArgs *>(args))));
+ }
+
+ }
+
+ friend class QQuasiVirtualSubclass<Subclass, Interface>;
+ };
+};
+
+}
+
namespace QRangeModelDetails
{
template <typename T, template <typename...> typename... Templates>
@@ -592,9 +788,11 @@ namespace QRangeModelDetails
class QRangeModel;
-class QRangeModelImplBase
+class QRangeModelImplBase : public QtPrivate::QQuasiVirtualInterface<QRangeModelImplBase>
{
- Q_DISABLE_COPY_MOVE(QRangeModelImplBase)
+private:
+ using Self = QRangeModelImplBase;
+ using QtPrivate::QQuasiVirtualInterface<Self>::Method;
protected:
// Helpers for calling a lambda with the tuple element at a runtime index.
template <typename Tuple, typename F, size_t ...Is>
@@ -632,87 +830,91 @@ protected:
return makeMetaTypes<type>(std::make_index_sequence<size>{}).at(idx);
}
- // Helpers to call a given member function with the correct arguments.
- template <typename Class, typename T, typename F, size_t...I>
- static auto apply(std::integer_sequence<size_t, I...>, Class* obj, F&& fn, T&& tuple)
- {
- return std::invoke(fn, obj, std::get<I>(tuple)...);
- }
- template <typename Ret, typename Class, typename ...Args>
- static void makeCall(QRangeModelImplBase *obj, Ret(Class::* &&fn)(Args...),
- void *ret, const void *args)
- {
- const auto &tuple = *static_cast<const std::tuple<Args&...> *>(args);
- *static_cast<Ret *>(ret) = apply(std::make_index_sequence<sizeof...(Args)>{},
- static_cast<Class *>(obj), fn, tuple);
- }
- template <typename Ret, typename Class, typename ...Args>
- static void makeCall(const QRangeModelImplBase *obj, Ret(Class::* &&fn)(Args...) const,
- void *ret, const void *args)
- {
- const auto &tuple = *static_cast<const std::tuple<Args&...> *>(args);
- *static_cast<Ret *>(ret) = apply(std::make_index_sequence<sizeof...(Args)>{},
- static_cast<const Class *>(obj), fn, tuple);
- }
-
public:
- enum ConstOp {
- Index,
- Parent,
- Sibling,
- RowCount,
- ColumnCount,
- Flags,
- HeaderData,
- Data,
- ItemData,
- RoleNames,
- };
+ // overridable prototypes (quasi-pure-virtual methods)
+
+ void invalidateCaches();
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role);
+ bool setData(const QModelIndex &index, const QVariant &data, int role);
+ bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &data);
+ bool clearItemData(const QModelIndex &index);
+ bool insertColumns(int column, int count, const QModelIndex &parent);
+ bool removeColumns(int column, int count, const QModelIndex &parent);
+ bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destParent, int destColumn);
+ bool insertRows(int row, int count, const QModelIndex &parent);
+ bool removeRows(int row, int count, const QModelIndex &parent);
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destParent, int destRow);
+
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ QModelIndex sibling(int row, int column, const QModelIndex &index) const;
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ QMap<int, QVariant> itemData(const QModelIndex &index) const;
+ inline QHash<int, QByteArray> roleNames() const;
+ QModelIndex parent(const QModelIndex &child) const;
+
+ // bindings for overriding
+
+ using InvalidateCaches = Method<decltype(&Self::invalidateCaches)>;
+ using SetHeaderData = Method<decltype(&Self::setHeaderData)>;
+ using SetData = Method<decltype(&Self::setData)>;
+ using SetItemData = Method<decltype(&Self::setItemData)>;
+ using ClearItemData = Method<decltype(&Self::clearItemData)>;
+ using InsertColumns = Method<decltype(&Self::insertColumns), &Self::insertColumns>;
+ using RemoveColumns = Method<decltype(&Self::removeColumns), &Self::removeColumns>;
+ using MoveColumns = Method<decltype(&Self::moveColumns), &Self::moveColumns>;
+ using InsertRows = Method<decltype(&Self::insertRows), &Self::insertRows>;
+ using RemoveRows = Method<decltype(&Self::removeRows), &Self::removeRows>;
+ using MoveRows = Method<decltype(&Self::moveRows), &Self::moveRows>;
+
+ using Index = Method<decltype(&Self::index), &Self::index>;
+ using Sibling = Method<decltype(&Self::sibling), &Self::sibling>;
+ using RowCount = Method<decltype(&Self::rowCount), &Self::rowCount>;
+ using ColumnCount = Method<decltype(&Self::columnCount), &Self::columnCount>;
+ using Flags = Method<decltype(&Self::flags)>;
+ using HeaderData = Method<decltype(&Self::headerData)>;
+ using Data = Method<decltype(&Self::data)>;
+ using ItemData = Method<decltype(&Self::itemData)>;
+ using RoleNames = Method<decltype(&Self::roleNames)>;
+ using Parent = Method<decltype(&Self::parent)>;
- enum Op {
- Destroy,
- InvalidateCaches,
- SetHeaderData,
- SetData,
- SetItemData,
- ClearItemData,
- InsertColumns,
- RemoveColumns,
- MoveColumns,
- InsertRows,
- RemoveRows,
- MoveRows,
- };
-
- void destroy()
- {
- call_fn(Destroy, this, nullptr, nullptr);
- }
-
- void invalidateCaches()
- {
- call_fn(InvalidateCaches, this, nullptr, nullptr);
- }
+ template <typename C>
+ using MethodTemplates = std::tuple<
+ typename C::Destroy,
+ typename C::InvalidateCaches,
+ typename C::SetHeaderData,
+ typename C::SetData,
+ typename C::SetItemData,
+ typename C::ClearItemData,
+ typename C::InsertColumns,
+ typename C::RemoveColumns,
+ typename C::MoveColumns,
+ typename C::InsertRows,
+ typename C::RemoveRows,
+ typename C::MoveRows,
+ typename C::Index,
+ typename C::Parent,
+ typename C::Sibling,
+ typename C::RowCount,
+ typename C::ColumnCount,
+ typename C::Flags,
+ typename C::HeaderData,
+ typename C::Data,
+ typename C::ItemData,
+ typename C::RoleNames
+ >;
private:
- // prototypes
- static void callConst(ConstOp, const QRangeModelImplBase *, void *, const void *);
- static void call(Op, QRangeModelImplBase *, void *, const void *);
-
- using CallConstFN = decltype(callConst);
- using CallTupleFN = decltype(call);
-
friend class QRangeModelPrivate;
- CallConstFN *callConst_fn;
- CallTupleFN *call_fn;
QRangeModel *m_rangeModel;
protected:
- template <typename Impl> // type deduction
- explicit QRangeModelImplBase(QRangeModel *itemModel, const Impl *)
- : callConst_fn(&Impl::callConst), call_fn(&Impl::call), m_rangeModel(itemModel)
+ explicit QRangeModelImplBase(QRangeModel *itemModel)
+ : m_rangeModel(itemModel)
{}
- ~QRangeModelImplBase() = default;
inline QModelIndex createIndex(int row, int column, const void *ptr = nullptr) const;
inline void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to);
@@ -742,9 +944,10 @@ protected:
template <typename Structure, typename Range,
typename Protocol = QRangeModelDetails::table_protocol_t<Range>>
-class QRangeModelImpl : public QRangeModelImplBase
+class QRangeModelImpl
+ : public QtPrivate::QQuasiVirtualSubclass<QRangeModelImpl<Structure, Range, Protocol>,
+ QRangeModelImplBase>
{
- Q_DISABLE_COPY_MOVE(QRangeModelImpl)
public:
using range_type = QRangeModelDetails::wrapped_t<Range>;
using row_reference = decltype(*QRangeModelDetails::begin(std::declval<range_type&>()));
@@ -759,7 +962,10 @@ public:
"std::optional for ranges and rows will be supported.");
protected:
+
using Self = QRangeModelImpl<Structure, Range, Protocol>;
+ using Ancestor = QtPrivate::QQuasiVirtualSubclass<Self, QRangeModelImplBase>;
+
Structure& that() { return static_cast<Structure &>(*this); }
const Structure& that() const { return static_cast<const Structure &>(*this); }
@@ -854,75 +1060,25 @@ protected:
public:
explicit QRangeModelImpl(Range &&model, Protocol&& protocol, QRangeModel *itemModel)
- : QRangeModelImplBase(itemModel, static_cast<const Self*>(nullptr))
+ : Ancestor(itemModel)
, m_data{std::forward<Range>(model)}
, m_protocol(std::forward<Protocol>(protocol))
{
}
+
// static interface, called by QRangeModelImplBase
- static void callConst(ConstOp op, const QRangeModelImplBase *that, void *r, const void *args)
- {
- switch (op) {
- case Index: makeCall(that, &Self::index, r, args);
- break;
- case Parent: makeCall(that, &Structure::parent, r, args);
- break;
- case Sibling: makeCall(that, &Self::sibling, r, args);
- break;
- case RowCount: makeCall(that, &Structure::rowCount, r, args);
- break;
- case ColumnCount: makeCall(that, &Structure::columnCount, r, args);
- break;
- case Flags: makeCall(that, &Self::flags, r, args);
- break;
- case HeaderData: makeCall(that, &Self::headerData, r, args);
- break;
- case Data: makeCall(that, &Self::data, r, args);
- break;
- case ItemData: makeCall(that, &Self::itemData, r, args);
- break;
- case RoleNames: makeCall(that, &Self::roleNames, r, args);
- break;
- }
- }
- static void call(Op op, QRangeModelImplBase *that, void *r, const void *args)
- {
- switch (op) {
- case Destroy: delete static_cast<Structure *>(that);
- break;
- case InvalidateCaches: static_cast<Self *>(that)->m_data.invalidateCaches();
- break;
- case SetHeaderData:
- // not implemented
- break;
- case SetData: makeCall(that, &Self::setData, r, args);
- break;
- case SetItemData: makeCall(that, &Self::setItemData, r, args);
- break;
- case ClearItemData: makeCall(that, &Self::clearItemData, r, args);
- break;
- case InsertColumns: makeCall(that, &Self::insertColumns, r, args);
- break;
- case RemoveColumns: makeCall(that, &Self::removeColumns, r, args);
- break;
- case MoveColumns: makeCall(that, &Self::moveColumns, r, args);
- break;
- case InsertRows: makeCall(that, &Self::insertRows, r, args);
- break;
- case RemoveRows: makeCall(that, &Self::removeRows, r, args);
- break;
- case MoveRows: makeCall(that, &Self::moveRows, r, args);
- break;
- }
- }
+ void invalidateCaches() { m_data.invalidateCaches(); }
+
+ // Not implemented
+ bool setHeaderData(int , Qt::Orientation , const QVariant &, int ) { return false; }
// actual implementations
QModelIndex index(int row, int column, const QModelIndex &parent) const
{
- if (row < 0 || column < 0 || column >= that().columnCount(parent)
- || row >= that().rowCount(parent)) {
+ if (row < 0 || column < 0 || column >= columnCount(parent)
+ || row >= rowCount(parent)) {
return {};
}
@@ -934,17 +1090,17 @@ public:
if (row == index.row() && column == index.column())
return index;
- if (column < 0 || column >= itemModel().columnCount())
+ if (column < 0 || column >= this->itemModel().columnCount())
return {};
if (row == index.row())
- return createIndex(row, column, index.constInternalPointer());
+ return this->createIndex(row, column, index.constInternalPointer());
const_row_ptr parentRow = static_cast<const_row_ptr>(index.constInternalPointer());
const auto siblingCount = size(that().childrenOf(parentRow));
if (row < 0 || row >= int(siblingCount))
return {};
- return createIndex(row, column, parentRow);
+ return this->createIndex(row, column, parentRow);
}
Qt::ItemFlags flags(const QModelIndex &index) const
@@ -970,7 +1126,7 @@ public:
const_row_reference row = rowData(index);
row_reference mutableRow = const_cast<row_reference>(row);
if (QRangeModelDetails::isValid(mutableRow)) {
- for_element_at(mutableRow, index.column(), [&f](auto &&ref){
+ QRangeModelImplBase::for_element_at(mutableRow, index.column(), [&f](auto &&ref){
using target_type = decltype(ref);
if constexpr (std::is_const_v<std::remove_reference_t<target_type>>)
f &= ~Qt::ItemIsEditable;
@@ -990,8 +1146,8 @@ public:
{
QVariant result;
if (role != Qt::DisplayRole || orientation != Qt::Horizontal
- || section < 0 || section >= that().columnCount({})) {
- return itemModel().QAbstractItemModel::headerData(section, orientation, role);
+ || section < 0 || section >= columnCount({})) {
+ return this->itemModel().QAbstractItemModel::headerData(section, orientation, role);
}
if constexpr (row_traits::hasMetaObject) {
@@ -1004,12 +1160,12 @@ public:
result = QString::fromUtf8(prop.name());
}
} else if constexpr (static_column_count >= 1) {
- const QMetaType metaType = meta_type_at<row_type>(section);
+ const QMetaType metaType = QRangeModelImplBase::meta_type_at<row_type>(section);
if (metaType.isValid())
result = QString::fromUtf8(metaType.name());
}
if (!result.isValid())
- result = itemModel().QAbstractItemModel::headerData(section, orientation, role);
+ result = this->itemModel().QAbstractItemModel::headerData(section, orientation, role);
return result;
}
@@ -1044,7 +1200,7 @@ public:
if constexpr (multi_role::int_key)
return std::as_const(value).find(Qt::ItemDataRole(role));
else
- return std::as_const(value).find(itemModel().roleNames().value(role));
+ return std::as_const(value).find(this->itemModel().roleNames().value(role));
}();
if (it != value.cend())
result = QRangeModelDetails::value(it);
@@ -1076,7 +1232,7 @@ public:
const auto roleNames = [this]() -> QHash<int, QByteArray> {
Q_UNUSED(this);
if constexpr (!multi_role::int_key)
- return itemModel().roleNames();
+ return this->itemModel().roleNames();
else
return {};
}();
@@ -1096,7 +1252,7 @@ public:
} else if constexpr (has_metaobject<value_type>) {
if (row_traits::fixed_size() <= 1) {
tried = true;
- const auto roleNames = itemModel().roleNames();
+ const auto roleNames = this->itemModel().roleNames();
const auto end = roleNames.keyEnd();
for (auto it = roleNames.keyBegin(); it != end; ++it) {
const int role = *it;
@@ -1114,7 +1270,7 @@ public:
readAt(index, readItemData);
if (!tried) // no multi-role item found
- result = itemModel().QAbstractItemModel::itemData(index);
+ result = this->itemModel().QAbstractItemModel::itemData(index);
}
return result;
}
@@ -1128,7 +1284,7 @@ public:
if constexpr (isMutable()) {
auto emitDataChanged = qScopeGuard([&success, this, &index, role]{
if (success) {
- Q_EMIT dataChanged(index, index,
+ Q_EMIT this->dataChanged(index, index,
role == Qt::EditRole || role == Qt::RangeModelDataRole
? QList<int>{} : QList<int>{role});
}
@@ -1169,8 +1325,10 @@ public:
targetRef = *data.value<value_type *>();
return true;
}
+#ifndef QT_NO_DEBUG
qCritical("Not able to assign %s to %s",
qPrintable(QDebug::toString(data)), targetMetaType.name());
+#endif
return false;
} else if (row_traits::fixed_size() <= 1) {
return writeRole(role, QRangeModelDetails::pointerTo(target), data);
@@ -1185,7 +1343,7 @@ public:
const auto roleNames = [this]() -> QHash<int, QByteArray> {
Q_UNUSED(this);
if constexpr (!multi_role::int_key)
- return itemModel().roleNames();
+ return this->itemModel().roleNames();
else
return {};
}();
@@ -1223,7 +1381,7 @@ public:
if constexpr (isMutable()) {
auto emitDataChanged = qScopeGuard([&success, this, &index, &data]{
if (success)
- Q_EMIT dataChanged(index, index, data.keys());
+ Q_EMIT this->dataChanged(index, index, data.keys());
});
bool tried = false;
@@ -1234,7 +1392,7 @@ public:
if constexpr (multi_role()) {
using key_type = typename value_type::key_type;
tried = true;
- const auto roleName = [map = itemModel().roleNames()](int role) {
+ const auto roleName = [map = this->itemModel().roleNames()](int role) {
return map.value(role);
};
@@ -1247,7 +1405,9 @@ public:
);
if (invalid != data.keyEnd()) {
+#ifndef QT_NO_DEBUG
qWarning("No role name set for %d", *invalid);
+#endif
return false;
}
}
@@ -1275,14 +1435,16 @@ public:
else
return QRangeModelDetails::pointerTo(origin);
}(target);
- const auto roleNames = itemModel().roleNames();
+ const auto roleNames = this->itemModel().roleNames();
for (auto &&[role, value] : data.asKeyValueRange()) {
if (role == Qt::RangeModelDataRole)
continue;
if (!writeRole(role, QRangeModelDetails::pointerTo(targetCopy), value)) {
const QByteArray roleName = roleNames.value(role);
+#ifndef QT_NO_DEBUG
qWarning("Failed to write value '%s' to role '%s'",
qPrintable(QDebug::toString(value)), roleName.data());
+#endif
return false;
}
}
@@ -1304,7 +1466,7 @@ public:
// setItemData will emit the dataChanged signal
Q_ASSERT(!success);
emitDataChanged.dismiss();
- success = itemModel().QAbstractItemModel::setItemData(index, data);
+ success = this->itemModel().QAbstractItemModel::setItemData(index, data);
}
}
return success;
@@ -1319,7 +1481,7 @@ public:
if constexpr (isMutable()) {
auto emitDataChanged = qScopeGuard([&success, this, &index]{
if (success)
- Q_EMIT dataChanged(index, index, {});
+ Q_EMIT this->dataChanged(index, index, {});
});
auto clearData = [column = index.column()](auto &&target) {
@@ -1347,13 +1509,13 @@ public:
// will be 'void' if columns don't all have the same type
using item_type = typename row_traits::item_type;
if constexpr (QRangeModelDetails::has_metaobject_v<item_type>) {
- return roleNamesForMetaObject(QRangeModelDetails::wrapped_t<item_type>::staticMetaObject);
+ return this->roleNamesForMetaObject(QRangeModelDetails::wrapped_t<item_type>::staticMetaObject);
} else if constexpr (std::negation_v<std::disjunction<std::is_void<item_type>,
QRangeModelDetails::is_multi_role<item_type>>>) {
- return roleNamesForSimpleType();
+ return this->roleNamesForSimpleType();
}
- return itemModel().QAbstractItemModel::roleNames();
+ return this->itemModel().QAbstractItemModel::roleNames();
}
bool insertColumns(int column, int count, const QModelIndex &parent)
@@ -1365,12 +1527,12 @@ public:
if (!children)
return false;
- beginInsertColumns(parent, column, column + count - 1);
+ this->beginInsertColumns(parent, column, column + count - 1);
for (auto &child : *children) {
auto it = QRangeModelDetails::pos(child, column);
QRangeModelDetails::refTo(child).insert(it, count, {});
}
- endInsertColumns();
+ this->endInsertColumns();
return true;
}
return false;
@@ -1379,19 +1541,19 @@ public:
bool removeColumns(int column, int count, const QModelIndex &parent)
{
if constexpr (dynamicColumns() && isMutable() && row_features::has_erase) {
- if (column < 0 || column + count > that().columnCount(parent))
+ if (column < 0 || column + count > columnCount(parent))
return false;
range_type * const children = childRange(parent);
if (!children)
return false;
- beginRemoveColumns(parent, column, column + count - 1);
+ this->beginRemoveColumns(parent, column, column + count - 1);
for (auto &child : *children) {
const auto start = QRangeModelDetails::pos(child, column);
QRangeModelDetails::refTo(child).erase(start, std::next(start, count));
}
- endRemoveColumns();
+ this->endRemoveColumns();
return true;
}
return false;
@@ -1414,7 +1576,7 @@ public:
if (!children)
return false;
- if (!beginMoveColumns(sourceParent, sourceColumn, sourceColumn + count - 1,
+ if (!this->beginMoveColumns(sourceParent, sourceColumn, sourceColumn + count - 1,
destParent, destColumn)) {
return false;
}
@@ -1430,7 +1592,7 @@ public:
std::rotate(last, first, middle);
}
- endMoveColumns();
+ this->endMoveColumns();
return true;
}
}
@@ -1446,7 +1608,7 @@ public:
EmptyRowGenerator generator{0, &that(), &parent};
- beginInsertRows(parent, row, row + count - 1);
+ this->beginInsertRows(parent, row, row + count - 1);
const auto pos = QRangeModelDetails::pos(children, row);
if constexpr (range_features::has_insert_range) {
@@ -1462,7 +1624,7 @@ public:
// references back to the parent might have become invalid.
that().resetParentInChildren(children);
- endInsertRows();
+ this->endInsertRows();
return true;
} else {
return false;
@@ -1472,7 +1634,7 @@ public:
bool removeRows(int row, int count, const QModelIndex &parent = {})
{
if constexpr (canRemoveRows()) {
- const int prevRowCount = that().rowCount(parent);
+ const int prevRowCount = rowCount(parent);
if (row < 0 || row + count > prevRowCount)
return false;
@@ -1480,15 +1642,15 @@ public:
if (!children)
return false;
- beginRemoveRows(parent, row, row + count - 1);
+ this->beginRemoveRows(parent, row, row + count - 1);
[[maybe_unused]] bool callEndRemoveColumns = false;
if constexpr (dynamicColumns()) {
// if we remove the last row in a dynamic model, then we no longer
// know how many columns we should have, so they will be reported as 0.
if (prevRowCount == count) {
- if (const int columns = that().columnCount(parent)) {
+ if (const int columns = columnCount(parent)) {
callEndRemoveColumns = true;
- beginRemoveColumns(parent, 0, columns - 1);
+ this->beginRemoveColumns(parent, 0, columns - 1);
}
}
}
@@ -1504,11 +1666,11 @@ public:
if constexpr (dynamicColumns()) {
if (callEndRemoveColumns) {
- Q_ASSERT(that().columnCount(parent) == 0);
- endRemoveColumns();
+ Q_ASSERT(columnCount(parent) == 0);
+ this->endRemoveColumns();
}
}
- endRemoveRows();
+ this->endRemoveRows();
return true;
} else {
return false;
@@ -1528,14 +1690,14 @@ public:
}
if (sourceRow == destRow || sourceRow == destRow - 1 || count <= 0
- || sourceRow < 0 || sourceRow + count - 1 >= itemModel().rowCount(sourceParent)
- || destRow < 0 || destRow > itemModel().rowCount(destParent)) {
+ || sourceRow < 0 || sourceRow + count - 1 >= this->itemModel().rowCount(sourceParent)
+ || destRow < 0 || destRow > this->itemModel().rowCount(destParent)) {
return false;
}
range_type *source = childRange(sourceParent);
// moving within the same range
- if (!beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destParent, destRow))
+ if (!this->beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destParent, destRow))
return false;
const auto first = QRangeModelDetails::pos(source, sourceRow);
@@ -1549,13 +1711,48 @@ public:
that().resetParentInChildren(source);
- endMoveRows();
+ this->endMoveRows();
return true;
} else {
return false;
}
}
+ QModelIndex parent(const QModelIndex &child) const { return that().parent(child); }
+
+ int rowCount(const QModelIndex &parent) const { return that().rowCount(parent); }
+
+ int columnCount(const QModelIndex &parent) const { return that().columnCount(parent); }
+
+ void destroy() { delete std::addressof(that()); }
+
+ template <typename BaseMethod, typename BaseMethod::template Overridden<Self> overridden>
+ using Override = typename Ancestor::template Override<BaseMethod, overridden>;
+
+ using Destroy = Override<QRangeModelImplBase::Destroy, &Self::destroy>;
+ using Index = Override<QRangeModelImplBase::Index, &Self::index>;
+ using Parent = Override<QRangeModelImplBase::Parent, &Self::parent>;
+ using Sibling = Override<QRangeModelImplBase::Sibling, &Self::sibling>;
+ using RowCount = Override<QRangeModelImplBase::RowCount, &Self::rowCount>;
+ using ColumnCount = Override<QRangeModelImplBase::ColumnCount, &Self::columnCount>;
+ using Flags = Override<QRangeModelImplBase::Flags, &Self::flags>;
+ using HeaderData = Override<QRangeModelImplBase::HeaderData, &Self::headerData>;
+
+ using Data = Override<QRangeModelImplBase::Data, &Self::data>;
+ using ItemData = Override<QRangeModelImplBase::ItemData, &Self::itemData>;
+ using RoleNames = Override<QRangeModelImplBase::RoleNames, &Self::roleNames>;
+ using InvalidateCaches = Override<QRangeModelImplBase::InvalidateCaches, &Self::invalidateCaches>;
+ using SetHeaderData = Override<QRangeModelImplBase::SetHeaderData, &Self::setHeaderData>;
+ using SetData = Override<QRangeModelImplBase::SetData, &Self::setData>;
+ using SetItemData = Override<QRangeModelImplBase::SetItemData, &Self::setItemData>;
+ using ClearItemData = Override<QRangeModelImplBase::ClearItemData, &Self::clearItemData>;
+ using InsertColumns = Override<QRangeModelImplBase::InsertColumns, &Self::insertColumns>;
+ using RemoveColumns = Override<QRangeModelImplBase::RemoveColumns, &Self::removeColumns>;
+ using MoveColumns = Override<QRangeModelImplBase::MoveColumns, &Self::moveColumns>;
+ using InsertRows = Override<QRangeModelImplBase::InsertRows, &Self::insertRows>;
+ using RemoveRows = Override<QRangeModelImplBase::RemoveRows, &Self::removeRows>;
+ using MoveRows = Override<QRangeModelImplBase::MoveRows, &Self::moveRows>;
+
protected:
~QRangeModelImpl()
{
@@ -1611,7 +1808,7 @@ protected:
if constexpr (dynamicColumns()) {
result = writer(*QRangeModelDetails::pos(row, index.column()));
} else {
- for_element_at(row, index.column(), [&writer, &result](auto &&target) {
+ QRangeModelImplBase::for_element_at(row, index.column(), [&writer, &result](auto &&target) {
using target_type = decltype(target);
// we can only assign to an lvalue reference
if constexpr (std::is_lvalue_reference_v<target_type>
@@ -1634,7 +1831,7 @@ protected:
if constexpr (dynamicColumns())
reader(*QRangeModelDetails::cpos(row, index.column()));
else
- for_element_at(row, index.column(), std::forward<F>(reader));
+ QRangeModelImplBase::for_element_at(row, index.column(), std::forward<F>(reader));
}
}
@@ -2192,8 +2389,10 @@ protected:
if constexpr (Base::dynamicColumns()) {
if (column < int(Base::size(*QRangeModelDetails::cpos(*this->m_data.model(), row))))
return this->createIndex(row, column);
- // if we got here, then column < columnCount(), but this row is to short
+#ifndef QT_NO_DEBUG
+ // if we got here, then column < columnCount(), but this row is too short
qCritical("QRangeModel: Column-range at row %d is not large enough!", row);
+#endif
return {};
} else {
return this->createIndex(row, column);
diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp
index 739082afcce..1b464433d42 100644
--- a/src/corelib/kernel/qdeadlinetimer.cpp
+++ b/src/corelib/kernel/qdeadlinetimer.cpp
@@ -124,7 +124,7 @@ static qint64 add_saturate(qint64 t1, Duration1 dur, Durations... extra)
\snippet code/src_corelib_kernel_qdeadlinetimer.cpp 2
- \sa QTime, QChronoTimer, QDeadlineTimer, Qt::TimerType
+ \sa QTime, QChronoTimer, QElapsedTimer, Qt::TimerType
*/
/*!
@@ -500,7 +500,7 @@ qint64 QDeadlineTimer::deadline() const noexcept
\note Timers that were created as expired have an indetermine time point in
the past as their deadline, so the above calculation may not work.
- \sa remainingTime(), deadlineNSecs()
+ \sa remainingTime(), deadline(), setDeadline()
*/
qint64 QDeadlineTimer::deadlineNSecs() const noexcept
{
diff --git a/src/corelib/kernel/qmetacontainer.cpp b/src/corelib/kernel/qmetacontainer.cpp
index 9c2e5f5401b..de635f65e60 100644
--- a/src/corelib/kernel/qmetacontainer.cpp
+++ b/src/corelib/kernel/qmetacontainer.cpp
@@ -467,7 +467,7 @@ void *QMetaContainer::begin(void *container) const
Returns \c nullptr if the container doesn't offer any non-const iterators.
- \sa hasIterator(), end(), constBegin(), constEnd(), destroyIterator()
+ \sa hasIterator(), begin(), constBegin(), constEnd(), destroyIterator()
*/
void *QMetaContainer::end(void *container) const
{
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 411b8bc75be..1850a148d19 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -611,7 +611,7 @@ int QMetaType::registerHelper(const QtPrivate::QMetaTypeInterface *iface)
This function is typically used together with construct()
to perform low-level management of the memory used by a type.
- \sa QMetaType::construct(), QMetaType::sizeOf(), QMetaType::alignOf()
+ \sa QMetaType::construct(), QMetaType::alignOf()
*/
/*!
@@ -637,7 +637,7 @@ int QMetaType::registerHelper(const QtPrivate::QMetaTypeInterface *iface)
constructed. To inspect specific type traits, prefer using one of the "is-"
functions rather than the flags directly.
- \sa QMetaType::TypeFlags, QMetaType::flags(), isDefaultConstructible(),
+ \sa QMetaType::TypeFlags, isDefaultConstructible(),
isCopyConstructible(), isMoveConstructible(), isDestructible(),
isEqualityComparable(), isOrdered()
*/
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/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 01d2f595aeb..0b88013800e 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -445,12 +445,11 @@ inline QList<T> QFutureInterface<T>::results()
template<typename T>
T QFutureInterface<T>::takeResult()
{
- Q_ASSERT(isValid());
-
// Note: we wait for all, this is intentional,
// not to mess with other unready results.
waitForResult(-1);
+ Q_ASSERT(isValid());
Q_ASSERT(!hasException());
const QMutexLocker<QMutex> locker{&mutex()};
@@ -466,10 +465,9 @@ T QFutureInterface<T>::takeResult()
template<typename T>
std::vector<T> QFutureInterface<T>::takeResults()
{
- Q_ASSERT(isValid());
-
waitForResult(-1);
+ Q_ASSERT(isValid());
Q_ASSERT(!hasException());
std::vector<T> res;
diff --git a/src/gui/doc/snippets/CMakeLists.txt b/src/gui/doc/snippets/CMakeLists.txt
index b7e8e5a2784..e314d577d27 100644
--- a/src/gui/doc/snippets/CMakeLists.txt
+++ b/src/gui/doc/snippets/CMakeLists.txt
@@ -10,18 +10,21 @@ qt_add_library(gui_snippets OBJECT
polygon/polygon.cpp
qimagewriter/main.cpp
qtextobject/textobjectinterface.h
+ rhioffscreen/main.cpp
textdocument-end/textdocumentendsnippet.cpp
)
target_link_libraries(gui_snippets PRIVATE
Qt::Core
Qt::Gui
+ Qt::GuiPrivate
)
-qt_internal_extend_target(gui_snippets CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(gui_snippets PRIVATE
Qt::Widgets
- SOURCES
+ )
+ target_sources(gui_snippets PRIVATE
draganddrop/dragwidget.cpp
dragging/mainwindow.cpp
droparea/droparea.cpp
@@ -50,33 +53,33 @@ qt_internal_extend_target(gui_snippets CONDITION QT_FEATURE_widgets
textdocument-tables/mainwindow.cpp
textdocument-tables/mainwindow.cpp
transform/main.cpp
-)
+ )
+endif()
-qt_internal_extend_target(gui_snippets
- LIBRARIES
- Qt::GuiPrivate
- SOURCES
- rhioffscreen/main.cpp
-)
-qt_internal_extend_target(gui_snippets CONDITION QT_FEATURE_xml
- LIBRARIES
+if(QT_FEATURE_xml)
+ target_link_libraries(gui_snippets PRIVATE
Qt::Xml
- SOURCES
+ )
+ target_sources(gui_snippets PRIVATE
textblock-fragments/xmlwriter.cpp
-)
+ )
+endif()
-qt_internal_extend_target(gui_snippets CONDITION QT_FEATURE_printsupport
- LIBRARIES
+if(QT_FEATURE_printsupport)
+ target_link_libraries(gui_snippets PRIVATE
Qt::PrintSupport
- SOURCES
+ )
+ target_sources(gui_snippets PRIVATE
textdocument-printing/mainwindow.cpp
-)
+ )
+endif()
-qt_internal_extend_target(gui_snippets CONDITION QT_FEATURE_widgets AND QT_FEATURE_clipboard
- SOURCES
+if(QT_FEATURE_widgets AND QT_FEATURE_clipboard)
+ target_sources(gui_snippets PRIVATE
clipboard/clipwindow.cpp
-)
+ )
+endif()
set_target_properties(gui_snippets PROPERTIES COMPILE_OPTIONS "-w")
diff --git a/src/gui/doc/snippets/code/CMakeLists.txt b/src/gui/doc/snippets/code/CMakeLists.txt
index 7f8897ec8fa..0db976f7c21 100644
--- a/src/gui/doc/snippets/code/CMakeLists.txt
+++ b/src/gui/doc/snippets/code/CMakeLists.txt
@@ -36,10 +36,11 @@ target_link_libraries(gui_snippets_code PRIVATE
Qt::Gui
)
-qt_internal_extend_target(gui_snippets_code CONDITION QT_FEATURE_widgets
- LIBRARIES
+if(QT_FEATURE_widgets)
+ target_link_libraries(gui_snippets_code PRIVATE
Qt::Widgets
- SOURCES
+ )
+ target_sources(gui_snippets_code PRIVATE
doc_src_coordsys.cpp
doc_src_richtext.cpp
src_gui_image_qicon.cpp
@@ -53,19 +54,22 @@ qt_internal_extend_target(gui_snippets_code CONDITION QT_FEATURE_widgets
src_gui_painting_qpainter.cpp
src_gui_text_qsyntaxhighlighter.cpp
src_gui_util_qvalidator.cpp
-)
+ )
+endif()
-qt_internal_extend_target(gui_snippets_code CONDITION QT_FEATURE_vulkan
- SOURCES
+if(QT_FEATURE_vulkan)
+ target_sources(gui_snippets_code PRIVATE
src_gui_vulkan_qvulkanfunctions.cpp
src_gui_vulkan_qvulkaninstance.cpp
src_gui_vulkan_qvulkanwindow.cpp
-)
+ )
+endif()
-qt_internal_extend_target(gui_snippets_code CONDITION QT_FEATURE_clipboard
- SOURCES
+if(QT_FEATURE_clipboard)
+ target_sources(gui_snippets_code PRIVATE
src_gui_kernel_qclipboard.cpp
-)
+ )
+endif()
set_target_properties(gui_snippets_code PROPERTIES COMPILE_OPTIONS "-w")
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..08fa4365fae 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -34,7 +34,6 @@
#include <QtCore/QDebug>
#include <QtCore/QThread>
-#include <QtCore/private/qthread_p.h>
#include <QtWaylandClient/private/qwayland-fractional-scale-v1.h>
@@ -121,7 +120,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 +345,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 +476,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);
@@ -714,7 +712,7 @@ void QWaylandWindow::applyConfigure()
if (!mWaitingToApplyConfigure)
return;
- Q_ASSERT_X(QThread::currentThreadId() == QThreadData::get2(thread())->threadId.loadRelaxed(),
+ Q_ASSERT_X(QThread::isMainThread(),
"QWaylandWindow::applyConfigure", "not called from main thread");
// If we're mid paint, use an exposeEvent to flush the current frame.
@@ -1082,7 +1080,7 @@ Qt::WindowFlags QWaylandWindow::windowFlags() const
bool QWaylandWindow::createDecoration()
{
- Q_ASSERT_X(QThread::currentThreadId() == QThreadData::get2(thread())->threadId.loadRelaxed(),
+ Q_ASSERT_X(QThread::isMainThread(),
"QWaylandWindow::createDecoration", "not called from main thread");
// TODO: client side decorations do not work with Vulkan backend.
if (window()->surfaceType() == QSurface::VulkanSurface)
@@ -1219,12 +1217,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 +1497,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 +1648,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/testlib/doc/snippets/code/CMakeLists.txt b/src/testlib/doc/snippets/code/CMakeLists.txt
index 54c655a5214..2df704b83e0 100644
--- a/src/testlib/doc/snippets/code/CMakeLists.txt
+++ b/src/testlib/doc/snippets/code/CMakeLists.txt
@@ -11,18 +11,22 @@ target_link_libraries(testlib_code_snippets PRIVATE
Qt::Test
)
-qt_internal_extend_target(testlib_code_snippets CONDITION QT_FEATURE_gui AND QT_FEATURE_sql
- SOURCES
+if(QT_FEATURE_gui AND QT_FEATURE_sql)
+ target_sources(testlib_code_snippets PRIVATE
doc_src_qtestlib.cpp
- PUBLIC_LIBRARIES
+ )
+ target_link_libraries(testlib_code_snippets PUBLIC
Qt::Gui
Qt::Sql
-)
+ )
+endif()
-qt_internal_extend_target(testlib_code_snippets CONDITION QT_FEATURE_widgets
- SOURCES
+if(QT_FEATURE_widgets)
+ target_sources(testlib_code_snippets PRIVATE
doc_src_qtestevent.cpp
doc_src_qtestevent.h
- PUBLIC_LIBRARIES
+ )
+ target_link_libraries(testlib_code_snippets PUBLIC
Qt::Widgets
-)
+ )
+endif()
diff --git a/src/widgets/doc/snippets/CMakeLists.txt b/src/widgets/doc/snippets/CMakeLists.txt
index 8c6e6dda6e6..505363aef3f 100644
--- a/src/widgets/doc/snippets/CMakeLists.txt
+++ b/src/widgets/doc/snippets/CMakeLists.txt
@@ -12,6 +12,7 @@ add_library(widgets_snippets OBJECT
qlistview-dnd/mainwindow.cpp
qlistview-dnd/model.cpp
qlistwidget-dnd/mainwindow.cpp
+ qrhiwidget/rhiwidgetintro.cpp
qsortfilterproxymodel/main.cpp
qsplashscreen/main.cpp
qstackedlayout/main.cpp
@@ -43,50 +44,51 @@ add_library(widgets_snippets OBJECT
target_link_libraries(widgets_snippets PRIVATE
Qt::Core
Qt::Gui
+ Qt::GuiPrivate
Qt::Widgets
)
-qt_internal_extend_target(widgets_snippets
- LIBRARIES
- Qt::GuiPrivate
- SOURCES
- qrhiwidget/rhiwidgetintro.cpp
-)
-
-qt_internal_extend_target(widgets_snippets CONDITION QT_FEATURE_filedialog
- SOURCES
+if(QT_FEATURE_filedialog)
+ target_sources(widgets_snippets PRIVATE
filedialogurls/filedialogurls.cpp
-)
+ )
+endif()
-qt_internal_extend_target(widgets_snippets CONDITION QT_FEATURE_graphicsview
- SOURCES
+if(QT_FEATURE_graphicsview)
+ target_sources(widgets_snippets PRIVATE
graphicssceneadditem/graphicssceneadditemsnippet.cpp
graphicsview/graphicsview_snippet.cpp
-)
+ )
+endif()
-qt_internal_extend_target(widgets_snippets CONDITION QT_FEATURE_opengl AND QT_FEATURE_printsupport
- LIBRARIES
+if(QT_FEATURE_opengl AND QT_FEATURE_printsupport)
+ target_link_libraries(widgets_snippets PRIVATE
Qt::OpenGL
Qt::OpenGLWidgets
Qt::PrintSupport
- SOURCES
+ )
+ target_sources(widgets_snippets PRIVATE
graphicsview/graphicsview.cpp
-)
+ )
+endif()
-qt_internal_extend_target(widgets_snippets CONDITION QT_FEATURE_mdiarea
- SOURCES
+if(QT_FEATURE_mdiarea)
+ target_sources(widgets_snippets PRIVATE
mdiarea/mdiareasnippets.cpp
-)
+ )
+endif()
-qt_internal_extend_target(widgets_snippets CONDITION QT_FEATURE_scrollarea
- SOURCES
+if(QT_FEATURE_scrollarea)
+ target_sources(widgets_snippets PRIVATE
myscrollarea/myscrollarea.cpp
-)
+ )
+endif()
-qt_internal_extend_target(widgets_snippets CONDITION QT_FEATURE_spinbox AND QT_FEATURE_itemviews
- SOURCES
+if(QT_FEATURE_spinbox AND QT_FEATURE_itemviews)
+ target_sources(widgets_snippets PRIVATE
qitemdelegate/spinbox-delegate.cpp
-)
+ )
+endif()
set_target_properties(widgets_snippets PROPERTIES COMPILE_OPTIONS "-w")
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);