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