diff --git a/BUILD.gn b/BUILD.gn
index d7002f07a..901283c35 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -14,62 +14,62 @@ if (defined(ohos_lite)) {
import("//build/ohos.gni")
}
config("harfbuzz_config") {
- include_dirs = [ "${target_gen_dir}/harfbuzz-2.8.2/src" ]
+ include_dirs = [ "${target_gen_dir}/harfbuzz-11.0.0/src" ]
}
action("harfbuzz_action") {
script = "//third_party/harfbuzz/install.py"
outputs = [
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-aat-layout.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-aat-map.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-blob.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-buffer-serialize.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-buffer.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-common.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-face.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-fallback-shape.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-font.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-map.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-number.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-cff1-table.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-cff2-table.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-face.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-font.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-layout.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-map.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-math.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-meta.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-metrics.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-name.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-arabic.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-default.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-hangul.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-hebrew.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-indic-table.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-indic.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-khmer.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-myanmar.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-syllabic.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-thai.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-use.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-complex-vowel-constraints.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-fallback.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape-normalize.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-shape.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-tag.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ot-var.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-set.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-shape-plan.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-shape.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-shaper.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-static.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-subset-cff2.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-subset-cff-common.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-ucd.cc",
- "${target_gen_dir}/harfbuzz-2.8.2/src/hb-unicode.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-aat-layout.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-aat-map.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-blob.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-buffer-serialize.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-buffer.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-common.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-face.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-fallback-shape.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-font.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-map.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-number.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-cff1-table.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-cff2-table.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-face.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-font.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-layout.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-map.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-math.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-meta.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-metrics.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-name.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-arabic.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-default.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-hangul.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-hebrew.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-indic-table.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-indic.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-khmer.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-myanmar.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-syllabic.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-thai.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-use.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shaper-vowel-constraints.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shape-fallback.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shape-normalize.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-shape.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-tag.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ot-var.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-set.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-shape-plan.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-shape.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-shaper.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-static.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-subset-cff2.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-subset-cff-common.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-ucd.cc",
+ "${target_gen_dir}/harfbuzz-11.0.0/src/hb-unicode.cc",
]
- inputs = [ "//third_party/harfbuzz/harfbuzz-2.8.2.tar.xz" ]
+ inputs = [ "//third_party/harfbuzz/harfbuzz-11.0.0.tar.xz" ]
harfbuzz_path = rebase_path("${target_gen_dir}", root_build_dir)
harfbuzz_source_path = rebase_path("//third_party/harfbuzz", root_build_dir)
args = [
@@ -124,7 +124,7 @@ if (defined(ohos_lite)) {
ohos_static_library("harfbuzz_static") {
sources = get_target_outputs(":harfbuzz_action")
deps = [ ":harfbuzz_action" ]
- include_dirs = [ "${target_gen_dir}/harfbuzz-2.8.2/src" ]
+ include_dirs = [ "${target_gen_dir}/harfbuzz-11.0.0/src" ]
defines = [ "HAVE_PTHREAD = 1" ]
public_configs = [ ":harfbuzz_config" ]
part_name = "harfbuzz"
diff --git a/COPYING b/COPYING
index 48d1b30f9..1dd917e9f 100644
--- a/COPYING
+++ b/COPYING
@@ -2,19 +2,23 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
For parts of HarfBuzz that are licensed under different licenses see individual
files names COPYING in subdirectories where applicable.
-Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 Google, Inc.
-Copyright © 2018,2019,2020 Ebrahim Byagowi
+Copyright © 2010-2022 Google, Inc.
+Copyright © 2015-2020 Ebrahim Byagowi
Copyright © 2019,2020 Facebook, Inc.
-Copyright © 2012 Mozilla Foundation
+Copyright © 2012,2015 Mozilla Foundation
Copyright © 2011 Codethink Limited
Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
Copyright © 2009 Keith Stribley
-Copyright © 2009 Martin Hosken and SIL International
+Copyright © 2011 Martin Hosken and SIL International
Copyright © 2007 Chris Wilson
-Copyright © 2005,2006,2020,2021 Behdad Esfahbod
-Copyright © 2005 David Turner
-Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
-Copyright © 1998-2004 David Turner and Werner Lemberg
+Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod
+Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc.
+Copyright © 1998-2005 David Turner and Werner Lemberg
+Copyright © 2016 Igalia S.L.
+Copyright © 2022 Matthias Clasen
+Copyright © 2018,2021 Khaled Hosny
+Copyright © 2018,2019,2020 Adobe, Inc
+Copyright © 2013-2015 Alexei Podtelezhnikov
For full copyright notices consult the individual files in the package.
diff --git a/OAT.xml b/OAT.xml
deleted file mode 100644
index 7ef4cefe9..000000000
--- a/OAT.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
- COPYING
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.OpenSource b/README.OpenSource
index e887c5a7a..9a057fb2f 100755
--- a/README.OpenSource
+++ b/README.OpenSource
@@ -1,11 +1,11 @@
[
{
- "Name" : "openEuler:HarfBuzz",
+ "Name" : "HarfBuzz",
"License" : "MIT License",
"License File" : "COPYING",
- "Version Number" : "2.8.2-4.oe2203sp3",
- "Owner" : "liyujia4@huawei.com",
- "Upstream URL" : " https://repo.openeuler.org/openEuler-22.03-LTS-SP3/source/Packages/harfbuzz-2.8.2-4.oe2203sp3.src.rpm ",
+ "Version Number" : "11.0.0",
+ "Owner" : "zhangyifan39@huawei.com",
+ "Upstream URL" : "https://github.com/harfbuzz/harfbuzz",
"Description" : "HarfBuzz is a text shaping engine. It primarily supports OpenType, but also Apple Advanced Typography. HarfBuzz is used in Android, Chrome, ChromeOS, Firefox, GNOME, GTK+, KDE, LibreOffice, OpenJDK, PlayStation, Qt, XeTeX, and other places."
}
]
\ No newline at end of file
diff --git a/backport-0001-CVE-2023-25193.patch b/backport-0001-CVE-2023-25193.patch
deleted file mode 100644
index ce065a468..000000000
--- a/backport-0001-CVE-2023-25193.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 56f11ec938260836387256225bc47665473e2bbe Mon Sep 17 00:00:00 2001
-From: Behdad Esfahbod
-Date: Fri, 18 Feb 2022 14:08:43 -0600
-Subject: [PATCH] [buffer] Add HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
-
----
- src/hb-buffer.h | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/src/hb-buffer.h b/src/hb-buffer.h
-index 865ccb2..51b1760 100644
---- a/src/hb-buffer.h
-+++ b/src/hb-buffer.h
-@@ -296,7 +296,10 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
- * flag indicating that a dotted circle should
- * not be inserted in the rendering of incorrect
- * character sequences (such at <0905 093E>). Since: 2.4
-- *
-+ * @HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT:
-+ * flag indicating that the @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
-+ * glyph-flag should be produced by the shaper. By default
-+ * it will not be produced since it incurs a cost. Since: REPLACEME
- * Flags for #hb_buffer_t.
- *
- * Since: 0.9.20
-@@ -307,7 +310,8 @@ typedef enum { /*< flags >*/
- HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
- HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u,
- HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u,
-- HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u
-+ HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u,
-+ HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u
- } hb_buffer_flags_t;
-
- HB_EXTERN void
---
-2.27.0
diff --git a/backport-0002-CVE-2023-25193.patch b/backport-0002-CVE-2023-25193.patch
deleted file mode 100644
index 6827d99bb..000000000
--- a/backport-0002-CVE-2023-25193.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 85be877925ddbf34f74a1229f3ca1716bb6170dc Mon Sep 17 00:00:00 2001
-From: Behdad Esfahbod
-Date: Wed, 1 Feb 2023 20:00:43 -0700
-Subject: [PATCH] [layout] Limit how far we skip when looking back
-
-See comments.
----
- src/hb-ot-layout-gsubgpos.hh | 12 +++++++++++-
- 1 file changed, 11 insertions(+), 1 deletion(-)
-
-diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
-index c17bf92..712e307 100644
---- a/src/hb-ot-layout-gsubgpos.hh
-+++ b/src/hb-ot-layout-gsubgpos.hh
-@@ -535,7 +535,19 @@ struct hb_ot_apply_context_t :
- bool prev ()
- {
- assert (num_items > 0);
-- while (idx > num_items - 1)
-+ /* The alternate condition below is faster at string boundaries,
-+ * but produces subpar "unsafe-to-concat" values. */
-+ unsigned stop = num_items - 1;
-+ if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
-+ stop = 1 - 1;
-+
-+ /* When looking back, limit how far we search; this function is mostly
-+ * used for looking back for base glyphs when attaching marks. If we
-+ * don't limit, we can get O(n^2) behavior where n is the number of
-+ * consecutive marks. */
-+ stop = (unsigned) hb_max ((int) stop, (int) idx - HB_MAX_CONTEXT_LENGTH);
-+
-+ while (idx > stop)
- {
- idx--;
- const hb_glyph_info_t &info = c->buffer->out_info[idx];
---
-2.33.0
-
diff --git a/backport-CVE-2022-33068.patch b/backport-CVE-2022-33068.patch
deleted file mode 100644
index 2a87e7590..000000000
--- a/backport-CVE-2022-33068.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 62e803b36173fd096d7ad460dd1d1db9be542593 Mon Sep 17 00:00:00 2001
-From: Behdad Esfahbod
-Date: Wed, 1 Jun 2022 07:38:21 -0600
-Subject: [PATCH] [sbix] Limit glyph extents
-
-Fixes https://github.com/harfbuzz/harfbuzz/issues/3557
----
- src/hb-ot-color-sbix-table.hh | 6 ++++++
- test/fuzzing/fonts/sbix-extents.ttf | Bin 0 -> 582 bytes
- 2 files changed, 6 insertions(+)
- create mode 100644 test/fuzzing/fonts/sbix-extents.ttf
-
-diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh
-index 9741ebd450..6efae43cda 100644
---- a/src/hb-ot-color-sbix-table.hh
-+++ b/src/hb-ot-color-sbix-table.hh
-@@ -298,6 +298,12 @@ struct sbix
-
- const PNGHeader &png = *blob->as();
-
-+ if (png.IHDR.height >= 65536 | png.IHDR.width >= 65536)
-+ {
-+ hb_blob_destroy (blob);
-+ return false;
-+ }
-+
- extents->x_bearing = x_offset;
- extents->y_bearing = png.IHDR.height + y_offset;
- extents->width = png.IHDR.width;
diff --git a/harfbuzz-11.0.0.tar.xz b/harfbuzz-11.0.0.tar.xz
new file mode 100644
index 000000000..ec7f3994b
Binary files /dev/null and b/harfbuzz-11.0.0.tar.xz differ
diff --git a/harfbuzz-2.8.2.tar.xz b/harfbuzz-2.8.2.tar.xz
deleted file mode 100644
index d8ea8f972..000000000
Binary files a/harfbuzz-2.8.2.tar.xz and /dev/null differ
diff --git a/harfbuzz.spec b/harfbuzz.spec
deleted file mode 100644
index 1f2f19304..000000000
--- a/harfbuzz.spec
+++ /dev/null
@@ -1,113 +0,0 @@
-Name: harfbuzz
-Version: 2.8.2
-Release: 4
-Summary: A text shaping engine
-
-License: MIT
-URL: https://harfbuzz.github.io/what-is-harfbuzz.html
-Source0: https://github.com/harfbuzz/harfbuzz/releases/download/2.8.2/%{name}-%{version}.tar.xz
-
-Patch0001: backport-CVE-2022-33068.patch
-Patch0002: backport-0001-CVE-2023-25193.patch
-Patch0003: backport-0002-CVE-2023-25193.patch
-
-BuildRequires: gcc-c++ freetype-devel cairo-devel glib2-devel graphite2-devel
-BuildRequires: gtk-doc libicu-devel gobject-introspection-devel
-Provides: harfbuzz-icu
-Obsoletes: harfbuzz-icu
-
-%description
-HarfBuzz is a text-shaping engine. If you give HarfBuzz a font and a string
-containing a sequence of Unicode codepoints, HarfBuzz selects and positions
-the corresponding glyphs from the font, applying all of the necessary layout
-rules and font features. HarfBuzz then returns the string to you in the form
-that is correctly arranged for the language and writing system.
-
-%package devel
-Summary: The development environment for %{name}
-Requires: %{name} = %{version}-%{release}
-
-%description devel
-Header files and libraries for building a extension library for %{name}.
-
-%package_help
-
-%prep
-%autosetup -n %{name}-%{version} -p1
-
-%build
-%configure --disable-static --with-graphite2 --with-gobject --enable-introspection
-
-make %{?_smp_mflags}
-
-%check
-make check
-
-%install
-make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p"
-%delete_la
-
-%ldconfig_scriptlets
-
-%files
-%doc AUTHORS NEWS
-%license COPYING
-%{_libdir}/libharfbuzz.so.*
-%{_libdir}/libharfbuzz-subset.so.*
-%{_libdir}/libharfbuzz-gobject.so.0*
-%{_libdir}/libharfbuzz-icu.so.*
-%dir %{_libdir}/girepository-1.0
-%{_libdir}/girepository-1.0/HarfBuzz-0.0.typelib
-
-%files devel
-%{_bindir}/*
-%{_libdir}/*.so
-%{_libdir}/pkgconfig/*.pc
-%{_libdir}/cmake/harfbuzz/
-%{_includedir}/harfbuzz/
-%dir %{_datadir}/gir-1.0
-%{_datadir}/gir-1.0/HarfBuzz-0.0.gir
-
-%files help
-%doc README
-%{_datadir}/gtk-doc/html/harfbuzz/*
-
-%changelog
-* Wed Feb 15 2023 zhouwenpei - 2.8.2-4
-- fix CVE-2023-25193
-
-* Thu Jul 14 2022 zhouwenpei - 2.8.2-3
-- fix CVE-2022-33068
-
-* Tue May 24 2022 loong_C - 2.8.2-2
-- fix spec changelog date
-
-* Fri Dec 03 2021 liuyumeng - 2.8.2-1
-- update to harfbuzz-2.8.2-1
-
-* Mon Jul 05 2021 wangkerong - 2.8.1-2
-- enable make check
-
-* Fri Jun 25 2021 wangkerong - 2.8.1-1
-- update to 2.8.1
-
-* Thu Jan 28 2021 zhanzhimin - 2.7.4-1
-- update to 2.7.4
-
-* Thu Sep 10 2020 chengguipeng - 2.6.8-3
-- Type:bugfix
-- ID:NA
-- SUG:NA
-- DESC:modify source0 url
-
-* Wed Jul 29 2020 hanhui - 2.6.8-2
-- modify HarfBuzz-0.0.gir patch
-
-* Tue Jul 21 2020 hanhui - 2.6.8-1
-- Update to 2.6.8
-
-* Mon Jun 15 2020 hanhui - 2.6.1-1
-- Update to 2.6.1
-
-* Mon Aug 26 2019 openEuler Buildteam - 1.8.7-2
-- Package Init
diff --git a/harfbuzz.yaml b/harfbuzz.yaml
deleted file mode 100644
index 643e6b79e..000000000
--- a/harfbuzz.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-version_control: github
-src_repo: harfbuzz/harfbuzz
-tag_prefix: "^"
-seperator: "."
diff --git a/huawei_harfbuzz.patch b/huawei_harfbuzz.patch
index 02f4364a1..df7f5a2e3 100644
--- a/huawei_harfbuzz.patch
+++ b/huawei_harfbuzz.patch
@@ -1,28 +1,1039 @@
-diff --git a/src/hb-buffer.h b/src/hb-buffer.h
-index 865ccb2..88f1f4c 100644
---- a/src/hb-buffer.h
-+++ b/src/hb-buffer.h
-@@ -307,7 +307,8 @@ typedef enum { /*< flags >*/
- HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
- HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u,
- HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u,
-- HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u
-+ HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u,
-+ HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u
- } hb_buffer_flags_t;
+From 847c0d2d7901446c4c6df54c7361792d9b637ec8 Mon Sep 17 00:00:00 2001
+From: Zacoh
+Date: Wed, 14 May 2025 14:17:05 +0800
+Subject: [PATCH] harfbuzz update 11.0.0
+
+---
+ src/OT/Color/COLR/COLR.hh | 506 ++++++++++++++++++++++++
+ src/OT/Layout/Common/CoverageFormat2.hh | 4 +
+ src/OT/glyf/Glyph.hh | 244 ++++++++++++
+ src/OT/glyf/GlyphHeader.hh | 25 ++
+ src/hb-open-type.hh | 6 +
+ src/hb-ot-cmap-table.hh | 19 +
+ src/hb-ot-layout-common.hh | 36 ++
+ src/hb-ot-layout-gpos-table.hh | 20 +
+ src/hb-ot-layout-gsubgpos.hh | 7 +
+ src/hb-static.cc | 5 +
+ 10 files changed, 872 insertions(+)
+
+diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh
+index 16cd96e..46b96db 100644
+--- a/src/OT/Color/COLR/COLR.hh
++++ b/src/OT/Color/COLR/COLR.hh
+@@ -915,6 +915,12 @@ struct PaintGlyph
+ {
+ void closurev1 (hb_colrv1_closure_context_t* c) const;
- HB_EXTERN void
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer) const
+ {
+@@ -946,6 +952,7 @@ struct PaintGlyph
+ c->funcs->pop_clip (c->data);
+ c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 10 */
+ Offset24To paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
+@@ -1027,6 +1034,13 @@ struct PaintTranslate
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1063,6 +1077,7 @@ struct PaintTranslate
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 14(noVar) or 15 (Var) */
+ Offset24To src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
+@@ -1076,6 +1091,13 @@ struct PaintScale
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1112,6 +1134,7 @@ struct PaintScale
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 16 (noVar) or 17(Var) */
+ Offset24To src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
+@@ -1125,6 +1148,13 @@ struct PaintScaleAroundCenter
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1169,6 +1199,7 @@ struct PaintScaleAroundCenter
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 18 (noVar) or 19(Var) */
+ Offset24To src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
+@@ -1184,6 +1215,13 @@ struct PaintScaleUniform
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1216,6 +1254,7 @@ struct PaintScaleUniform
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 20 (noVar) or 21(Var) */
+ Offset24To src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
+@@ -1228,6 +1267,13 @@ struct PaintScaleUniformAroundCenter
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1270,6 +1316,7 @@ struct PaintScaleUniformAroundCenter
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 22 (noVar) or 23(Var) */
+ Offset24To src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
+@@ -1284,6 +1331,13 @@ struct PaintRotate
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1316,6 +1370,7 @@ struct PaintRotate
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 24 (noVar) or 25(Var) */
+ Offset24To src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
+@@ -1328,6 +1383,13 @@ struct PaintRotateAroundCenter
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1370,6 +1432,7 @@ struct PaintRotateAroundCenter
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 26 (noVar) or 27(Var) */
+ Offset24To src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
+@@ -1384,6 +1447,13 @@ struct PaintSkew
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1420,6 +1490,7 @@ struct PaintSkew
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 28(noVar) or 29 (Var) */
+ Offset24To src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
+@@ -1433,6 +1504,13 @@ struct PaintSkewAroundCenter
+ {
+ HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer,
+ uint32_t varIdxBase) const
+@@ -1477,6 +1555,7 @@ struct PaintSkewAroundCenter
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
++#endif
+
+ HBUINT8 format; /* format = 30(noVar) or 31 (Var) */
+ Offset24To src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
+@@ -1492,6 +1571,12 @@ struct PaintComposite
+ {
+ void closurev1 (hb_colrv1_closure_context_t* c) const;
+
++#ifdef ENABLE_ICCARM
++ bool subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer) const;
++ bool sanitize (hb_sanitize_context_t *c) const;
++ void paint_glyph (hb_paint_context_t *c) const;
++#else
+ bool subset (hb_subset_context_t *c,
+ const ItemVarStoreInstancer &instancer) const
+ {
+@@ -1524,6 +1609,7 @@ struct PaintComposite
+ c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
+ c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+ }
++#endif
+
+ HBUINT8 format; /* format = 32 */
+ Offset24To src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
+@@ -1920,6 +2006,426 @@ struct Paint
+ DEFINE_SIZE_MIN (2);
+ };
+
++#ifdef ENABLE_ICCARM
++inline bool PaintGlyph::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
++ HB_SERIALIZE_ERROR_INT_OVERFLOW))
++ return_trace (false);
++
++ return_trace (out->paint.serialize_subset (c, paint, this, instancer));
++}
++
++inline bool PaintGlyph::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && paint.sanitize (c, this));
++}
++
++inline void PaintGlyph::paint_glyph (hb_paint_context_t *c) const
++{
++ TRACE_PAINT (this);
++ c->funcs->push_inverse_font_transform (c->data, c->font);
++ c->funcs->push_clip_glyph (c->data, gid, c->font);
++ c->funcs->push_font_transform (c->data, c->font);
++ c->recurse (this+paint);
++ c->funcs->pop_transform (c->data);
++ c->funcs->pop_clip (c->data);
++ c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintTranslate::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
++ out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
++ }
++
++ if (format == 15 && c->plan->all_axes_pinned)
++ out->format = 14;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintTranslate::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintTranslate::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float ddx = dx + c->instancer (varIdxBase, 0);
++ float ddy = dy + c->instancer (varIdxBase, 1);
++
++ bool p1 = c->funcs->push_translate (c->data, ddx, ddy);
++ c->recurse (this+src);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintScale::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
++ out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
++ }
++
++ if (format == 17 && c->plan->all_axes_pinned)
++ out->format = 16;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintScale::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintScale::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
++ float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
++
++ bool p1 = c->funcs->push_scale (c->data, sx, sy);
++ c->recurse (this+src);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintScaleAroundCenter::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
++ out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
++ out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
++ out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
++ }
++
++ if (format == 19 && c->plan->all_axes_pinned)
++ out->format = 18;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintScaleAroundCenter::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintScaleAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
++ float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
++ float tCenterX = centerX + c->instancer (varIdxBase, 2);
++ float tCenterY = centerY + c->instancer (varIdxBase, 3);
++
++ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
++ bool p2 = c->funcs->push_scale (c->data, sx, sy);
++ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
++ c->recurse (this+src);
++ if (p3) c->funcs->pop_transform (c->data);
++ if (p2) c->funcs->pop_transform (c->data);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintScaleUniform::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
++
++ if (format == 21 && c->plan->all_axes_pinned)
++ out->format = 20;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintScaleUniform::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintScaleUniform::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float s = scale.to_float (c->instancer (varIdxBase, 0));
++
++ bool p1 = c->funcs->push_scale (c->data, s, s);
++ c->recurse (this+src);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintScaleUniformAroundCenter::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
++ out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
++ out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
++ }
++
++ if (format == 23 && c->plan->all_axes_pinned)
++ out->format = 22;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintScaleUniformAroundCenter::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintScaleUniformAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float s = scale.to_float (c->instancer (varIdxBase, 0));
++ float tCenterX = centerX + c->instancer (varIdxBase, 1);
++ float tCenterY = centerY + c->instancer (varIdxBase, 2);
++
++ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
++ bool p2 = c->funcs->push_scale (c->data, s, s);
++ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
++ c->recurse (this+src);
++ if (p3) c->funcs->pop_transform (c->data);
++ if (p2) c->funcs->pop_transform (c->data);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintRotate::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
++
++ if (format == 25 && c->plan->all_axes_pinned)
++ out->format = 24;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintRotate::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintRotate::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float a = angle.to_float (c->instancer (varIdxBase, 0));
++
++ bool p1 = c->funcs->push_rotate (c->data, a);
++ c->recurse (this+src);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintRotateAroundCenter::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
++ out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
++ out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
++ }
++
++ if (format ==27 && c->plan->all_axes_pinned)
++ out->format = 26;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintRotateAroundCenter::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintRotateAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float a = angle.to_float (c->instancer (varIdxBase, 0));
++ float tCenterX = centerX + c->instancer (varIdxBase, 1);
++ float tCenterY = centerY + c->instancer (varIdxBase, 2);
++
++ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
++ bool p2 = c->funcs->push_rotate (c->data, a);
++ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
++ c->recurse (this+src);
++ if (p3) c->funcs->pop_transform (c->data);
++ if (p2) c->funcs->pop_transform (c->data);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintSkew::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
++ out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
++ }
++
++ if (format == 29 && c->plan->all_axes_pinned)
++ out->format = 28;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintSkew::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintSkew::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
++ float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
++
++ bool p1 = c->funcs->push_skew (c->data, sx, sy);
++ c->recurse (this+src);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintSkewAroundCenter::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer,
++ uint32_t varIdxBase) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
++ {
++ out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
++ out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
++ out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
++ out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
++ }
++
++ if (format == 31 && c->plan->all_axes_pinned)
++ out->format = 30;
++
++ return_trace (out->src.serialize_subset (c, src, this, instancer));
++}
++
++inline bool PaintSkewAroundCenter::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) && src.sanitize (c, this));
++}
++
++inline void PaintSkewAroundCenter::paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
++{
++ TRACE_PAINT (this);
++ float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
++ float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
++ float tCenterX = centerX + c->instancer (varIdxBase, 2);
++ float tCenterY = centerY + c->instancer (varIdxBase, 3);
++
++ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
++ bool p2 = c->funcs->push_skew (c->data, sx, sy);
++ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
++ c->recurse (this+src);
++ if (p3) c->funcs->pop_transform (c->data);
++ if (p2) c->funcs->pop_transform (c->data);
++ if (p1) c->funcs->pop_transform (c->data);
++}
++
++inline bool PaintComposite::subset (hb_subset_context_t *c,
++ const ItemVarStoreInstancer &instancer) const
++{
++ TRACE_SUBSET (this);
++ auto *out = c->serializer->embed (this);
++ if (unlikely (!out)) return_trace (false);
++
++ bool ret = false;
++ ret |= out->src.serialize_subset (c, src, this, instancer);
++ ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer);
++ return_trace (ret);
++}
++
++inline bool PaintComposite::sanitize (hb_sanitize_context_t *c) const
++{
++ TRACE_SANITIZE (this);
++ return_trace (c->check_struct (this) &&
++ c->check_ops (this->min_size) && // PainComposite can get exponential
++ src.sanitize (c, this) &&
++ backdrop.sanitize (c, this));
++}
++
++inline void PaintComposite::paint_glyph (hb_paint_context_t *c) const
++{
++ TRACE_PAINT (this);
++ c->funcs->push_group (c->data);
++ c->recurse (this+backdrop);
++ c->funcs->push_group (c->data);
++ c->recurse (this+src);
++ c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
++ c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
++}
++#endif
++
+ struct BaseGlyphPaintRecord
+ {
+ int cmp (hb_codepoint_t g) const
+diff --git a/src/OT/Layout/Common/CoverageFormat2.hh b/src/OT/Layout/Common/CoverageFormat2.hh
+index dd577fd..18c93ac 100644
+--- a/src/OT/Layout/Common/CoverageFormat2.hh
++++ b/src/OT/Layout/Common/CoverageFormat2.hh
+@@ -70,7 +70,11 @@ struct CoverageFormat2_4
+ typename Types::large_int ret = 0;
+ for (const auto &r : rangeRecord)
+ ret += r.get_population ();
++#ifdef ENABLE_ICCARM
++ return ret;
++#else
+ return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
++#endif
+ }
+
+ template
++ bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
++ contour_point_vector_t &all_points /* OUT */,
++ hb_glyf_scratch_t &scratch,
++ contour_point_vector_t *points_with_deltas = nullptr, /* OUT */
++ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
++ unsigned *composite_contours = nullptr, /* OUT */
++ bool shift_points_hori = true,
++ bool use_my_metrics = true,
++ bool phantom_only = false,
++ hb_array_t coords = hb_array_t (),
++ unsigned int depth = 0,
++ unsigned *edge_count = nullptr) const;
++#else
+ template
+ bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
+ contour_point_vector_t &all_points /* OUT */,
+@@ -529,6 +544,7 @@ struct Glyph
+
+ return !all_points.in_error ();
+ }
++#endif
+
+ bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
+ hb_glyph_extents_t *extents) const
+@@ -566,6 +582,234 @@ struct Glyph
+ glyph_type_t type;
+ };
+
++#ifdef ENABLE_ICCARM
++template
++inline bool Glyph::get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
++ contour_point_vector_t &all_points /* OUT */,
++ hb_glyf_scratch_t &scratch,
++ contour_point_vector_t *points_with_deltas, /* OUT */
++ head_maxp_info_t * head_maxp_info, /* OUT */
++ unsigned *composite_contours, /* OUT */
++ bool shift_points_hori,
++ bool use_my_metrics,
++ bool phantom_only,
++ hb_array_t coords,
++ unsigned int depth,
++ unsigned *edge_count) const
++{
++ if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
++ unsigned stack_edge_count = 0;
++ if (!edge_count) edge_count = &stack_edge_count;
++ if (unlikely (*edge_count > HB_MAX_GRAPH_EDGE_COUNT)) return false;
++ (*edge_count)++;
++
++ if (head_maxp_info)
++ {
++ head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
++ }
++
++ if (!coords)
++ coords = hb_array (font->coords, font->num_coords);
++
++ contour_point_vector_t &points = type == SIMPLE ? all_points : scratch.comp_points;
++ unsigned old_length = points.length;
++
++ switch (type) {
++ case SIMPLE:
++ if (depth == 0 && head_maxp_info)
++ head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
++ if (depth > 0 && composite_contours)
++ *composite_contours += (unsigned) header->numberOfContours;
++ if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (all_points, phantom_only)))
++return false;
++ break;
++ case COMPOSITE:
++ {
++ for (auto &item : get_composite_iterator ())
++ if (unlikely (!item.get_points (points))) return false;
++ break;
++ }
++ case EMPTY:
++ break;
++ }
++
++ /* Init phantom points */
++ if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
++ hb_array_t phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
++ {
++ int lsb = 0;
++ int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
++ (int) header->xMin - lsb : 0;
++ HB_UNUSED int tsb = 0;
++ int v_orig = (int) header->yMax +
++#ifndef HB_NO_VERTICAL
++ ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
++#else
++ 0
++#endif
++ ;
++ unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid);
++ unsigned v_adv =
++#ifndef HB_NO_VERTICAL
++ glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid)
++#else
++ - font->face->get_upem ()
++#endif
++ ;
++ phantoms[PHANTOM_LEFT].x = h_delta;
++ phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
++ phantoms[PHANTOM_TOP].y = v_orig;
++ phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
++ }
++
++#ifndef HB_NO_VAR
++ if (coords)
++ {
++#ifndef HB_NO_BEYOND_64K
++ if (glyf_accelerator.GVAR->has_data ())
++glyf_accelerator.GVAR->apply_deltas_to_points (gid,
++ coords,
++ points.as_array ().sub_array (old_length),
++ scratch,
++ phantom_only && type == SIMPLE);
++ else
++#endif
++glyf_accelerator.gvar->apply_deltas_to_points (gid,
++ coords,
++ points.as_array ().sub_array (old_length),
++ scratch,
++ phantom_only && type == SIMPLE);
++ }
++#endif
++
++ // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
++ // with child glyphs' points
++ if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
++ {
++ assert (old_length == 0);
++ *points_with_deltas = points;
++ }
++
++ float shift = 0;
++ switch (type) {
++ case SIMPLE:
++ if (depth == 0 && head_maxp_info)
++ head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
++ shift = phantoms[PHANTOM_LEFT].x;
++ break;
++ case COMPOSITE:
++ {
++ hb_decycler_node_t decycler_node (scratch.decycler);
++
++ unsigned int comp_index = 0;
++ for (auto &item : get_composite_iterator ())
++ {
++hb_codepoint_t item_gid = item.get_gid ();
++
++ if (unlikely (!decycler_node.visit (item_gid)))
++{
++ comp_index++;
++ continue;
++}
++
++unsigned old_count = all_points.length;
++
++if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
++ !glyf_accelerator.glyph_for_gid (item_gid)
++ .get_points (font,
++ glyf_accelerator,
++ all_points,
++ scratch,
++ points_with_deltas,
++ head_maxp_info,
++ composite_contours,
++ shift_points_hori,
++ use_my_metrics,
++ phantom_only,
++ coords,
++ depth + 1,
++ edge_count)))
++{
++ points.resize (old_length);
++ return false;
++}
++
++// points might have been reallocated. Relocate phantoms.
++phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
++
++auto comp_points = all_points.as_array ().sub_array (old_count);
++
++/* Copy phantom points from component if USE_MY_METRICS flag set */
++if (use_my_metrics && item.is_use_my_metrics ())
++ for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
++ phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
++
++if (comp_points) // Empty in case of phantom_only
++{
++ float matrix[4];
++ contour_point_t default_trans;
++ item.get_transformation (matrix, default_trans);
++
++ /* Apply component transformation & translation (with deltas applied) */
++ item.transform_points (comp_points, matrix, points[old_length + comp_index]);
++}
++
++if (item.is_anchored () && !phantom_only)
++{
++ unsigned int p1, p2;
++ item.get_anchor_points (p1, p2);
++ if (likely (p1 < all_points.length && p2 < comp_points.length))
++ {
++ contour_point_t delta;
++ delta.init (all_points[p1].x - comp_points[p2].x,
++ all_points[p1].y - comp_points[p2].y);
++
++ item.translate (delta, comp_points);
++ }
++}
++
++all_points.resize (all_points.length - PHANTOM_COUNT);
++
++if (all_points.length > HB_GLYF_MAX_POINTS)
++{
++ points.resize (old_length);
++ return false;
++}
++
++comp_index++;
++ }
++
++ if (head_maxp_info && depth == 0)
++ {
++ if (composite_contours)
++ head_maxp_info->maxCompositeContours = hb_max (head_maxp_info->maxCompositeContours, *composite_contours);
++ head_maxp_info->maxCompositePoints = hb_max (head_maxp_info->maxCompositePoints, all_points.length);
++ head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index);
++ }
++ all_points.extend (phantoms);
++ shift = phantoms[PHANTOM_LEFT].x;
++ points.resize (old_length);
++ } break;
++ case EMPTY:
++ all_points.extend (phantoms);
++ shift = phantoms[PHANTOM_LEFT].x;
++ points.resize (old_length);
++ break;
++ }
++
++ if (depth == 0 && shift_points_hori) /* Apply at top level */
++ {
++ /* Undocumented rasterizer behavior:
++ * Shift points horizontally by the updated left side bearing
++ */
++ if (shift)
++ for (auto &point : all_points)
++ point.x -= shift;
++ }
++
++ return !all_points.in_error ();
++}
++#endif
+
+ } /* namespace glyf_impl */
+ } /* namespace OT */
+diff --git a/src/OT/glyf/GlyphHeader.hh b/src/OT/glyf/GlyphHeader.hh
+index a43b669..14ab9d7 100644
+--- a/src/OT/glyf/GlyphHeader.hh
++++ b/src/OT/glyf/GlyphHeader.hh
+@@ -13,6 +13,11 @@ struct GlyphHeader
+ {
+ bool has_data () const { return numberOfContours; }
+
++#ifdef ENABLE_ICCARM
++ template
++ bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
++ hb_codepoint_t gid, hb_glyph_extents_t *extents) const;
++#else
+ template
+ bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
+ hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+@@ -30,6 +35,7 @@ struct GlyphHeader
+
+ return true;
+ }
++#endif
+
+ HBINT16 numberOfContours;
+ /* If the number of contours is
+@@ -44,6 +50,25 @@ struct GlyphHeader
+ DEFINE_SIZE_STATIC (10);
+ };
+
++#ifdef ENABLE_ICCARM
++template
++bool GlyphHeader::get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
++ hb_codepoint_t gid, hb_glyph_extents_t *extents) const
++{
++ /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
++ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
++ int lsb = hb_min (xMin, xMax);
++ (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb);
++ extents->x_bearing = lsb;
++ extents->y_bearing = hb_max (yMin, yMax);
++ extents->width = hb_max (xMin, xMax) - hb_min (xMin, xMax);
++ extents->height = hb_min (yMin, yMax) - hb_max (yMin, yMax);
++
++ font->scale_glyph_extents (extents);
++
++ return true;
++}
++#endif
+
+ } /* namespace glyf_impl */
+ } /* namespace OT */
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
-index 406771f..b8ac4c5 100644
+index f2040ea..844704a 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
-@@ -575,8 +575,13 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf
+@@ -669,8 +669,14 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf
{ return hb_sorted_array (this->arrayZ, len); }
hb_sorted_array_t as_array (unsigned int len) const
{ return hb_sorted_array (this->arrayZ, len); }
++
+#ifdef ENABLE_ICCARM
-+ operator hb_sorted_array_t () { return as_array (0); }
-+ operator hb_sorted_array_t () const { return as_array (0); }
++ operator hb_sorted_array_t () { return as_array ( 0 ); }
++ operator hb_sorted_array_t () const { return as_array ( 0 ); }
+#else
operator hb_sorted_array_t () { return as_array (); }
operator hb_sorted_array_t () const { return as_array (); }
@@ -30,430 +1041,215 @@ index 406771f..b8ac4c5 100644
template
Type &bsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type))
+diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
+index 7a7a77a..eaba5d2 100644
+--- a/src/hb-ot-cmap-table.hh
++++ b/src/hb-ot-cmap-table.hh
+@@ -1695,6 +1695,10 @@ struct SubtableUnicodesCache {
+ hb_free (cache);
+ }
+
++#ifdef ENABLE_ICCARM
++ SubtableUnicodesCache(const void* cmap_base);
++ SubtableUnicodesCache(hb_blob_ptr_t base_blob_);
++#else
+ SubtableUnicodesCache(const void* cmap_base)
+ : base_blob(),
+ base ((const char*) cmap_base),
+@@ -1706,6 +1710,7 @@ struct SubtableUnicodesCache {
+ base ((const char *) base_blob.get()),
+ cached_unicodes ()
+ {}
++#endif
+
+ ~SubtableUnicodesCache()
+ {
+@@ -2266,6 +2271,20 @@ struct cmap
+ DEFINE_SIZE_ARRAY (4, encodingRecord);
+ };
+
++#ifdef ENABLE_ICCARM
++inline SubtableUnicodesCache::SubtableUnicodesCache(const void* cmap_base)
++ : base_blob(),
++ base ((const char*) cmap_base),
++ cached_unicodes ()
++{}
++
++inline SubtableUnicodesCache::SubtableUnicodesCache(hb_blob_ptr_t base_blob_)
++ : base_blob(base_blob_),
++ base ((const char *) base_blob.get()),
++ cached_unicodes ()
++{}
++#endif
++
+ struct cmap_accelerator_t : cmap::accelerator_t {
+ cmap_accelerator_t (hb_face_t *face) : cmap::accelerator_t (face) {}
+ };
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
-index c78f820..c9d93a7 100644
+index ad54a1d..f8212a6 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
-@@ -445,6 +445,7 @@ struct RecordListOf : RecordArrayOf
+@@ -1768,7 +1768,11 @@ struct ClassDefFormat2_4
+ typename Types::large_int ret = 0;
+ for (const auto &r : rangeRecord)
+ ret += r.get_population ();
++#ifdef ENABLE_ICCARM
++ return ret;
++#else
+ return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
++#endif
}
+
+ template
+ bool
+ _hb_recurse_condition_evaluate (const struct Condition &condition,
+diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
+index 0cfa139..a2e87e8 100644
+--- a/src/hb-ot-layout-gpos-table.hh
++++ b/src/hb-ot-layout-gpos-table.hh
+@@ -75,6 +75,26 @@ inline bool PosLookup::dispatch_recurse_func (hb_ot_apply
- struct RecordListOfFeature : RecordListOf
-@@ -797,7 +798,7 @@ struct Script
- };
-
- typedef RecordListOfScript ScriptList;
--
-+#endif // ENABLE_ICCARM
-
- /* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
- struct FeatureParamsSize
-@@ -1081,6 +1082,52 @@ struct FeatureParams
- DEFINE_SIZE_MIN (0);
- };
-
-+#ifdef ENABLE_ICCARM // Adaptive compilation, only changes the order of the code, does not affect the function
-+struct IndexArray : Array16Of
+ } /* namespace GPOS_impl */
+ } /* namespace Layout */
++
++#ifdef ENABLE_ICCARM
++template
++void GSUBGPOS::closure_lookups (hb_face_t *face,
++ const hb_set_t *glyphs,
++ hb_set_t *lookup_indexes /* IN/OUT */) const
+{
-+ bool intersects (const hb_map_t *indexes) const
-+ { return hb_any (*this, indexes); }
++ hb_set_t visited_lookups, inactive_lookups;
++ hb_closure_lookups_context_t c (face, glyphs, &visited_lookups, &inactive_lookups);
+
-+ template
-+ void serialize (hb_serialize_context_t *c,
-+ hb_subset_layout_context_t *l,
-+ Iterator it)
-+ {
-+ if (!it) return;
-+ if (unlikely (!c->extend_min ((*this)))) return;
++ c.set_recurse_func (TLookup::template dispatch_recurse_func);
+
-+ for (const auto _ : it)
-+ {
-+ if (!l->visitLookupIndex()) break;
++ for (unsigned lookup_index : *lookup_indexes)
++ reinterpret_cast (get_lookup (lookup_index)).closure_lookups (&c, lookup_index);
+
-+ Index i;
-+ i = _;
-+ c->copy (i);
-+ this->len++;
-+ }
-+ }
++ hb_set_union (lookup_indexes, &visited_lookups);
++ hb_set_subtract (lookup_indexes, &inactive_lookups);
++}
++#endif
+
-+ unsigned int get_indexes (unsigned int start_offset,
-+ unsigned int *_count /* IN/OUT */,
-+ unsigned int *_indexes /* OUT */) const
-+ {
-+ if (_count)
-+ {
-+ + this->sub_array (start_offset, _count)
-+ | hb_sink (hb_array (_indexes, *_count))
-+ ;
-+ }
-+ return this->len;
-+ }
-+
-+ void add_indexes_to (hb_set_t* output /* OUT */) const
-+ {
-+ output->add_array (as_array ());
-+ }
-+};
-+#endif // ENABLE_ICCARM
-+
- struct Feature
- {
- unsigned int get_lookup_count () const
-@@ -1176,6 +1223,311 @@ struct Feature
- DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex);
- };
-
-+#ifdef ENABLE_ICCARM // Adaptive compilation, only changes the order of the code, does not affect the function
-+struct RecordListOfFeature : RecordListOf
-+{
-+ bool subset (hb_subset_context_t *c,
-+ hb_subset_layout_context_t *l) const
-+ {
-+ TRACE_SUBSET (this);
-+ auto *out = c->serializer->start_embed (*this);
-+ if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-+
-+ unsigned count = this->len;
-+ + hb_zip (*this, hb_range (count))
-+ | hb_filter (l->feature_index_map, hb_second)
-+ | hb_map (hb_first)
-+ | hb_apply (subset_record_array (l, out, this))
-+ ;
-+ return_trace (true);
-+ }
-+};
-+
-+struct LangSys
-+{
-+ unsigned int get_feature_count () const
-+ { return featureIndex.len; }
-+ hb_tag_t get_feature_index (unsigned int i) const
-+ { return featureIndex[i]; }
-+ unsigned int get_feature_indexes (unsigned int start_offset,
-+ unsigned int *feature_count /* IN/OUT */,
-+ unsigned int *feature_indexes /* OUT */) const
-+ { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
-+ void add_feature_indexes_to (hb_set_t *feature_indexes) const
-+ { featureIndex.add_indexes_to (feature_indexes); }
-+
-+ bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; }
-+ unsigned int get_required_feature_index () const
-+ {
-+ if (reqFeatureIndex == 0xFFFFu)
-+ return Index::NOT_FOUND_INDEX;
-+ return reqFeatureIndex;
-+ }
-+
-+ LangSys* copy (hb_serialize_context_t *c) const
-+ {
-+ TRACE_SERIALIZE (this);
-+ return_trace (c->embed (*this));
-+ }
-+
-+ bool compare (const LangSys& o, const hb_map_t *feature_index_map) const
-+ {
-+ if (reqFeatureIndex != o.reqFeatureIndex)
-+ return false;
-+
-+ auto iter =
-+ + hb_iter (featureIndex)
-+ | hb_filter (feature_index_map)
-+ | hb_map (feature_index_map)
-+ ;
-+
-+ auto o_iter =
-+ + hb_iter (o.featureIndex)
-+ | hb_filter (feature_index_map)
-+ | hb_map (feature_index_map)
-+ ;
-+
-+ if (iter.len () != o_iter.len ())
-+ return false;
-+
-+ for (const auto _ : + hb_zip (iter, o_iter))
-+ if (_.first != _.second) return false;
-+
-+ return true;
-+ }
-+
-+ void collect_features (hb_prune_langsys_context_t *c) const
-+ {
-+ if (!has_required_feature () && !get_feature_count ()) return;
-+ if (c->visitedLangsys (this)) return;
-+ if (has_required_feature () &&
-+ c->duplicate_feature_map->has (reqFeatureIndex))
-+ c->new_feature_indexes->add (get_required_feature_index ());
-+
-+ + hb_iter (featureIndex)
-+ | hb_filter (c->duplicate_feature_map)
-+ | hb_sink (c->new_feature_indexes)
-+ ;
-+ }
-+
-+ bool subset (hb_subset_context_t *c,
-+ hb_subset_layout_context_t *l,
-+ const Tag *tag = nullptr) const
-+ {
-+ TRACE_SUBSET (this);
-+ auto *out = c->serializer->start_embed (*this);
-+ if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-+
-+ out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex) ? l->feature_index_map->get (reqFeatureIndex) : 0xFFFFu;
-+
-+ if (!l->visitFeatureIndex (featureIndex.len))
-+ return_trace (false);
-+
-+ auto it =
-+ + hb_iter (featureIndex)
-+ | hb_filter (l->feature_index_map)
-+ | hb_map (l->feature_index_map)
-+ ;
-+
-+ bool ret = bool (it);
-+ out->featureIndex.serialize (c->serializer, l, it);
-+ return_trace (ret);
-+ }
-+
-+ bool sanitize (hb_sanitize_context_t *c,
-+ const Record_sanitize_closure_t * = nullptr) const
-+ {
-+ TRACE_SANITIZE (this);
-+ return_trace (c->check_struct (this) && featureIndex.sanitize (c));
-+ }
-+
-+ Offset16 lookupOrderZ; /* = Null (reserved for an offset to a
-+ * reordering table) */
-+ HBUINT16 reqFeatureIndex;/* Index of a feature required for this
-+ * language system--if no required features
-+ * = 0xFFFFu */
-+ IndexArray featureIndex; /* Array of indices into the FeatureList */
-+ public:
-+ DEFINE_SIZE_ARRAY_SIZED (6, featureIndex);
-+};
-+DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys);
-+
-+struct Script
-+{
-+ unsigned int get_lang_sys_count () const
-+ { return langSys.len; }
-+ const Tag& get_lang_sys_tag (unsigned int i) const
-+ { return langSys.get_tag (i); }
-+ unsigned int get_lang_sys_tags (unsigned int start_offset,
-+ unsigned int *lang_sys_count /* IN/OUT */,
-+ hb_tag_t *lang_sys_tags /* OUT */) const
-+ { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
-+ const LangSys& get_lang_sys (unsigned int i) const
-+ {
-+ if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
-+ return this+langSys[i].offset;
-+ }
-+ bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
-+ { return langSys.find_index (tag, index); }
-+
-+ bool has_default_lang_sys () const { return defaultLangSys != 0; }
-+ const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
-+
-+ void prune_langsys (hb_prune_langsys_context_t *c,
-+ unsigned script_index) const
-+ {
-+ if (!has_default_lang_sys () && !get_lang_sys_count ()) return;
-+ if (c->visitedScript (this)) return;
-+
-+ if (!c->script_langsys_map->has (script_index))
-+ {
-+ hb_set_t* empty_set = hb_set_create ();
-+ if (unlikely (!c->script_langsys_map->set (script_index, empty_set)))
-+ {
-+ hb_set_destroy (empty_set);
-+ return;
-+ }
-+ }
-+
-+ unsigned langsys_count = get_lang_sys_count ();
-+ if (has_default_lang_sys ())
-+ {
-+ //only collect features from non-redundant langsys
-+ const LangSys& d = get_default_lang_sys ();
-+ d.collect_features (c);
-+
-+ for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
-+ {
-+ const LangSys& l = this+_.first.offset;
-+ if (l.compare (d, c->duplicate_feature_map)) continue;
-+
-+ l.collect_features (c);
-+ c->script_langsys_map->get (script_index)->add (_.second);
-+ }
-+ }
-+ else
-+ {
-+ for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
-+ {
-+ const LangSys& l = this+_.first.offset;
-+ l.collect_features (c);
-+ c->script_langsys_map->get (script_index)->add (_.second);
-+ }
-+ }
-+ }
-+
-+ bool subset (hb_subset_context_t *c,
-+ hb_subset_layout_context_t *l,
-+ const Tag *tag) const
-+ {
-+ TRACE_SUBSET (this);
-+ if (!l->visitScript ()) return_trace (false);
-+
-+ auto *out = c->serializer->start_embed (*this);
-+ if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
-+
-+ bool defaultLang = false;
-+ if (has_default_lang_sys ())
-+ {
-+ c->serializer->push ();
-+ const LangSys& ls = this+defaultLangSys;
-+ bool ret = ls.subset (c, l);
-+ if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T'))
-+ {
-+ c->serializer->pop_discard ();
-+ out->defaultLangSys = 0;
-+ }
-+ else
-+ {
-+ c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ());
-+ defaultLang = true;
-+ }
-+ }
-+
-+ const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index);
-+ if (active_langsys)
-+ {
-+ unsigned count = langSys.len;
-+ + hb_zip (langSys, hb_range (count))
-+ | hb_filter (active_langsys, hb_second)
-+ | hb_map (hb_first)
-+ | hb_filter ([=] (const Record& record) {return l->visitLangSys (); })
-+ | hb_apply (subset_record_array (l, &(out->langSys), this))
-+ ;
-+ }
-+
-+ return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB);
-+ }
-+
-+ bool sanitize (hb_sanitize_context_t *c,
-+ const Record_sanitize_closure_t * = nullptr) const
-+ {
-+ TRACE_SANITIZE (this);
-+ return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
-+ }
-+
-+ protected:
-+ Offset16To
-+ defaultLangSys; /* Offset to DefaultLangSys table--from
-+ * beginning of Script table--may be Null */
-+ RecordArrayOf
-+ langSys; /* Array of LangSysRecords--listed
-+ * alphabetically by LangSysTag */
-+ public:
-+ DEFINE_SIZE_ARRAY_SIZED (4, langSys);
-+};
-+struct RecordListOfScript : RecordListOf