texlive[65798] Build/source/libs: harfbuzz 7.0.0

commits+kakuto at tug.org commits+kakuto at tug.org
Sun Feb 12 05:02:24 CET 2023


Revision: 65798
          http://tug.org/svn/texlive?view=revision&revision=65798
Author:   kakuto
Date:     2023-02-12 05:02:23 +0100 (Sun, 12 Feb 2023)
Log Message:
-----------
harfbuzz 7.0.0

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/harfbuzz/ChangeLog
    trunk/Build/source/libs/harfbuzz/Makefile.am
    trunk/Build/source/libs/harfbuzz/Makefile.in
    trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
    trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
    trunk/Build/source/libs/harfbuzz/configure
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-tag.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-gvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-pool.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-priority-queue.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-repacker.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-sanitize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-serialize.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-accelerator.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff-common.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-cff2.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-repacker.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-unicode.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-utf.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/main.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/meson.build
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-buffer-serialize.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-map.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-ot-meta.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-set.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test-unicode-ranges.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/test.cc
    trunk/Build/source/libs/harfbuzz/include/Makefile.am
    trunk/Build/source/libs/harfbuzz/include/Makefile.in
    trunk/Build/source/libs/harfbuzz/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/colrv1-closure.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/sbix/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/sbix/sbix.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/svg/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/svg/svg.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/name/
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-builder.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-outline.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-outline.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint-extents.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint-extents.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.cc
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.h
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-paint.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-instancer-solver.cc

Removed Paths:
-------------
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
    trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/README	2023-02-12 04:02:23 UTC (rev 65798)
@@ -25,8 +25,8 @@
   http://sourceforge.net/projects/silgraphite/files/graphite2/
   (requires C++11)
 
-harfbuzz 6.0.0 - checked 18dec22
-  https://github.com/harfbuzz/harfbuzz/releases/tag/6.0.0
+harfbuzz 7.0.0 - checked 12feb23
+  https://github.com/harfbuzz/harfbuzz/releases/tag/7.0.0
 
 icu 70.1 - checked 16jan22
   https://github.com/unicode-org/icu/releases/

Modified: trunk/Build/source/libs/harfbuzz/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/ChangeLog	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/ChangeLog	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,3 +1,8 @@
+2023-02-12  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Import harfbuzz-7.0.0.
+	* version.ac, Makefile.am, include/Makefile.am: Adjusted.
+
 2022-12-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Import harfbuzz-6.0.0.

Modified: trunk/Build/source/libs/harfbuzz/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.am	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/Makefile.am	2023-02-12 04:02:23 UTC (rev 65798)
@@ -59,6 +59,7 @@
 	@HARFBUZZ_TREE@/src/hb-dispatch.hh \
 	@HARFBUZZ_TREE@/src/hb-draw.cc \
 	@HARFBUZZ_TREE@/src/hb-draw.hh \
+	@HARFBUZZ_TREE@/src/hb-face-builder.cc \
 	@HARFBUZZ_TREE@/src/hb-face.hh \
 	@HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh \
@@ -65,6 +66,7 @@
 	@HARFBUZZ_TREE@/src/hb-font.cc \
 	@HARFBUZZ_TREE@/src/hb-iter.hh \
 	@HARFBUZZ_TREE@/src/hb-kern.hh \
+	@HARFBUZZ_TREE@/src/hb-limits.hh \
 	@HARFBUZZ_TREE@/src/hb-map.hh \
 	@HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
@@ -85,8 +87,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-gasp-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-cbdt-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-colrv1-closure.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cmap-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-face.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-face.hh \
@@ -112,6 +112,12 @@
 	@HARFBUZZ_TREE@/src/hb-ot-tag.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-var-common.hh \
+	@HARFBUZZ_TREE@/src/hb-outline.cc \
+	@HARFBUZZ_TREE@/src/hb-outline.hh \
+	@HARFBUZZ_TREE@/src/hb-paint-extents.cc \
+	@HARFBUZZ_TREE@/src/hb-paint-extents.hh \
+	@HARFBUZZ_TREE@/src/hb-paint.cc \
+	@HARFBUZZ_TREE@/src/hb-paint.hh \
 	@HARFBUZZ_TREE@/src/hb-sanitize.hh \
 	@HARFBUZZ_TREE@/src/hb-serialize.hh \
 	@HARFBUZZ_TREE@/src/hb-set-digest.hh \
@@ -135,6 +141,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.cc \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.hh \
 	@HARFBUZZ_TREE@/src/hb-subset-input.hh \
+	@HARFBUZZ_TREE@/src/hb-subset-instancer-solver.cc \
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd.cc \
@@ -144,7 +151,8 @@
 	@HARFBUZZ_TREE@/src/hb-vector.hh \
 	@HARFBUZZ_TREE@/src/hb-utf.hh \
 	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-json.hh \
-	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text.hh \
+	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text-glyphs.hh \
+	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text-unicode.hh \
 	@HARFBUZZ_TREE@/src/hb-fallback-shape.cc \
 	@HARFBUZZ_TREE@/src/hb.hh
 
@@ -177,10 +185,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-layout-jstf-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-layout.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-color.cc \
-	@HARFBUZZ_TREE@/src/hb-ot-color-colr-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-cpal-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-sbix-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-svg-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-map.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-map.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-math.cc \
@@ -231,6 +235,12 @@
 	@HARFBUZZ_TREE@/src/hb-ot-vorg-table.hh
 ##
 libharfbuzz_a_SOURCES += \
+	@HARFBUZZ_TREE@/src/OT/Color/CBDT/CBDT.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/COLR/COLR.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/COLR/colrv1-closure.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/CPAL/CPAL.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/sbix/sbix.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/svg/svg.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/glyf.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/glyf-helpers.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/loca.hh \
@@ -247,6 +257,7 @@
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat1.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat2.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/RangeRecord.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GDEF/GDEF.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Common.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Sequence.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubstFormat1.hh \
@@ -301,6 +312,7 @@
 	@HARFBUZZ_TREE@/src/OT/Layout/GPOS/SinglePosFormat2.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GPOS/SinglePos.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GPOS/ValueFormat.hh \
+	@HARFBUZZ_TREE@/src/OT/name/name.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/types.hh \
 	@HARFBUZZ_TREE@/src/graph/graph.hh \
 	@HARFBUZZ_TREE@/src/graph/serialize.hh

Modified: trunk/Build/source/libs/harfbuzz/Makefile.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/Makefile.in	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/Makefile.in	2023-02-12 04:02:23 UTC (rev 65798)
@@ -125,6 +125,7 @@
 	@HARFBUZZ_TREE@/src/hb-buffer.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-common.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-draw.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-face-builder.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-face.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-font.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-map.$(OBJEXT) \
@@ -134,6 +135,9 @@
 	@HARFBUZZ_TREE@/src/hb-ot-face.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-name.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ot-tag.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-outline.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-paint-extents.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-paint.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-set.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-shape.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-shape-plan.$(OBJEXT) \
@@ -143,6 +147,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff-common.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-subset-cff1.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT) \
+	@HARFBUZZ_TREE@/src/hb-subset-instancer-solver.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-unicode.$(OBJEXT) \
 	@HARFBUZZ_TREE@/src/hb-fallback-shape.$(OBJEXT) \
@@ -204,6 +209,7 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face-builder.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po \
@@ -238,6 +244,9 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shaper-vowel-constraints.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-tag.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-var.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-outline.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint-extents.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-set.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape-plan.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape.Po \
@@ -247,6 +256,7 @@
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-instancer-solver.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 am__mv = mv -f
@@ -739,10 +749,12 @@
 	@HARFBUZZ_TREE@/src/hb-debug.hh \
 	@HARFBUZZ_TREE@/src/hb-dispatch.hh \
 	@HARFBUZZ_TREE@/src/hb-draw.cc @HARFBUZZ_TREE@/src/hb-draw.hh \
+	@HARFBUZZ_TREE@/src/hb-face-builder.cc \
 	@HARFBUZZ_TREE@/src/hb-face.hh @HARFBUZZ_TREE@/src/hb-face.cc \
 	@HARFBUZZ_TREE@/src/hb-font.hh @HARFBUZZ_TREE@/src/hb-font.cc \
 	@HARFBUZZ_TREE@/src/hb-iter.hh @HARFBUZZ_TREE@/src/hb-kern.hh \
-	@HARFBUZZ_TREE@/src/hb-map.hh @HARFBUZZ_TREE@/src/hb-map.cc \
+	@HARFBUZZ_TREE@/src/hb-limits.hh @HARFBUZZ_TREE@/src/hb-map.hh \
+	@HARFBUZZ_TREE@/src/hb-map.cc \
 	@HARFBUZZ_TREE@/src/hb-machinery.hh \
 	@HARFBUZZ_TREE@/src/hb-meta.hh \
 	@HARFBUZZ_TREE@/src/hb-ms-feature-ranges.hh \
@@ -760,8 +772,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-cff2-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-gasp-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-cbdt-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-colrv1-closure.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-cmap-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-face.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-face.hh \
@@ -787,6 +797,12 @@
 	@HARFBUZZ_TREE@/src/hb-ot-tag.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-tag-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-var-common.hh \
+	@HARFBUZZ_TREE@/src/hb-outline.cc \
+	@HARFBUZZ_TREE@/src/hb-outline.hh \
+	@HARFBUZZ_TREE@/src/hb-paint-extents.cc \
+	@HARFBUZZ_TREE@/src/hb-paint-extents.hh \
+	@HARFBUZZ_TREE@/src/hb-paint.cc \
+	@HARFBUZZ_TREE@/src/hb-paint.hh \
 	@HARFBUZZ_TREE@/src/hb-sanitize.hh \
 	@HARFBUZZ_TREE@/src/hb-serialize.hh \
 	@HARFBUZZ_TREE@/src/hb-set-digest.hh \
@@ -809,6 +825,7 @@
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.cc \
 	@HARFBUZZ_TREE@/src/hb-subset-cff2.hh \
 	@HARFBUZZ_TREE@/src/hb-subset-input.hh \
+	@HARFBUZZ_TREE@/src/hb-subset-instancer-solver.cc \
 	@HARFBUZZ_TREE@/src/hb-subset.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ucd.cc \
@@ -817,7 +834,8 @@
 	@HARFBUZZ_TREE@/src/hb-unicode-emoji-table.hh \
 	@HARFBUZZ_TREE@/src/hb-vector.hh @HARFBUZZ_TREE@/src/hb-utf.hh \
 	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-json.hh \
-	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text.hh \
+	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text-glyphs.hh \
+	@HARFBUZZ_TREE@/src/hb-buffer-deserialize-text-unicode.hh \
 	@HARFBUZZ_TREE@/src/hb-fallback-shape.cc \
 	@HARFBUZZ_TREE@/src/hb.hh @HARFBUZZ_TREE@/src/hb-aat-layout.cc \
 	@HARFBUZZ_TREE@/src/hb-aat-layout-common.hh \
@@ -846,10 +864,6 @@
 	@HARFBUZZ_TREE@/src/hb-ot-layout-jstf-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-layout.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-color.cc \
-	@HARFBUZZ_TREE@/src/hb-ot-color-colr-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-cpal-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-sbix-table.hh \
-	@HARFBUZZ_TREE@/src/hb-ot-color-svg-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-map.cc \
 	@HARFBUZZ_TREE@/src/hb-ot-map.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-math.cc \
@@ -898,6 +912,12 @@
 	@HARFBUZZ_TREE@/src/hb-ot-var-hvar-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-var-mvar-table.hh \
 	@HARFBUZZ_TREE@/src/hb-ot-vorg-table.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/CBDT/CBDT.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/COLR/COLR.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/COLR/colrv1-closure.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/CPAL/CPAL.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/sbix/sbix.hh \
+	@HARFBUZZ_TREE@/src/OT/Color/svg/svg.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/glyf.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/glyf-helpers.hh \
 	@HARFBUZZ_TREE@/src/OT/glyf/loca.hh \
@@ -914,6 +934,7 @@
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat1.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/CoverageFormat2.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/Common/RangeRecord.hh \
+	@HARFBUZZ_TREE@/src/OT/Layout/GDEF/GDEF.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Common.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/Sequence.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GSUB/SingleSubstFormat1.hh \
@@ -968,6 +989,7 @@
 	@HARFBUZZ_TREE@/src/OT/Layout/GPOS/SinglePosFormat2.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GPOS/SinglePos.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/GPOS/ValueFormat.hh \
+	@HARFBUZZ_TREE@/src/OT/name/name.hh \
 	@HARFBUZZ_TREE@/src/OT/Layout/types.hh \
 	@HARFBUZZ_TREE@/src/graph/graph.hh \
 	@HARFBUZZ_TREE@/src/graph/serialize.hh \
@@ -1075,6 +1097,9 @@
 @HARFBUZZ_TREE@/src/hb-draw.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-face-builder.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-face.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1102,6 +1127,15 @@
 @HARFBUZZ_TREE@/src/hb-ot-tag.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-outline.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-paint-extents.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-paint.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-set.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1129,6 +1163,9 @@
 @HARFBUZZ_TREE@/src/hb-subset-cff2.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at HARFBUZZ_TREE@/src/hb-subset-instancer-solver.$(OBJEXT):  \
+	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
+	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @HARFBUZZ_TREE@/src/hb-ucd.$(OBJEXT):  \
 	@HARFBUZZ_TREE@/src/$(am__dirstamp) \
 	@HARFBUZZ_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1243,6 +1280,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face-builder.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po at am__quote@ # am--include-marker
@@ -1277,6 +1315,9 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shaper-vowel-constraints.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-tag.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-var.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-outline.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint-extents.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-set.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape-plan.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape.Po at am__quote@ # am--include-marker
@@ -1286,6 +1327,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-instancer-solver.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po at am__quote@ # am--include-marker
 
@@ -1894,6 +1936,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face-builder.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po
@@ -1928,6 +1971,9 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shaper-vowel-constraints.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-tag.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-var.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-outline.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint-extents.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-set.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape-plan.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape.Po
@@ -1937,6 +1983,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-instancer-solver.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 	-rm -f Makefile
@@ -1996,6 +2043,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-buffer.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-draw.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face-builder.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-face.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-fallback-shape.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-font.Po
@@ -2030,6 +2078,9 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-shaper-vowel-constraints.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-tag.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ot-var.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-outline.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint-extents.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-paint.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-set.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape-plan.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-shape.Po
@@ -2039,6 +2090,7 @@
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff-common.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff1.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-cff2.Po
+	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-subset-instancer-solver.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-ucd.Po
 	-rm -f @HARFBUZZ_TREE@/src/$(DEPDIR)/hb-unicode.Po
 	-rm -f Makefile

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/ChangeLog	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,3 +1,8 @@
+2023-02-12  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	Imported harfbuzz-7.0.0 source tree from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/7.0.0/
+
 2022-12-18  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	Imported harfbuzz-6.0.0 source tree from:

Modified: trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/TLpatches/TL-Changes	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,5 +1,5 @@
-Changes applied to the harfbuzz-6.0.0/ tree as obtained from:
-	https://github.com/harfbuzz/harfbuzz/releases/download/6.0.0/
+Changes applied to the harfbuzz-7.0.0/ tree as obtained from:
+	https://github.com/harfbuzz/harfbuzz/releases/download/7.0.0/
 
 Removed:
 	COPYING

Modified: trunk/Build/source/libs/harfbuzz/configure
===================================================================
--- trunk/Build/source/libs/harfbuzz/configure	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/configure	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 6.0.0.
+# Generated by GNU Autoconf 2.71 for harfbuzz (TeX Live) 7.0.0.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -611,8 +611,8 @@
 # Identity of this package.
 PACKAGE_NAME='harfbuzz (TeX Live)'
 PACKAGE_TARNAME='harfbuzz--tex-live-'
-PACKAGE_VERSION='6.0.0'
-PACKAGE_STRING='harfbuzz (TeX Live) 6.0.0'
+PACKAGE_VERSION='7.0.0'
+PACKAGE_STRING='harfbuzz (TeX Live) 7.0.0'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1346,7 +1346,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures harfbuzz (TeX Live) 6.0.0 to adapt to many kinds of systems.
+\`configure' configures harfbuzz (TeX Live) 7.0.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1418,7 +1418,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 6.0.0:";;
+     short | recursive ) echo "Configuration of harfbuzz (TeX Live) 7.0.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-harfbuzz (TeX Live) configure 6.0.0
+harfbuzz (TeX Live) configure 7.0.0
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2064,7 +2064,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by harfbuzz (TeX Live) $as_me 6.0.0, which was
+It was created by harfbuzz (TeX Live) $as_me 7.0.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4823,7 +4823,7 @@
 
 # Define the identity of the package.
  PACKAGE='harfbuzz--tex-live-'
- VERSION='6.0.0'
+ VERSION='7.0.0'
 
 
 # Some tools Automake needs.
@@ -5033,10 +5033,10 @@
 
 
 
-HB_VERSION_MAJOR=6
+HB_VERSION_MAJOR=7
 HB_VERSION_MINOR=0
 HB_VERSION_MICRO=0
-HB_VERSION=6.0.0
+HB_VERSION=7.0.0
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -8817,7 +8817,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by harfbuzz (TeX Live) $as_me 6.0.0, which was
+This file was extended by harfbuzz (TeX Live) $as_me 7.0.0, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8885,7 +8885,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-harfbuzz (TeX Live) config.status 6.0.0
+harfbuzz (TeX Live) config.status 7.0.0
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/CMakeLists.txt	2023-02-12 04:02:23 UTC (rev 65798)
@@ -566,7 +566,7 @@
   # We need to account for the varying output directories
   # when we build using Visual Studio projects
   if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
-    set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
+    set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
   else ()
     set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
   endif ()
@@ -816,7 +816,7 @@
     make_pkgconfig_pc_file("harfbuzz-gobject")
     if (HB_HAVE_INTROSPECTION)
       if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
-        set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
+        set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
       else ()
         set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
       endif ()

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/ChangeLog	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,3 +1,11390 @@
+commit 8bdaeddfcd86aa66f560ff1ae1ae71b1e1723463
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 23:44:58 2023 +0200
+
+    7.0.0
+
+ NEWS                   | 130 +++++++++++++++++++++++++++++++++++++++++++++++++
+ configure.ac           |   2 +-
+ docs/harfbuzz-docs.xml |   1 +
+ meson.build            |   2 +-
+ src/hb-cairo.cc        |  18 +++----
+ src/hb-cairo.h         |   2 +-
+ src/hb-draw.cc         |   6 +--
+ src/hb-face.cc         |   2 +-
+ src/hb-font.cc         |  13 ++---
+ src/hb-font.h          |  16 +++---
+ src/hb-map.cc          |   8 +--
+ src/hb-ot-color.cc     |   4 +-
+ src/hb-ot-layout.cc    |   2 +-
+ src/hb-ot-name.h       |   2 +-
+ src/hb-paint.cc        |  46 ++++++++---------
+ src/hb-paint.h         |  72 +++++++++++++--------------
+ src/hb-set.cc          |   2 +-
+ src/hb-subset-input.cc |   2 +-
+ src/hb-version.h       |   4 +-
+ 19 files changed, 232 insertions(+), 102 deletions(-)
+
+commit df6324cbe7f1ebf43f243cbefe60902e0e0d6085
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 22:35:09 2023 +0200
+
+    [ci] Build with default wrap mode
+    
+    Forcing fallback forces checking the subproject even if the option is
+    disabled.
+
+ .ci/build-win32.sh | 2 +-
+ .ci/build-win64.sh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 5b82fa91c5b955ed5bea4b848e9afcda1f4a519b
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 22:22:48 2023 +0200
+
+    [meson] Update Glib subproject
+
+ subprojects/glib.wrap | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 31e099fd212491045b9743d5b3b4ed718f80902a
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 22:21:53 2023 +0200
+
+    [meson] Update Cairo subproject
+
+ subprojects/cairo.wrap | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8f0da5e5e6d6fb5b827ec090ece871bf13324c87
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 22:20:41 2023 +0200
+
+    [meson] Update FreeType subproject
+
+ subprojects/freetype2.wrap |  9 ++++-----
+ subprojects/zlib.wrap      | 13 -------------
+ 2 files changed, 4 insertions(+), 18 deletions(-)
+
+commit 59cd1b17a96e6a8024f4fb5c1de1c1c8c3896633
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 20:24:49 2023 +0200
+
+    [ci] Don’t build docs on macos-aat-fonts job
+    
+    It fails ninja test, but superfluous anyway.
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7188c5643a45c11d82a04589d03a970fdffe8c0a
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 20:02:34 2023 +0200
+
+    [doc] Enable gtkdoc-check
+    
+    Should catch the most blatant issues.
+
+ docs/meson.build | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 0ea8bbd91a5addd10d1c5e4c1f4098937840f1e8
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 20:01:06 2023 +0200
+
+    [doc] Use XSince for REPLACEME/EXPERIMENTAL
+    
+    To hide them from gtk-doc so that we can finally enable gtkdoc-check.
+
+ RELEASING.md              |  2 +-
+ src/hb-cairo.cc           | 18 ++++++------
+ src/hb-cairo.h            |  2 +-
+ src/hb-draw.cc            |  6 ++--
+ src/hb-face.cc            |  2 +-
+ src/hb-font.cc            | 10 +++----
+ src/hb-font.h             | 10 +++----
+ src/hb-map.cc             |  8 +++---
+ src/hb-ot-color.cc        |  4 +--
+ src/hb-ot-layout.cc       |  2 +-
+ src/hb-ot-name.h          |  2 +-
+ src/hb-paint.cc           | 46 +++++++++++++++---------------
+ src/hb-paint.h            | 72 +++++++++++++++++++++++------------------------
+ src/hb-set.cc             |  2 +-
+ src/hb-subset-input.cc    |  4 +--
+ src/hb-subset-repacker.cc |  2 +-
+ 16 files changed, 96 insertions(+), 96 deletions(-)
+
+commit 16dfd263b143e343973bfda478975457841f225d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 19:31:29 2023 +0200
+
+    [subset] Remove docs for unimplemented flags
+    
+    GTK-Doc does not like this.
+
+ src/hb-subset.h | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit 4d25941315b785f711562216241a674fbfa01509
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 19:25:52 2023 +0200
+
+    [doc] Fix hb_ot_name_[id|predefined]_t
+    
+    Shuffle the docs around, so that the enum values appear in documentation
+    as they now belong to hb_ot_name_predefined_t. The Since field will be
+    misleading now, though.
+
+ src/hb-ot-name.h | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+commit 13741e68f8db429e432677f12e227de6e014dec0
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Feb 11 19:17:37 2023 +0200
+
+    [doc] Minor
+
+ src/hb-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ab191d9dc7eb126759cd6224131db8df4b730b81
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 11 09:31:07 2023 -0700
+
+    [ot-font] Minor division rounding
+
+ src/hb-ot-font.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c6c1c6ddf12e9e4f7fd343f0641288d62432962f
+Merge: af1e605be 6ddd49019
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 11 09:20:51 2023 -0700
+
+    Merge pull request #4107 from harfbuzz/cubic-glyf
+    
+    [glyf] Support cubic curves
+
+commit 6ddd490191b11ae7ac02f8d69486c771e0803a00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 10 14:24:03 2023 -0700
+
+    [path-builder] Comment re cubic
+
+ src/OT/glyf/path-builder.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 91c2f098d09b36c25e4e849bf65483aa030c3f22
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 10 14:15:16 2023 -0700
+
+    [cubic-glyf] Add HB_NO_CUBIC_GLYF
+
+ src/OT/glyf/path-builder.hh | 4 ++++
+ src/hb-config.hh            | 1 +
+ 2 files changed, 5 insertions(+)
+
+commit af1e605be27afc79c293fdd0a45e6f6e2edd9054
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Feb 10 11:08:05 2023 -0800
+
+    [instancer] bug fix
+    
+    It's possible that length of all_points equals to 4 for non-empty
+    glyphs: a composite glyph which contains only one child glyph that is
+    empty.
+
+ src/OT/glyf/Glyph.hh                                     |   2 +-
+ test/subset/data/Makefile.am                             |   1 +
+ test/subset/data/Makefile.sources                        |   1 +
+ .../RobotoMono.default.retain-all-codepoint.wght=700.ttf | Bin 0 -> 1264 bytes
+ test/subset/data/fonts/RobotoMono.ttf                    | Bin 0 -> 1932 bytes
+ .../data/tests/instance_comp_glyph_empty_child.tests     |  11 +++++++++++
+ test/subset/meson.build                                  |   1 +
+ 7 files changed, 15 insertions(+), 1 deletion(-)
+
+commit 8302da86303f68b1c9308ce2984cca0d28f1716a
+Merge: 219e2f12f 737b15c5a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Feb 10 12:50:45 2023 -0700
+
+    Merge pull request #4097 from harfbuzz/embolden
+    
+    Embolden
+
+commit 219e2f12f0d0ce02ef06351faa1ccb14fd69258c
+Author: Jens Kutilek <webmail at kutilek.de>
+Date:   Fri Feb 10 17:23:31 2023 +0100
+
+    Clarify that those two test fonts are CC0-licensed
+
+ .../fonts/TestGVAR-Composite-0.ttf                    | Bin 3136 -> 3592 bytes
+ .../fonts/TestGVAR-Composite-Missing.ttf              | Bin 2984 -> 3440 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit b1680e914362000de04a494d7134efbabc5fb3bc
+Author: Pedro J. Estébanez <pedrojrulez at gmail.com>
+Date:   Fri Feb 10 14:14:43 2023 +0100
+
+    Use proper preprocessor checks for UWP
+
+ src/hb-blob.cc  | 6 +++---
+ src/hb-mutex.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 96d9e8624c410842ee3bf32bfc45f3240dc6d720
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 9 12:53:17 2023 -0700
+
+    [docs] Improve cluster-level docs
+
+ docs/usermanual-clusters.xml | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+commit 737b15c5a0251d1579bc4b6a41cb08bc8c66e275
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 8 17:45:59 2023 -0700
+
+    [embolden] Docs
+
+ src/hb-font.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 00a6f8945c5c8c4174619c0703b4edf8a96db47d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Feb 8 22:43:39 2023 +0200
+
+    [meson] Minor
+    
+    alias_target() is variadic function.
+
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1d9dafbfd5a59143a009403798beae1e1ad1753a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 22:19:45 2023 -0700
+
+    [glyf] Support cubic curves
+    
+    https://github.com/harfbuzz/boring-expansion-spec/issues/41
+
+ src/OT/glyf/SimpleGlyph.hh  |  2 +-
+ src/OT/glyf/path-builder.hh | 55 ++++++++++++++++++++++++++++++++++++---------
+ 2 files changed, 45 insertions(+), 12 deletions(-)
+
+commit 64fa5cd482d0be2e215998aa1c2a05b978133e7c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 15:50:36 2023 -0700
+
+    [GPOS] Fix assert fail introduced recently
+    
+    Was introduced in 8708b9e081192786c027bb7f5f23d76dbe5c19e8.
+    
+    If these lookups are recursed to from (Chain)Context out-of-order,
+    it was possible that last_base > buffer->idx, in which case we
+    were attaching marks to a base after them... and an assertion
+    was failing fortunately.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/6377756666757120
+
+ src/OT/Layout/GPOS/MarkBasePosFormat1.hh                  |   5 +++++
+ src/OT/Layout/GPOS/MarkLigPosFormat1.hh                   |   5 +++++
+ ...zz-testcase-minimized-hb-shape-fuzzer-6377756666757120 | Bin 0 -> 607 bytes
+ 3 files changed, 10 insertions(+)
+
+commit 840e1b6b84e8c421ab695f8fa99eae8cfc08e3e8
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Feb 7 13:49:19 2023 -0800
+
+    [instancer] bug fix
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3fd9311649e2e0e5e2bfbe27c082e3f2dbc797f5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 14:16:24 2023 -0700
+
+    [indic] Use a hb_swap()
+
+ src/hb-ot-shaper-indic.cc | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit be1c14ee0ad7702250f2a8b1969387d8018d4012
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 13:52:53 2023 -0700
+
+    [embolden] Adjust font_h_extents
+
+ src/hb-ft.cc      |  2 +-
+ src/hb-ot-font.cc | 13 ++++++++++---
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+commit b350122fb3af6d4eff9a2cf9c8fc3b7157601944
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 13:49:16 2023 -0700
+
+    [embolden] Fix glyph_extents in hb-ft
+
+ src/hb-ft.cc | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 61a1a88940f808f0f1184c6afdfbf025f21c1527
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 13:47:04 2023 -0700
+
+    [hb-ft] Fix --font-grade
+
+ src/hb-ft.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 560a65e456275e927d64f650235bdaa10049ee50
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 13:46:13 2023 -0700
+
+    [embolden] Update glyph_extents in hb-ot-font
+
+ src/hb-font.hh | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+commit aef002e0d92caeed512ae1f40904d02ebcb8d506
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 11:29:49 2023 -0700
+
+    [embolden] Add in-place option
+    
+    Adds --font-grade to hb-view and hb-shape.
+
+ src/hb-font.cc       | 44 ++++++++++++++++++++++++++++++--------------
+ src/hb-font.h        |  8 ++++++--
+ src/hb-font.hh       |  9 +++++----
+ src/hb-ft.cc         | 43 +++++++++++++++++++++++++++++++++++++------
+ src/hb-ot-font.cc    | 22 ++++++++++++++--------
+ src/hb-outline.cc    |  7 ++++---
+ src/hb-outline.hh    |  3 ++-
+ util/font-options.hh | 37 ++++++++++++++++++++++++++++++++-----
+ 8 files changed, 130 insertions(+), 43 deletions(-)
+
+commit 0b92c579844a666e679c1741beded1edd0860611
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Feb 7 10:20:46 2023 -0700
+
+    [meson] Add alias "libs" target
+    
+    Builds libharfbuzz and libharfbuzz-subset.
+
+ meson.build | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 434c98d4c672a95f380eed0b4c08b94f16426cf9
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Feb 7 10:06:13 2023 +0200
+
+    [meson] Add alias "lib" target
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4105
+
+ meson.build | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ce6440fceb0c0213dd4a39cc999efc67fe5dfb41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 16:12:03 2023 -0700
+
+    [buffer] Speed up merge_clusters_impl
+
+ src/hb-buffer.cc | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 1930760bc2c2b4185a772e38b6ecc174a95a47b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 15:54:09 2023 -0700
+
+    [buffer] Fix up previous commit
+    
+    https://github.com/harfbuzz/harfbuzz/commit/85be877925ddbf34f74a1229f3ca1716bb6170dc#commitcomment-99547060
+
+ src/hb-buffer.hh | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+commit 30b84faba7811bed1b7c9828afd719f20e0086da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 15:27:13 2023 -0700
+
+    [buffer] Optimize _infos_set_glyph_flags to avoid O(n^2) behavior
+    
+    https://github.com/harfbuzz/harfbuzz/commit/85be877925ddbf34f74a1229f3ca1716bb6170dc#commitcomment-99547060
+
+ src/hb-buffer.hh | 44 ++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 38 insertions(+), 6 deletions(-)
+
+commit 0b97ac39ac0bbe4d0027d1bb96668f456aaf634b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 15:17:09 2023 -0700
+
+    [buffer] Optimize _infos_find_min_cluster for monotone clusters
+
+ src/hb-buffer.hh | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+commit 8708b9e081192786c027bb7f5f23d76dbe5c19e8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 14:51:25 2023 -0700
+
+    [GPOS] Avoid O(n^2) behavior in mark-attachment
+    
+    Better implementation; avoids arbitrary limit on look-back.
+
+ src/OT/Layout/GPOS/MarkBasePosFormat1.hh | 76 ++++++++++++++++++++------------
+ src/OT/Layout/GPOS/MarkLigPosFormat1.hh  | 24 +++++++---
+ src/hb-ot-layout-gsubgpos.hh             |  5 ++-
+ 3 files changed, 69 insertions(+), 36 deletions(-)
+
+commit 661050b4659ee490dfe622821bc7fde7d1c40510
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 12:38:17 2023 -0700
+
+    Revert "[layout] Limit how far we skip when looking back"
+    
+    This reverts commit 85be877925ddbf34f74a1229f3ca1716bb6170dc.
+
+ src/hb-ot-layout-gsubgpos.hh | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit b29fbd16fa82b82bdf0dcb2f13a63f7dc23cf324
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 13:08:52 2023 -0700
+
+    [gsubgpos] Refactor skippy_iter.match()
+
+ src/hb-ot-layout-gsubgpos.hh | 94 +++++++++++++++++++++++++-------------------
+ 1 file changed, 54 insertions(+), 40 deletions(-)
+
+commit ef2a8f722fc0ec12f5a59d44d4d60d376907fd31
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Feb 6 12:04:16 2023 -0700
+
+    [VarComposite] Adjust for RESET_UNSPECIFIED_AXES semantic change
+    
+    https://github.com/harfbuzz/boring-expansion-spec/issues/81
+
+ src/OT/glyf/Glyph.hh | 2 +-
+ src/hb-array.hh      | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 474b99d12238d4c401c970874688a2567c017534
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Feb 4 10:16:11 2023 -0700
+
+    [test-paint] Fix build without FreeType
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4103
+
+ test/api/test-paint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d250fd979b54d26b7f432c809a153c3f90f020a9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 2 10:57:30 2023 -0700
+
+    [font] Docs
+
+ docs/harfbuzz-sections.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit cf39d316d86edb253873143596484baaeddce30e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 2 10:45:35 2023 -0700
+
+    [outline] Add FreeType authors copyrights
+
+ COPYING           | 4 ++--
+ src/hb-outline.cc | 8 +++++++-
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+commit 061f995845f347a481e4ff6f66fd66c6b50bfcfb
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Feb 2 08:15:02 2023 +0100
+
+    [font] Document synthetic boldness APIs
+
+ src/hb-font.cc | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+commit 2119eab69f5e8c5323fa23ab6c7dc26c2ab5aab3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 17:37:10 2023 -0700
+
+    [embolden] Adjust advance values
+
+ src/hb-ft.cc      | 16 +++++++++++++++-
+ src/hb-ot-font.cc | 29 +++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+), 1 deletion(-)
+
+commit b087266e511d21b5c63b02fa7eed45af4061e543
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 17:09:29 2023 -0700
+
+    [ot-font] Conditionalize emboldening
+
+ src/hb-ot-font.cc | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 36dcc9a4327f824ccaa5751412707731504e1023
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 17:06:15 2023 -0700
+
+    [ot-font] Fix emboldening CFF
+
+ src/hb-ot-font.cc | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 6b3fe8ac1beeb97194e5171b5fe3873236879fdd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 17:00:14 2023 -0700
+
+    [embolden] Semi-handle with negative scales
+
+ src/hb-font.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e39104ba1920a1bd2f6b4a56ace6cb66f7fcab6e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 16:56:56 2023 -0700
+
+    [font/util] Add emboldening API, --font-bold
+    
+    Needs documentation.
+
+ src/hb-font.cc       | 34 ++++++++++++++++++++++++++++++++--
+ src/hb-font.h        |  6 ++++++
+ src/hb-font.hh       | 12 ++++++++++++
+ src/hb-ft.cc         |  4 +---
+ src/hb-ot-font.cc    |  4 +---
+ util/font-options.hh | 25 ++++++++++++++++++++++++-
+ 6 files changed, 76 insertions(+), 9 deletions(-)
+
+commit 4247b78e31e00d02d3a6951888d5cae89d4e9060
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 16:26:07 2023 -0700
+
+    [outline] Comment
+
+ src/hb-outline.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ae522a1372c34bd013990de1b09d5cfa84433590
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 16:24:44 2023 -0700
+
+    [embolden] Rename to hb-outline
+
+ src/Makefile.sources                       |  2 +
+ src/harfbuzz-subset.cc                     |  1 +
+ src/harfbuzz.cc                            |  1 +
+ src/hb-ot-font.cc                          |  2 +-
+ src/{hb-draw-embolden.hh => hb-outline.cc} | 54 ++------------------
+ src/hb-outline.hh                          | 82 ++++++++++++++++++++++++++++++
+ src/meson.build                            |  2 +
+ 7 files changed, 94 insertions(+), 50 deletions(-)
+
+commit fda2f6f64e5033c824187b50fcdd07b1d65d1080
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 16:16:10 2023 -0700
+
+    [embolden] Shuffle under hb_outline_t
+
+ src/hb-draw-embolden.hh | 377 ++++++++++++++++++++++++------------------------
+ src/hb-ot-font.cc       |  10 +-
+ 2 files changed, 192 insertions(+), 195 deletions(-)
+
+commit 7774bccb48404f4b998d16b701463039bf0955da
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 16:12:10 2023 -0700
+
+    [embolden] Renames
+
+ src/hb-draw-embolden.hh | 134 ++++++++++++++++++++++++------------------------
+ 1 file changed, 66 insertions(+), 68 deletions(-)
+
+commit c06f95ebe18e7f6a093e28e8dcb322ca6e4d5a8d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 16:02:48 2023 -0700
+
+    [embolden] Move code
+
+ src/hb-draw-embolden.hh | 72 +++++++++++++++++++++++--------------------------
+ 1 file changed, 34 insertions(+), 38 deletions(-)
+
+commit 6b4a6fbedded342182cca5356707050696912753
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 15:59:37 2023 -0700
+
+    [embolden] Add orientation detection
+
+ src/hb-draw-embolden.hh | 24 ++++++++++++++++++++++--
+ 1 file changed, 22 insertions(+), 2 deletions(-)
+
+commit 1817f18085a7476759e794cfb0b4a627fc1487cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 15:49:05 2023 -0700
+
+    [embolden] Simplify recording-pen
+
+ src/hb-draw-embolden.hh | 109 +++++++++++++++++++++++-------------------------
+ 1 file changed, 53 insertions(+), 56 deletions(-)
+
+commit 70149885a78017475ebedd732ca5d3b0d4d8c595
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 14:27:45 2023 -0700
+
+    [font] Towards implementing emboldening
+
+ src/hb-draw-embolden.hh | 349 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ft.cc            |   6 +-
+ src/hb-ot-font.cc       |  20 ++-
+ src/hb-vector.hh        |   5 +-
+ 4 files changed, 373 insertions(+), 7 deletions(-)
+
+commit b5c68c1cf3a64b1be0708201bf433e7ae73c1f34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 2 15:50:53 2023 -0700
+
+    [codecov] Enable information patch mode
+
+ .codecov.yml | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit fda200658e3d3e2db466c9eb81be349df94c6704
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Feb 2 22:03:36 2023 +0000
+
+    [subset] fix missing compiled glyph cleanup when serialization succeeds.
+
+ src/OT/glyf/glyf.hh | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit 9bd3259335322338e2181935dc031fb9d7805e10
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Feb 2 13:36:23 2023 -0700
+
+    [cairo] Fix uninitialized value
+    
+    Ouch!
+
+ src/hb-cairo-utils.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 85be877925ddbf34f74a1229f3ca1716bb6170dc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Feb 1 20:00:43 2023 -0700
+
+    [layout] Limit how far we skip when looking back
+    
+    See comments.
+
+ src/hb-ot-layout-gsubgpos.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit d18fd3f7ebcd75e99c928c52fabfc51359000d26
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 31 16:28:49 2023 -0700
+
+    [layout] Comment
+
+ src/hb-ot-layout-gsubgpos.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 7a4bd97e4a3633429675a91df069b927ff3c580c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 31 14:59:39 2023 -0700
+
+    [layout] Build lookup accelerators lazily on-demand
+    
+    Reduces memory consumption for large multi-script fonts
+    drastically.
+
+ src/hb-ot-font.cc                   |  3 +-
+ src/hb-ot-layout-gpos-table.hh      |  7 ++--
+ src/hb-ot-layout-gsub-table.hh      |  7 ++--
+ src/hb-ot-layout-gsubgpos.hh        | 66 ++++++++++++++++++++++++-------------
+ src/hb-ot-layout.cc                 | 35 +++++++++++---------
+ src/hb-ot-shaper-arabic-fallback.hh | 15 +++++----
+ 6 files changed, 76 insertions(+), 57 deletions(-)
+
+commit 83353f13f45fefbf0ad1eb0d5388b2c8bf2f7702
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 31 14:32:14 2023 -0700
+
+    [layout] Reduce memory use slightly
+    
+    By using raw pointer instead of vector for subtable accelerator.
+    
+    To be used for more memory saving by making subtable accelerators
+    lazy-loaded by shape-plans for large fonts.
+
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 37 +++++++++++++++++++++----------------
+ src/hb-ot-layout.cc            | 15 +++++++++------
+ 4 files changed, 32 insertions(+), 24 deletions(-)
+
+commit 2b6d74b42e2320f2caf8a99dcf98ef692819d689
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jan 31 17:37:37 2023 +0000
+
+    [subset] for keep everything, don't drop any tables.
+
+ src/hb-subset-input.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 277003d553293c7af0b5b6d25be02fac0925e597
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 30 22:43:01 2023 -0700
+
+    [ft] Fit advance cache into short int
+
+ src/hb-ft.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit a924bbcfce67fed3da4ad6cf92178f7135a3359a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 30 14:13:33 2023 -0700
+
+    [atomic/cache] Add hb_atomic_short_t
+
+ src/hb-atomic.hh | 30 +++++++++++++++++++++++++-----
+ src/hb-cache.hh  |  4 +++-
+ 2 files changed, 28 insertions(+), 6 deletions(-)
+
+commit e7a71ea15b1df6feb3ca9811eb3abe721a63e21f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 30 11:21:08 2023 -0700
+
+    [font] Docs
+
+ src/hb-font.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit cb47dca74cbf6d147aac9cf3067f249555aa68b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 29 10:03:52 2023 -0700
+
+    [object] Handle mallocation error in set_user_data
+    
+    Should make bots happy.
+
+ src/hb-object.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 548bad221c6ba8a82fc3387923ca0382d183ab5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 29 10:10:48 2023 -0700
+
+    [user-data] Move methods to header file
+    
+    No idea why they were in hb-static.
+
+ src/hb-object.hh | 32 ++++++++++++++++++++++++++------
+ src/hb-static.cc | 32 --------------------------------
+ 2 files changed, 26 insertions(+), 38 deletions(-)
+
+commit 02f79f60f26d800d55194be174210bf47968812e
+Merge: 6622e04aa 784fe9ac6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 29 09:36:46 2023 -0700
+
+    Merge pull request #4092 from harfbuzz/more-cmap-cache
+    
+    [ot-font] Use the cmap cache more
+
+commit 784fe9ac67f9c0a203367222671d431a85c98cfa
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 29 09:26:52 2023 -0700
+
+    [cmap] Simplify caching
+
+ src/hb-ot-cmap-table.hh | 19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+commit a451aa5465ed80963f09c9f0290979608b1d675e
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 29 11:25:28 2023 -0500
+
+    Add back a null check
+    
+    This was accidentally dropped in the previous commit.
+
+ src/hb-ot-cmap-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 6622e04aa1b9d8b38e53cbe3e71c0b7066fd7208
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 29 09:06:52 2023 -0700
+
+    [solver] Fix unused-variable error
+    
+    https://github.com/harfbuzz/harfbuzz/commit/223abd72b9f48c951ce1e99d89328edbcff43515
+
+ src/hb-subset-instancer-solver.cc | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+commit 318aa107082cf4ab1c2fcc5f0bf2ead145216e1d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 29 09:17:17 2023 -0500
+
+    [ot-font] Use the cmap cache more
+    
+    Use the cmap cache for get_nominal_glyph and
+    get_variation_glyph as well. The first of these
+    is used a lot in pango.
+
+ src/hb-ot-cmap-table.hh | 21 +++++++++++++++------
+ src/hb-ot-font.cc       |  6 ++++--
+ 2 files changed, 19 insertions(+), 8 deletions(-)
+
+commit 5da829eaf534b78ee2fee7fbea86e8deb36bfef3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 22:18:53 2023 -0700
+
+    [font] Comments
+
+ src/hb-ot-font.cc | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 544dd9678c51458c9a19a951a873a0a259cdfe7a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 22:06:46 2023 -0700
+
+    [font] Fix unlikely
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c1d0daf5f12caf2b13f267941d761fd9c37d4fd6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 22:05:24 2023 -0700
+
+    [font] unlikely
+
+ src/hb-ot-font.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 30ee7a21e174e56a2f9caf750e666d16f002247a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 21:48:16 2023 -0700
+
+    [font] Typo
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 04056d44e2265a44fe3090ff7eb5a7a493d3221c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Jan 28 22:52:25 2023 -0500
+
+    [layout] Optimize more buffer message calls
+    
+    Continuation of da7b66c1f8bbf7147f8113.
+
+ src/hb-ot-layout.cc | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit f8a744d9d52d64f69778c2bfc2848ae2f2d1f63b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 13:37:43 2023 -0700
+
+    [ot-font] Add a cmap cache
+    
+    Speeds up Roboto shaping by 7%, for 1kb per face.
+
+ src/hb-ot-cmap-table.hh | 27 ++++++++++++++++++++++-----
+ src/hb-ot-font.cc       | 33 ++++++++++++++++++++++++++++++++-
+ 2 files changed, 54 insertions(+), 6 deletions(-)
+
+commit 1b53ed3c418298c760c42c612e2b6a2126237ee1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 13:22:52 2023 -0700
+
+    [cache] Remove empty fini()
+
+ src/hb-cache.hh   | 1 -
+ src/hb-ft.cc      | 2 --
+ src/hb-ot-font.cc | 3 ---
+ 3 files changed, 6 deletions(-)
+
+commit 115d572571fbd5fdb3bf677a0248dc8fdd29b31d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 28 13:22:08 2023 -0700
+
+    [cache] Add constructor
+
+ src/hb-cache.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ae96295d6737a9e6f925ffb8043118d3e051cdaa
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 28 22:12:33 2023 +0200
+
+    Delete commented out include
+
+ src/OT/Color/COLR/colrv1-closure.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 09b7fce857c4cde4f1a8e7925aa5c96052e5c050
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Jan 28 13:21:27 2023 -0500
+
+    Make includes relative
+
+ src/OT/Layout/GDEF/GDEF.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e25e4c9a52233056bfda866fbbe635dc490726fc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Jan 28 00:10:47 2023 -0500
+
+    Move GDEF table to src/OT/Layout/GDEF
+
+ src/Makefile.sources           |   1 +
+ src/OT/Layout/GDEF/GDEF.hh     | 918 +++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-gdef-table.hh | 886 +--------------------------------------
+ src/meson.build                |   1 +
+ 4 files changed, 921 insertions(+), 885 deletions(-)
+
+commit f89fa6dcfe8fc9ea53c9502f51024ec1dfac9a39
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Jan 27 23:54:34 2023 -0500
+
+    Move name table to src/OT/name
+
+ src/Makefile.sources    |   1 +
+ src/OT/name/name.hh     | 589 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-name-table.hh | 559 +--------------------------------------------
+ src/meson.build         |   1 +
+ 4 files changed, 592 insertions(+), 558 deletions(-)
+
+commit b8193357c1a0ce5013d074beaffda5cb6f6ae9c6
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Jan 28 00:00:30 2023 -0500
+
+    [OT::Color] Drop unused includes
+
+ src/OT/Color/COLR/COLR.hh           | 1 -
+ src/OT/Color/COLR/colrv1-closure.hh | 2 +-
+ src/OT/Color/sbix/sbix.hh           | 1 -
+ 3 files changed, 1 insertion(+), 3 deletions(-)
+
+commit da7b66c1f8bbf7147f8113922f81c02002af818c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 27 16:39:06 2023 -0700
+
+    [layout] Optimize buffer message calls
+    
+    Those aren't exactly free. They were showing up in profiles.
+
+ src/hb-ot-layout.cc | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 49d75ef331a372fc6545fbf0643ce053dbe39341
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 27 15:37:11 2023 -0700
+
+    [gsubgpos] Fix bug in cached ChainContextFormat2 application
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d2279a204f4452ac88a08eec07958fea7a70e549
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 27 12:32:55 2023 -0700
+
+    [gsubgpos] Avoid a copy into the vector
+
+ src/hb-ot-layout-gsubgpos.hh | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit 615595689c9b0e5ee8af3c689e78cbbca7d7c4be
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Jan 27 11:05:13 2023 -0800
+
+    [subset/COLR] add tests for copying varStore
+
+ test/subset/data/Makefile.am                            |   1 +
+ test/subset/data/Makefile.sources                       |   1 +
+ .../colrv1_copy_varstore/Foldit.default.41,42.ttf       | Bin 0 -> 43860 bytes
+ .../expected/colrv1_copy_varstore/Foldit.default.41.ttf | Bin 0 -> 43048 bytes
+ .../Foldit.default.retain-all-codepoint.ttf             | Bin 0 -> 44336 bytes
+ .../Foldit.drop-hints-retain-gids.41,42.ttf             | Bin 0 -> 43836 bytes
+ .../Foldit.drop-hints-retain-gids.41.ttf                | Bin 0 -> 43032 bytes
+ ...ldit.drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 0 -> 44300 bytes
+ .../colrv1_copy_varstore/Foldit.drop-hints.41,42.ttf    | Bin 0 -> 43820 bytes
+ .../colrv1_copy_varstore/Foldit.drop-hints.41.ttf       | Bin 0 -> 43016 bytes
+ .../Foldit.drop-hints.retain-all-codepoint.ttf          | Bin 0 -> 44300 bytes
+ .../colrv1_copy_varstore/Foldit.retain-gids.41,42.ttf   | Bin 0 -> 43876 bytes
+ .../colrv1_copy_varstore/Foldit.retain-gids.41.ttf      | Bin 0 -> 43064 bytes
+ .../Foldit.retain-gids.retain-all-codepoint.ttf         | Bin 0 -> 44336 bytes
+ test/subset/data/fonts/Foldit.ttf                       | Bin 0 -> 44340 bytes
+ test/subset/data/tests/colrv1_copy_varstore.tests       |  13 +++++++++++++
+ test/subset/meson.build                                 |   1 +
+ 17 files changed, 16 insertions(+)
+
+commit 0f33ea8c4fe39ee1b39a2ce87f07a7522a99808c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 27 11:26:57 2023 -0700
+
+    [subset/COLR] Copy VarStore
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4085
+
+ src/OT/Color/COLR/COLR.hh  |  2 +-
+ src/hb-ot-layout-common.hh | 26 ++++++++++++++++++++++++++
+ 2 files changed, 27 insertions(+), 1 deletion(-)
+
+commit 6c46da7710616b7f085da789ce4131d1169fce5d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Jan 27 10:34:50 2023 +0200
+
+    [test] Fix shell script quoting
+
+ test/shape/record-test.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c03c8548f48c08434957ec4de4f59c2af422fe0a
+Merge: 950c7ab3f 7a714d1a8
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Thu Jan 26 23:17:11 2023 -0500
+
+    Merge pull request #4084 from harfbuzz/cairo-check-funcs
+    
+    [meson] Enable all checked for Cairo functions for internal Cairo
+
+commit 7a714d1a8d28f626efeb7e1785acda104ffce29f
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Jan 27 03:12:36 2023 +0200
+
+    [meson] Enable all checked for Cairo functions for internal Cairo
+    
+    Similar to what we do with FreeType ones.
+
+ meson.build | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+commit 950c7ab3f0486b5baa0f602c7b12fc85cadd5428
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 15:26:05 2023 -0700
+
+    [gsubgpos] Use accelerator when recursing
+
+ src/hb-ot-layout-gpos-table.hh | 12 ++++++++++--
+ src/hb-ot-layout-gsub-table.hh | 12 ++++++++++--
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+commit e377888990239dc6d108777c1be61a99bade6e01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 13:26:47 2023 -0700
+
+    [ft-colr] Conditionalize on (unreleased0 FreeType 2.13.0
+    
+    That's the version that the color API is called stable, and
+    includes changes that we rely on.
+
+ src/hb-ft.cc          |  6 +++---
+ test/api/test-paint.c | 10 +++++-----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 281db89a688f253ea91c780ebe2c0c9494d234f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 13:05:12 2023 -0700
+
+    [cairo] Try to handle failure in set_user_data
+
+ src/hb-cairo.cc | 42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+commit 2fede3ef4a95184d831fae698c20d5616cccb89a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 12:23:12 2023 -0700
+
+    [layout] Fix a return_trace
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 05a2f31592711e02c359d5f1d9955052df9455e2
+Merge: aea37bfd3 e484d6b99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 12:56:02 2023 -0700
+
+    Merge pull request #4065 from harfbuzz/cairo-fix-foreground-color
+    
+    hb-cairo: Fix handling of foreground color
+
+commit e484d6b990171ba28e7ee8811f3a41d32b1d0418
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 12:55:25 2023 -0700
+
+    [cairo] Handle malloc failure
+
+ src/hb-cairo-utils.cc | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+commit 29a36010a1514c72c207fec8b5ab8361617a0078
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 17:26:33 2023 -0700
+
+    [cairo] Adapt to cairo foreground API change again
+
+ src/hb-cairo-utils.cc | 2 +-
+ src/hb-cairo.cc       | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 30d0d9c56c5f481b93141ca2742f6c992443ac46
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 24 15:43:17 2023 -0500
+
+    Adapt to cairo changes
+    
+    Adapt to the api in the cairo MR that will be used,
+    and make the code build with older cairo.
+
+ meson.build           | 1 +
+ src/hb-cairo-utils.cc | 4 +++-
+ src/hb-cairo.cc       | 4 +++-
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+commit 034d4d26f2dc31b73db72b94ca265ee45da44ddd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 16:22:26 2023 -0700
+
+    [hb-cairo] Minor simplify
+
+ src/hb-cairo-utils.cc | 4 +---
+ src/hb-cairo.cc       | 4 +---
+ 2 files changed, 2 insertions(+), 6 deletions(-)
+
+commit 26d34392e2dd2ea0e9908c1d53e1223487f021cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 16:21:13 2023 -0700
+
+    [hb-cairo] Fix condition
+
+ src/hb-cairo.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f9b3c79047aaedbffe4690b3bc6093c241ca5e90
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 23 18:09:09 2023 -0500
+
+    Update to different cairo API
+    
+    The cairo will likely end up begin a getter for
+    a cairo_pattern_t instead of a color.
+
+ src/hb-cairo-utils.cc | 11 ++++++++---
+ src/hb-cairo.cc       | 12 +++++++-----
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+commit 4afdbcbad55e5b5a4718c52398663cfd889a92ae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 15:53:26 2023 -0700
+
+    [hb-cairo] Don't call get_foreground_color unnecessarily
+    
+    That would invalidate cairo cache on foreground change, even
+    if the glyph doesn't need that.
+
+ src/hb-cairo-utils.cc | 42 +++++++++++++++++++++++++++---------------
+ src/hb-cairo.cc       | 23 +++++++++++++++--------
+ 2 files changed, 42 insertions(+), 23 deletions(-)
+
+commit c37ea4f93ed726c37739325e3f181b3973182e29
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 23 08:31:24 2023 -0500
+
+    hb-cairo: Fix handling of foreground color
+    
+    Use the new cairo_user_scaled_font_get_foreground_color
+    to obtain the foreground color, since the cr's source
+    can't be trusted.
+    
+    Requires https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/420
+
+ src/hb-cairo.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit aea37bfd370b880c553c1b5c80b7ddba59a28be6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 12:18:50 2023 -0700
+
+    Fix c++20 build
+
+ src/hb-subset-instancer-solver.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e1dc4920eeb220b5cb3d5f20446748e63b158623
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 12:11:35 2023 -0700
+
+    [iter] Allow hb_len() to fetch c.len as non-function
+
+ src/hb-iter.hh | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+commit 8d29be39b2fa777f70a4481629ac0c29fb1813fe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 26 11:41:58 2023 -0700
+
+    [gsubgpos] Minor drop an unnecessary hb_iter
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 06b9b3b5b66b0883d2274c6a6522378df6f4859c
+Merge: c1a5d2095 4a632dec7
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Thu Jan 26 14:15:52 2023 -0500
+
+    Merge pull request #4083 from harfbuzz/bump-cairo
+    
+    build: Bump to newer cairo
+
+commit 4a632dec788fbb90d61d196e563f342440448240
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Jan 26 13:19:50 2023 -0500
+
+    build: Bump to newer cairo
+
+ subprojects/cairo.wrap | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c1a5d20951803f8619094b98bac76d474963e264
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jan 25 21:52:05 2023 -0500
+
+    [doc] Add a missing comma
+
+ src/hb-paint.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8d80d1dd184c06a94d07afe5f06b1513e1ccae3a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jan 25 19:06:51 2023 -0500
+
+    [paint] Update expected test results
+    
+    These tests were affected by recent fixes.
+
+ test/api/results/test-106   | 6 +++---
+ test/api/results/testvf-106 | 6 +++---
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 570fe998c942e1042c66bbab2f848a9e05ad777a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 15:42:24 2023 -0700
+
+    [cairo] Another sweep_gradient fix
+    
+    k was -1 sometimes.
+    
+    Fixes the rest of https://roettsch.es/var_colrv1.html
+
+ src/hb-cairo-utils.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 13bfef9f01d2e11e5520c25d884ac51162d33cf2
+Author: Andres Salomon <dilinger at queued.net>
+Date:   Wed Jan 25 16:14:59 2023 -0500
+
+    [COPYING] Another update
+    
+    Adobe, Inc has copyright in src/hb-subset-cff*, test/api/test-subset*, and
+    misc other places.
+    
+    Ebrahim Byagowi has copyright as far back as 2015 in places like
+    src/hb-directwrite.cc.
+    
+    Google, Inc has newer copyright into 2022 in places like
+    src/graph/test-classdef-graph.cc. Also, listing every year was getting a bit
+    unwieldy, so just do 2010-2022.
+    
+    Igalia S.L. contributed the stuff in src/hb-ot-math*.
+    
+    The only references I could find to Martin Hosken & SIL were in
+    src/hb-graphite2*, and they were 2011, not 2009.
+    
+    Mozilla's got a bunch of 2015 code in src/hb-ot-shaper-*.
+    
+    Red Hat has copyright up to 2023 (eg, test/api/test-glyph-names.c).
+
+ COPYING | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit ea316b56a0ef1e84c29cd31b45b083bbe0120f83
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 15:31:29 2023 -0700
+
+    [cairo] Flip offsets when reversing
+    
+    Fixes many of the var_colrv1 first row tests.
+    
+    https://roettsch.es/var_colrv1.html
+
+ src/hb-cairo-utils.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 5b05e198cf047335ee9d421d60a0d57e6693424a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 15:24:14 2023 -0700
+
+    [cairo] More hb_malloc
+
+ src/hb-cairo-utils.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 57352b8bd4cc35ca6f2e3db7127c266e1a6a938d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 15:22:27 2023 -0700
+
+    [cairo] Use hb_malloc / hb_free
+
+ src/hb-cairo-utils.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit a9392c0cbb44111c2d5424257aafdebf2de8604c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:54:52 2023 -0700
+
+    [cairo] Use hb_swap()
+
+ src/hb-cairo-utils.cc | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit 5e868703788057696eb062fc30de0898058fdc41
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 25 12:27:16 2023 -0800
+
+    [instancer] compute head/maxp values using only non-empty glyphs
+
+ src/OT/glyf/Glyph.hh                                     |  14 +++++++++++++-
+ ...fault.retain-all-codepoint.wght=100,ELGR=1,ELSH=2.ttf | Bin 0 -> 2244 bytes
+ test/subset/data/tests/instance_no_double_free.tests     |   1 +
+ 3 files changed, 14 insertions(+), 1 deletion(-)
+
+commit d15551c6f394e8a7732f81fd51b8a0304e8e050c
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 25 11:01:08 2023 -0800
+
+    [instancer] update head table flagbit: allXMinIsLsb
+
+ src/OT/glyf/Glyph.hh        | 3 +++
+ src/OT/glyf/glyf-helpers.hh | 7 +++++++
+ src/hb-ot-head-table.hh     | 2 ++
+ src/hb-subset-plan.hh       | 4 +++-
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+commit 2c49eba044be55d81470ffaa9f854734c607e6e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:52:39 2023 -0700
+
+    [cairo] Indent
+
+ src/hb-cairo-utils.cc | 398 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 199 insertions(+), 199 deletions(-)
+
+commit 2accbdc0b6cbee4b6d9f581d8a890601881506fb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:40:04 2023 -0700
+
+    [paint] Minor skew
+
+ src/hb-paint.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a4420479a8f2d4d9b11039f5b7862f7f5f684db1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:37:10 2023 -0700
+
+    Revert "[VarComposite] Fix skew"
+    
+    This reverts commit 8cf7076309da014e8e2af033b1c636785ae407cd.
+
+ src/OT/glyf/VarCompositeGlyph.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 8cf7076309da014e8e2af033b1c636785ae407cd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:35:35 2023 -0700
+
+    [VarComposite] Fix skew
+
+ src/OT/glyf/VarCompositeGlyph.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 626f8e4de3060376d12c77ac4967fd6fb908169a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:33:46 2023 -0700
+
+    [paint] Fix skew to match Chrome
+
+ src/hb-paint.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit b44ff062e1dcddb51c13d3df9e66b31339d7e4b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:16:46 2023 -0700
+
+    [deserialize] Some more
+
+ src/hb-buffer-deserialize-text-glyphs.hh  | 9 ++++++++-
+ src/hb-buffer-deserialize-text-glyphs.rl  | 9 ++++++++-
+ src/hb-buffer-deserialize-text-unicode.hh | 9 ++++++++-
+ src/hb-buffer-deserialize-text-unicode.rl | 9 ++++++++-
+ src/test-buffer-serialize.cc              | 2 +-
+ 5 files changed, 33 insertions(+), 5 deletions(-)
+
+commit 57ff696430bf28072aa9b532250ea556f04d40e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:09:22 2023 -0700
+
+    [deserialize] One more fix
+
+ src/hb-buffer-deserialize-text-unicode.hh | 128 +++++++++++++++++-------------
+ src/hb-buffer-deserialize-text-unicode.rl |   4 +-
+ 2 files changed, 77 insertions(+), 55 deletions(-)
+
+commit e973050986b298458ef95c77356b2cdfdbb0c227
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 14:07:01 2023 -0700
+
+    [hb-buffer-deserialize] Fixups
+
+ src/hb-buffer-deserialize-text-glyphs.hh  | 689 +++++++++++++++++-------------
+ src/hb-buffer-deserialize-text-glyphs.rl  |  20 +-
+ src/hb-buffer-deserialize-text-unicode.hh |  27 +-
+ src/hb-buffer-deserialize-text-unicode.rl |  19 +-
+ src/hb-buffer-serialize.cc                |   6 +-
+ src/test-buffer-serialize.cc              |  27 +-
+ 6 files changed, 480 insertions(+), 308 deletions(-)
+
+commit a1101f09ca896610cdb9361e3f924da74e9d043d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 13:10:57 2023 -0700
+
+    [test-buffer-serialize] Handle too-small out buffer
+    
+    Need to handle too-small in buffer still.
+
+ src/test-buffer-serialize.cc | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+commit 39d50008f85d087c4ccb09b4954416c39c29cf1a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 12:53:50 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4e2267b729e6f97f4697d5332d8f6b6e601cb516
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 12:51:53 2023 -0700
+
+    [hb-info] Add --get-meta
+
+ util/hb-info.cc | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+commit 42ed6abb6a9ee832025d29c96e77e5fcc10cc2fd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 12:47:16 2023 -0700
+
+    [hb-info] Add --list-meta
+
+ util/hb-info.cc | 37 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+commit 2fec4f1c3db4e3ab6f3cc6a7a6bff81b756614f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 12:09:12 2023 -0700
+
+    [subset] Finish out hb-subset-instancer-solver.cc
+
+ src/hb-subset-instancer-solver.cc | 100 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 83 insertions(+), 17 deletions(-)
+
+commit 90a98dd62a3b8e9eb416b6777f36951c7f5a56a4
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 25 10:06:23 2023 -0800
+
+    [instancer] fix potential memory leak for compiled glyph bytes
+    
+    Also calculate max_offsets after glyph bytes are compiled, cause byte
+    length of a glyph might change after compile
+
+ src/OT/glyf/SubsetGlyph.hh | 10 +-----
+ src/OT/glyf/glyf.hh        | 81 ++++++++++++++++++++++++++++------------------
+ 2 files changed, 51 insertions(+), 40 deletions(-)
+
+commit 223abd72b9f48c951ce1e99d89328edbcff43515
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 11:36:47 2023 -0700
+
+    [subset] Add unfinished port of fonttools instancer solver
+
+ src/Makefile.sources              |   1 +
+ src/harfbuzz-subset.cc            |   1 +
+ src/hb-subset-instancer-solver.cc | 405 ++++++++++++++++++++++++++++++++++++++
+ src/meson.build                   |   1 +
+ 4 files changed, 408 insertions(+)
+
+commit 167443e9fc4f25b661ba7f17e7ea39691839297a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 10:32:01 2023 -0700
+
+    [hb-info] Respect HB_CHAFA=0
+
+ util/hb-info.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 87df84c386d2c03e8df75507b680b02044ee8cdd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 10:20:48 2023 -0700
+
+    [hb-info] Fix copyright header
+
+ util/hb-info.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 0bbc9d5256b3ba0f350b0d5136d2253113723c8b
+Author: Andres Salomon <dilinger at queued.net>
+Date:   Wed Jan 25 00:44:38 2023 -0500
+
+    [fonts] move OFL-1.1 license to a higher directory
+    
+    There's a bunch of font directories inside of test/ for which the vast
+    majority of fonts are licensed under the SIL open font license. We currently
+    have a COPYING file in test/shape/data/in-house/COPYING that says that most
+    of the fonts are OFL-1.1, but that doesn't apply to the fonts in, say,
+    test/api/fonts/ or test/fuzzing/fonts/. Since there are so many OFL-1.1
+    fonts all over test, let's move the COPYING file to the top-level test/
+    directory.
+
+ test/{shape/data/in-house => }/COPYING | 0
+ test/Makefile.am                       | 2 +-
+ test/shape/data/in-house/Makefile.am   | 1 -
+ 3 files changed, 1 insertion(+), 2 deletions(-)
+
+commit 44a9c4bf596ce5da51ab3844de6a685aa5e9e211
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 25 09:58:29 2023 -0700
+
+    [COPYING] Update
+
+ COPYING | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit c622c6b883f514982888a8a40be8223f672c21da
+Author: Andres Salomon <dilinger at queued.net>
+Date:   Tue Jan 24 23:52:10 2023 -0500
+
+    [font] update the license url for TestGVAREight.ttf
+    
+    The url in the exif data incorrectly links to a proprietary license. However,
+    permission was granted for distribution under Apache-2 as part of another project,
+    so link to that project's license instead.
+    
+    fixes #4062
+
+ test/api/fonts/TestGVAREight.ttf                      | Bin 4692 -> 4680 bytes
+ .../data/text-rendering-tests/fonts/TestGVAREight.ttf | Bin 4692 -> 4680 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+commit eb0a025e491a6e2c600836b0a440cd782048b025
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 24 20:40:32 2023 -0500
+
+    Add a test for glyph names
+    
+    This verifies that hb_font_get_glyph_name
+    returns false for nonexisting glyphs.
+
+ test/api/Makefile.am        |   1 +
+ test/api/meson.build        |   1 +
+ test/api/test-glyph-names.c | 112 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 114 insertions(+)
+
+commit 1b143b0f0c1f0fbd1675f077d03c997a6b72b613
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 18:34:04 2023 -0700
+
+    [font] Docs
+
+ src/hb-font.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 64ed03c9be0ddb0cba2674e22e8f377090ec5124
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 18:30:49 2023 -0700
+
+    [cff1] Return no name for out-of-range glyph IDs
+    
+    Was returning .notdef before.
+
+ src/hb-ot-cff1-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c89aebc40b2c29ad6bcae8e5fff7189f70b35d55
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 24 20:24:27 2023 -0500
+
+    hb-font: Document length limit for glyph names
+    
+    This is useful information for users of the
+    hb_font_get_glyph_name() API.
+
+ src/hb-font.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit dd64266ea444baa4507ce29d88f63d81132d9577
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 24 19:26:20 2023 -0500
+
+    Add a test for glyph extents
+    
+    This verifies a recent fix for COLRv1 returning
+    0,0,-1,1 for extents of non-painting glyphs.
+
+ test/api/Makefile.am       |   1 +
+ test/api/fonts/adwaita.ttf | Bin 0 -> 1332 bytes
+ test/api/meson.build       |   1 +
+ test/api/test-extents.c    | 104 +++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 106 insertions(+)
+
+commit 73e6f6cc88f6656e6061067fbd4170073c068975
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 24 16:14:11 2023 -0800
+
+    [instancer] enable the missing test
+
+ test/subset/data/Makefile.am      | 1 +
+ test/subset/data/Makefile.sources | 1 +
+ test/subset/meson.build           | 1 +
+ 3 files changed, 3 insertions(+)
+
+commit 27f72f0deb12ac99868da28d77c8b60f37d8d893
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 24 16:08:32 2023 -0800
+
+    [instancer] avoid double free for compiled glyph bytes
+    
+    also increase the HB_GLYF_MAX_POINTS limit to 20000 cause the test file has a
+    .notdef glyph which is a composite glyph and has 10176 points after
+    get_points() call
+
+ src/OT/glyf/glyf.hh                                     |   4 +++-
+ src/hb-limits.hh                                        |   2 +-
+ test/subset/data/Makefile.am                            |   1 +
+ test/subset/data/Makefile.sources                       |   1 +
+ ...line.retain-all-codepoint.wght=100,ELGR=1,ELSH=2.ttf | Bin 0 -> 2696 bytes
+ test/subset/data/fonts/Handjet.ttf                      | Bin 0 -> 58944 bytes
+ test/subset/data/tests/instance_no_double_free.tests    |  11 +++++++++++
+ test/subset/meson.build                                 |   1 +
+ 8 files changed, 18 insertions(+), 2 deletions(-)
+
+commit ac969fffa287dc67d3e3c78cbb28a34b48bafa05
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 24 19:06:15 2023 -0500
+
+    Update meson summary
+    
+    Include builtin font callbacks and Cairo integration
+    in the configuration summary.
+
+ meson.build | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 192361cb4dd6fa522a6871c6cbb11151bbc8e1b1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 17:05:38 2023 -0700
+
+    [hb-info] Show color swatch only if printing to terminal
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 817ec182eb8bcd78de06947602e189aa09308660
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 17:02:08 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 66ddeb0737df78a73c91f5cd32239ca2cfa435c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 17:01:01 2023 -0700
+
+    [hb-info] Change Chafa repeat to 16
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7a29ded1691ba0f3bfcac74045f0c14c6e53b138
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 16:59:44 2023 -0700
+
+    [hb-info] Render colors in --list-palette
+    
+    Uses chafa if available
+
+ util/hb-info.cc  | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ util/meson.build |  2 +-
+ 2 files changed, 91 insertions(+), 2 deletions(-)
+
+commit b684c6edd4b024f0c3b7d237dd0c9a1308c28c4b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 15:44:22 2023 -0700
+
+    [hb-cairo] Add hb_cairo_context_t
+
+ src/hb-cairo-utils.cc | 16 +++++++++----
+ src/hb-cairo-utils.hh | 15 ++++++++----
+ src/hb-cairo.cc       | 63 ++++++++++++++++++++++++++++++---------------------
+ 3 files changed, 60 insertions(+), 34 deletions(-)
+
+commit 279f13c1870148c0b649d8c435b58d4edf2bade2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:50:59 2023 -0700
+
+    [hb-shape] Write trace output to stderr
+
+ util/shape-output.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 161d8f9d26ff2725a9965b2b36d2f6045373973d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:48:10 2023 -0700
+
+    [util] Rename a variable
+
+ util/shape-options.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 68a790261c75e35466952b231e4d2b9f3979cc6e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:44:32 2023 -0700
+
+    [util] If --glyphs doesn't have positions, use glyph advances
+    
+    Such that eg --glyphs=10 works.
+
+ util/shape-options.hh | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+commit 91a174f151f20ede983eb879fc62631f83919098
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:27:35 2023 -0700
+
+    [hb-view] Hide --annotate and make it alias for --show-extents
+
+ util/helper-cairo.hh |  2 +-
+ util/view-cairo.hh   | 13 ++++---------
+ util/view-options.hh | 10 ++--------
+ 3 files changed, 7 insertions(+), 18 deletions(-)
+
+commit 8cfb0ed07289dc8982003e53277f064b65a7a1eb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:24:31 2023 -0700
+
+    [hb-view] --annotate enables --show-extents
+
+ util/view-options.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 20fcf5c5b8c2c068dc4956b3100d4d9b150c2a41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:22:55 2023 -0700
+
+    [hb-view] Add --show-extents
+
+ util/view-cairo.hh   | 25 ++++++++++++++++++++++++-
+ util/view-options.hh |  2 ++
+ 2 files changed, 26 insertions(+), 1 deletion(-)
+
+commit 72e13fff6537febcd4dd316954b52a2a0d3cf1a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:05:38 2023 -0700
+
+    [COLRv1] Handle void extents
+
+ src/OT/Color/COLR/COLR.hh | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+commit 20318feddf71e5d275bb48ebee12829f2e113f70
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 24 11:04:10 2023 -0700
+
+    [COLRv1] Don't return extents if glyph has no paint
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4068
+
+ src/OT/Color/COLR/COLR.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 32afdcdb46dbb9e54272a142f4d6fa742ca724f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 21:10:11 2023 -0700
+
+    [hb-buffer-deserialize-text-unicode] Relax parsing
+
+ src/hb-buffer-deserialize-text-unicode.hh | 88 ++++++++++++++++++-------------
+ src/hb-buffer-deserialize-text-unicode.rl |  2 +-
+ 2 files changed, 53 insertions(+), 37 deletions(-)
+
+commit 328ee9b4ad2fcdb5f78db0dfb6a9c168b1c9b918
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 21:06:27 2023 -0700
+
+    [hb-buffer-deserialize-text-unicodes] Rename
+
+ src/Makefile.sources                               |  4 +-
+ ...es.hh => hb-buffer-deserialize-text-unicode.hh} | 78 +++++++++++-----------
+ ...es.rl => hb-buffer-deserialize-text-unicode.rl} | 18 ++---
+ src/hb-buffer-serialize.cc                         |  8 +--
+ src/meson.build                                    |  4 +-
+ 5 files changed, 56 insertions(+), 56 deletions(-)
+
+commit bc596b8ccae15502f641cc88ddf5fa52e3c6473d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 21:03:59 2023 -0700
+
+    [buffer-deserialize-text-unicode] Simplify
+
+ src/hb-buffer-deserialize-text-unicodes.hh | 21 ++++++++++-----------
+ src/hb-buffer-deserialize-text-unicodes.rl |  3 +--
+ 2 files changed, 11 insertions(+), 13 deletions(-)
+
+commit 649973a316ef4616b26210a553727a3cdd33ed98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 21:02:14 2023 -0700
+
+    Fix build
+
+ src/hb-buffer-deserialize-text-glyphs.hh   | 570 ++++++++++++++++++++
+ src/hb-buffer-deserialize-text-unicodes.hh | 275 ++++++++++
+ src/hb-buffer-deserialize-text.hh          | 801 -----------------------------
+ 3 files changed, 845 insertions(+), 801 deletions(-)
+
+commit f798cf225ec4dab7fa4683224e26f3df08c59189
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 20:57:30 2023 -0700
+
+    [util] Don't require final ']' in --glyphs
+
+ util/shape-options.hh | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+commit 4268283e5463f72cc93a8c66f6b0537b991017a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 20:53:17 2023 -0700
+
+    [buffer-deserialize-text] Accept initial comma
+
+ src/hb-buffer-deserialize-json.hh          | 10 ++++------
+ src/hb-buffer-deserialize-json.rl          |  2 --
+ src/hb-buffer-deserialize-text-glyphs.rl   |  4 +++-
+ src/hb-buffer-deserialize-text-unicodes.rl |  4 +++-
+ 4 files changed, 10 insertions(+), 10 deletions(-)
+
+commit 2c29b81e7f36cf56e92f5b5eb406cc46e6394178
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 20:49:19 2023 -0700
+
+    [buffer-deserialize-text] Separate glyphs / unicodes machines
+
+ src/Makefile.sources                               |   6 +-
+ ...ext.rl => hb-buffer-deserialize-text-glyphs.rl} |  31 ++----
+ src/hb-buffer-deserialize-text-unicodes.rl         | 108 +++++++++++++++++++++
+ src/hb-buffer-serialize.cc                         |  15 +--
+ src/meson.build                                    |   6 +-
+ 5 files changed, 130 insertions(+), 36 deletions(-)
+
+commit d0355eb4bd778adae86d9e0e3c17ceea29a115bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 20:37:53 2023 -0700
+
+    [buffer-deserialize] Parse whole items at a time
+    
+    Previous logic would fail if char buffer was partial.
+
+ src/hb-buffer-deserialize-json.hh | 362 +++++++++++------------
+ src/hb-buffer-deserialize-json.rl |   2 +-
+ src/hb-buffer-deserialize-text.hh | 586 +++++++++++++++-----------------------
+ src/hb-buffer-deserialize-text.rl |   6 +-
+ 4 files changed, 420 insertions(+), 536 deletions(-)
+
+commit f65b04c17c45587f4500c8af52418b4f0ca39886
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 23 21:57:05 2023 -0500
+
+    Tweak wording
+
+ src/hb-paint.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 7e01976bcc573a1cdd40649be3e2d8d68ca0af01
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 23 20:44:22 2023 -0500
+
+    [hb-paint] Add some details to the docs
+
+ src/hb-paint.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit e4fff64ce31902674a5b8c667c6a7b61e5429381
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jan 24 00:52:26 2023 +0000
+
+    [repacker] check duplicate() for success.
+    
+    Fixes fuzzer testcase https://oss-fuzz.com/testcase-detail/5475787333828608.
+
+ src/graph/graph.hh                                     |   9 ++++++++-
+ ...tcase-minimized-hb-repacker-fuzzer-5475787333828608 | Bin 0 -> 127193 bytes
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+commit 6b72a4ddb05c7226d58d0f156db13153dec4a0e8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 18:36:04 2023 -0700
+
+    Revert "[sanitize] Simplify(?) check_range"
+    
+    This reverts commit af0b1ef8a72d4f6b778dbba3606ebe7df39d5288.
+
+ src/hb-sanitize.hh | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+commit 00cf322e237eaf81086130e989b8bf88402b959e
+Merge: af0b1ef8a 699485b34
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 16:06:26 2023 -0700
+
+    Merge pull request #4046 from harfbuzz/hb-features-docs
+    
+    [doc] Try to fix generating hb-features docs
+
+commit 699485b349030b1b8fdbb742758718b88bee1212
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 24 00:07:45 2023 +0200
+
+    [meson] Further simplify generating hb-features.h
+
+ src/meson.build | 38 +++++++++++++++++---------------------
+ 1 file changed, 17 insertions(+), 21 deletions(-)
+
+commit 2486d6d22fcbdeb2ec89bb33265665e60dc8461a
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 23 23:57:16 2023 +0200
+
+    [meson] Reduce repetitions
+
+ src/meson.build | 46 +++++++++++++++++++++-------------------------
+ 1 file changed, 21 insertions(+), 25 deletions(-)
+
+commit 12f2ecbddb65328a6e3312921ccb6946a76a665e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 23 23:41:11 2023 +0200
+
+    [doc] Generate hb-supported-features.h
+    
+    See inline comment.
+
+ docs/meson.build |  1 +
+ src/meson.build  | 19 +++++++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+commit 0bbd3360eeb00fbbb9544524a330e405450f44e5
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 19 20:11:35 2023 +0200
+
+    [doc] Try to fix generating hb-features docs
+    
+    Move it to a separate section, since hb-common says include hb.h, while
+    we want to include hb-features.h here.
+    
+    This still does not fix generating documentation of undefined macros
+    (e.g. HB_HAS_GDI since we build docs on Linux).
+
+ docs/harfbuzz-docs.xml     |  1 +
+ docs/harfbuzz-sections.txt | 24 ++++++++++++++----------
+ src/hb-features.h.in       |  8 ++++++++
+ 3 files changed, 23 insertions(+), 10 deletions(-)
+
+commit af0b1ef8a72d4f6b778dbba3606ebe7df39d5288
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 14:31:10 2023 -0700
+
+    [sanitize] Simplify(?) check_range
+
+ src/hb-sanitize.hh | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+commit fe94c760e1cc9a5f3824c48accd4d1cfd86ebcb0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 23 14:05:28 2023 -0700
+
+    [algs] Build fix for clang and __builtin_mul_overflow
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4066
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1cf61f3053e2c0a5c4df3623ac08f68834ccf7b4
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 23 13:43:35 2023 +0200
+
+    [meson] Fix build with -Dgobject=disabled
+
+ src/meson.build  | 14 ++++++++------
+ util/meson.build |  2 +-
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+commit 2b87af808bb55c0635b16ecc39331b2e6ab7ae6b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 17:37:51 2023 -0700
+
+    [hb-info] Typo
+
+ util/hb-info.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fe22afe7f9ba4440ddb19dc2b262358555374f07
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 16:47:50 2023 -0700
+
+    [hb-info] Simplify
+
+ util/hb-info.cc | 129 ++++++++++++++++++++++++++------------------------------
+ 1 file changed, 59 insertions(+), 70 deletions(-)
+
+commit eba5762919ab02f5dd9b2b9dd319d106ddaf9de9
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 23 01:10:56 2023 +0200
+
+    Another try
+
+ util/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 37ab12a372a74c25b34cae909ac89c79aef8c376
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 23 01:02:51 2023 +0200
+
+    [util] Try to fix hb-info build
+
+ util/meson.build | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5880ab06030dd7e3f77711319480cd908ca19195
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 16:20:23 2023 -0700
+
+    [hb-info] More build fix try
+
+ util/Makefile.am | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+commit d76ef46d0a25ee8d0093afde3424dc9589bcc6d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 16:17:39 2023 -0700
+
+    Try to fix autotools build
+
+ util/Makefile.am | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 6e58598520069ab144f0705c6960fc3109858b5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 15:22:30 2023 -0700
+
+    [hb-info] Subfamily
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4142a460af34cdbca705b5a2309dda03dcd2deb3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 15:11:50 2023 -0700
+
+    [hb-info] Add --list-baselines
+
+ util/hb-info.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 67 insertions(+), 1 deletion(-)
+
+commit 9c62022dedfecf5bc423ff142a8181d6b829595b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 15:02:21 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit 0b7d3952bade88c066fbdde78f461613c89a1eea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 15:00:10 2023 -0700
+
+    [hb-info] Add --list-style
+
+ util/hb-info.cc | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+commit 090a6d0dde90bc1ee393e70f7064e13f8fea86fe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:56:25 2023 -0700
+
+    [hb-info] Add --get-style
+
+ util/hb-info.cc | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 5b291d49e80f4e2b79e91e046f4858a45eb2f0ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:51:17 2023 -0700
+
+    [hb-info] Rename style to subfamily
+
+ util/hb-info.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit c300bf00f0c1297516658917f1e001be8259c569
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:46:20 2023 -0700
+
+    [hb-info] Move include around
+
+ util/hb-info.cc | 4 ++++
+ util/options.hh | 3 ---
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit b839f53cdecee5b0c7fed1bd543753ece9e10e86
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:39:26 2023 -0700
+
+    [hb-info] Write fallback metrics in --list-metrics
+
+ util/hb-info.cc | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+commit 7ba3d0c419b61ddb07b9f38fb5fa0bb36ecb4fd6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:27:31 2023 -0700
+
+    [hb-info] Add --list-metrics
+    
+    Requires hb-gobject
+
+ util/hb-info.cc | 39 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+commit 4ec3d2e32ac0ec805518137ef887805377ee4143
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:12:44 2023 -0700
+
+    [hb-info List enum nicks in --list-names
+
+ util/hb-info.cc  | 16 ++++++++++++++--
+ util/meson.build |  4 ++--
+ util/options.hh  |  6 ++++++
+ 3 files changed, 22 insertions(+), 4 deletions(-)
+
+commit def94aa8c5575f1bbaa8c3ea07356e78c0af6067
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 14:01:34 2023 -0700
+
+    [features] Add HB_HAS_GOBJECT
+
+ docs/harfbuzz-sections.txt | 1 +
+ src/Makefile.am            | 4 ++++
+ src/hb-features.h.in       | 7 +++++++
+ src/meson.build            | 4 ++++
+ 4 files changed, 16 insertions(+)
+
+commit b3006ba9cbc1fdb8cc2a8c7600b0fc0aa975fd2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 13:46:35 2023 -0700
+
+    Docs
+
+ docs/harfbuzz-sections.txt | 1 +
+ src/hb-ot-name.h           | 7 +++++++
+ 2 files changed, 8 insertions(+)
+
+commit e3e4d1ecdcd0c07be352e9d19775bbd9a207cbd5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 13:41:43 2023 -0700
+
+    [name] Add hb_ot_name_id_predefined_t
+    
+    Not sure what to do about its docs.
+
+ src/hb-ot-name.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3feac1a408429c78f1470164976b266d0095d96d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 10:15:14 2023 -0700
+
+    [hb-info] Use tab in --list-palettes
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 752ad51cce0c3e6033ed6de6d8257f46129fac06
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 10:07:24 2023 -0700
+
+    [hb-info] Move some initialization to post_parse
+
+ util/hb-info.cc | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+commit 334f59c955088e840004e85cb0c4bd10e4175b41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 10:06:05 2023 -0700
+
+    [hb-info] If name not found, fall back to English
+
+ util/hb-info.cc | 69 +++++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 45 insertions(+), 24 deletions(-)
+
+commit 7cae55359220da8310dc1257b3fd7177359e2235
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 09:33:25 2023 -0700
+
+    [hb-info] Rename --dump-table to --get-table
+
+ util/hb-info.cc | 30 +++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 17 deletions(-)
+
+commit 9b499a48bbcb7a1bc8b95e5c23df2eae29549e02
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 09:27:05 2023 -0700
+
+    [hb-info] Add --get-name
+
+ util/hb-info.cc | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 7a47a369d3a15716fa4d9c5ccd5681c72a155a99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 09:09:45 2023 -0700
+
+    [hmtx] Fix typo
+
+ src/hb-ot-hmtx-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit b9879181254b94a38f9a478d8fcae7daed0dd6c6
+Merge: e4cdaa1d3 89d332559
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 09:08:51 2023 -0700
+
+    Merge pull request #4052 from googlefonts/instancer_recalc_bounds
+    
+    [instancer] recalc bounds by default when --instance option is enabled
+
+commit e4cdaa1d3f7aa9725ba1d2beed4096287a8d59ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 08:36:51 2023 -0700
+
+    [test] Fix build
+
+ test/shape/data/in-house/Makefile.sources | 1 -
+ test/shape/data/in-house/meson.build      | 1 -
+ 2 files changed, 2 deletions(-)
+
+commit 9ba1e400d6831d5cd08f104b460f05346234a1d7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 22 08:31:39 2023 -0700
+
+    [test] Remove non-free font and its test
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4059
+
+ .../fonts/641ca9d7808b01cafa9a666c13811c9b56eb9c52.ttf  | Bin 11492 -> 0 bytes
+ test/shape/data/in-house/tests/arabic-mark-attach.tests |   1 -
+ 2 files changed, 1 deletion(-)
+
+commit 749df4ee8449107b39d76df353785a6f96b1cfa0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 16:00:54 2023 -0700
+
+    [PairPosFormat1] One more
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b648ceb72f281e739ec8bd73cbc243624854238d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 15:58:59 2023 -0700
+
+    [PairSet] Optimize last commit
+
+ src/OT/Layout/GPOS/PairSet.hh | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit 891623243c167217fcbd9480b111b110cc004c9c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 15:57:18 2023 -0700
+
+    [PairSet] Unify get_size()
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh |  4 +---
+ src/OT/Layout/GPOS/PairSet.hh        | 24 ++++++++++++------------
+ 2 files changed, 13 insertions(+), 15 deletions(-)
+
+commit b63159e8bf579345a6f56d04ad1b2c28eee66bac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 15:50:48 2023 -0700
+
+    [PairPosFormat1] Fix stride
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55287
+    and generally the lookup with MediumTypes.
+
+ src/OT/Layout/GPOS/PairPosFormat1.hh                     |   4 ++--
+ src/OT/Layout/GPOS/PairPosFormat2.hh                     |   2 +-
+ src/OT/Layout/GPOS/PairSet.hh                            |  13 ++++++-------
+ src/OT/Layout/GPOS/ValueFormat.hh                        |   2 +-
+ ...z-testcase-minimized-hb-shape-fuzzer-5965759719538688 | Bin 0 -> 1154 bytes
+ 5 files changed, 10 insertions(+), 11 deletions(-)
+
+commit be8a87c453473b4ac0d1895f89fdf4e50bcf5e52
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 15:00:41 2023 -0700
+
+    Move TRACE_DISPATCH after may_recurse()
+    
+    Such that we don't get memory access issues if DEBUG_SANITIZE is
+    on and may_recurse() returns false.
+
+ src/OT/Color/COLR/COLR.hh                     | 4 ++--
+ src/OT/Layout/GPOS/CursivePos.hh              | 2 +-
+ src/OT/Layout/GPOS/MarkBasePos.hh             | 2 +-
+ src/OT/Layout/GPOS/MarkLigPos.hh              | 2 +-
+ src/OT/Layout/GPOS/MarkMarkPos.hh             | 2 +-
+ src/OT/Layout/GPOS/PairPos.hh                 | 2 +-
+ src/OT/Layout/GPOS/SinglePos.hh               | 2 +-
+ src/OT/Layout/GSUB/AlternateSubst.hh          | 2 +-
+ src/OT/Layout/GSUB/LigatureSubst.hh           | 2 +-
+ src/OT/Layout/GSUB/MultipleSubst.hh           | 2 +-
+ src/OT/Layout/GSUB/ReverseChainSingleSubst.hh | 2 +-
+ src/OT/Layout/GSUB/SingleSubst.hh             | 2 +-
+ src/hb-ot-layout-common.hh                    | 2 +-
+ src/hb-ot-layout-gdef-table.hh                | 2 +-
+ src/hb-ot-layout-gsubgpos.hh                  | 8 ++++----
+ src/hb-ot-stat-table.hh                       | 2 +-
+ 16 files changed, 20 insertions(+), 20 deletions(-)
+
+commit 84b9a632ed6d9cf0a5eb00722c6409025cb839a6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 14:36:26 2023 -0700
+
+    [debug] Fix printf signness warnings
+
+ src/hb-debug.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit c54a7022feeb42aa89c0e9aeb80fd3c959d02c97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 21 14:07:41 2023 -0700
+
+    [hb-view] Require cairo 1.17.5 for HB_DRAW=1 default again
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4051
+
+ util/helper-cairo.hh | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+commit 67e652cd5d875f2c78ee97885039c180cacab39d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 21 15:57:13 2023 +0200
+
+    [meson] Update Cairo subproject
+
+ meson.build            | 1 +
+ subprojects/cairo.wrap | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit ed68db2c010a14c0613becd1685586836d4099aa
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 21 03:54:57 2023 +0200
+
+    [util] Fix MSVC warning
+    
+    Apparently \e is non-standard extension not supported by MSVC. Use \033
+    instead.
+    
+    Fixes:
+    
+    warning C4129: 'e': unrecognized character escape sequence
+
+ util/ansi-print.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit c08e5d094a3bd7e6c3b9d6475a30aa8883429a89
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 21 03:40:09 2023 +0200
+
+    [hb-draw] Fix MSVC warning
+    
+    warning C4305: 'initializing': truncation from 'double' to 'float'
+
+ src/hb-cairo-utils.cc | 4 ++--
+ test/api/test-paint.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit e1a0705128c2e6fd068374c47c13220ede9ee5a2
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 21 03:16:20 2023 +0200
+
+    [meson] Enabled needlessly disabled MSVC warnings
+    
+    We don’t seem to hot any of these warnings currently.
+
+ meson.build | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit f96e32a0aad4092f3f551ed390f3e3b884a8e4fe
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 21 00:39:00 2023 +0200
+
+    [meson] Try to make MSVC build less spammy
+    
+    Enable exceptions in ragel subproject, and revert the exceptions part of:
+    
+    commit 22cbd038d3578c344e265a098fc98ef168f8d18b
+    Author: Khaled Hosny <khaled at aliftype.com>
+    Date:   Tue Sep 14 12:34:25 2021 +0200
+    
+        [meson] Add ragel subproject
+    
+    To get ride of the following warnings:
+    
+    cl : Command line warning D9025 : overriding '/EHs' with '/EHs-'
+
+ meson.build                                |  5 ++---
+ subprojects/packagefiles/ragel/meson.build | 10 +++++++++-
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+commit 32f9b467d6265498dc4d8023bc4b6dc947896576
+Merge: 179c93c5c 7f59bed52
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Sat Jan 21 02:20:39 2023 -0500
+
+    Merge pull request #4045 from harfbuzz/custom-palette-cairo
+    
+    Custom palette cairo
+
+commit 179c93c5c21dc7dda7840d2bfc1ef27bcebdad71
+Merge: 54d5321d1 c574eda74
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Sat Jan 21 02:20:00 2023 -0500
+
+    Merge pull request #4054 from harfbuzz/hb-info-color-format
+    
+    [hb-info] Fix output for CPAL
+
+commit 54d5321d136ebd4be799d8c3dcf4e433b1c3778f
+Merge: fcb5111cc 47baa1da6
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Sat Jan 21 02:19:43 2023 -0500
+
+    Merge pull request #4056 from harfbuzz/fix-sweep-gradient-hang
+    
+    [hb-cairo] Fixes for sweep gradients
+
+commit 47baa1da6bbf386d7be73ca4a79d2c819ca2a3c9
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Jan 20 23:38:22 2023 -0500
+
+    [hb-cairo] Fixes for sweep gradients
+    
+    Make reversed angles not infloop, and
+    cap the number of interval repetitions
+    at 1000.
+    
+    Fixes: https://github.com/harfbuzz/harfbuzz/issues/4055
+
+ src/hb-cairo-utils.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit c574eda74b027b514665c978d32cef0aa284bee5
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Jan 20 22:06:47 2023 -0500
+
+    [hb-info] Fix output for CPAL
+    
+    The output for palette names was mangled.
+    This commit makes things come out ok.
+    
+    For flags, we use "Both" when both LIGHT
+    and DARK are set.
+
+ util/hb-info.cc | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+commit 7f59bed528e75e5336ace1d9cdbee20932e3e211
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 16:42:55 2023 -0700
+
+    [hb-cairo] Round foreground color
+
+ src/hb-cairo.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 76b059cadb805df3df860be6a130ab5480cb8846
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 16:41:47 2023 -0700
+
+    [hb-cairo] Simplify foreground color fetching
+
+ src/hb-cairo.cc | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit f70f7194de5f24625d12d40cf639a7a0e7ef48b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 16:30:59 2023 -0700
+
+    [hb-cairo] Remove unused prototype
+
+ src/hb-cairo.cc | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit 61719a835089ea2c2cda36702f630c9343b029c7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:52:09 2023 -0700
+
+    [hb-view] Support specifying color indices again
+
+ src/hb-number.cc     |  1 -
+ util/helper-cairo.hh | 16 ++++++++++++++--
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+commit 89d332559ee4d5349315b35e64b34c27116ba441
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Jan 20 14:15:19 2023 -0800
+
+    [instancer] add tests
+
+ ...fault.retain-all-codepoint.wght=150,wdth=80.ttf | Bin 114200 -> 114200 bytes
+ ...fault.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 114300 -> 114300 bytes
+ ...anges.retain-all-codepoint.wght=150,wdth=80.ttf | Bin 114200 -> 114200 bytes
+ ...anges.retain-all-codepoint.wght=300,wdth=90.ttf | Bin 114300 -> 114300 bytes
+ .../MPLUS1-Variable.default.30DD.wght=100.ttf      | Bin 1460 -> 1460 bytes
+ .../MPLUS1-Variable.default.30DD.wght=400.ttf      | Bin 1712 -> 1712 bytes
+ ...fault.retain-all-codepoint.wght=200,wdth=90.ttf | Bin 6760 -> 6760 bytes
+ ...fault.retain-all-codepoint.wght=650,wdth=85.ttf | Bin 6712 -> 6712 bytes
+ ...fault.retain-all-codepoint.wght=200,wdth=90.ttf | Bin 6440 -> 6440 bytes
+ ...fault.retain-all-codepoint.wght=650,wdth=85.ttf | Bin 6392 -> 6392 bytes
+ ...etain-all-codepoint.wght=150,wdth=80,CTGR=0.ttf | Bin 1396 -> 1396 bytes
+ ...etain-all-codepoint.wght=300,wdth=90,CTGR=0.ttf | Bin 1432 -> 1432 bytes
+ ...lt.retain-all-codepoint.wght=400,wdth=100.0.ttf | Bin 6804 -> 6804 bytes
+ ...ult.retain-all-codepoint.wght=drop,wdth=100.ttf | Bin 6804 -> 6804 bytes
+ test/subset/generate-expected-outputs.py           |   3 ++-
+ 15 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 30058f489a43c39b7bd9278c1e04baf1952bba48
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 18 15:23:24 2023 -0800
+
+    [instancer] trim .notdef outline data after recalc bounds
+    
+    If outline data present, we use it to recalc bounds and then trim it
+    accordingly
+
+ src/OT/glyf/Glyph.hh | 4 ++++
+ src/OT/glyf/glyf.hh  | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 0de7f83a9fe2054ad2d63c3f8e08dc61e1397c62
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 18 13:33:34 2023 -0800
+
+    [instancer] update maxp table
+
+ src/hb-ot-maxp-table.hh | 13 +++++++++++++
+ src/hb-subset.cc        |  1 +
+ 2 files changed, 14 insertions(+)
+
+commit 94c390d07835727c201bfdbe0b4d208dc3fe3fc2
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 18 10:15:47 2023 -0800
+
+    [instancer] update head table
+
+ src/OT/glyf/glyf-helpers.hh | 7 +++++++
+ src/hb-ot-head-table.hh     | 2 ++
+ src/hb-subset.cc            | 2 +-
+ 3 files changed, 10 insertions(+), 1 deletion(-)
+
+commit 2ecb1c31e90657a5a264f4b84907bad6f07673c1
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Wed Jan 18 09:52:00 2023 -0800
+
+    [instancer] always recalculate bounds when --instance option enabled
+    
+    But don't recompile glyph bytes if pinned at default
+
+ src/OT/glyf/Glyph.hh | 48 ++++++++++++++++++++++++++----------------------
+ src/OT/glyf/glyf.hh  |  5 +++--
+ 2 files changed, 29 insertions(+), 24 deletions(-)
+
+commit 1f948e7fd55ff6a65aa3a6b038284db3d211493e
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Tue Jan 17 15:16:17 2023 -0800
+
+    [instancer] store recalculated head/maxp info in subset plan
+
+ src/OT/glyf/Glyph.hh  | 50 ++++++++++++++++++++++++++++++++++++++++++++------
+ src/OT/glyf/glyf.hh   |  2 +-
+ src/hb-subset-plan.hh | 27 +++++++++++++++++++++++++++
+ 3 files changed, 72 insertions(+), 7 deletions(-)
+
+commit 92122421c951f6f126eff902f917b403bdf027a5
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Jan 13 11:42:58 2023 -0800
+
+    [instancer] update vhea/hhea tables
+
+ src/OT/glyf/Glyph.hh    | 11 +++++++++--
+ src/hb-ot-hmtx-table.hh | 43 +++++++++++++++++++++++++++++++++++++------
+ src/hb-subset-plan.hh   |  4 ++++
+ 3 files changed, 50 insertions(+), 8 deletions(-)
+
+commit ab7c91442536086f0baebe2d419827bb9e4cce06
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:43:01 2023 -0700
+
+    [hb-cairo] Macro shuffle again
+
+ src/hb-cairo.cc | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 4759932bcfb5af5f576868cc96dfe2755361fe9d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:33:38 2023 -0700
+
+    [hb-cairo] Round colors
+
+ src/hb-cairo.cc | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 876675e090e2b55fdb5f3e8b187022184145b2f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:31:43 2023 -0700
+
+    [hb-cairo] Macro shuffling
+
+ src/hb-cairo.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 68a73e436a37851465b1b8b59e3b7a2c552d28f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:30:07 2023 -0700
+
+    [hb-cairo] Macro hygiene
+
+ src/hb-cairo.cc | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit fcb5111cc6db8e310d62e27d93980a0f67ee936a
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Jan 21 00:24:50 2023 +0200
+
+    [doc] Fix gtk-doc warning
+
+ src/hb-cairo.cc | 6 +++---
+ src/hb-face.cc  | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 574d9344dccdd7c79a02070dac48bf825c8095de
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:22:50 2023 -0700
+
+    [hb-cairo] Fix build with old cairo
+
+ src/hb-cairo.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 4f19c3b3be07b75235684b969677725fe50494f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:15:52 2023 -0700
+
+    [hb-cairo] Move color-cache to scaled-font
+
+ src/hb-cairo.cc | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit beba43eebe235dac402a66ffd58fa29a9689fe15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 15:02:24 2023 -0700
+
+    [hb-cairo] Fix color cache on not-found
+
+ src/hb-cairo.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit cc9b55c79469b93583f21f8a45cd3cb0759aa789
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 14:57:57 2023 -0700
+
+    [hb-cairo] Add a color cache
+
+ src/hb-cairo.cc | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+commit 10def9b3df1241eec912b94ba82d43cd8f93caa4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 14:06:18 2023 -0700
+
+    meson fix
+
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eb00088bcfea640d2d1d591d08cdcdd01d5acf91
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 13:55:13 2023 -0700
+
+    [paint] Docs
+
+ docs/harfbuzz-sections.txt | 2 --
+ src/hb-paint.cc            | 3 ++-
+ src/hb-paint.h             | 4 +++-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+commit f21b15dcc318aa62d256443be3ccec7953a64242
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 13:38:22 2023 -0700
+
+    [hb-view] Update to alternative cairo custom-palette API
+
+ meson.build          | 1 +
+ src/hb-cairo.cc      | 5 +++--
+ util/helper-cairo.hh | 2 +-
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+commit 638e0ed4fdd06a6215f2d7c74786b6436074d564
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 13:01:22 2023 -0700
+
+    [paint] Overlay custom-palette on top of chosen palette
+    
+    Got to agree this is more ergonomic.
+
+ src/OT/Color/COLR/COLR.hh |  4 +---
+ src/hb-cairo.cc           |  8 +++++---
+ src/hb-font.cc            |  3 +--
+ src/hb-ft-colr.hh         |  7 +++----
+ src/hb-paint.cc           | 12 +++++++-----
+ src/hb-paint.h            | 25 ++++++++-----------------
+ src/hb-paint.hh           |  6 ++++--
+ util/helper-cairo.hh      | 10 ++++------
+ 8 files changed, 33 insertions(+), 42 deletions(-)
+
+commit 03e2e586423ada331ae433db7dea705a8b6ad3fe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 11:24:35 2023 -0700
+
+    [hb-view] Improve color parsing
+    
+    Now supports 3, 4, 6, 8 digit colors.
+
+ util/helper-cairo.hh | 13 +++++++------
+ util/options.hh      | 40 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+), 6 deletions(-)
+
+commit dc4af478d14ca5d0270e317a87d60dfba111381d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 11:11:02 2023 -0700
+
+    [hb-view] Default background to white when parsing
+
+ util/helper-cairo.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b81db8d3d82af7a369a2b26ec35dcec81060a965
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Jan 19 08:19:04 2023 -0500
+
+    Avoid a compiler warning
+
+ src/hb-cairo.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e998cec1d94f32ac44ff0dca42941b28a4fdd546
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 23:33:21 2023 -0700
+
+    [hb-view] Move palette options to --help-view
+
+ util/font-options.hh | 5 -----
+ util/helper-cairo.hh | 9 +++++----
+ util/view-cairo.hh   | 3 ++-
+ util/view-options.hh | 5 +++++
+ 4 files changed, 12 insertions(+), 10 deletions(-)
+
+commit 253b4cecae0729330ec04fab93972db86ee1b203
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 23:28:25 2023 -0700
+
+    [hb-view] Simplify palette format
+
+ util/font-options.hh | 2 +-
+ util/helper-cairo.hh | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 52b78d526b522f95897bfcb4d9652ea328fbdb6a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 23:06:08 2023 -0700
+
+    [hb-view] Fix leak
+
+ util/helper-cairo.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 5847ec24ff65d7f7c59d105b2cca86ac235ac7eb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 22:37:54 2023 -0700
+
+    Fix bots
+
+ util/helper-cairo.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4fe6ece425c19e8fd63e346179de5bd14415d732
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 22:33:56 2023 -0700
+
+    [cairo] Don't fallback to CPAL if cairo doesn't support custom palette
+
+ src/hb-cairo.cc | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+commit 0bff5704912fb99789ca7e09d3fafb640c2ccfed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 22:33:32 2023 -0700
+
+    [hb-view] Use custom palette if any set
+
+ util/helper-cairo.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit c41892a01229404d4d0c31b8056fd7b72ac3a58a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jan 18 23:45:53 2023 -0500
+
+    hb-view: Add a --custom-palette option
+
+ util/font-options.hh |  3 +++
+ util/helper-cairo.hh | 12 ++++++++++++
+ 2 files changed, 15 insertions(+)
+
+commit ab37ade7e46ac00152113c275dd8cd7fc9d1a11c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jan 18 23:29:37 2023 -0500
+
+    Hook up custom palettes for cairo
+
+ src/hb-cairo.cc | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+commit cce7c441eb0bd097f63016aa7e5962aa6615951b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 13:57:05 2023 -0700
+
+    [name] Fix doc
+    
+    That's part of an enum now.
+
+ docs/harfbuzz-sections.txt | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 3711455154373d0400bad77221cb02a785882623
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 12:32:41 2023 -0700
+
+    [hb-info] Minor set parse hooks
+    
+    Unused.
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 89371419a91f88ae503dbbb99fb9ebbb5c1239ab
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 12:20:38 2023 -0700
+
+    [hb-info] Move code around
+
+ util/hb-info.cc | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit 32b42eb5687bf0bc4fd27545e19753066620af60
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 12:18:04 2023 -0700
+
+    [hb-info] Add --show-face-count
+
+ util/hb-info.cc | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+commit fd84605b5898e6cb9738c4d821e2893edd0a2cf6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 12:10:03 2023 -0700
+
+    [hb-info] Add --show-technology
+
+ util/hb-info.cc | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+commit c05230256d52e8c62135e8133cd2a6b75296e54a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 12:08:31 2023 -0700
+
+    [util] Add -y for --face-index
+    
+    Ala ttx.
+
+ util/face-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6bf9237e5f467073021483cd06251955ef28c84f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 11:54:08 2023 -0700
+
+    [hb-info] Format --list-palettes
+
+ util/hb-info.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 64625ed85d27102fcd4b499e007b88229c4b0221
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 11:48:01 2023 -0700
+
+    [hb-info] Write palette flags
+
+ util/hb-info.cc | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+commit d811dcdbde935cd8ec897d84332a572b76e772a3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 11:42:51 2023 -0700
+
+    [hb-info] Add --list-palettes
+
+ util/hb-info.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 58 insertions(+), 1 deletion(-)
+
+commit 2590578162692e24afe4a333f9c6b1c9423d6937
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 11:04:22 2023 -0700
+
+    [hb-info] Add --get-baseline
+
+ util/hb-info.cc | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 49 insertions(+), 1 deletion(-)
+
+commit b77baa31c36d4b8375ebb3fe97a7bbe36b71b463
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 10:13:21 2023 -0700
+
+    [hb-info] Show whether --get-metric value is fallback
+
+ util/hb-info.cc | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+commit 2a8df82aca15df45c5abfd6d8e18e294a8d6dadf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 09:57:28 2023 -0700
+
+    [hb-info] Add --get-metric
+
+ util/hb-info.cc | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+commit ba4f5e9f220b7e33c5ea0438c824a99f433f41d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 09:29:39 2023 -0700
+
+    [hb-info] Add --ot-script and --ot-language
+
+ util/hb-info.cc | 46 ++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 40 insertions(+), 6 deletions(-)
+
+commit edec8946ed376c2888f9444b038b80dad57c162e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 09:28:59 2023 -0700
+
+    New API: hb_ot_layout_script_select_language2()
+    
+    Variant that outputs chosen_language.
+    
+    Not sure why the original API didn't have this. The script
+    counterpart has.
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-ot-layout.cc        | 66 +++++++++++++++++++++++++++++++++++++++-------
+ src/hb-ot-layout.h         |  9 +++++++
+ 3 files changed, 66 insertions(+), 10 deletions(-)
+
+commit 2fd8e36ea5891f462f4bff8b6657c4421943a4f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 09:09:14 2023 -0700
+
+    [layout] Fix return value of chosen_script when matching fails
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d06976e68fd475eb12fcec538b207354ddcffd92
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 08:21:43 2023 -0700
+
+    [glyf] Add an edge-count limit
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55246
+
+ src/OT/glyf/Glyph.hh | 13 ++++++++++---
+ src/hb-limits.hh     |  4 ++++
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+commit 2cfd4133fb7e42237fbe47f09e448285fdbd1975
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 20 07:11:16 2023 -0700
+
+    [hb-info] Print Zyyy for DFLT script
+
+ util/hb-info.cc | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 178c5bed39c66595ca4198c2e377fd5bee719351
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Jan 20 00:42:29 2023 +0200
+
+    [ci] Use unique ccache cache keys per job
+
+ .github/workflows/linux-ci.yml | 2 ++
+ .github/workflows/macos-ci.yml | 2 ++
+ 2 files changed, 4 insertions(+)
+
+commit a0afde70c53a6e7b64dbbc932236a8d9b124b9e6
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 19 22:55:11 2023 +0200
+
+    [ci] Re-enable coverage reporting on macOS
+
+ .github/workflows/macos-ci.yml | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+commit 8785d515d073679fa15db97ed01f2f6525ae6566
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 19 22:43:16 2023 +0200
+
+    [ci] Don’t install glib-utils on macOS
+    
+    Homebrew can’t make up their mind, they seem to have merged the glib
+    packages again.
+
+ .github/workflows/macos-ci.yml | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 5ddb5fb847c741201bca382780e4cde9d627f2bb
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 19 22:41:49 2023 +0200
+
+    [ci] Don’t install gtk-doc on macOS
+    
+    We are not building the documentation here.
+
+ .github/workflows/macos-ci.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 48df846a413a3734a18bfe13e661e41a1bafed88
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Jan 19 22:38:36 2023 +0200
+
+    [ci] Make homebrew do less work
+
+ .github/workflows/macos-ci.yml | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 35f0184bfd260f08eab869a7911453c8e612a122
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 20:48:11 2023 +0200
+
+    [ci] Clean a bit and add some consistency
+
+ .github/workflows/linux-ci.yml | 70 ++++++++++++++++++++-----------------
+ .github/workflows/macos-ci.yml | 39 ++++++++++++++++-----
+ .github/workflows/msvc-ci.yml  | 64 +++++++++++++++++-----------------
+ .github/workflows/msys2-ci.yml | 79 +++++++++++++++++++++---------------------
+ 4 files changed, 141 insertions(+), 111 deletions(-)
+
+commit edd5a37e791569ed1df9291d95e6c8ee0839987e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 18:39:32 2023 -0700
+
+    [hb-info] Implement script/language-sensitive --list-features
+    
+    I'm not very confident in the implementation.
+
+ util/hb-info.cc | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 97 insertions(+), 9 deletions(-)
+
+commit a67b6aad925e31aace8d81647ce341e448af22b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 18:07:05 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4927e215a4065045d64786fd0cf74be38656b708
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 18:03:31 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+commit 9ca320d69ee99025977d76a4228bc4e786ade6e9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:54:46 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit b24c7add808bae277bd2b3246d7efdb72f7387ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:53:07 2023 -0700
+
+    [hb-info] Write ISO/BCP script/language in --scripts
+
+ util/hb-info.cc | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit b8dacd46f5558b4d6313392a536309ddd49bfbeb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:46:24 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b9a2917c2ea4b81bcbf7510c054369a8edbc170b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:34:10 2023 -0700
+
+    [hb-info] Simplify direction/script/language handling
+
+ util/hb-info.cc | 30 ++++++++++--------------------
+ 1 file changed, 10 insertions(+), 20 deletions(-)
+
+commit e6544148b590c2d846eee608b39501de6826a9a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:28:41 2023 -0700
+
+    [hb-info] Enlarge name buffer
+
+ util/hb-info.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d759918d181b1e8b53ae618dc476506a49b913e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:26:00 2023 -0700
+
+    [hb-info] TODO
+
+ util/hb-info.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 4baf0ada694602f63a6fd34bafc5a75f74872ad4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 17:24:05 2023 -0700
+
+    [hb-info] Add --direction, --script, --language
+
+ util/hb-info.cc | 46 +++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 39 insertions(+), 7 deletions(-)
+
+commit 66692c82e925b2ca8d9e6fc567b1f0abbc32d331
+Merge: f43ba351e e52a23c5f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 16:26:15 2023 -0700
+
+    Merge pull request #4048 from harfbuzz/hb-info
+    
+    hb-info
+
+commit e52a23c5f8d25441bf164b4e63b28aae8082acfb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 16:01:29 2023 -0700
+
+    [hb-info] Add --show-extents
+
+ util/hb-info.cc | 29 +++++++++++++++++++++++++----
+ 1 file changed, 25 insertions(+), 4 deletions(-)
+
+commit 1302a88b25f38dfb0cf463ed0cbb3bb21811f590
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:51:46 2023 -0700
+
+    [hb-info] Add --dump-table
+
+ util/hb-info.cc | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 148ee3e0c73dd9c00988ad46b01fcd18ef5f5cc4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:41:13 2023 -0700
+
+    [hb-info] Make --show-style and --show-postscript-name show named-instance
+
+ util/hb-info.cc | 23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+commit 2a3903b37fbfdf49e56ba6a343f98b4f60a0196e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:34:14 2023 -0700
+
+    [hb-info] TODO items
+
+ util/hb-info.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5540367ee2e0be55b782bb6ff33df48613c4d904
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:30:27 2023 -0700
+
+    [hb-info] Add --show-version
+
+ util/hb-info.cc | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 3c734f4479068c0b9a6a768ff55d9ecd0d73d6f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:27:13 2023 -0700
+
+    [hb-info] Add --show-postscript-name
+
+ util/hb-info.cc | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 895d3f9e3e146e0f185000962f0897c1fc693dac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:24:32 2023 -0700
+
+    [hb-info] Mark --show-all as default
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dec320a4630a1d71f94d6e81ea95b5c855dfe01a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:18:06 2023 -0700
+
+    [hb-info] Put back -l for --list-tables
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9395bbaa6710ad3b7c8415340d068c467cc31f8f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:17:33 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit d7cf69ede2fe9ad7f1eb9559a4f8638b11c550f2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:15:56 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 7af0624bdf9d2c8d712eacb5dd46787deeb5cfd6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:11:55 2023 -0700
+
+    [hb-info] Remove unintended short option
+
+ util/hb-info.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 21151401219a4f6b4a907f14b783bc61d397136f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:10:00 2023 -0700
+
+    [hb-info] Add --show-unique-name and --show-full-name
+
+ util/hb-info.cc | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+commit 2d9ba17a535d2c466dce1f09064dfba73a92e387
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:06:21 2023 -0700
+
+    [hb-info] Add --show-style
+
+ util/hb-info.cc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit fecb2eeca0120e4cf9d06f3164e38d4daa983bd0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 15:05:00 2023 -0700
+
+    [hb-info] Add --show-family
+
+ util/hb-info.cc | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+commit f25c03162b2b6132199712bdd165faee0075b2f6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:57:45 2023 -0700
+
+    [hb-info] Change separator to ===
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5b05edd221d85b9d6c83dfc2d8e0aa32781b8b1f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:57:30 2023 -0700
+
+    [hb-info] Add --list-names
+
+ util/hb-info.cc | 31 ++++++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+commit 67c9845301a317dae5a33ba0de003ec060427ee4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:45:04 2023 -0700
+
+    [hb-info] Make -l list tables ala ttx
+
+ util/hb-info.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 972e3b76da8330faec20883f978c40d701908d98
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:42:18 2023 -0700
+
+    [hb-info] Minor formatting
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c1679e02662d1589dfcdc8802a8ae7889807405b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:41:13 2023 -0700
+
+    [hb-info] Default to --show-all
+
+ util/hb-info.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 1eca2c88a29c2a29c6f7687c79f567598ecae869
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:38:12 2023 -0700
+
+    [hb-info] Add a few short option forms
+
+ util/hb-info.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit e5a07c883c90ad8c0108c967f664e7468b4ca14a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:34:32 2023 -0700
+
+    [hb-info] --help format
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b215f6a84f38725a628248ea25cbb88e57f2c464
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:31:45 2023 -0700
+
+    [hb-info] Add --show-unicode-count
+
+ util/hb-info.cc | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+commit 3189b614b1d3ac3343c17b1b67acadb8d4f4e6e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:24:26 2023 -0700
+
+    [hb-info] Format
+
+ util/hb-info.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fd20a7e143e2e2dfa4c13ab255570200510cd508
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:23:36 2023 -0700
+
+    [hb-info] Add --show-glyph-count
+
+ util/hb-info.cc | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+commit 38c71cebd070ee0e1e25836ab1fb485bebfd066e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:19:05 2023 -0700
+
+    [hb-info] Add --show-upem --show-all --all
+
+ util/hb-info.cc | 38 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 37 insertions(+), 1 deletion(-)
+
+commit aee7454d05256b206a4aa5892d9ca6211c7d3189
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:09:45 2023 -0700
+
+    [hb-info] Add --list-scripts
+
+ util/hb-info.cc | 31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+commit 9ca2f86fe0807c7abf8e967130734be76a25f52d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 14:04:37 2023 -0700
+
+    [hb-info] Minor verbose print
+
+ util/hb-info.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9a94c06052e6dd6e752aaac7ce5924f205b73072
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 13:56:36 2023 -0700
+
+    [hb-info] Minor we have face available
+
+ util/hb-info.cc | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit 8921f593f953947760ab97bd844b20b0c9edc1be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 13:49:22 2023 -0700
+
+    [hb-info] Print "---" separator
+
+ util/hb-info.cc | 38 +++++++++++++++++++++++++++-----------
+ 1 file changed, 27 insertions(+), 11 deletions(-)
+
+commit f514f697246bd9a19429c5e42038532b48bbab4f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 13:35:15 2023 -0700
+
+    [hb-info] Add --quiet
+
+ util/hb-info.cc | 60 +++++++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 52 insertions(+), 8 deletions(-)
+
+commit dc717ced8d378aa455a3ca749b8b932bf2b53b97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 13:16:34 2023 -0700
+
+    [hb-info] Simplify
+
+ util/hb-info.cc | 42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+commit 1816d3664d52b94547a6f0882173a8d5d7f93d19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 12:59:26 2023 -0700
+
+    [hb-info] Flesh out
+
+ util/face-options.hh |  29 -----
+ util/font-options.hh | 281 ---------------------------------------------
+ util/hb-info.cc      | 318 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 316 insertions(+), 312 deletions(-)
+
+commit ca903f7531f71a81c06a4e9fc4f7166af3f04968
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 12:40:27 2023 -0700
+
+    [hb-info] Start adding
+
+ util/Makefile.am      |   3 ++
+ util/Makefile.sources |   8 ++++
+ util/hb-info.cc       | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ util/meson.build      |  13 ++++++
+ 4 files changed, 132 insertions(+)
+
+commit f43ba351e87e6abc084c4c67ab0cdb093689d415
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 12:17:30 2023 -0700
+
+    [util] Limit chafa to one thread
+
+ util/helper-cairo-ansi.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 2b010d8017c18375d16e897eee22a092f65d80c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 12:14:50 2023 -0700
+
+    [util] Minor hide --font-ptem sometimes
+
+ util/font-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 06c064a351bca485cc7d1245b57835b413459e32
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 19 11:17:49 2023 -0700
+
+    [util] Use hb_font_glyph_to_string
+
+ util/font-options.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit 0c7d386748e7cf0bfb09598f82b84b8927d78190
+Merge: ea291493d 0b32cf902
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 21:50:10 2023 -0700
+
+    Merge pull request #4044 from harfbuzz/custom-palette
+    
+    Custom palette
+
+commit 0b32cf902322a38b067ef7748380d91430dd4151
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 21:16:38 2023 -0700
+
+    [COLR] Rename a variable
+
+ src/OT/Color/COLR/COLR.hh | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 1d58c8fb0ec78ee92e3274e9cb07d56c1f5b342f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 21:14:24 2023 -0700
+
+    [paint] Typo
+
+ src/hb-paint.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7aca3b509039b3a522cfd03e3aaaca9fe7017dba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 20:49:06 2023 -0700
+
+    [COLRv1] Hook up custom palette colors
+
+ src/OT/Color/COLR/COLR.hh | 12 +++++++++---
+ src/hb-ft-colr.hh         | 50 +++++++++++++++++++++++++++++++++++------------
+ 2 files changed, 46 insertions(+), 16 deletions(-)
+
+commit d695cc87353f59f1647351e2194d513b42ae55ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 20:45:19 2023 -0700
+
+    [paint] Docs
+
+ docs/harfbuzz-sections.txt | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 53bd9039e77d822d2d258dc5b056509cb758ad24
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 20:44:05 2023 -0700
+
+    [paint] Doc
+
+ src/hb-font.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 8afd3ccb106196c230741417d8364722df7f6e32
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 20:43:10 2023 -0700
+
+    [paint] Add HB_PAINT_PALETTE_INDEX_CUSTOM
+
+ src/hb-font.cc |  3 ++-
+ src/hb-paint.h | 12 ++++++++++++
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+commit 9a2f2b593eca24fc5e4a412d7ab2d776d28953e1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 20:39:36 2023 -0700
+
+    [font] Rename palette to palette_index
+
+ src/hb-font.cc | 8 ++++----
+ src/hb-font.h  | 6 +++---
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+commit bd733146168bce4cb0ea6dd6dc314d5366d85f0a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 20:37:21 2023 -0700
+
+    [paint] Add API for custom palettes
+
+ src/hb-paint.cc | 23 +++++++++++++++++++++++
+ src/hb-paint.h  | 39 +++++++++++++++++++++++++++++++++++++++
+ src/hb-paint.hh |  6 ++++++
+ 3 files changed, 68 insertions(+)
+
+commit ea291493d2d52480accfb2402946b19ef00ce74b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 19:51:22 2023 -0700
+
+    [hb-shape/view] List variation sequences in --list-unicodes
+
+ util/font-options.hh | 36 ++++++++++++++++++++++++++++++++----
+ 1 file changed, 32 insertions(+), 4 deletions(-)
+
+commit 8564d2266bc7988b6744e20bfb188d9328ef56e8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 19:43:33 2023 -0700
+
+    [hb-shape/view] Add --list-glyphs
+
+ util/font-options.hh | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+commit bf8bb9fb83575e99484f953d078fe0328d3dc344
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 19:39:30 2023 -0700
+
+    [hb-shape/view] Add --list-unicodes
+
+ util/font-options.hh | 37 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+commit 13c70066de00b46a0c30a32daa9e10647fd2e531
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 17:29:26 2023 -0700
+
+    Shut up gcc 13 -Wdangling-reference
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4043
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 1abcc32137be9cce13bd8dc63b11a2759e5f8679
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Jan 18 18:22:00 2023 +0200
+
+    Revert "[ci] Use sccache with msys2"
+    
+    This reverts commit b9646dfd6290dbf7819cc042bb6f541b80ef8b68.
+    
+    For some reason using sccache re-introduces the random CI crashes that
+    was previously fixed in 80dd751564e8a9153f7466e687b8699a5e7e27c6.
+
+ .github/workflows/msys2-ci.yml | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit eed5d5efdd37bfbf06f52b67a5dd9d170576d2ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 14:13:12 2023 -0700
+
+    [VarComposite] Implement RESET_UNSPECIFIED_AXES
+    
+    Fixes https://github.com/harfbuzz/boring-expansion-spec/issues/79
+
+ src/OT/glyf/Glyph.hh             | 6 +++++-
+ src/OT/glyf/VarCompositeGlyph.hh | 2 ++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+commit 4300a18b852f67ad2b45fb9c1c04474c9f234eb2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 18 10:44:13 2023 -0700
+
+    [arabic-fallback] Fix ligature code
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4042
+    
+    This was broken in 20e9f0b.
+
+ src/hb-ot-shaper-arabic-fallback.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit b9646dfd6290dbf7819cc042bb6f541b80ef8b68
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 20:46:33 2023 +0200
+
+    [ci] Use sccache with msys2
+
+ .github/workflows/msys2-ci.yml | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 22a4fca375e54c5b3fabb56559ef2400cc5807a3
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 18:10:36 2023 +0200
+
+    [ci] Use sccache for msvc jobs
+    
+    Meson will not use ccache with MSVC, so we use sccache here.
+
+ .github/workflows/msvc-ci.yml | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 582636bce035e655392d82c400a2953ccb815a2c
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 18:09:41 2023 +0200
+
+    [ci] Use ccache for linux and macos jobs
+
+ .github/workflows/linux-ci.yml | 5 ++++-
+ .github/workflows/macos-ci.yml | 6 +++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+commit 99146e76090787fd3e2f39289556da9bcf911e60
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 17:20:19 2023 +0200
+
+    [ci] We don’t need to install ragel on msys2
+
+ .github/workflows/msys2-ci.yml | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 842e26d32ca42ed7715eb3f1018be6fd86f3d036
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 17:02:56 2023 +0200
+
+    [ci] Remove no longer needed workaround
+    
+    Meson seems to take care of this itself now.
+
+ .github/workflows/msvc-ci.yml | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 4d86c65c7ab544fe614c1c8f49d6154ea7b1ee04
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 17 07:34:45 2023 -0700
+
+    [hb-cairo] Fix linear-gradient reduce_anchors
+
+ src/hb-cairo-utils.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 910adc7e9263fb6f8456e282c5d5b62faa0bc923
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 14:23:46 2023 +0200
+
+    [test-paint] Update expectations
+
+ test/api/results/bad-154    | 622 ++++++++++++++++++++++++--------------------
+ test/api/results/test-154   |  28 +-
+ test/api/results/testvf-154 |  28 +-
+ 3 files changed, 375 insertions(+), 303 deletions(-)
+
+commit 4f4b6e03f43e651bc18d8c9b724d779855e62e03
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 17 14:08:58 2023 +0200
+
+    [wrap] Add fallback source URL for zlib
+    
+    Hopefully this fixes the intermittent CI failures due to download
+    failures.
+
+ subprojects/zlib.wrap | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c86bab3fb4d2a52d6970d1fffd00e1b112b0b3c9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 17 06:29:17 2023 -0700
+
+    [test-paint] Use G_GNUC_PRINTF
+
+ test/api/test-paint.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 92d5ec2f1618c3b899c74216f7f05ea85f815b8e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 17 05:59:19 2023 -0700
+
+    [bit-page] Mark len() function static
+
+ src/hb-bit-page.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0a3e4c12ac770f36e52a1934862c1f98429d9b1b
+Author: Amir Masoud Abdol <amirmasoudabdol at icloud.com>
+Date:   Tue Jan 17 09:36:03 2023 +0100
+
+    Replace the deprecated $<CONFIGURATION> with $<CONFIG>
+
+ CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f38e35ebc317eaf311a334af40488a607c693194
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 18:07:39 2023 -0700
+
+    [cairo] Internal function renames
+
+ src/hb-cairo-utils.cc | 42 +++++++++++++++++++++---------------------
+ src/hb-cairo-utils.hh | 42 +++++++++++++++++++++---------------------
+ src/hb-cairo.cc       | 10 +++++-----
+ 3 files changed, 47 insertions(+), 47 deletions(-)
+
+commit e4a41f5e16b56a7c84055960dcac34e7b5ac94df
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 16:27:04 2023 -0700
+
+    [COLRv1] Implement recursive clip boxes
+    
+    Tests need update.
+    
+    hb-view test_glyphs-glyf_colr_1_variable.ttf -u f0c00
+
+ src/OT/Color/COLR/COLR.hh | 31 ++++++++++++++++++++++++-------
+ src/hb-ft-colr.hh         | 24 ++++++++++++++++--------
+ 2 files changed, 40 insertions(+), 15 deletions(-)
+
+commit f02c4ebb409befa41857d4df9465c5944f25e87b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 14:17:16 2023 -0700
+
+    [test-paint] Adjust condition for enabling ft backend
+
+ test/api/test-paint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7dfa672dac958bdbc7703ab0920e167eaa126754
+Author: Sergei Trofimovich <slyich at gmail.com>
+Date:   Mon Jan 16 19:49:53 2023 +0000
+
+    test/threads/hb-subset-threads.cc: add missing <cstdio> include
+    
+    This week's `gcc-13` snapshot cleaned further up it's standard headers
+    and exposed missing declaration as a build failure:
+    
+        ../test/threads/hb-subset-threads.cc: In function 'void test_operation(operation_t, const char*, const test_input_t&)':
+        ../test/threads/hb-subset-threads.cc:127:3: error: 'printf' was not declared in this scope
+    
+        ../test/threads/hb-subset-threads.cc: In function 'int main(int, char**)':
+        ../test/threads/hb-subset-threads.cc:157:19: error: 'atoi' was not declared in this scope
+
+ test/threads/hb-subset-threads.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f11271cc036ae6ecee5e75a93da13078a6b97d11
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 13:14:58 2023 -0700
+
+    [cairo] Version-check the variations code
+
+ src/hb-cairo.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a180ae43ce0ae8bccc45913a6443c0d109ce7ee9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 13:06:30 2023 -0700
+
+    [bit-set] Use for loop instead of memset for page clear
+    
+    Produces faster code.
+
+ src/hb-bit-page.hh | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+commit 8e8ca03b2a970f816e024d21ad9ab7dcd4ed76ad
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 12:38:53 2023 -0700
+
+    [hb-fc] Minor remove unused variable
+
+ util/hb-fc.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit e903397bc33a202410255b56abdbe05aa4963b78
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 12:33:17 2023 -0700
+
+    Whitespace
+
+ util/ansi-print.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit ca1de29e0a85508b9938defd5e7a4b08e3134c7b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 12:08:11 2023 -0700
+
+    [set] Adjust hb_set_copy()
+
+ src/hb-set.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit b7f1c30c2062837932d70bd7fbd5fb69289e4f36
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 12:07:15 2023 -0700
+
+    [map] Adjust hb_map_copy()
+
+ src/hb-map.cc | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit e0883d60e4203e9a01e6276c7c56dc5d427c60b6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 12:02:21 2023 -0700
+
+    Whitespace
+
+ src/hb-paint-extents.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 82a3b2dbb5fa65c2dba8f2ec81796f45e4ffe9a1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 11:18:22 2023 -0700
+
+    [util] Fix --named-instance
+
+ util/font-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ad6b9c417d240b82ed4e03f6cd9a1b4bec993064
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 11:07:03 2023 -0700
+
+    [util] Format --list-features
+
+ util/font-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0f4da85074a0de1c0221d8af1d100eba4e78e3b9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 11:04:38 2023 -0700
+
+    [util] Minor in --list-features clear feature set between GSUB/GPOS
+
+ util/font-options.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit f25e3696eb315e3bccc24b9d4b89ce22c9f05c5f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 16 10:54:23 2023 -0700
+
+    [hb-shape/hb-view] Better --list-features
+
+ util/font-options.hh | 111 +++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 72 insertions(+), 39 deletions(-)
+
+commit 32d439596d8d6157f4b621570f120afea6b3ca38
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 22:34:14 2023 -0700
+
+    [hb-shape/view] Print feature names in --list-features
+
+ util/font-options.hh | 41 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 38 insertions(+), 3 deletions(-)
+
+commit cc6a9bfa6f4eca07b8dec693acfc557cd21c073c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 18:16:19 2023 -0700
+
+    [hb-shape/view] Print table length in --list-tables
+
+ util/face-options.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 880d65c9056dc029140af0084693189dbab5fb71
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 18:14:14 2023 -0700
+
+    [hb-shape/view] Add --list-tables
+
+ util/face-options.hh | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+commit 3d5a922bcac06a47a589070b49f58b44d0c7ba2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 16:15:52 2023 -0700
+
+    Fix really
+
+ util/font-options.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 484831be3dd1e113c92370cc5df781432b770ccd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 16:14:53 2023 -0700
+
+    [util] Fix build
+
+ util/font-options.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 8a6ecc5c89c524bf0a2d985dc39eaf793bfe5a01
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 13:54:27 2023 -0700
+
+    [hb-view/shape] Add --list-features
+
+ util/font-options.hh | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+commit 40a8145acc7e90535c0089e393216a5602f7f9e4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 11:30:24 2023 -0700
+
+    [util] Don't use hb_vector_t
+
+ util/font-options.hh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit d769e8ae7c125cf2ed0686f3c9e99e9525ecbbd4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 10:58:15 2023 -0700
+
+    [hb-shape/view] Add --named-instance
+
+ src/hb-font.cc       | 11 ++++++-----
+ util/font-options.hh |  3 +++
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+commit 99838770abbd810caf63db7957d524537cb34290
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 10:54:01 2023 -0700
+
+    [font] Add hb_font_get_var_named_instance()
+    
+    Two new API:
+    +HB_FONT_NO_VAR_NAMED_INSTANCE
+    +hb_font_get_var_named_instance
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-font.cc             | 28 ++++++++++++++++++++++------
+ src/hb-font.h              | 15 ++++++++++++++-
+ 3 files changed, 38 insertions(+), 7 deletions(-)
+
+commit 40bf30bfeb5cda9a8e147313f7b3a7ba8f671275
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 10:45:47 2023 -0700
+
+    [util] Print named-instance index in --list-variations
+
+ util/font-options.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d195e077e9ba22c2c54c2efc1677a4ded6ff250b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 10:44:04 2023 -0700
+
+    [font] Remember named_instance index
+    
+    Specially, in hb_font_set_variations() default to the named_instance
+    for unspecified axes.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1883
+
+ src/hb-font.cc | 36 ++++++++++++++++++++----------------
+ src/hb-font.hh |  1 +
+ 2 files changed, 21 insertions(+), 16 deletions(-)
+
+commit 14a83d6cc7c6da9f82d1d048ad930d9654c3e479
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 10:11:54 2023 -0700
+
+    [hb-shape/view] --list-variations cleanup
+
+ util/font-options.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit e1a5448306a555a66cb337a419e275bb5d98d461
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 10:00:26 2023 -0700
+
+    [hb-shape/view] Print named-instances in --list-variations
+    
+    Might remove the coordinates.
+
+ util/font-options.hh | 30 +++++++++++++++++++++++++++++-
+ 1 file changed, 29 insertions(+), 1 deletion(-)
+
+commit 9abc21072b34b4170fbc73bdec7e6b7dcd70d123
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 15 09:46:19 2023 -0700
+
+    [hb-shape/view] Add --list-variations
+
+ util/font-options.hh | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+commit d015e9016c4c4028996ba6ea2be11756963d2a2c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:50:16 2023 -0700
+
+    [ms-features] Comment
+
+ src/hb-ms-feature-ranges.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit ea1ee0d4b6e283b025cf37cee9f8359c8b848ac1
+Author: Garret Rieger <grieger at google.com>
+Date:   Sat Jan 14 00:23:53 2023 +0000
+
+    [instance] drop and don't collect lookups from feature variations when fully instancing.
+    
+    This previously incorrectly collected lookups that could be reached via feature variations that are dropped and not activated by the current instance position.
+
+ src/hb-ot-layout-gsubgpos.hh                       |  23 ++++++++++++++++++---
+ src/hb-subset-plan.cc                              |  12 ++++++++++-
+ .../MPLUS1-Variable.default.30DD.wght=100.ttf      | Bin 0 -> 1460 bytes
+ .../MPLUS1-Variable.default.30DD.wght=400.ttf      | Bin 0 -> 1712 bytes
+ ...iable.default.retain-all-codepoint.wght=400.ttf | Bin 1660624 -> 0 bytes
+ ...otdef-outline.retain-all-codepoint.wght=400.ttf | Bin 1660668 -> 0 bytes
+ ...ototype.layout-test-retain-gids.41,42,43,57.otf | Bin 5924 -> 5920 bytes
+ ...FPrototype.layout-test-retain-gids.41,42,43.otf | Bin 5212 -> 5208 bytes
+ ...beVFPrototype.layout-test-retain-gids.41,42.otf | Bin 4732 -> 4728 bytes
+ ...FPrototype.layout-test-retain-gids.41,56,57.otf | Bin 5048 -> 5044 bytes
+ ...AdobeVFPrototype.layout-test-retain-gids.41.otf | Bin 3996 -> 3992 bytes
+ ...beVFPrototype.layout-test-retain-gids.42,57.otf | Bin 5040 -> 5036 bytes
+ .../AdobeVFPrototype.layout-test.41,42,43,57.otf   | Bin 5480 -> 5476 bytes
+ .../AdobeVFPrototype.layout-test.41,42,43.otf      | Bin 4952 -> 4948 bytes
+ .../AdobeVFPrototype.layout-test.41,42.otf         | Bin 4468 -> 4464 bytes
+ .../AdobeVFPrototype.layout-test.41,56,57.otf      | Bin 4620 -> 4616 bytes
+ .../AdobeVFPrototype.layout-test.41.otf            | Bin 3768 -> 3764 bytes
+ .../AdobeVFPrototype.layout-test.42,57.otf         | Bin 4600 -> 4596 bytes
+ .../data/expected/variable/Fraunces.default.61.ttf | Bin 4232 -> 4228 bytes
+ .../data/tests/instance_feature_variations.tests   |   4 ++--
+ 20 files changed, 33 insertions(+), 6 deletions(-)
+
+commit d250148db08f620022092487578f36474f35b127
+Merge: 81b942e36 60a4f2e6f
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Thu Jan 12 21:26:24 2023 -0500
+
+    Merge pull request #4024 from harfbuzz/test-paint-variable
+    
+    test-paint: Add variable font tests
+
+commit 60a4f2e6f5fd8896cd09a1274a4e772c987d695d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 19:12:46 2023 -0700
+
+    [test-paint] Detect FreeType COLRv1 from struct size
+
+ test/api/test-paint.c | 55 +++++++++++++++++++++++++++++----------------------
+ 1 file changed, 31 insertions(+), 24 deletions(-)
+
+commit b783967242cce70e814fc817c49f08e4ec0599ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:58:07 2023 -0700
+
+    [test] Minor save glyph_count
+
+ test/api/test-paint.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit cca0ed9bcd91fbdb4611cfba51ebf068d50081ed
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jan 11 06:44:25 2023 -0500
+
+    test-paint: Add variable font tests
+    
+    These needs freetype master to work.
+
+ .../api/fonts/test_glyphs-glyf_colr_1_variable.ttf | Bin 0 -> 70336 bytes
+ test/api/results/testvf-10                         |  22 +++++++++
+ test/api/results/testvf-106                        |  30 ++++++++++++
+ test/api/results/testvf-116                        |  26 +++++++++++
+ test/api/results/testvf-123                        |  47 +++++++++++++++++++
+ test/api/results/testvf-154                        |  30 ++++++++++++
+ test/api/results/testvf-165                        |  22 +++++++++
+ test/api/results/testvf-175                        |  36 +++++++++++++++
+ test/api/results/testvf-6                          |  21 +++++++++
+ test/api/results/testvf-92                         |  21 +++++++++
+ test/api/test-paint.c                              |  51 +++++++++++++++++----
+ 11 files changed, 296 insertions(+), 10 deletions(-)
+
+commit 81b942e363f3ca7b156e2a1ba21f74c1f3de8848
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:42:22 2023 -0700
+
+    [os2] Comment
+
+ src/hb-ot-os2-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 9fb9be8d43262f46c8a639d80fa049dcb0e440f0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:37:45 2023 -0700
+
+    [os2] Rewrite a loop
+
+ src/hb-ot-os2-table.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 082e5c5defec424856fdc82c94a388eac1c409c2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:37:07 2023 -0700
+
+    [os2] Minor add a cast
+
+ src/hb-ot-os2-unicode-ranges.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 45fe897e89f348bc16db538d2da7583e5fa4808a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:36:16 2023 -0700
+
+    [os2] Rename a couple of variables
+
+ src/hb-ot-os2-unicode-ranges.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 2dcbf3bd07ea10bf81548f4407afead2cc1ea2b0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 18:29:16 2023 -0700
+
+    [os2] Inline a trivial function
+
+ src/hb-ot-os2-table.hh | 16 ++--------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+commit 075fe33446aa66ee36004f23a309b41e18991d49
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 17:14:42 2023 -0700
+
+    Enable -Wunsafe-loop-optimizations
+    
+    I don't get any.
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ed023f66df642b58e486da855e871c7dbc0a9576
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 17:04:24 2023 -0700
+
+    Enable -Wformat-signedness
+    
+    And fix the codebase.
+
+ src/OT/Layout/GPOS/CursivePosFormat1.hh            |  4 +--
+ src/OT/Layout/GPOS/MarkArray.hh                    |  4 +--
+ src/OT/Layout/GPOS/PairPosFormat2.hh               |  6 ++--
+ src/OT/Layout/GPOS/PairSet.hh                      |  6 ++--
+ src/OT/Layout/GPOS/SinglePosFormat1.hh             |  4 +--
+ src/OT/Layout/GPOS/SinglePosFormat2.hh             |  4 +--
+ src/OT/Layout/GSUB/AlternateSet.hh                 |  6 ++--
+ src/OT/Layout/GSUB/Ligature.hh                     |  8 ++---
+ .../Layout/GSUB/ReverseChainSingleSubstFormat1.hh  |  4 +--
+ src/OT/Layout/GSUB/Sequence.hh                     | 12 ++++----
+ src/OT/Layout/GSUB/SingleSubstFormat1.hh           |  6 ++--
+ src/OT/Layout/GSUB/SingleSubstFormat2.hh           |  6 ++--
+ src/OT/glyf/SubsetGlyph.hh                         |  2 +-
+ src/OT/glyf/glyf-helpers.hh                        |  4 +--
+ src/graph/graph.hh                                 |  8 ++---
+ src/graph/serialize.hh                             |  6 ++--
+ src/hb-aat-layout-kerx-table.hh                    |  4 +--
+ src/hb-aat-layout-morx-table.hh                    |  6 ++--
+ src/hb-buffer-verify.cc                            |  4 +--
+ src/hb-debug.hh                                    |  2 +-
+ src/hb-ot-layout-gsubgpos.hh                       |  2 +-
+ src/hb-ot-layout.cc                                |  6 ++--
+ src/hb-ot-shaper-arabic.cc                         | 16 +++++-----
+ src/hb-ot-shaper-indic-machine.hh                  |  2 +-
+ src/hb-ot-shaper-indic-machine.rl                  |  2 +-
+ src/hb-ot-shaper-khmer-machine.hh                  |  2 +-
+ src/hb-ot-shaper-khmer-machine.rl                  |  2 +-
+ src/hb-ot-shaper-myanmar-machine.hh                |  2 +-
+ src/hb-ot-shaper-myanmar-machine.rl                |  2 +-
+ src/hb-ot-shaper-use-machine.hh                    |  2 +-
+ src/hb-ot-shaper-use-machine.rl                    |  2 +-
+ src/hb-ot-tag.cc                                   |  4 +--
+ src/hb-repacker.hh                                 |  4 +--
+ src/hb-sanitize.hh                                 |  8 ++---
+ src/hb-shape-plan.cc                               |  6 ++--
+ src/hb-subset-plan.hh                              |  2 +-
+ src/hb.hh                                          |  2 +-
+ src/main.cc                                        | 36 +++++++++++-----------
+ src/test-ot-meta.cc                                |  4 +--
+ src/test-unicode-ranges.cc                         |  2 +-
+ src/test.cc                                        |  2 +-
+ util/font-options.hh                               |  2 +-
+ util/shape-format.hh                               |  2 +-
+ 43 files changed, 110 insertions(+), 110 deletions(-)
+
+commit 7b5f0dd3a8b4a126b7952fea1c4c30b8b456083e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 15:05:19 2023 -0700
+
+    Move hb-ot-name-language-static.hh out of hb-static.cc
+    
+    Since hb-static.cc is used by libharfbuzz-cairo as well.
+
+ src/hb-ot-name.cc | 2 ++
+ src/hb-static.cc  | 1 -
+ src/hb-subset.cc  | 5 +++++
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+commit 449f6df7622c2e363841823c92ca5fd4faee9d62
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 14:52:00 2023 -0700
+
+    [mutex] Add constructor/destructor
+    
+    Use in one place.
+
+ src/hb-mutex.hh              | 3 +++
+ src/hb-subset-accelerator.hh | 7 +------
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+commit 8e71f7e8eda4ab4c664ee5c073db56f223bf6b20
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 14:46:44 2023 -0700
+
+    [subset-accelerator] Streamline constructor/destructor
+
+ src/hb-subset-accelerator.hh | 52 +++++++++++++++++++++++++++++---------------
+ 1 file changed, 34 insertions(+), 18 deletions(-)
+
+commit c4c646280fd2b6e3141ecc0f45d477c8f2b43bc7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 13:58:46 2023 -0700
+
+    [unicode] Adjust error message
+
+ src/hb-unicode.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0d665291358f2648725e605e7deb88cbe4ee0490
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 13:14:24 2023 -0700
+
+    [bit-page] Minor simplify bit-page specification
+
+ src/hb-bit-page.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 32866a331e49da465812f329d494bb8612dc14db
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 13:02:30 2023 -0700
+
+    [subset-input] Simplify destruction
+
+ src/hb-subset-input.hh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit d5b826fd0910f68dcdc4c6f6e990c7b188a95255
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 12:55:47 2023 -0700
+
+    [subset-input] Fix leak
+
+ src/hb-subset-input.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit c52810529e8eae366b0d7d94b8077b5e2ab5f06b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 12:53:46 2023 -0700
+
+    [subset-plan] Move construction to constructor
+
+ src/hb-subset-plan.cc | 157 ++++++++++++++++++++++++++------------------------
+ src/hb-subset-plan.hh |   3 +
+ 2 files changed, 84 insertions(+), 76 deletions(-)
+
+commit 26d69e059dc2fbf03ae28e52a08c1bd38f7ce2bf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 12:46:44 2023 -0700
+
+    [subset-input] Move constructor to .cc file
+
+ src/hb-subset-input.cc | 160 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-subset-input.hh | 158 +-----------------------------------------------
+ 2 files changed, 161 insertions(+), 157 deletions(-)
+
+commit a916ad9ea9b8cfc1cc34608fd4a3e608a4ef76f0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 12:44:16 2023 -0700
+
+    [subset-input] Move initialization to constructor
+
+ src/hb-subset-input.cc | 157 ------------------------------------------------
+ src/hb-subset-input.hh | 158 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 157 insertions(+), 158 deletions(-)
+
+commit 875f9f6f22451f1cc02782a8269f7e1e4bce0ca0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 12:37:48 2023 -0700
+
+    [subset-input] Use shared_ptr for sets
+
+ src/hb-subset-input.cc |  2 +-
+ src/hb-subset-input.hh | 29 ++++++++++++++---------------
+ 2 files changed, 15 insertions(+), 16 deletions(-)
+
+commit ef005bc82a48d8ee0acd073a17c7d3481ecb702e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 12:09:14 2023 -0700
+
+    [subset-input] Fix destruction
+    
+    Ouch! Object was already destroyed at that point before.
+
+ src/hb-subset-input.cc |  8 --------
+ src/hb-subset-input.hh | 11 +++++++++++
+ src/hb-subset-plan.hh  |  3 ---
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+commit c60c5995bb36a4796c747243d1e43bca04b1332f
+Merge: 8c83de139 cfb672f1e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 11:59:51 2023 -0700
+
+    Merge pull request #4028 from harfbuzz/mvar-instancing
+    
+    [instancer] Add MVAR values to OS/2
+
+commit cfb672f1e5cb0e855cec3e5baacee1507e973ce3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 10:36:39 2023 -0700
+
+    [glyf] Revert sign of advance widths back
+
+ src/OT/glyf/Glyph.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit c324d999521d3886af4560a810dcd34ef779125f
+Author: Garret Rieger <grieger at google.com>
+Date:   Thu Jan 12 18:15:07 2023 +0000
+
+    [instancing] Add tests for MVAR instancing.
+
+ ...out.retain-all-codepoint.wght=150,wdth=80,CTGR=0.ttf | Bin 0 -> 1396 bytes
+ ...out.retain-all-codepoint.wght=300,wdth=90,CTGR=0.ttf | Bin 0 -> 1432 bytes
+ test/subset/data/fonts/NotoSans-VF.abc.ttf              | Bin 0 -> 11156 bytes
+ test/subset/data/profiles/no-layout.txt                 |   1 +
+ test/subset/data/tests/mvar_full_instance.tests         |  12 ++++++++++++
+ 5 files changed, 13 insertions(+)
+
+commit 8c83de1396c7b51acfd1ba1482e2dbe816048363
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 12 10:44:08 2023 -0700
+
+    [aat] Initialize values
+
+ src/hb-aat-map.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ca1909154938084be149bf84e1f38edec5bb682b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 14:36:02 2023 -0700
+
+    [hhea/vhea] Add MVAR during instancing
+
+ src/hb-ot-hmtx-table.hh | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+commit f4550001380bf1c8f70119908d83538d4bafb918
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 14:25:37 2023 -0700
+
+    [post] Add MVAR to subsetting
+
+ src/hb-ot-post-table.hh | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 9dc3e785aad419c832b69fb6d8ad53258dc8273a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 14:09:47 2023 -0700
+
+    [instancer] Add MVAR values to OS/2
+
+ src/hb-ot-os2-table.hh      | 33 +++++++++++++++++++++++++++++++++
+ src/hb-ot-var-mvar-table.hh |  9 +++++++++
+ 2 files changed, 42 insertions(+)
+
+commit e78a68bf467b86daa17377dc08f382cadb8d748c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 15:34:11 2023 -0700
+
+    [subset-input] Don't RETAIN_GIDs in keep-everything
+
+ src/hb-subset-input.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit d675f0d4f2d6269ac1dd92fa0ea0db79ce5ee3a1
+Merge: 52c8c5a05 bfd7548e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 15:06:31 2023 -0700
+
+    Merge pull request #4023 from harfbuzz/aat-features2
+    
+    [aat] Support feature ranges
+
+commit 52c8c5a058dbbfe9373d786718b69568a25b41e0
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Jan 11 18:50:24 2023 +0200
+
+    [doc] Fix API indices generation
+    
+    For whatever reason, GTK-Doc 1.33.1 will not generate HTML files for
+    indices that has these role attributes.
+
+ docs/harfbuzz-docs.xml | 128 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 64 insertions(+), 64 deletions(-)
+
+commit 1135f0b8cc9fc00129012f7022986c75732ffd60
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 13:45:16 2023 -0700
+
+    Another try at fixing arm build
+
+ src/hb-ot-hmtx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 527e2d7ce2a2659c69f90c6bc86b5bb8838ed682
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 13:41:44 2023 -0700
+
+    [gobject] Add another value type hb_ot_var_axis_info
+
+ src/hb-gobject-structs.cc | 1 +
+ src/hb-gobject-structs.h  | 4 ++++
+ 2 files changed, 5 insertions(+)
+
+commit 8206569d6373a0fe97602788c7a43a0cf1f0345a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 13:24:50 2023 -0700
+
+    [map] Remove hashmap create/destroy/vtable
+    
+    Unused now.
+
+ src/hb-map.hh   | 32 --------------------------------
+ src/test-map.cc | 10 ----------
+ 2 files changed, 42 deletions(-)
+
+commit 1426f1c8ea29a6b71ab0f1ce9d9c79b41f407eb0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 13:23:34 2023 -0700
+
+    [subset-plan] Simplify name_table_overrides allocation
+
+ src/hb-subset-input.cc | 20 ++++----------------
+ src/hb-subset-input.hh |  4 ++--
+ src/hb-subset-plan.cc  | 21 +++++++++------------
+ 3 files changed, 15 insertions(+), 30 deletions(-)
+
+commit 5cab4a55d28ec51abe1cf4a7bd09c1814378fc67
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 13:21:57 2023 -0700
+
+    [subset-input] Simplify axes_location allocation
+
+ src/hb-subset-input.cc | 9 +++------
+ src/hb-subset-input.hh | 4 ++--
+ src/hb-subset-plan.cc  | 3 +--
+ 3 files changed, 6 insertions(+), 10 deletions(-)
+
+commit df721e05628daa0d5dd9998ff22dec98db9433e7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:50:52 2023 -0700
+
+    [gobject] Add draw/paint value types
+
+ src/hb-gobject-structs.cc |  3 +++
+ src/hb-gobject-structs.h  | 12 ++++++++++++
+ 2 files changed, 15 insertions(+)
+
+commit 41352c08b8baa2a731331126a64978df80371b0f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:42:14 2023 -0700
+
+    [hmtx] Fix types
+
+ src/hb-ot-hmtx-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4e7c80396928aef328a31b84f1d8df479e31d340
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:38:26 2023 -0700
+
+    [subset-plan] Simplify name_table_overrides allocation
+
+ src/hb-ot-name-table.hh |  2 +-
+ src/hb-subset-plan.cc   |  5 ++---
+ src/hb-subset-plan.hh   | 10 +++-------
+ 3 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 65d3db375cb51204ac971dcd2d978684ab8a9422
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:36:54 2023 -0700
+
+    [subset-plan] Simplify user_axes_location allocation
+
+ src/OT/glyf/glyf.hh         |  6 +++---
+ src/hb-ot-layout-common.hh  |  4 ++--
+ src/hb-ot-os2-table.hh      |  8 ++++----
+ src/hb-ot-post-table.hh     |  4 ++--
+ src/hb-ot-stat-table.hh     |  8 ++++----
+ src/hb-ot-var-fvar-table.hh |  2 +-
+ src/hb-subset-plan.cc       | 23 +++++++++++------------
+ src/hb-subset-plan.hh       |  4 +---
+ src/hb-subset.cc            |  2 +-
+ 9 files changed, 29 insertions(+), 32 deletions(-)
+
+commit 60418fcb95519013d1cf7ef57d9e63431401dc6a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:33:25 2023 -0700
+
+    [subset-plan] Simplify axes_index_map allocation
+
+ src/hb-ot-layout-common.hh  | 2 +-
+ src/hb-ot-var-fvar-table.hh | 6 +++---
+ src/hb-subset-plan.cc       | 3 +--
+ src/hb-subset-plan.hh       | 3 +--
+ 4 files changed, 6 insertions(+), 8 deletions(-)
+
+commit 8265277c2ee60c6d9f4e6b87f86bc2b3b296338a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:32:04 2023 -0700
+
+    [subset-plan] Simplify axes_location allocation
+
+ src/hb-subset-plan.cc | 5 ++---
+ src/hb-subset-plan.hh | 3 +--
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+commit d54902c6598045112374f1f51e1775677dd77d94
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:29:25 2023 -0700
+
+    [subset-plan] Simplify axes_old_index_tag_map allocation
+
+ src/hb-ot-var-fvar-table.hh | 2 +-
+ src/hb-subset-plan.cc       | 5 ++---
+ src/hb-subset-plan.hh       | 3 +--
+ 3 files changed, 4 insertions(+), 6 deletions(-)
+
+commit 9f4c8fb7004bfce2bcc29f3be900a5f907e92fb3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:28:18 2023 -0700
+
+    [subset-plan] Minor move code around
+
+ src/hb-subset-plan.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit a34a204bf74ee0c08a67c97444ce803d6f0a0b6d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:27:19 2023 -0700
+
+    [subset-plan] Simplify unicodes allocation
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ src/hb-ot-os2-table.hh  | 4 ++--
+ src/hb-subset-plan.cc   | 9 ++++-----
+ src/hb-subset-plan.hh   | 3 +--
+ 4 files changed, 8 insertions(+), 10 deletions(-)
+
+commit 75b33cb04b783f9f8473df46b603b6e94dc226b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:24:35 2023 -0700
+
+    [subset-plan] Simplify hmtx_map / vmtx_map allocation
+
+ src/OT/glyf/Glyph.hh    | 4 ++--
+ src/hb-ot-hmtx-table.hh | 2 +-
+ src/hb-subset-plan.cc   | 3 ---
+ src/hb-subset-plan.hh   | 6 ++----
+ 4 files changed, 5 insertions(+), 10 deletions(-)
+
+commit 33ce3a0d446bef5b26fb11032849115ad948d76b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:21:26 2023 -0700
+
+    [subset] Minor adjust a couple types
+
+ src/OT/glyf/Glyph.hh  | 4 ++--
+ src/hb-subset-plan.cc | 4 ++--
+ src/hb-subset-plan.hh | 4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 865d1747066a4dc91bf99cff182ae4504a53aa4f
+Merge: 5f51dd276 67eefebf8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 12:14:17 2023 -0700
+
+    Merge pull request #4027 from harfbuzz/plan-simplify
+    
+    Plan simplify
+
+commit 67eefebf8d61796a63e6e8e7c79a40564c45d723
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:44:09 2023 -0700
+
+    [subset-plan] Simplify user_axes_location destruction
+
+ src/hb-subset-plan.hh | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+commit b2007abff75f0d5d8b472e66e3b84947c9d06a70
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:27:22 2023 -0700
+
+    [subset-plan] Simplify glyph_map_gsub allocation
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-subset-plan.cc      | 3 +--
+ src/hb-subset-plan.hh      | 3 +--
+ 3 files changed, 4 insertions(+), 6 deletions(-)
+
+commit bd4b040e7f6c34afd811d5b8d37e967f18ffe728
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:23:48 2023 -0700
+
+    [shape-plan] Simplify glyphs_requested allocation
+
+ src/hb-ot-cmap-table.hh | 2 +-
+ src/hb-subset-plan.cc   | 2 +-
+ src/hb-subset-plan.hh   | 3 +--
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+commit c51d33685db7a85243260585f2e8f0aba904f982
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:22:22 2023 -0700
+
+    [subset-plan] Simplify no_subset_tables allocation
+
+ src/hb-subset-plan.cc | 2 +-
+ src/hb-subset-plan.hh | 3 +--
+ src/hb-subset.cc      | 6 +++---
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+commit 999be72135a45f1e1e36b32d1944a6d6b7335f17
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:21:17 2023 -0700
+
+    [subset-plan] Simplify drop_tables allocation
+
+ src/hb-subset-plan.cc | 2 +-
+ src/hb-subset-plan.hh | 3 +--
+ src/hb-subset.cc      | 2 +-
+ 3 files changed, 3 insertions(+), 4 deletions(-)
+
+commit b33eb9ecfc255f43006ccd422f0f6807f4f7a100
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:20:04 2023 -0700
+
+    [subset-plan] Simplify layout_variation_idx_delta_map allocation
+
+ src/OT/Layout/GPOS/AnchorFormat3.hh    | 12 ++++++------
+ src/OT/Layout/GPOS/PairPosFormat2.hh   |  4 ++--
+ src/OT/Layout/GPOS/PairSet.hh          |  2 +-
+ src/OT/Layout/GPOS/SinglePosFormat1.hh |  2 +-
+ src/OT/Layout/GPOS/SinglePosFormat2.hh |  2 +-
+ src/hb-ot-layout-gdef-table.hh         |  6 +++---
+ src/hb-subset-plan.cc                  |  5 ++---
+ src/hb-subset-plan.hh                  |  3 +--
+ 8 files changed, 17 insertions(+), 19 deletions(-)
+
+commit 9c45d98f732304e59ec2f81b3c7bb3c1f55fa78c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:16:18 2023 -0700
+
+    [subset-plan] Simplify colr_palettes allocation
+
+ src/OT/Color/COLR/COLR.hh | 6 +++---
+ src/OT/Color/CPAL/CPAL.hh | 2 +-
+ src/hb-subset-plan.cc     | 3 +--
+ src/hb-subset-plan.hh     | 3 +--
+ 4 files changed, 6 insertions(+), 8 deletions(-)
+
+commit b74a26519614c816a92bdcc8f6cd920647da90d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:15:15 2023 -0700
+
+    [subset-plan] Simplify colrv1_layers allocation
+
+ src/OT/Color/COLR/COLR.hh | 2 +-
+ src/hb-subset-plan.cc     | 3 +--
+ src/hb-subset-plan.hh     | 3 +--
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+commit 89905368ca75496fac663710ea03f1bb90cd33cb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:13:49 2023 -0700
+
+    [subset-plan] Simplify sanitized_table_cache allocation
+
+ src/hb-subset-plan.cc | 1 -
+ src/hb-subset-plan.hh | 5 ++---
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+commit 9e24873c1e2459a78bb97ef31e0c42779aa88ae8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:12:07 2023 -0700
+
+    [subset-plan] Simplify gsub/gpos_feature_substitutes_map allocation
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-subset-plan.cc      | 7 ++-----
+ src/hb-subset-plan.hh      | 6 ++----
+ 3 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 01208c7c02b779fb816391eb4a7ea6b76bd91cdc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:10:28 2023 -0700
+
+    [subset-plan] Simplify gsub/gpos_feature_record_cond_idx_map allocation
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-subset-plan.cc      | 7 ++-----
+ src/hb-subset-plan.hh      | 6 ++----
+ 3 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 06039db0801f68bfe93dcff1c733595d77a1580e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:07:31 2023 -0700
+
+    [subset-plan] Simplify gsub_langsys and gpos_langsys allocation
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-subset-plan.cc      | 7 ++-----
+ src/hb-subset-plan.hh      | 6 ++----
+ 3 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 5fc91de2c0f32f0e067950ce004f498a378690e9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:04:17 2023 -0700
+
+    [shape-plan] Simplify _glyphset_colred allocation
+
+ src/OT/Color/COLR/COLR.hh | 6 +++---
+ src/hb-subset-plan.cc     | 3 +--
+ src/hb-subset-plan.hh     | 3 +--
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+commit efafe7aa3bef6d4367ca10caefb24802f809b299
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:03:19 2023 -0700
+
+    [subset-plan] Simplify _glyphset_mathed allocation
+
+ src/hb-ot-math-table.hh | 10 +++++-----
+ src/hb-subset-plan.cc   |  9 ++++-----
+ src/hb-subset-plan.hh   |  3 +--
+ 3 files changed, 10 insertions(+), 12 deletions(-)
+
+commit 113a1700df64b4ade259fac37bf434925664b050
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:01:11 2023 -0700
+
+    [subset-plan] Simplify _glyphset_gsub allocation
+
+ src/hb-subset-plan.cc | 21 ++++++++++-----------
+ src/hb-subset-plan.hh |  5 ++---
+ 2 files changed, 12 insertions(+), 14 deletions(-)
+
+commit 4a9268f2807db09f3b6480b7a1deb544d99b6f87
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 11:00:02 2023 -0700
+
+    [subset-plan] Simplify _glyphset allocation
+
+ src/hb-subset-plan.cc | 11 +++++------
+ src/hb-subset-plan.hh |  7 +++----
+ 2 files changed, 8 insertions(+), 10 deletions(-)
+
+commit 1a00ab69ec012e296f9ec11a9c5619d637012b3b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 10:56:16 2023 -0700
+
+    [subset-plan] Simplify gsub_lookups and gpos_lookups allocation
+
+ src/hb-ot-layout-common.hh   |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh | 12 ++++++------
+ src/hb-subset-plan.cc        |  8 +++-----
+ src/hb-subset-plan.hh        |  6 ++----
+ 4 files changed, 13 insertions(+), 17 deletions(-)
+
+commit 1a716bad03a9d628a97d8212f37cd83b7ad3e76f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 10:51:48 2023 -0700
+
+    [subset-plan] Simplify gsub_features and gpos_features allocation
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-subset-plan.cc      | 7 ++-----
+ src/hb-subset-plan.hh      | 6 ++----
+ 3 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 78aa9f1e9c5f68249628746178c4088c2eb3e8d5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 10:47:40 2023 -0700
+
+    [subset-plan] Simplify name_ids allocation
+
+ src/hb-subset-plan.cc | 4 ++--
+ src/hb-subset-plan.hh | 3 +--
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit cfb48f91da9089c8f9ea0069c4e001562980b7e9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 10:45:02 2023 -0700
+
+    [subset-plan] Simplify name_languages allocation
+
+ src/hb-subset-plan.cc | 2 +-
+ src/hb-subset-plan.hh | 3 +--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+commit e4ca0fe436b691bba3f405a722cb178c3e62a828
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 10:43:01 2023 -0700
+
+    [subset-plan] Simplify layout_features allocation
+
+ src/hb-subset-plan.cc | 4 ++--
+ src/hb-subset-plan.hh | 3 +--
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 4de66eec5751e57eee64730aec271313b2f3ea2f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 11 10:40:54 2023 -0700
+
+    [subset-plan] Simplify layout_scripts allocation
+
+ src/hb-ot-layout-common.hh | 2 +-
+ src/hb-subset-plan.cc      | 6 +++---
+ src/hb-subset-plan.hh      | 3 +--
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+commit 5f51dd276b5636d541d4a6b94314f48432b08ff2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 22:57:07 2023 -0700
+
+    [ft-colr] Minor use false instead of 0
+
+ src/hb-ft-colr.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f84a8e3289212b261fa9d9847c4628a1dd4b2153
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 22:43:30 2023 -0700
+
+    [ft-colr] Comment
+
+ src/hb-ft-colr.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 1cb5a87febb84dd3c8323e82da1db33d539310be
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 10 22:13:44 2023 -0500
+
+    test-pain: Print out extend for color lines
+    
+    Update all expected results to include this value.
+
+ test/api/results/bad-154   |  2 +-
+ test/api/results/hand-10   | 10 +++++-----
+ test/api/results/hand-10.2 | 10 +++++-----
+ test/api/results/rocher-1  |  2 +-
+ test/api/results/rocher-2  |  2 +-
+ test/api/results/rocher-3  |  2 +-
+ test/api/results/test-10   |  4 ++--
+ test/api/results/test-106  |  2 +-
+ test/api/results/test-116  |  2 +-
+ test/api/results/test-123  |  2 +-
+ test/api/results/test-154  |  4 ++--
+ test/api/results/test-165  |  4 ++--
+ test/api/results/test-175  |  4 ++--
+ test/api/results/test-6    |  4 ++--
+ test/api/results/test-92   |  4 ++--
+ test/api/test-paint.c      |  2 +-
+ 16 files changed, 30 insertions(+), 30 deletions(-)
+
+commit 6648e6e3e5b0d93dee8fcc3cbe7fd886ba324ee3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Jan 10 22:07:44 2023 -0500
+
+    Add one more paint test
+    
+    Add a test for the clip_box_top_left_glyph,
+    since we've seen broken rendering with it.
+
+ test/api/results/test-154 | 30 ++++++++++++++++++++++++++++++
+ test/api/test-paint.c     |  1 +
+ 2 files changed, 31 insertions(+)
+
+commit bf16dad55aac9225a7b857a392267959600568e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 17:29:25 2023 -0700
+
+    [paint-extents] Return unbounded on memory allocation failure
+
+ src/hb-paint-extents.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3e1c524e64c9829234f9c89f99a31af3aabe3ab8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 17:18:34 2023 -0700
+
+    [bit-page] Comment
+
+ src/hb-bit-page.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 626def03f8abbc818661a4178b2463ce6b108093
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 17:12:50 2023 -0700
+
+    [hmtx] Remove TODO items
+
+ src/hb-ot-hmtx-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit adf0bd6dcd20b684dc3a64bcb219fced5918a1be
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 17:04:58 2023 -0700
+
+    [test-map] Add a test
+
+ src/test-map.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 4fd03540679b3630cd023825ed2ee2a5ecc60457
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 14:32:08 2023 -0700
+
+    [font] Docs
+
+ src/hb-font.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit bfd7548e243ab92ed02e66c95d244c78dd6e622b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 13:31:58 2023 -0700
+
+    [aat] Optimize feature-range application
+
+ src/hb-aat-layout-morx-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit dd42939e318c90f2c0f7d0efc1c4354182552f72
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 13:23:19 2023 -0700
+
+    [aat] Reduce unsafe_to_concat calls
+
+ src/hb-aat-layout-common.hh     | 2 --
+ src/hb-aat-layout-kerx-table.hh | 2 ++
+ src/hb-aat-layout-morx-table.hh | 3 +++
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+commit fecce62a45d996fbca11cea6c34bdbadec283ba4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 13:13:43 2023 -0700
+
+    [ft] Docs
+
+ src/hb-ft.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit cb509d9c894a8b9aa586eebf896526578fdd8822
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 13:11:48 2023 -0700
+
+    [face] Docs
+
+ src/hb-face.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 8a2efbd8a113ec885b3a437c014912ca9ee22460
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 13:10:36 2023 -0700
+
+    [upem] More docs
+
+ src/hb-face.cc | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit ccffce58cc5bcb07d82b2085a3ebb42ea04b2579
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 13:09:30 2023 -0700
+
+    [scale] More docs
+
+ src/hb-font.cc | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+commit c4580d8670218c750e9c8e058b4e10841526acd0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 12:56:02 2023 -0700
+
+    [scale] More docs
+
+ src/hb-font.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit f0e695a3a96cc2396c47a2a29966a8e0f9f682cb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 12:55:17 2023 -0700
+
+    [scale] Comment
+
+ src/hb-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 8c47580ac85b3eed0b932d50236d589e8c8747cf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 12:53:54 2023 -0700
+
+    [scale] Document
+
+ src/hb-font.cc | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 8b17c6ca302e969ab285e0ea7da067cfe6a1a27d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 12:17:38 2023 -0700
+
+    [aat] Comment
+
+ src/hb-aat-layout-common.hh     | 1 +
+ src/hb-aat-layout-morx-table.hh | 1 +
+ 2 files changed, 2 insertions(+)
+
+commit 0e11d317ee329f1c6afd8473e0f8a2daa6b91e25
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 12:16:04 2023 -0700
+
+    [aat] Optimize feature application
+
+ src/hb-aat-layout-common.hh     | 3 ++-
+ src/hb-aat-layout-morx-table.hh | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+commit 4ee60941140924f7247bf8dc7720fa1bf43a5bff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 11:52:12 2023 -0700
+
+    [aat] Add test for feature range
+
+ test/shape/data/in-house/tests/macos.tests | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit a70543daf3f5f88c0bb4d1fc1515a9c0803297fc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 11:49:48 2023 -0700
+
+    [aat] Always unsafe-to-concat in state machine
+
+ src/hb-aat-layout-common.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 62383315fafd973415fa9ea9454f7a1db34b2d4c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 11:29:04 2023 -0700
+
+    [aat] Try fix leak on memory allocation failure
+
+ src/hb-aat-layout-morx-table.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit e122fe2acfde26b8b95ee96ebd7a33f20c02c77c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 11:06:20 2023 -0700
+
+    [aat] Adjust last range
+    
+    Otherwise a user cluster value of -1 would have tripped us.
+
+ src/hb-aat-map.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit e28c158c35081c1f412f8d2dd10471fae360a574
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 11:03:38 2023 -0700
+
+    [aat] Run subtable across ranges if flags match
+
+ src/hb-aat-layout-common.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit 2c9c49fd3289b7c27135f8379b92f413c6f5f1f0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 10:53:21 2023 -0700
+
+    [aat] Support ranges in NonContextual subtable as well
+
+ src/hb-aat-layout-common.hh     |  1 -
+ src/hb-aat-layout-morx-table.hh | 17 +++++++++++++++++
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+commit c08308a83ca3c1c24a7013df976c3d753c633d56
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 21:42:19 2023 -0700
+
+    [aat] Always generate a feature range
+
+ src/hb-aat-map.cc | 127 +++++++++++++++++++++++++++---------------------------
+ 1 file changed, 64 insertions(+), 63 deletions(-)
+
+commit db4c87475867bea79069132544b736c19895cfe2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 21:32:15 2023 -0700
+
+    Revert "Revert "[aat] Support feature ranges""
+    
+    This reverts commit 6a7a38521f940216f1e9e2fa2bf22f7b45ce2aef.
+
+ src/hb-aat-layout-common.hh     | 105 +++++++++++++++++++++------------
+ src/hb-aat-layout-kerx-table.hh |   4 +-
+ src/hb-aat-layout-morx-table.hh |  27 +++++----
+ src/hb-aat-layout.cc            |  14 ++++-
+ src/hb-aat-layout.hh            |   4 +-
+ src/hb-aat-map.cc               | 125 ++++++++++++++++++++++++++++++----------
+ src/hb-aat-map.hh               |  45 +++++++++++----
+ src/hb-ot-shape.cc              |  43 +++-----------
+ src/hb-ot-shape.hh              |   2 -
+ 9 files changed, 239 insertions(+), 130 deletions(-)
+
+commit 0728098e454bb4adfb2fa9a3dc824c75a653d0d6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 10 10:18:29 2023 -0700
+
+    [Coverage] Speed up subset for too-large Coverage tables
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54980
+
+ src/OT/Layout/Common/Coverage.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 8460909e0c8e6d045550fd50206946ee15ad48bd
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Jan 10 17:43:10 2023 +0200
+
+    [build] Fix make dist
+
+ test/api/Makefile.am | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 6a7a38521f940216f1e9e2fa2bf22f7b45ce2aef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 21:29:19 2023 -0700
+
+    Revert "[aat] Support feature ranges"
+    
+    This reverts commit 1b7994cb3a3c35f3618d7f40c7289496bdab6f06.
+    
+    Broke Zapfino with partial ligature disabling. Debugging.
+
+ src/hb-aat-layout-common.hh     | 105 ++++++++++++---------------------
+ src/hb-aat-layout-kerx-table.hh |   4 +-
+ src/hb-aat-layout-morx-table.hh |  27 ++++-----
+ src/hb-aat-layout.cc            |  14 +----
+ src/hb-aat-layout.hh            |   4 +-
+ src/hb-aat-map.cc               | 125 ++++++++++------------------------------
+ src/hb-aat-map.hh               |  45 ++++-----------
+ src/hb-ot-shape.cc              |  43 +++++++++++---
+ src/hb-ot-shape.hh              |   2 +
+ 9 files changed, 130 insertions(+), 239 deletions(-)
+
+commit adfd5dd7a9df70f76e777627c7a0f44e89f5b0c4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 21:18:12 2023 -0700
+
+    Fix TINY build
+
+ src/hb-ot-shape.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1b7994cb3a3c35f3618d7f40c7289496bdab6f06
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 19:38:50 2023 -0700
+
+    [aat] Support feature ranges
+    
+    The hard way...
+    
+    A bit uglier than I liked it to be, but is proper at least.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4020
+
+ src/hb-aat-layout-common.hh     | 105 +++++++++++++++++++++------------
+ src/hb-aat-layout-kerx-table.hh |   4 +-
+ src/hb-aat-layout-morx-table.hh |  27 +++++----
+ src/hb-aat-layout.cc            |  14 ++++-
+ src/hb-aat-layout.hh            |   4 +-
+ src/hb-aat-map.cc               | 125 ++++++++++++++++++++++++++++++----------
+ src/hb-aat-map.hh               |  45 +++++++++++----
+ src/hb-ot-shape.cc              |  43 +++-----------
+ src/hb-ot-shape.hh              |   2 -
+ 9 files changed, 239 insertions(+), 130 deletions(-)
+
+commit 622a68695256d8505517ed58885b94b8520efe07
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 18:14:40 2023 -0700
+
+    Revert "Revert "Revert "[aat] Allow disable feature ranges"""
+    
+    This reverts commit 5202053c2c5fb2c8af9704e690b25a26bf2a0295.
+
+ src/hb-aat-layout-common.hh     | 12 +++---------
+ src/hb-aat-layout-kerx-table.hh |  4 ++--
+ src/hb-aat-layout-morx-table.hh | 38 ++++++++++++++------------------------
+ src/hb-aat-layout.cc            |  8 +++-----
+ src/hb-aat-layout.hh            |  3 +--
+ src/hb-aat-map.cc               |  8 +++-----
+ src/hb-aat-map.hh               | 17 ++++-------------
+ src/hb-ot-shape.cc              | 12 +++---------
+ 8 files changed, 33 insertions(+), 69 deletions(-)
+
+commit 0f01a8362221129729553b3b0f87bff812b32d14
+Author: Garret Rieger <grieger at google.com>
+Date:   Tue Jan 10 01:09:44 2023 +0000
+
+    [subset] add basic test for CFF2 subsetting.
+    
+    FontTools does not yet support CFF2 subsetting so we can't add a comparison test. Instead add a golden file test.
+
+ test/api/fonts/AdobeVFPrototype.abc.static.otf | Bin 0 -> 86112 bytes
+ test/api/meson.build                           |   9 ++-
+ test/api/test-instance-cff2.c                  |  75 +++++++++++++++++++++++++
+ 3 files changed, 83 insertions(+), 1 deletion(-)
+
+commit 5202053c2c5fb2c8af9704e690b25a26bf2a0295
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 17:29:43 2023 -0700
+
+    Revert "Revert "[aat] Allow disable feature ranges""
+    
+    This reverts commit 82b3e8af69b09fd908d1cd27b669234328d4a500.
+    
+    Another try.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4020
+
+ src/hb-aat-layout-common.hh     | 12 +++++++++---
+ src/hb-aat-layout-kerx-table.hh |  4 ++--
+ src/hb-aat-layout-morx-table.hh | 38 ++++++++++++++++++++++++--------------
+ src/hb-aat-layout.cc            |  8 +++++---
+ src/hb-aat-layout.hh            |  3 ++-
+ src/hb-aat-map.cc               |  8 +++++---
+ src/hb-aat-map.hh               | 17 +++++++++++++----
+ src/hb-ot-shape.cc              | 12 +++++++++---
+ 8 files changed, 69 insertions(+), 33 deletions(-)
+
+commit 82b3e8af69b09fd908d1cd27b669234328d4a500
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 17:28:52 2023 -0700
+
+    Revert "[aat] Allow disable feature ranges"
+    
+    This reverts commit 24a4d397bae6b614215086c85a714dc789af3e7f.
+    
+    This was broken.
+
+ src/hb-aat-layout-common.hh     | 12 +++---------
+ src/hb-aat-layout-kerx-table.hh |  4 ++--
+ src/hb-aat-layout-morx-table.hh | 40 +++++++++++++++-------------------------
+ src/hb-aat-layout.cc            |  7 +++----
+ src/hb-aat-layout.hh            |  3 +--
+ src/hb-aat-map.cc               |  8 +++-----
+ src/hb-aat-map.hh               | 17 ++++-------------
+ src/hb-ot-shape.cc              | 12 +++---------
+ 8 files changed, 34 insertions(+), 69 deletions(-)
+
+commit 24a4d397bae6b614215086c85a714dc789af3e7f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 17:26:08 2023 -0700
+
+    [aat] Allow disable feature ranges
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4020
+    
+    This is a hack.
+    
+    To implement this properly we need to treat runs with different features
+    as independent runs for running the state machine, as the subtable flags
+    might be different. That would be a significant change to our internal
+    implementation.
+
+ src/hb-aat-layout-common.hh     | 12 +++++++++---
+ src/hb-aat-layout-kerx-table.hh |  4 ++--
+ src/hb-aat-layout-morx-table.hh | 40 +++++++++++++++++++++++++---------------
+ src/hb-aat-layout.cc            |  7 ++++---
+ src/hb-aat-layout.hh            |  3 ++-
+ src/hb-aat-map.cc               |  8 +++++---
+ src/hb-aat-map.hh               | 17 +++++++++++++----
+ src/hb-ot-shape.cc              | 12 +++++++++---
+ 8 files changed, 69 insertions(+), 34 deletions(-)
+
+commit b20871322f02415e5d336ee1807d2c2175c7c07b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 16:30:25 2023 -0500
+
+    test-paint: Fix use of g_test_skip
+
+ test/api/test-paint.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit 3ff713ab80a4fd8c8de168863eaffae9cd410c81
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 13:59:50 2023 -0700
+
+    [coretext] Remove unused variable
+
+ src/hb-coretext.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 414848755696ff47e65b614f5201cbf9f5de15eb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 13:47:59 2023 -0700
+
+    [ft] Comment
+
+ src/hb-ft.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit d2aa2397bae6a6550060686da4cad1426eb2ad1f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 13:43:56 2023 -0700
+
+    Optimize non-slant extents code
+
+ src/hb-font.hh | 7 +++++--
+ src/hb-ft.cc   | 7 +++++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+commit 73dab7f784856b44f9f8f97f354e4286ac2e03e9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 13:36:55 2023 -0700
+
+    [ft] Fix slanting code
+
+ src/hb-ft.cc | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+commit eb0f0279d2bd31045e58711b75dc70fe0946d2bc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 15:33:34 2023 -0500
+
+    test-paint: Avoid g_test_skip_printf
+    
+    This is relatively recent api we don't need.
+
+ test/api/test-paint.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit e61c2be41cadd2ef304d1d47777618d2da2e1726
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 15:25:29 2023 -0500
+
+    test-paint: Skip tests if ft COLRv1 is missing
+
+ test/api/test-paint.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+commit 1d662632d961ab588b35ad8a33d4ff85b5c465a1
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 15:01:59 2023 -0500
+
+    test-paint: More output for failures
+
+ test/api/test-paint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 64e3f53fc238443cbbf96f0ba16941093757a76c
+Merge: 027515149 d0108d31a
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Mon Jan 9 14:43:33 2023 -0500
+
+    Merge pull request #4015 from harfbuzz/more-paint-tests
+    
+    Add more paint tests
+
+commit d0108d31a283a8bb3a4dd61696b416059346050b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 8 11:20:21 2023 -0500
+
+    Add more paint tests
+    
+    These tests compare the output of the ft and ot
+    implementations for all the glyphs in the test_glyphs
+    font.
+
+ test/api/results/bad-154   |  10 ++++
+ test/api/results/hand-10   |   2 +-
+ test/api/results/hand-10.2 |   2 +-
+ test/api/results/rocher-1  |   2 +-
+ test/api/results/rocher-2  |   2 +-
+ test/api/results/rocher-3  |   2 +-
+ test/api/results/test-10   |   2 +-
+ test/api/results/test-106  |   2 +-
+ test/api/results/test-116  |   2 +-
+ test/api/results/test-123  |   2 +-
+ test/api/results/test-165  |   2 +-
+ test/api/results/test-175  |   2 +-
+ test/api/results/test-6    |   2 +-
+ test/api/results/test-92   |   2 +-
+ test/api/test-paint.c      | 124 +++++++++++++++++++++++++++++++++++----------
+ 15 files changed, 121 insertions(+), 39 deletions(-)
+
+commit 0275151490902461d2680056820b766c7d39c208
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 12:26:39 2023 -0700
+
+    [paint] Align deptch/edge count conditions across two backends
+
+ src/OT/Color/COLR/COLR.hh | 4 ++--
+ src/hb-ft-colr.hh         | 3 +--
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit 5f976d86a7a24cfe186129294d4779cd1fe67d8c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 13:42:22 2023 -0500
+
+    test-paint: Use %.3g for results
+    
+    This produces more readable output.
+
+ test/api/results/bad-154   | 132 ++++++++++++++++++++++-----------------------
+ test/api/results/hand-10   |  90 +++++++++++++++----------------
+ test/api/results/hand-10.2 |  90 +++++++++++++++----------------
+ test/api/results/rocher-1  |   2 +-
+ test/api/results/rocher-2  |   2 +-
+ test/api/results/rocher-3  |   2 +-
+ test/api/results/test-10   |  22 ++++----
+ test/api/results/test-106  |  20 +++----
+ test/api/results/test-116  |  16 +++---
+ test/api/results/test-123  |  30 +++++------
+ test/api/results/test-165  |  22 ++++----
+ test/api/results/test-175  |  28 +++++-----
+ test/api/results/test-6    |  20 +++----
+ test/api/results/test-92   |  20 +++----
+ test/api/test-paint.c      |  52 +++++++++---------
+ 15 files changed, 271 insertions(+), 277 deletions(-)
+
+commit ec78a486bf4f81ce3bacf1f10558443c64483344
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 13:38:19 2023 -0500
+
+    Run paint tests at upem scale
+    
+    This avoids problems with rouding.
+
+ test/api/results/bad-154   |  2 +-
+ test/api/results/hand-10   | 44 ++++++++++++++++++++++++--------------------
+ test/api/results/hand-10.2 | 42 +++++++++++++++++++++---------------------
+ test/api/results/rocher-1  |  2 +-
+ test/api/results/rocher-2  |  2 +-
+ test/api/results/rocher-3  |  2 +-
+ test/api/results/test-10   |  2 +-
+ test/api/results/test-106  |  2 +-
+ test/api/results/test-116  |  2 +-
+ test/api/results/test-123  |  2 +-
+ test/api/results/test-165  |  2 +-
+ test/api/results/test-175  |  2 +-
+ test/api/results/test-6    |  2 +-
+ test/api/results/test-92   |  2 +-
+ 14 files changed, 57 insertions(+), 53 deletions(-)
+
+commit 839f4b64941be2e4a6f1ec5325fe5ee8def11277
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 12:01:46 2023 -0700
+
+    [ft] Fix slanting clip box
+
+ src/hb-ft-colr.hh | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 30adbc22d9a93d825ff9418eacf16737379a6987
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 11:54:44 2023 -0700
+
+    hb-font: Fix scale_glyph_extents() again
+    
+    And better fix this time.
+
+ src/hb-font.hh | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+commit 6c1a4bed4a94619898052bfe3bd03e1dfb71806f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 11:37:39 2023 -0700
+
+    Better rounding clip boxes
+
+ src/hb-font.hh    | 4 ++--
+ src/hb-ft-colr.hh | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit a085efa69922784850ef4ae68e6b43bf933d3d6d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 13:11:16 2023 -0500
+
+    test-paint: Fix font setup for ft
+    
+    We must call hb_ft_font_set_funcs after
+    setting the font scale.
+
+ test/api/test-paint.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 26f713a7f5bed1c0543e070473008bd6ff065233
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Jan 9 12:54:06 2023 -0500
+
+    paint-test: Use larger scales
+    
+    A scale of 20 is noise, so use 1000.
+
+ test/api/results/{bad-20-0-154 => bad-154}      | 134 ++++++++++++------------
+ test/api/results/{hand-20-0.2-10 => hand-10}    |  48 ++++-----
+ test/api/results/{hand-20-0-10 => hand-10.2}    |  46 ++++----
+ test/api/results/{rocher-120-0.3-1 => rocher-1} |   4 +
+ test/api/results/{rocher-120-0.3-2 => rocher-2} |   4 +
+ test/api/results/{rocher-120-0-3 => rocher-3}   |   4 +
+ test/api/results/{test-20-0-10 => test-10}      |  14 +--
+ test/api/results/{test-20-0-106 => test-106}    |  18 ++--
+ test/api/results/test-116                       |  26 +++++
+ test/api/results/{test-20-0-123 => test-123}    |  22 ++--
+ test/api/results/{test-20-0-165 => test-165}    |  14 +--
+ test/api/results/{test-20-0-175 => test-175}    |  18 ++--
+ test/api/results/test-20-0-116                  |  26 -----
+ test/api/results/{test-20-0-6 => test-6}        |  14 +--
+ test/api/results/{test-20-0-92 => test-92}      |  14 +--
+ test/api/test-paint.c                           |  28 ++---
+ 16 files changed, 221 insertions(+), 213 deletions(-)
+
+commit e886b6b8a6f165c57498760e3e8a3e40dfcec4b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 9 10:26:01 2023 -0700
+
+    [test-draw] Use a larger scale
+    
+    A scale of 20 is in the noise category for us. Using a larger
+    scale makes the test pass.
+
+ test/api/test-draw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 347910fd4c7fe9327e45d3cef02a184b486eb710
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 8 20:06:24 2023 -0500
+
+    Add a draw test
+    
+    This test compares output between ft and ot
+    font funcs.
+
+ test/api/test-draw.c | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+commit f46dcf147b0bc8be6e8d78093a049aaec01089b8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 8 14:33:54 2023 -0700
+
+    [paint/COLR] Fix clip transform
+    
+    Sigh. So complicated.
+
+ src/OT/Color/COLR/COLR.hh | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+commit 42047070ddec3d8182fd7591d3a97e2b16aef4b3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 8 16:08:16 2023 -0500
+
+    test-paint: More helpful output
+    
+    No need to print ASCII chars as hex.
+
+ test/api/test-paint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f283d4d366e1c10ec7e7a89b468911b00d948b9d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 8 12:42:34 2023 -0700
+
+    [paint] Try to adjust both renderers to use same clip order
+
+ src/OT/Color/COLR/COLR.hh | 20 ++++++++++++++------
+ src/hb-ft-colr.hh         |  1 -
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+commit 3fd6c0d97aa33758005a45a3c8d8bd98f8e79df8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 8 12:30:26 2023 -0700
+
+    [test-paint] Remove unused FT_Library
+
+ test/api/test-paint.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+commit 28be4f8805f2f69167930f30b9e4c27fc84429ea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 8 12:19:41 2023 -0700
+
+    [test-paint] Actually run against hb-ft
+
+ test/api/test-paint.c | 49 ++++++++-----------------------------------------
+ 1 file changed, 8 insertions(+), 41 deletions(-)
+
+commit ed7d0234e12aa82f60b9e37a823d55cfc8805c3d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 8 11:47:19 2023 -0500
+
+    test-paint: Limit the precision of clip boxes
+    
+    Update expected test results.
+
+ test/api/results/bad-20-0-154   | 6 +++++-
+ test/api/results/hand-20-0-10   | 6 +++++-
+ test/api/results/hand-20-0.2-10 | 6 +++++-
+ test/api/results/test-20-0-10   | 6 +++++-
+ test/api/results/test-20-0-106  | 4 ++--
+ test/api/results/test-20-0-116  | 4 ++--
+ test/api/results/test-20-0-123  | 6 +++++-
+ test/api/results/test-20-0-165  | 6 +++++-
+ test/api/results/test-20-0-175  | 6 +++++-
+ test/api/results/test-20-0-6    | 6 +++++-
+ test/api/results/test-20-0-92   | 6 +++++-
+ test/api/test-paint.c           | 2 +-
+ 12 files changed, 50 insertions(+), 14 deletions(-)
+
+commit 5d94eb61b883eb194bd952d6d5c552a614c68c19
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 8 11:55:13 2023 -0700
+
+    [hb-cairo] Fix hb_cairo_glyphs_from_buffer() when utf8 missing
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4016
+
+ src/hb-cairo.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 10390ec5c6b6a133f5dcf3a2908249f6c7b40ef6
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 8 09:06:03 2023 -0500
+
+    Update expected test results
+
+ test/api/results/test-20-0-106 | 12 ++++++++----
+ test/api/results/test-20-0-116 | 12 ++++++++----
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+commit f3ce137420721cb689179afadae812011739a129
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 8 09:01:31 2023 -0500
+
+    test-paint: Be more flexible for expected results
+    
+    When generating the expected output with GENERATE_DATA=1,
+    Glib's test framework puts out some comments at the top
+    of the file. Ignore them when comparing the expected
+    output. This makes it possible to directly use the output
+    of
+    
+    GENERATE_DATA=1 ./test-paint -p TESTCASE
+    
+    as expected result for TESTCASE.
+
+ test/api/test-paint.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 5bd6fc1acedfc17b65262f6a96ab3aa282852df7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 16:32:50 2023 -0700
+
+    Comment
+
+ src/OT/Color/COLR/COLR.hh | 4 ++--
+ src/hb-ft-colr.hh         | 1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit 432afa9dffd17df382b17c473e5c4d8199cdf8a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 16:25:30 2023 -0700
+
+    [paint] Fix paint_extents usage
+    
+    It was broken all this time :(.
+    
+    The two backends do this slightly differently...
+
+ src/OT/Color/COLR/COLR.hh | 13 +++----------
+ src/hb-ft-colr.hh         |  3 +++
+ 2 files changed, 6 insertions(+), 10 deletions(-)
+
+commit a63d329261b552126f1bae67ef175bb9a7e0cd90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 16:05:24 2023 -0700
+
+    [paint-extents] Simplify transform_extents
+
+ src/hb-paint-extents.hh | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+commit e062f982600c8e275931c7666f9658c78ea67b4e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 16:02:21 2023 -0700
+
+    [paint-extents] Fix transform_extents
+    
+    Ouch!
+
+ src/hb-paint-extents.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 70ca146033dd513b91468c53ff3f89d03b277f09
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 15:48:57 2023 -0700
+
+    [chafa] Re-enable truecolor mode
+    
+    See 42bf8e3d49
+    https://github.com/harfbuzz/harfbuzz/pull/2959#issuecomment-827056111
+
+ util/helper-cairo-ansi.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 823a9b18d93cb8a7520d175da7834de1bcd62891
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 14:49:02 2023 -0700
+
+    [cairo] Return COMPOSITE mode CLEAR for unknown values
+    
+    As per the spec.
+
+ src/hb-cairo-utils.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit d0aaea2319a3c32e129c58bf5b3464409ab83df7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Jan 7 16:27:13 2023 -0500
+
+    Update test results for paint-test
+    
+    These were affected by the PaintComposite optimization.
+
+ test/api/results/bad-20-0-154  | 620 ++++++++++++++++++-----------------------
+ test/api/results/test-20-0-106 |  38 ++-
+ test/api/results/test-20-0-116 |  34 ++-
+ test/api/results/test-20-0-123 |  38 ++-
+ 4 files changed, 330 insertions(+), 400 deletions(-)
+
+commit 65c3cde5dac3c64f24dd1837daad494d63b78960
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 14:29:18 2023 -0700
+
+    [COLRv1] Fix scale variation
+
+ src/OT/Color/COLR/COLR.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 004cdc10f87d7259a7192706c2996f9a9d0a26ed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 14:27:15 2023 -0700
+
+    [open-type] More tweaks to fixed types
+    
+    Add set_int().
+
+ src/hb-open-type.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c8486b63019e77257a9d30361a9fdc5f2eaaa837
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 14:15:17 2023 -0700
+
+    [open-type] Add to_int to fixed types
+    
+    To make sure we don't accidentally forget to_float().
+    As we did recently in COLRv1 code.
+
+ src/OT/glyf/VarCompositeGlyph.hh | 14 +++++++-------
+ src/hb-open-type.hh              |  3 +++
+ src/hb-ot-layout-common.hh       | 10 +++++-----
+ src/hb-ot-var-avar-table.hh      |  4 ++--
+ src/hb-ot-var-fvar-table.hh      |  8 ++++----
+ src/hb-ot-var-gvar-table.hh      |  6 +++---
+ 6 files changed, 24 insertions(+), 21 deletions(-)
+
+commit dfd9bf8a50f9597e55e7811dc0c6c237546e6aef
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 14:05:02 2023 -0700
+
+    [COLRv1] Fix a couple of missing to_float() calls
+    
+    Ouch!
+
+ src/OT/Color/COLR/COLR.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d045de78c1ff7b32f3d7082591f4112d1f8f796a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 13:55:17 2023 -0700
+
+    [paint] Optimize PAINT_COMPOSITE
+    
+    At the start of each paint call the current group is clear.
+    So we don't need to start a new group for the backdrop paint.
+    
+    A paint composite really needs one group push, not two.
+
+ src/OT/Color/COLR/COLR.hh | 2 --
+ src/hb-ft-colr.hh         | 2 --
+ 2 files changed, 4 deletions(-)
+
+commit 5ea5aacda9d14833a66e9d9869c69eda0bb4034a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Jan 7 13:24:41 2023 -0700
+
+    [ft-colr] Adjust for FreeType master color-stop change
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/4013
+
+ src/hb-ft-colr.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 1eb5445e7575c828c552a914708ca1650f146377
+Author: Qunxin Liu <qxliu at google.com>
+Date:   Fri Jan 6 15:19:16 2023 -0800
+
+    [subset] Fix issue in hb_subset_input_override_name_table()
+    
+    If a nameRecord with provided name_id/platform_id/encoding_id/lang_id
+    is not retained after subsetting, create it and insert it to
+    the name table. So we need to check against retained name_records
+    rather than name_record in the original name table.
+
+ src/hb-ot-name-table.hh        | 28 +++++++++++-----------------
+ test/api/test-subset-nameids.c |  2 +-
+ 2 files changed, 12 insertions(+), 18 deletions(-)
+
+commit 30d4a7347387a1e3e0bd7db3f5159ba42c89e642
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 16:00:53 2023 -0700
+
+    [hb-subset] Adjust help for instancing
+
+ util/hb-subset.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3bcf153ad8dba1dc518b61ac3f19b865d8508b80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 15:51:13 2023 -0700
+
+    Change library numbering scheme
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1431
+
+ configure.ac | 2 +-
+ meson.build  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 02948263f9a9ab8ef28078e69ed349e2d89b301d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Jan 6 22:53:19 2023 +0200
+
+    [subset] Document that CFF2 instancing is now supported
+
+ src/hb-subset-input.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit aba6cbe867ce1bf23673d44baef820e35001f487
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 13:09:10 2023 -0700
+
+    [hb-subset] Adjust --help-all formatting
+    
+    Meh.
+
+ util/hb-subset.cc | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit 82c863a50b9de8df7094b7267b50b4e191c03de8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 12:51:58 2023 -0700
+
+    Whitespace
+
+ src/hb-ot-os2-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 76879c5763643bf83680efbc610fede3d9faab00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:47:04 2023 -0700
+
+    [subset-cff] Minor hide num_coords again
+
+ src/hb-cff2-interp-cs.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 576b36a31b6623092e5ff36f632390198a57d1b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:40:21 2023 -0700
+
+    [cff2] Undo rounding change in draw() codepath
+
+ src/hb-cff2-interp-cs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4867e0b192b1efcc28e12bfd8f997ca9377d65ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:39:13 2023 -0700
+
+    [subset-cff2] Faster instancing
+    
+    Instantiate blends during parsing. Dedups code as well.
+
+ src/hb-cff2-interp-cs.hh | 12 +++++++-----
+ src/hb-subset-cff2.cc    | 37 +------------------------------------
+ 2 files changed, 8 insertions(+), 41 deletions(-)
+
+commit 3757baab2c039d1cad959ffc4ead4e746cc52960
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:23:37 2023 -0700
+
+    [subset-cff2] Better condition
+    
+    Previous condition wasn't working for dropping axes.
+
+ src/hb-subset-cff2.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit acc6c13f05c0c43ffa3e3e1053626ca4186428a5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:20:41 2023 -0700
+
+    [subset-cff] Round numbers when instancing
+
+ src/hb-subset-cff2.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2f174f23c38f5a14ec4c0535249b8b7ce247322f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:11:14 2023 -0700
+
+    Rename
+
+ src/hb-subset-cff2.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a59116cd8f20e34a8cd7f5d1179ab7ba96aa4113
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:09:09 2023 -0700
+
+    Oops
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c632a164b98de695b5cd3366689df8dd45021b6f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Jan 6 11:01:25 2023 -0700
+
+    [subset/cff] Support instancing
+
+ src/hb-cff1-interp-cs.hh    |  3 ++-
+ src/hb-cff2-interp-cs.hh    |  2 ++
+ src/hb-subset-cff-common.hh |  9 +++++++--
+ src/hb-subset-cff2.cc       | 38 +++++++++++++++++++++++++++++++++++++-
+ src/hb-subset-plan.cc       |  6 ++++++
+ src/hb-subset-plan.hh       |  1 +
+ 6 files changed, 55 insertions(+), 4 deletions(-)
+
+commit 5153218b41a5984673900d080daf4e3273e1d117
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 16:26:41 2023 -0700
+
+    [set] Add hb_set_is_inverted()
+
+ docs/harfbuzz-sections.txt   |  1 +
+ src/hb-bit-set-invertible.hh |  5 +++++
+ src/hb-set.cc                | 16 ++++++++++++++++
+ src/hb-set.h                 |  3 +++
+ src/hb-set.hh                |  1 +
+ src/test-set.cc              |  3 ++-
+ 6 files changed, 28 insertions(+), 1 deletion(-)
+
+commit e8ac0ef2fd3cacccaf3bd5dec8a9cab324d13467
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 16:20:43 2023 -0700
+
+    [face] Minor rename a variable
+
+ src/hb-face.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 14ff7470248c4ed1bfddb846237514c56b7b59bb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 16:19:41 2023 -0700
+
+    [set] Add tests for inverted set range iteration
+
+ src/test-set.cc | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+commit 381ac2fd78220b0ab521cfb0cc5b5f850e5c3964
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Jan 5 17:48:09 2023 -0500
+
+    docs: Fix a typo
+
+ src/hb-face.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2764a6169141a09f354abedee39c3430179e90e6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 15:14:54 2023 -0700
+
+    Revert "[gsubgpos] Use swap instead of move"
+    
+    This reverts commit 8a17cc4ecf21f6754e2d90562d0ced7496870f74.
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 167b7c604603d8a70e15c89714fa601e59248f08
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 14:48:20 2023 -0700
+
+    Revert "[gsubgpos] Reduce hb_set_t allocations"
+    
+    This reverts commit 0b7f6d6cf0e2deba637783ab3880fdfb90ca8ac3.
+    
+    Not much benefit as the main allocations come from other places.
+
+ src/hb-ot-layout-gsubgpos.hh | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+commit 3947cedd09a2386be5774400ac0b582d8173d078
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 14:47:47 2023 -0700
+
+    Revert "[gsubgpos] Cache pos_glyphs allocation in closure"
+    
+    This reverts commit 3961cc46bf438947b19063cb7e735247358f1d4f.
+    
+    This was wrong...
+
+ src/hb-ot-layout-gsubgpos.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 097fb8b8aa220e209c7673a5713def137c91924c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 14:38:10 2023 -0700
+
+    [priority-queue] Use resize instead of shrink
+    
+    To avoid reallocation of smaller array. Not desirable here.
+
+ src/hb-priority-queue.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8a17cc4ecf21f6754e2d90562d0ced7496870f74
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 14:15:38 2023 -0700
+
+    [gsubgpos] Use swap instead of move
+    
+    Move is wrong when we want to reuse the object.
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4401dd24822a07332b271d700fbab8612da5de45
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 14:13:57 2023 -0700
+
+    [gsubgpos] Minor use ->clear() directly
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 207ae11ab9f539272cd1969461a1023658b6e4b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 14:08:47 2023 -0700
+
+    [set] Allocate first page exact
+
+ src/hb-bit-set.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 0b7f6d6cf0e2deba637783ab3880fdfb90ca8ac3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 13:58:57 2023 -0700
+
+    [gsubgpos] Reduce hb_set_t allocations
+
+ src/hb-ot-layout-gsubgpos.hh | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+commit 3961cc46bf438947b19063cb7e735247358f1d4f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 13:58:57 2023 -0700
+
+    [gsubgpos] Cache pos_glyphs allocation in closure
+    
+    Saves some 3% in Gulzar-Regular subsetting.
+
+ src/hb-ot-layout-gsubgpos.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a90f149e1b9ce1dfb1295465ddc3d49bda175383
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 13:52:11 2023 -0700
+
+    [gsubgpos] Minor drop an allocation
+
+ src/hb-ot-layout-gsubgpos.hh | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+commit c54debc76dc120a696f24e9fd3dc9a9c4829b928
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 11:54:06 2023 -0700
+
+    [face] Add hb_face_collect_nominal_glyph_mapping
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3973
+
+ docs/harfbuzz-sections.txt       |  1 +
+ src/hb-face.cc                   | 27 ++++++++++++++++++++++++---
+ src/hb-face.h                    |  6 ++++++
+ test/api/test-collect-unicodes.c | 12 ++++++++++++
+ 4 files changed, 43 insertions(+), 3 deletions(-)
+
+commit ec70a3f7975907a4fc413255eec3b645f0a67c81
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 11:52:12 2023 -0700
+
+    [map] Include
+
+ src/hb-map.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 8b12c195738024107d5a8308ac29170d3f716f1d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 11:42:21 2023 -0700
+
+    [face] Split hb-face-builder.cc
+
+ src/Makefile.sources   |   1 +
+ src/harfbuzz-subset.cc |   1 +
+ src/harfbuzz.cc        |   1 +
+ src/hb-face-builder.cc | 246 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-face.cc         | 212 ------------------------------------------
+ src/meson.build        |   1 +
+ 6 files changed, 250 insertions(+), 212 deletions(-)
+
+commit b0d9421b1100ca00ac66ff83297affd3e9926529
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 11:21:46 2023 -0700
+
+    [docs] Remove reference to 2.x.x
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4006
+
+ docs/harfbuzz-docs.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dc7b3a627db66afe948610a46d0c4a9e7201464b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 10:49:10 2023 -0700
+
+    [test-map] Another test
+
+ src/test-map.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit a8df5cb07ddb4b5c0054564858e063a8c35c9a15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 10:47:31 2023 -0700
+
+    [test-map] Test keys() / values()
+
+ src/test-map.cc | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+commit a349eef6a6da1064368ab5c0c09123ed1b748c59
+Author: Konstantin Käfer <mail at kkaefer.com>
+Date:   Thu Jan 5 10:54:21 2023 +0100
+
+    Disable hb_paint_extents_* functions if HB_NO_PAINT is defined
+
+ src/hb-paint-extents.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 9420966f5b8df976c4c1514fbd1346556980c907
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Jan 5 10:17:24 2023 -0700
+
+    [map] Fix next()
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 35f46e74d1126b3db6dd342399e90874171f7ac8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 17:12:08 2023 -0700
+
+    [map] Add hb_map_keys() and hb_map_values()
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-machinery.hh        |  1 -
+ src/hb-map.cc              | 32 ++++++++++++++++++++++++++++++++
+ src/hb-map.h               |  8 ++++++++
+ src/hb-map.hh              | 12 ++++++++++++
+ src/hb-set.hh              |  5 +++++
+ src/hb-subset.hh           |  1 +
+ 7 files changed, 60 insertions(+), 1 deletion(-)
+
+commit 07f2d8d5384943445ca00c0e127de81d37539e65
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 15:42:56 2023 -0700
+
+    Comment
+
+ src/hb-buffer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4f6079138d74c1958c6345de28a08a8816e0c4af
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 13:58:46 2023 -0700
+
+    [map] Add hb_map_update()
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-map.cc              | 16 ++++++++++++++++
+ src/hb-map.h               |  4 ++++
+ src/hb-map.hh              |  7 +++++++
+ src/test-map.cc            | 16 ++++++++++++++--
+ 5 files changed, 42 insertions(+), 2 deletions(-)
+
+commit c350458539ee16bb06fde317ad440cd3c8159471
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 13:25:03 2023 -0700
+
+    [subset-plan] Relax const return type of a few functions
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4003
+
+ src/hb-subset-plan.cc | 6 +++---
+ src/hb-subset.h       | 6 +++---
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit dbf0964a0ff2fd36730c4179ab7ec7e8f0bd11cb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 13:17:14 2023 -0700
+
+    [map] Doc
+
+ src/hb-map.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 0875a420f7e04a27971b6b69a3364ba3eff9ed0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 13:11:37 2023 -0700
+
+    [map] Doc
+
+ src/hb-map.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ffafcf9633eae1c679b8835a31e9b00dca740dde
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 12:55:59 2023 -0700
+
+    [map] Add hb_map_next()
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-map.cc              | 25 ++++++++++++++++++++++++-
+ src/hb-map.h               |  6 ++++++
+ src/hb-map.hh              | 24 ++++++++++++++++++++++++
+ src/test-map.cc            | 27 +++++++++++++++++++++++++++
+ 5 files changed, 82 insertions(+), 1 deletion(-)
+
+commit 3e471bbc0801d8fc0093d4e536633e6a89d4d32b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 11:53:49 2023 -0700
+
+    [vector] Better test
+
+ src/hb-vector.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 45fc919a10dc7d13ea386904bddb601512ba2f28
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 11:35:44 2023 -0700
+
+    [bit-set] Minor setting length on allocation failure
+
+ src/hb-bit-set.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d8509061e6167a7132c7d4aa414df65d95703ee6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Jan 4 11:33:54 2023 -0700
+
+    [vector] It's okay if shrinking fails
+
+ src/hb-vector.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 6c272b920d14f34494a8415bad15e794be313fc5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 3 13:00:41 2023 -0700
+
+    [set] Don't discard allocation in operator=
+    
+    That had caused memory thrashing.
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54789
+
+ src/hb-bit-set.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e6bbf112ea05482e48136f910518f57b2b153256
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Jan 3 12:35:48 2023 -0700
+
+    [buffer] Better document set_content_type
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/4000
+
+ src/hb-buffer.cc | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+commit 8f2345ca365de26d3d4888c9087181ebccde29d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 18:08:45 2023 -0700
+
+    Use more vector resize_exact
+
+ src/hb-bit-set.hh        | 7 ++-----
+ src/hb-cff2-interp-cs.hh | 6 ++----
+ 2 files changed, 4 insertions(+), 9 deletions(-)
+
+commit b6be4550209af5cf33f3d0a35602ca8edeafcc5d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 18:05:43 2023 -0700
+
+    [vector] Add resize_exact()
+
+ src/hb-subset-cff-common.hh | 21 +++++++--------------
+ src/hb-vector.hh            |  8 ++++++--
+ 2 files changed, 13 insertions(+), 16 deletions(-)
+
+commit a516ce97e03877389bdb60a62234302e19266894
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 17:58:51 2023 -0700
+
+    [subset-cff] Add a few exact-allocation calls
+
+ src/hb-subset-cff-common.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 4a435dc0243329a409d4c23ca0ec07ca19fea9cb
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 17:41:31 2023 -0700
+
+    [subset-cff] Remove an unlikely
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f8c578fd93b22a144f5a28e504e629b8adcb3f5c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 17:33:04 2023 -0700
+
+    [subset-cff] Remove commented-out line
+
+ src/hb-subset-cff-common.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit d5e1748f31231d5283e6c006d4114c139f9d261b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 12:26:43 2023 -0700
+
+    [cff] Simplify add_op()
+
+ src/hb-cff-interp-common.hh | 12 +-----------
+ 1 file changed, 1 insertion(+), 11 deletions(-)
+
+commit 27531d853e36ba1050da6158d7349bdf85b0f9e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 12:05:11 2023 -0700
+
+    [subset-cff] Move code around
+
+ src/hb-subset-cff-common.hh | 64 ++++++++++++++++++++++-----------------------
+ 1 file changed, 32 insertions(+), 32 deletions(-)
+
+commit 9afe5f973ea62957542830662f4c61d3ce795678
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 11:44:29 2023 -0700
+
+    [vector] Fix leak
+    
+    Discovered by https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54767
+
+ src/hb-vector.hh | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+commit 4f013c42f0c0d87b068ff349fd96cb3dcff1831d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Jan 2 10:38:30 2023 -0700
+
+    [subset-cff] Always compact charstrings
+    
+    Reduces non-preprocessed subsetting memory footprint significantly.
+
+ src/hb-subset-cff-common.hh | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+commit d3ed6eed437d3123195d436a43babfaab6266edf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 23:29:35 2023 -0700
+
+    [cff] Initialize a member variable
+    
+    For good hygiene.
+
+ src/hb-cff-interp-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8ccc704c9af497cfeca5d58d80e42e043203c738
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Jan 2 18:14:55 2023 +0200
+
+    [ci/win32] Disable Cairo tests as well
+
+ .ci/build-win32.sh | 2 +-
+ .ci/build-win64.sh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 5d81fc0f1cec0ddece4e083e9befa4c4b429c546
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Wed Mar 23 06:07:15 2022 +0200
+
+    [meson] Update Cairo subproject
+    
+    Update to the latest master to get color fonts working. Disable dwrite
+    on Windows builds as it does not compile and we don’t need it.
+
+ .ci/build-win32.sh     | 1 +
+ .ci/build-win64.sh     | 1 +
+ subprojects/cairo.wrap | 4 ++--
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+commit 55a7d81740fd4e932ac101cb0c869eaa384fedc3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 23:07:42 2023 -0700
+
+    [vector] Allocate exact size in operator=
+
+ src/hb-vector.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 449910d43118b6f935fa1231531cc16c072cd455
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 19:27:10 2023 -0700
+
+    [vector] Allocate exact size in constructor
+
+ src/hb-vector.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 4dda1f7881d7584598467efb641927b56230250b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 19:00:04 2023 -0700
+
+    [cff-subset] Compact charstrings just after parsing
+    
+    Massive peak-memory saving when processing face.
+
+ src/hb-subset-cff-common.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit a7617c3cf194dfd5d2b96095f43915b60b41fb44
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 18:58:08 2023 -0700
+
+    [cff-subset] Drop hints just after parsing charstring
+    
+    In prep for next commit.
+
+ src/hb-subset-cff-common.hh | 36 ++++++++++++------------------------
+ 1 file changed, 12 insertions(+), 24 deletions(-)
+
+commit b1c4cb0caeae6c750c0cfd42fabb7fcb79ea30fd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 18:41:19 2023 -0700
+
+    [cff2] Use a shrink instead of resize
+    
+    Such that we can free the allocation.
+
+ src/hb-cff2-interp-cs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b87360763ece0494951071793140c1e4336cf19b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 18:38:28 2023 -0700
+
+    [vector] Support shrinking storage if exact size provided
+    
+    Only do it if requested size is less than quarter of allocated size.
+    
+    This has massive benefit during CFF subset preprocessing.
+
+ src/hb-vector.hh | 33 +++++++++++++++++++++++++--------
+ 1 file changed, 25 insertions(+), 8 deletions(-)
+
+commit 1119e6029609e31cc7548ddfb7ac5ba2c3001f0c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 18:31:32 2023 -0700
+
+    [subset-cff] Tweak another storage allocation
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 85e8f2b53ff373abf108053201d31742f6b24a79
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 18:26:08 2023 -0700
+
+    [hb-subset] Initialize preprocess variable
+
+ util/hb-subset.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f0b5286b36fb9eb45bf53ee3a6e2d8b5ee807471
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 17:04:59 2023 -0700
+
+    [features] Sort
+
+ src/hb-features.h.in | 48 ++++++++++++++++++++++++------------------------
+ 1 file changed, 24 insertions(+), 24 deletions(-)
+
+commit 4a5bd7a9267973c134c3fe1198d8cf8cf94cb4f1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 16:53:28 2023 -0700
+
+    [subset] Add hb_subset_input_keep_everything()
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3998
+    
+    New API:
+    + hb_subset_input_keep_everything()
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-subset-input.cc     | 56 ++++++++++++++++++++++++++++++----------------
+ src/hb-subset.h            |  3 +++
+ util/hb-subset.cc          | 15 +++++++++++++
+ 4 files changed, 56 insertions(+), 19 deletions(-)
+
+commit d87add41b3ff6ce19cf387cf20542525e8237b14
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 16:27:26 2023 -0700
+
+    [hb-subset] Rename --preprocess-face to --preprocess
+    
+    Keep old name working but hidden.
+
+ util/hb-subset.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 52110f13b02678c24daa3c1b588683a8fb13e125
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 16:22:02 2023 -0700
+
+    [subset-input] Refactor copy-pasta code
+
+ src/hb-subset-input.cc | 39 ++++++++++++++-------------------------
+ 1 file changed, 14 insertions(+), 25 deletions(-)
+
+commit 4adc748b13c3fdcb60162a269982590925750ce3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 1 09:46:11 2023 -0500
+
+    Move Color tables to src/OT/Color/
+
+ src/Makefile.sources                                   | 12 ++++++------
+ .../Color/CBDT/CBDT.hh}                                | 10 +++++-----
+ .../Color/COLR/COLR.hh}                                | 18 +++++++++---------
+ .../Color/COLR/colrv1-closure.hh}                      | 12 ++++++------
+ .../Color/CPAL/CPAL.hh}                                | 12 ++++++------
+ .../Color/sbix/sbix.hh}                                | 12 ++++++------
+ src/{hb-ot-color-svg-table.hh => OT/Color/svg/svg.hh}  | 12 ++++++------
+ src/hb-ot-color.cc                                     | 10 +++++-----
+ src/hb-ot-face.cc                                      |  6 +++---
+ src/hb-ot-font.cc                                      |  8 ++++----
+ src/hb-static.cc                                       |  2 +-
+ src/hb-subset-plan.cc                                  |  4 ++--
+ src/hb-subset.cc                                       |  8 ++++----
+ src/meson.build                                        | 10 +++++-----
+ 14 files changed, 68 insertions(+), 68 deletions(-)
+
+commit a5f1f3a05cc72a127ac29aa78c3b775ed4d63adc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Jan 1 13:14:04 2023 -0700
+
+    [ft] Conditionalize all COLOR code on >= 2.11.1
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3994
+
+ src/hb-ft-colr.hh | 9 ---------
+ src/hb-ft.cc      | 6 ++++++
+ 2 files changed, 6 insertions(+), 9 deletions(-)
+
+commit dc5179d465e5d39a60897a4c8cf14da6c2f6fefa
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 1 09:23:07 2023 -0500
+
+    Drop hb-ot-color-colr-table.cc
+    
+    Move everything into the .hh file.
+
+ src/Makefile.sources          |  1 -
+ src/harfbuzz-subset.cc        |  1 -
+ src/harfbuzz.cc               |  1 -
+ src/hb-ot-color-colr-table.cc | 27 ---------------------------
+ src/hb-ot-color-colr-table.hh | 26 ++++++++++++++++++++++++--
+ src/meson.build               |  1 -
+ 6 files changed, 24 insertions(+), 33 deletions(-)
+
+commit 27684f14be2a72b8aab863844931a980ace76db5
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Jan 1 00:41:55 2023 +0200
+
+    [introspection] Skip sources not usable with GObject Introspection
+    
+    There is no point in generating GIR for code interfacing with libraries
+    without introspection integration. This fixes spurious warnings on macOS
+    when g-ir-scanner mistakenly tries to scan system headers.
+
+ src/meson.build | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+commit 2bd09a99c1b1e84fe69c854f2b42cf9a55a006d8
+Merge: 3ff91c449 f60e7e3f8
+Author: Matthias Clasen <matthias.clasen at gmail.com>
+Date:   Sun Jan 1 10:30:40 2023 -0500
+
+    Merge pull request #3996 from harfbuzz/drop-unused-file
+    
+    Drop an unused file
+
+commit f60e7e3f8c91c81c21f401e654389767e182db41
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Jan 1 09:50:27 2023 -0500
+
+    Drop an unused file
+
+ src/hb-ot-color-colrv1-paint.hh | 286 ----------------------------------------
+ 1 file changed, 286 deletions(-)
+
+commit 3ff91c449f52d5cccdc24639a836d30878a62188
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 14:49:41 2022 -0700
+
+    [paint] Optimize transform operations again
+
+ src/hb-ft-colr.hh             | 46 +++++++++++-----------
+ src/hb-ot-color-colr-table.hh | 74 +++++++++++++++++------------------
+ src/hb-paint.hh               | 90 ++++++++++++++++---------------------------
+ 3 files changed, 94 insertions(+), 116 deletions(-)
+
+commit 1a0dd49f1ef09af11235645b65f32c65704bcae6
+Merge: edb812345 9f3b59fe6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 14:38:06 2022 -0700
+
+    Merge pull request #3991 from harfbuzz/paint-optimize-transform
+    
+    Paint optimize transform
+
+commit 9f3b59fe6b27e3f8c2a32a89263264ceaceaa5be
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 31 16:19:20 2022 -0500
+
+    Update expected test results
+    
+    These need updates, because they record
+    every callback, and we've changed what
+    callbacks are happening.
+
+ test/api/results/test-20-0-106 | 4 ++--
+ test/api/results/test-20-0-123 | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit edb812345a10a4eb737e2ab96578a49b533cddd7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 13:55:41 2022 -0700
+
+    [subset-cff] Another exact allocation
+
+ src/hb-subset-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 54dd01b86538f91dbbb75dab937bff01266fa4f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 13:33:25 2022 -0700
+
+    [set] Use exact-allocation in copying
+    
+    Significantly reduces memory consumption.
+
+ src/hb-bit-set.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 2c64048bc4b91cc45427faa437ae8368a5443c5f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 13:26:00 2022 -0700
+
+    [subset] Another exact-allocation
+
+ src/hb-subset.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0ec0214f10ee17786531d54416d4f006ff9c818b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 13:18:32 2022 -0700
+
+    [cff-subset] Adjust pre-allocation
+    
+    Reduces memory use significantly.
+
+ src/hb-cff-interp-common.hh | 2 +-
+ src/hb-subset-cff-common.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit b88ca81814059c71c0361d741c70b71b652240b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:51:28 2022 -0700
+
+    [paint-extents] Minor reorder
+
+ src/hb-paint-extents.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 0c6a72133766240c13649a69e783e12ad30ae08d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:42:29 2022 -0700
+
+    [set] Another exact-size allocation
+
+ src/hb-bit-set.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit b803024cafc76a5f23c88b8f248e4d19125d7933
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:40:07 2022 -0700
+
+    [cff2] Another exact-size allocation
+
+ src/hb-cff2-interp-cs.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 3d4659beaad042fe0b3f0a750ced96e8ca361cb9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:38:58 2022 -0700
+
+    [cff2] Use exact-size vector allocation for blends
+
+ src/hb-cff2-interp-cs.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 92e5933ee6c6382ea168ee5fdd30d80cece131d1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:35:30 2022 -0700
+
+    [vector] A couple more exact-size allocations
+
+ src/hb-ot-name-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2eacc37e08a07c2e79139056ae09c1047cbff5cd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:27:13 2022 -0700
+
+    [vector] Add internal API for exact-size allocation
+    
+    Use it from a couple of places.
+
+ src/OT/glyf/SimpleGlyph.hh   | 8 ++++----
+ src/OT/glyf/glyf.hh          | 2 +-
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ src/hb-repacker.hh           | 2 +-
+ src/hb-serialize.hh          | 4 ++--
+ src/hb-vector.hh             | 6 +++---
+ 6 files changed, 12 insertions(+), 12 deletions(-)
+
+commit a0b46f3f6bd4be906cde1f8a7fab765690c13f2f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:15:14 2022 -0700
+
+    [machinery] Refactor shared code into a macro
+
+ src/hb-machinery.hh | 48 ++++++++++++++++--------------------------------
+ 1 file changed, 16 insertions(+), 32 deletions(-)
+
+commit ebb475bae7b8e7af300251e4fd2d14a56e292b90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 12:11:14 2022 -0700
+
+    [multimap] Add consts
+
+ src/hb-multimap.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 9e3ff0e9f0078aa17d616ae9670a3843949a212d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:55:45 2022 -0700
+
+    [paint] Fixup
+
+ src/hb-ft-colr.hh             |  4 ++++
+ src/hb-ot-color-colr-table.hh | 13 +++++++++++--
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+commit 6b47fcb17aa138d1c60e07516ce4323c9fe594cc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:40:12 2022 -0700
+
+    [paint] Add internal push_skew/pop_skew API
+
+ src/hb-ft-colr.hh             |  8 ++++----
+ src/hb-ot-color-colr-table.hh | 16 ++++++++--------
+ src/hb-paint.hh               | 17 +++++++++++++++++
+ 3 files changed, 29 insertions(+), 12 deletions(-)
+
+commit 46adf31b4c6ac45c213c7ac492f27a18de8e1af5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:35:39 2022 -0700
+
+    [paint] Add internal push_rotate/pop_rotate API
+
+ src/hb-ft-colr.hh             |  6 ++----
+ src/hb-ot-color-colr-table.hh | 12 ++++--------
+ src/hb-paint.hh               | 17 +++++++++++++++++
+ 3 files changed, 23 insertions(+), 12 deletions(-)
+
+commit ce7835124a741a75748b941ef1ff228e70437dfe
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:32:15 2022 -0700
+
+    [paint] Add internal push_scale/pop_scale API
+
+ src/hb-ft-colr.hh             | 10 ++++------
+ src/hb-ot-color-colr-table.hh | 28 ++++++++++++----------------
+ src/hb-paint.hh               | 14 ++++++++++++++
+ 3 files changed, 30 insertions(+), 22 deletions(-)
+
+commit 7363eb373a14310a3d15b5a5889e4c158a55e533
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:24:42 2022 -0700
+
+    [paint] Add internal push_translate/pop_translate
+
+ src/hb-ft-colr.hh             | 63 +++++++++++++++----------------------------
+ src/hb-ot-color-colr-table.hh | 41 ++++++++++++++--------------
+ src/hb-paint.hh               | 14 ++++++++++
+ 3 files changed, 56 insertions(+), 62 deletions(-)
+
+commit df91677997c42cf5639718755267488af1389140
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:12:02 2022 -0700
+
+    [paint] Call internal API internally
+
+ src/hb-paint.hh | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+commit 99da0e6cc3433a86710c9ce6fec662afa677f03f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 11:04:40 2022 -0700
+
+    [paint] Avoid div-by-zero
+
+ src/hb-paint.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 4e94b65cffe4b2308c2c74fc113a93d597602b0b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 10:53:40 2022 -0700
+
+    [paint-extents] Const-correctness
+
+ src/hb-paint-extents.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit f6dc4698ef4ea042dd4858fd32fd0916b779b954
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 10:52:32 2022 -0700
+
+    [paint-extents] Minor move variable
+
+ src/hb-paint-extents.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 4e7807a09028a27f0240e6b8cee879a848c96f99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 10:50:30 2022 -0700
+
+    [paint-extents] Rename variable
+
+ src/hb-paint-extents.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit c86d1892ad32a6ef07ae0e67fe6e5deaaababc00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 10:46:46 2022 -0700
+
+    [paint-extents] Move code around
+
+ src/hb-paint-extents.cc | 32 +++++++-------------------------
+ src/hb-paint-extents.hh | 18 ++++++++++++++++++
+ 2 files changed, 25 insertions(+), 25 deletions(-)
+
+commit d9a9bd8fa8feda041ef39f78085d314677842159
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 31 10:41:30 2022 -0700
+
+    [paint-extents] Add HB_UNUSED
+
+ src/hb-paint-extents.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 956ccb11a8e29289302ff85f76713ceb31cfecc7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 31 10:14:37 2022 -0500
+
+    [docs] Add a section about rendering
+
+ docs/usermanual-fonts-and-faces.xml | 42 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+commit 63cd1cce67c8459696cf49c53aad5e4f1830ccb7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 31 08:56:12 2022 -0500
+
+    [docs] Drop stale commented-out section
+    
+    Freetype integration is documented elsewhere now.
+
+ docs/usermanual-fonts-and-faces.xml | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+commit a390590451ef75e069ea5c67c3843b526f01fcde
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 31 08:51:19 2022 -0500
+
+    Mention named instances in the var-fonts section
+
+ docs/usermanual-fonts-and-faces.xml | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+commit 37e90c64c17656e74f83e932ae750aed347855a7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 15:41:40 2022 -0700
+
+    [cairo] Fix warnings
+
+ src/hb-cairo-utils.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 04464c55b2644de67a9599a72c3c9126a8718a18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 14:55:32 2022 -0700
+
+    [pool] Change chunk-len from 16 to 32
+
+ src/hb-pool.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d7941e04df605549f97c9a48469c5c204609610a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 14:47:47 2022 -0700
+
+    [paint-extents] Unlikely
+
+ src/hb-paint-extents.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ca844b69759c0d7b6c7511267c935330392dab00
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 14:47:24 2022 -0700
+
+    [paint-extents] Whitespace
+
+ src/hb-paint-extents.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 62ca2be39dd1bb03a99417ba57e0d8a18e407534
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 14:41:36 2022 -0700
+
+    [paint-extents] Implement quadratic callback
+
+ src/hb-paint-extents.cc | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+commit 7389efd8e0d5ee18b5139932214d326c7901ab15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 13:58:34 2022 -0700
+
+    [post] Pre-alloc name index array
+
+ src/hb-ot-post-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 36bef5dccf0ba3b437fdf4246e39e7e1c5219ce8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 13:17:23 2022 -0700
+
+    [gsubgpos] Prealloc subtables vector
+
+ src/hb-ot-layout-gsubgpos.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 00060d99f300575dab95b255e31f75787f34078e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Fri Dec 30 22:55:56 2022 +0200
+
+    [hb-cairo] Silence warning when building with FreeType
+    
+    In file included from ../util/hb-view.cc:33:
+    In file included from ../util/view-cairo.hh:32:
+    ../util/helper-cairo.hh:102:7: warning: variable 'cairo_face' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
+      if (use_hb_draw)
+          ^~~~~~~~~~~
+    ../util/helper-cairo.hh:129:64: note: uninitialized use occurs here
+      cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (cairo_face,
+                                                                   ^~~~~~~~~~
+    ../util/helper-cairo.hh:102:3: note: remove the 'if' if its condition is always true
+      if (use_hb_draw)
+      ^~~~~~~~~~~~~~~~
+    ../util/helper-cairo.hh:101:32: note: initialize the variable 'cairo_face' to silence this warning
+      cairo_font_face_t *cairo_face;
+                                   ^
+                                    = nullptr
+    
+    We know that cairo_face will always be assigned since use_hb_draw will
+    always be true, but the compiler does not know that.
+
+ util/helper-cairo.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a45bf5b04c907c7071a41bac3235459f02eb1f8f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 11:19:36 2022 -0700
+
+    [ft-colr] Require FreeType >= 2.11.1
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3989
+
+ src/hb-ft-colr.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ceba6c9a90751fa82264889d31b0d8d6794bd2d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 30 10:44:34 2022 -0700
+
+    [config] Sort
+
+ src/hb-config.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 0d98c79b103a5bb2dfb684549077096853e08c55
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 21:07:38 2022 -0700
+
+    [util] Centralize includes again
+
+ util/helper-cairo.hh | 5 -----
+ util/options.hh      | 4 ++++
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+commit d90ccc1c5c28eb0480c10d57a53daea2c17c0384
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 21:02:06 2022 -0700
+
+    [view] More includes
+
+ util/helper-cairo.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 969914b2b526a8017dfc85efa6a23a8453d17666
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 21:01:16 2022 -0700
+
+    [view] Clean up includes
+
+ util/ansi-print.hh   | 5 -----
+ util/helper-cairo.hh | 4 ++++
+ util/options.hh      | 3 ---
+ 3 files changed, 4 insertions(+), 8 deletions(-)
+
+commit 2bbc57c3c4ed4c54cd9f0fcab48b17a1d57a5823
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 20:41:55 2022 -0700
+
+    [chafa] Residual
+
+ util/helper-cairo-ansi.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 962d4925b27a3adf3805b98e5b8d221161ded421
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 20:39:02 2022 -0700
+
+    [ansi] Optimize write
+
+ util/ansi-print.hh | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+commit a35f8e340baee34d5b31df425b3044e520626c96
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 20:34:23 2022 -0700
+
+    [ansi] Whitespace
+
+ util/ansi-print.hh | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+commit 0004ec13a6334f6a279922c4f7111277bec20a60
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 20:26:42 2022 -0700
+
+    [view] Write ansi output to --output-file
+    
+    Was writing to stdout all this time!
+
+ util/ansi-print.hh        | 23 ++++++++++++++++-------
+ util/helper-cairo-ansi.hh | 12 ++++++++----
+ 2 files changed, 24 insertions(+), 11 deletions(-)
+
+commit 3a319b59bd4e52a20dbe7cd34ab85efe71a4831d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 20:26:09 2022 -0700
+
+    [ansi] Write \e directly
+
+ util/ansi-print.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit ab8b9b444305dc01f5205ef0b7398a78184511b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 18:33:12 2022 -0700
+
+    [view] Streamline cairo-ft face lifecycle management
+
+ util/helper-cairo-ft.hh | 10 ++++++++++
+ util/helper-cairo.hh    |  7 -------
+ 2 files changed, 10 insertions(+), 7 deletions(-)
+
+commit 228a415470dec6c58b5543d00ca1fd7f72980be3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 18:19:06 2022 -0700
+
+    [view-cairo] Minor subpixel-bits
+
+ util/helper-cairo.hh |  4 ++--
+ util/view-cairo.hh   | 12 ++++++------
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 74d29cd16890b013302626bf566dabe26e3300e2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 18:11:41 2022 -0700
+
+    [helper-cairo] Remove a method
+
+ util/helper-cairo.hh | 66 ++++++++++++++++++++++++----------------------------
+ util/view-cairo.hh   |  3 +--
+ 2 files changed, 32 insertions(+), 37 deletions(-)
+
+commit f2a6643fc15da58c5aec60a90b3eeea6af4d0ea2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 18:00:39 2022 -0700
+
+    [cairo] Docs
+
+ src/hb-cairo.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit bfce4a60465e47f8c5f2cb916972e07242bbadc5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 10:43:37 2022 -0700
+
+    [cairo] Remove error path
+    
+    Assume cairo API always returns non-NULL.
+
+ src/hb-cairo.cc | 19 -------------------
+ 1 file changed, 19 deletions(-)
+
+commit b1de87b7f1ebe62fc9325679489718494ec1d3a2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 29 10:34:47 2022 -0700
+
+    [cairo] Document get_glyphs() arguments as inout
+
+ src/hb-cairo.cc      | 41 ++++++++++++++++++++++++++++++++++-------
+ util/helper-cairo.hh |  2 ++
+ 2 files changed, 36 insertions(+), 7 deletions(-)
+
+commit 3be9fa07f65130b3b534095d0c6cb2b36b85acdd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 29 10:14:51 2022 -0500
+
+    [docs] Mention new font-funcs in the user manual
+
+ docs/usermanual-fonts-and-faces.xml | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+commit 2c2121784a6b162b2cdbb31b1388e8abc15691b8
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 29 09:57:56 2022 -0500
+
+    [docs] Add a Cairo integration section
+
+ docs/usermanual-integration.xml | 44 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 43 insertions(+), 1 deletion(-)
+
+commit 89bd7f64ae91d9dfe2cf498233f38ecf054ec484
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 29 08:05:16 2022 -0500
+
+    [hb-cairo] Small docs fixes
+
+ src/hb-cairo.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit c9206df1667101fa4fa5c54ac6e0d9750a0d2d1f
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Dec 29 16:05:19 2022 +0200
+
+    [hb-cairo] Fix warnings
+
+ src/hb-cairo-utils.cc | 58 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 29 insertions(+), 29 deletions(-)
+
+commit 723e7a48e213ad9216f49762d6881745c36f6678
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Thu Dec 29 15:49:21 2022 +0200
+
+    [docs] Small fixes
+
+ src/hb-cairo.cc | 6 +++---
+ src/hb-font.h   | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 313f74a6931eef76d3d35a09c38c90851342a88f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jun 29 07:32:58 2022 -0400
+
+    Add a basic test for hb-coretext api
+    
+    This tests what would be my minimum assumption
+    about this api. It was written blindly.
+
+ test/api/Makefile.am     |  6 ++++
+ test/api/meson.build     |  6 ++++
+ test/api/test-coretext.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 91 insertions(+)
+
+commit 661baf403c9c6e8a8c7562adaf8cf39e21185101
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Jun 29 07:31:46 2022 -0400
+
+    Add a basic test for hb-ft api
+    
+    This tests what would be my minimum assumption
+    about this api.
+
+ test/api/Makefile.am |   4 ++
+ test/api/meson.build |   5 ++-
+ test/api/test-ft.c   | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 128 insertions(+), 1 deletion(-)
+
+commit 67456a7a02feee7bf9644f01402cbfade85bcac2
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 28 13:07:54 2022 -0500
+
+    [ft] Some more docs clarifications
+
+ src/hb-ft.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit c612d068e8a5b90675c4e27a8ca2bd90ba8798eb
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 28 10:42:59 2022 -0500
+
+    [ft] Clarify docs around faces too
+
+ src/hb-ft.cc | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 4dc955bb46f9f945e2cf0d79c0a12b15d200e3f7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 28 10:04:21 2022 -0500
+
+    [ft] Clarify docs
+    
+    Add some clarifications on what fonts these apis
+    work with.
+
+ src/hb-ft.cc | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+commit ef20b5e66f3e693b2c9e08f0e03802d2b8c2456c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 28 08:51:27 2022 -0500
+
+    Typo fix
+
+ src/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dc9ca63763234d5082db5e88944d1fccb65ed565
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 17:49:02 2022 -0700
+
+    [hb-view] Remove stale disabled code path
+    
+    With color rendering that code path is wrong anyway.
+    And cairo now supports subpixel text positioning.
+
+ util/view-cairo.hh | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+commit 5efb3bc6919f771f68780e3879e4be0d5121e99e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 17:47:46 2022 -0700
+
+    [hb-view] Set hb-cairo scale-factor
+    
+    Unused.
+
+ util/helper-cairo.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 81c04b0c2176b6dce850a76ace059b74d59bbee5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 17:46:25 2022 -0700
+
+    [cairo] Add separate x/y scale factors
+
+ src/hb-cairo.cc      | 43 ++++++++++++++++++++++---------------------
+ src/hb-cairo.h       |  3 ++-
+ util/helper-cairo.hh |  2 +-
+ 3 files changed, 25 insertions(+), 23 deletions(-)
+
+commit 50b7fff0c6f38819a66735d66ebd670655b4e961
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 17:37:42 2022 -0700
+
+    [cairo] Fix text_to_glyphs scale factor
+
+ src/hb-cairo.cc | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+commit 8f62b8c6bb1ecf1ef5abcdf88798076d48ef28b5
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 17:26:39 2022 -0700
+
+    [cairo] Fix cluster conversion
+
+ src/hb-cairo.cc | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+commit 326db329f84793152838ff8c45d284f4766c0a7a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 14:38:17 2022 -0700
+
+    [directwrite] Simplify delete
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3981
+
+ src/hb-directwrite.cc | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+commit 7b0f9abc897f656addc55ad875bd4737cbb17128
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 12:37:53 2022 -0700
+
+    [paint] Add back "remote-control" API
+    
+    This reverts commit f146299a405b8338542a245b85e664de29f0c972.
+
+ docs/harfbuzz-sections.txt |  13 +++
+ src/hb-paint.cc            | 246 +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-paint.h             |  67 ++++++++++++
+ 3 files changed, 326 insertions(+)
+
+commit 43b0364edacaa487ea18bc0261d72e3e45e42197
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 12:29:53 2022 -0700
+
+    [paint] Document composition modes
+
+ src/hb-paint.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+commit ec9e8a5993727174c765572cd71eba6fd3b38f90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 12:22:56 2022 -0700
+
+    [paint] Document extend modes.
+
+ src/hb-paint.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit fa3fa9422deb7bf9330f62412bbe24fe11eb7c4d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 11:54:23 2022 -0700
+
+    [cairo] Doc
+
+ src/hb-cairo.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit bbf6f42d3b3b7d5310255013eb1bb17528565121
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 11:50:06 2022 -0700
+
+    [cairo] TODO
+
+ src/hb-cairo.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit f9fc13287b5b384cb3485687c150d284a9fe53b2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 11:08:34 2022 -0700
+
+    [hb-cairo] Return hb_font_t* from init-func
+
+ src/hb-cairo.cc | 2 +-
+ src/hb-cairo.h  | 8 +++++---
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit d18903e44334d198e1d5445a4316da17887a75dc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Dec 27 09:25:05 2022 -0500
+
+    Add def files for libharfbuzz-cairo
+
+ src/Makefile.am | 7 ++++++-
+ src/meson.build | 6 ++++++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+commit d88787b6cab610ab961648e9f6c000a69c25d43b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 10:59:17 2022 -0700
+
+    [cairo] Add func to init fonts on creation
+    
+    To set, for example, font-funcs.
+
+ docs/harfbuzz-sections.txt |   6 +-
+ src/hb-cairo.cc            | 138 ++++++++++++++++++++++++++++++---------------
+ src/hb-cairo.h             |  30 ++++++++--
+ 3 files changed, 121 insertions(+), 53 deletions(-)
+
+commit c52bff2d6132c5716825f45bf7e0a64e48e83a51
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 27 10:42:13 2022 -0700
+
+    [cairo] Hide internal symbols
+
+ src/hb-cairo-utils.hh | 44 ++++++++++++++++++++++++--------------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+commit 7d3b3739253a901b88cd4da9916007ae7166c9de
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Dec 27 08:37:46 2022 -0500
+
+    Fix the autotools build
+
+ util/Makefile.sources | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 34aa8b0148dc03fcaff7dfe09ca7dab7f3c91a97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:54:31 2022 -0700
+
+    [cairo] Add to library tests
+
+ src/check-libstdc++.py | 2 +-
+ src/check-symbols.py   | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 5fdfe6ae5d8118d7e2c0f90a8a7014e4d60a3a28
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:52:53 2022 -0700
+
+    [cairo] Use hb_qsort
+
+ src/hb-cairo-utils.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 21573265e92006eedac5bd5a3d43dc5b28e108b4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:52:13 2022 -0700
+
+    [cairo] More namespacing
+
+ src/hb-cairo-utils.cc | 196 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 98 insertions(+), 98 deletions(-)
+
+commit 84d1b00cd4e29d428d60b45610231b9b93967693
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:45:23 2022 -0700
+
+    [cairo] More namespacing
+
+ src/hb-cairo-utils.cc | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 8f16e98c1b645d7374f0e61388d8e6a427a53c63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:44:07 2022 -0700
+
+    [cairo] Namespace types
+
+ src/hb-cairo-utils.cc | 84 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 42 insertions(+), 42 deletions(-)
+
+commit 488be5246778b8e4f7177b84bb452f48e4217b41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:42:22 2022 -0700
+
+    [cairo] Try fix msvc build
+
+ src/hb-cairo-utils.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit c652e8e1b7a2a92d898b08941dc081546a26c101
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:25:22 2022 -0700
+
+    [cairo] Docs
+
+ src/hb-cairo.cc | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit 23980d3cb2e0d374933f28e58ff0631b4a59e1e0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:22:35 2022 -0700
+
+    [cairo] Docs
+
+ src/hb-cairo.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit f5fd46aa3d905a7c69c12fa35c48d8c3b64f0cf2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:18:27 2022 -0700
+
+    [cairo] Docs
+
+ src/hb-cairo.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 36482b684b16f752965485b41c39558c1f144504
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:15:06 2022 -0700
+
+    [cairo] Err, utf8_clusters
+
+ src/hb-cairo.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 48cb25dd36a83f48748b295eebdfd74de170dc41
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:13:57 2022 -0700
+
+    [cairo] Implement (untested) text_to_glyphs callback
+
+ src/hb-cairo.cc | 41 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+commit c38abcb3fbe30d835988f2a0920c5eb80cf42266
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 16:03:25 2022 -0700
+
+    [cairo] Add x,y args to get_glyphs
+
+ src/hb-cairo.cc      | 18 +++++++++++-------
+ src/hb-cairo.h       |  2 ++
+ util/helper-cairo.hh | 10 ++++------
+ 3 files changed, 17 insertions(+), 13 deletions(-)
+
+commit 847ed695473306e76c3084df893e2c24bf79c440
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:59:57 2022 -0700
+
+    [cairo] Reorder arguments of a call
+
+ src/hb-cairo.cc      | 22 +++++++++++-----------
+ src/hb-cairo.h       |  4 ++--
+ util/helper-cairo.hh |  4 ++--
+ 3 files changed, 15 insertions(+), 15 deletions(-)
+
+commit 726cfffc0d37c0bb5aa4bd98403e369c829cbbed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:55:56 2022 -0700
+
+    [cairo] Doc fix
+
+ src/hb-cairo.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0fe0cdf066791b8805826a149cd438d56ba7e2f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:52:55 2022 -0700
+
+    [cairo] Document scale-factor business
+
+ src/hb-cairo.cc | 32 ++++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+commit 4e3e879c1cb25eb87bf0c0076067024184f875b7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:33:04 2022 -0700
+
+    [cairo] Add [sg]et_scale_factor
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-cairo.cc            | 58 +++++++++++++++++++++++++++++++++++++++++++---
+ src/hb-cairo.h             |  7 ++++++
+ 3 files changed, 64 insertions(+), 3 deletions(-)
+
+commit 186bfa99f54747698bcebea35cb52fff680b3807
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:15:40 2022 -0700
+
+    [cairo] Make scale_factor a double
+
+ src/hb-cairo.cc | 4 ++--
+ src/hb-cairo.h  | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 120419e180843b1183345d50d73585bc55805a17
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:10:26 2022 -0700
+
+    [hb-view] Fix autotools build
+
+ src/Makefile.am       | 1 +
+ util/Makefile.am      | 1 +
+ util/Makefile.sources | 2 --
+ 3 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 650a46d919dec6f55cbeb21685ab064086b5bf92
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:02:01 2022 -0700
+
+    [cairo] Fix autotools build
+
+ src/Makefile.am      |  4 ++--
+ src/Makefile.sources | 11 +++++++++--
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+commit b417ac8a19ed09df3702722a9af4e74296d4bee2
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 08:43:52 2022 -0500
+
+    Try to fix autotools build
+
+ src/Makefile.am          | 10 ++++++++++
+ src/Makefile.sources     |  3 +++
+ src/harfbuzz-cairo.pc.in | 12 ++++++++++++
+ 3 files changed, 25 insertions(+)
+
+commit 8d0e18b51d37c7f7e4d49e42e612d82e40f88656
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 22:12:29 2022 -0500
+
+    [cairo] More details in the docs
+    
+    Mention slant as well.
+
+ src/hb-cairo.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 30605e09b9e9be7469bd4b6989af3c99da36a691
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 22:04:22 2022 -0500
+
+    [cairo] Mention variations in the docs
+
+ src/hb-cairo.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit c4f7563f8178eee8ec1dbf9de5a3198efc1a9e18
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:40:44 2022 -0700
+
+    [cairo] Fix build
+
+ src/meson.build | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 7a52ac4bbe5951626756ccd3cb8e50e382bbbe44
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:39:02 2022 -0700
+
+    [cairo] Set variations
+
+ src/hb-cairo.cc | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+commit 4be4e017fc0685745e6e9d3d44c40d191f26ff5a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:27:53 2022 -0700
+
+    [cairo] Make font immutable
+
+ src/hb-cairo.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit ea993af8e7819826b98573a98b4b11363fed0e57
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:17:18 2022 -0700
+
+    [view] Don't double-slant
+
+ util/helper-cairo.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 70babda6adcadeac883b1ba14ed2b8c46d09cd99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:10:11 2022 -0700
+
+    [cairo] docs
+
+ docs/harfbuzz-sections.txt |  5 ++++-
+ src/hb-cairo.cc            | 31 +++++++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+commit 1c67180d6dd7be650c47eddfcaa1ea1b73220fe2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:07:02 2022 -0700
+
+    [cairo] Add typed destroy funcs
+
+ src/hb-cairo.cc | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 43da222e6dca2117fd2bbd4cd428dfe3cf056d23
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:05:24 2022 -0700
+
+    [cairo] Rename
+
+ src/hb-cairo.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit cf001f6ec777e40bd01c2087d8f9c5a4575e33f3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 19:01:28 2022 -0700
+
+    [cairo] Add constructor from hb_face_t
+
+ src/hb-cairo.cc      | 70 +++++++++++++++++++++++++++++++++++++++++-----------
+ src/hb-cairo.h       | 11 ++++++++-
+ util/helper-cairo.hh |  2 +-
+ 3 files changed, 67 insertions(+), 16 deletions(-)
+
+commit 2e897cc90b754e67240cba2589e7e28027b436cc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 20:03:59 2022 -0500
+
+    Add a pc file for harfbuzz-cairo
+
+ src/meson.build | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit ddb52e4a30375c2455f6c019c355d3bcf1adc196
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 19:52:39 2022 -0500
+
+    [cairo] Add docs
+
+ docs/harfbuzz-docs.xml     |  1 +
+ docs/harfbuzz-sections.txt |  7 ++++++
+ src/hb-cairo.cc            | 53 +++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 60 insertions(+), 1 deletion(-)
+
+commit dc2bf2664deb7700dd32b82612a49f363a51c443
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 18:02:34 2022 -0700
+
+    [cairo] Set scaled-font extents
+
+ src/hb-cairo.cc | 46 +++++++++++++++++++++++++++++++---------------
+ 1 file changed, 31 insertions(+), 15 deletions(-)
+
+commit d6ecda36bf43aad91de016771e2176b990225eea
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 17:39:26 2022 -0700
+
+    [cairo] Renames
+
+ src/hb-cairo.cc | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit ffa45f243c6ae9977b67340cad7beaa8ce7110b4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 17:14:45 2022 -0700
+
+    [cairo] #ifdef HAVE_CAIRO
+
+ src/hb-cairo-utils.cc | 4 ++++
+ src/hb-cairo.cc       | 4 ++++
+ src/hb-ft.cc          | 1 -
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+commit 9e61fd770562967c7ac9fa4f7ddfa64a04167cfd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 17:09:43 2022 -0700
+
+    [hb-cairo] Lazy-load funcs thread-safe
+
+ src/hb-cairo.cc         | 68 ++++++++++++++++++++++++++++++++++++-------------
+ src/hb-paint-extents.cc |  3 +++
+ 2 files changed, 54 insertions(+), 17 deletions(-)
+
+commit 49a6aa97d97ccbd8d17deefbbdadb1edd2227e42
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 19:09:19 2022 -0500
+
+    [docs] Add missing HB_HAS macros
+
+ docs/harfbuzz-sections.txt | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 306645503d1d019b4ec011e9bacec43bb7a46a9a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 19:03:50 2022 -0500
+
+    Work on proper build integration
+    
+    Install hb-cairo.h and define HB_HAS_CAIRO.
+
+ docs/harfbuzz-sections.txt |  1 +
+ src/hb-features.h.in       |  7 +++++++
+ src/meson.build            | 51 +++++++++++++++++++++++++++++++---------------
+ 3 files changed, 43 insertions(+), 16 deletions(-)
+
+commit a7c2e839e1850c875aab2d563be2fd9f89530430
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:59:58 2022 -0700
+
+    [hb-cairo] Prefix internal methods
+
+ src/hb-cairo.cc | 224 +++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 116 insertions(+), 108 deletions(-)
+
+commit bb640d403141c7f2b32e2d1f080d155d23c33e52
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:55:27 2022 -0700
+
+    [hb-cairo] Use nullptr instead of NULL
+
+ src/hb-cairo.cc | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+commit b3a3656683fedabbe8f5e5e1e7d71fee6b61a91b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:53:54 2022 -0700
+
+    [hb-cairo] Minor
+
+ src/hb-cairo-utils.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3a11a09f542715aa92d956614089050a7b83d318
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:53:21 2022 -0700
+
+    [hb-cairo] Rename cairo_extend
+
+ src/hb-cairo-utils.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 20a50acc91946f1ae3421dd7dd5657b81e1ffd24
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:09:26 2022 -0700
+
+    [hb-cairo] Make hb_cairo_glyphs_from_buffer public
+
+ src/hb-cairo.cc      | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-cairo.h       |  12 +++++
+ src/hb-utf.hh        |  30 ++++++++++++-
+ util/helper-cairo.hh | 121 -------------------------------------------------
+ 4 files changed, 166 insertions(+), 122 deletions(-)
+
+commit bf52386cfa6ca0c41750e40950b48727d67c7441
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:10:31 2022 -0700
+
+    [cairo] Silence warning
+
+ src/hb-cairo.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit e594780e2893ca3b5c0e4c252225258964a7ffd6
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 16:05:33 2022 -0700
+
+    [hb-cairo] Some header tweaks
+
+ src/hb-cairo-utils.hh | 11 ++++++-----
+ src/hb-cairo.h        |  1 +
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+commit 1ad24421a67ec4ce2d62587586aaf0eace71d866
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 15:55:14 2022 -0700
+
+    [hb-cairo] Rename files to C++
+
+ src/{hb-cairo-utils.c => hb-cairo-utils.cc} | 78 +++++++++++------------------
+ src/{hb-cairo-utils.h => hb-cairo-utils.hh} |  0
+ src/{hb-cairo.c => hb-cairo.cc}             | 11 ++--
+ src/meson.build                             |  4 +-
+ 4 files changed, 36 insertions(+), 57 deletions(-)
+
+commit a230eb8cf587cd00140f5361e119967524125438
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 15:49:14 2022 -0700
+
+    [hb-cairo] Factorize hb_cairo_glyphs_from_buffer
+    
+    To be made public.
+
+ util/helper-cairo.hh | 146 +++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 100 insertions(+), 46 deletions(-)
+
+commit 5c3da76a439cb00d3cb45eacd51de40959c73cc1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 15:04:13 2022 -0700
+
+    [hb-cairo] Change API again
+    
+    We need to work with a hb-font for variations and font-funcs
+    to be fetched properly.
+
+ src/hb-cairo.c       | 21 ++++++---------------
+ src/hb-cairo.h       |  6 +++---
+ util/helper-cairo.hh |  8 +++++---
+ 3 files changed, 14 insertions(+), 21 deletions(-)
+
+commit 9f7538c2606d330f64bed5e71d7676195bb74975
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 25 13:46:37 2022 -0700
+
+    [hb-cairo] Change API
+
+ src/hb-cairo.c       | 46 ++++++++++++----------------------------------
+ src/hb-cairo.h       |  9 ++++-----
+ util/helper-cairo.hh | 23 ++++++++++-------------
+ 3 files changed, 26 insertions(+), 52 deletions(-)
+
+commit 0d6ee4621e7cc20f273430d4a041e31355cf716d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 10:50:56 2022 -0500
+
+    wip: Make hb-view use hb-cairo
+    
+    This is a quick hack to prove that the
+    hb-cairo apis work
+
+ util/hb-cairo-utils.c     | 847 ----------------------------------------------
+ util/hb-cairo-utils.h     |  97 ------
+ util/helper-cairo-user.hh | 541 -----------------------------
+ util/helper-cairo.hh      |  43 +--
+ util/meson.build          |   3 +-
+ 5 files changed, 25 insertions(+), 1506 deletions(-)
+
+commit 767bdd43a63cf50a9b0339cea8bb1a7a3311410a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 25 10:32:33 2022 -0500
+
+    wip: Add libharfbuzz-cairo
+    
+    This library will provide integration with cairo
+    for font rendering.
+
+ src/hb-cairo-utils.c | 847 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-cairo-utils.h |  97 ++++++
+ src/hb-cairo.c       | 432 ++++++++++++++++++++++++++
+ src/hb-cairo.h       |  44 +++
+ src/meson.build      |  19 ++
+ 5 files changed, 1439 insertions(+)
+
+commit 2a515679251116e3058fc43bf7ff54e08e14e3e4
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 16:50:32 2022 -0500
+
+    [paint] Add a test for recursion
+
+ test/api/fonts/bad_colrv1.ttf | Bin 0 -> 16708 bytes
+ test/api/results/bad-20-0-154 | 349 ++++++++++++++++++++++++++++++++++++++++++
+ test/api/test-paint.c         |   2 +
+ 3 files changed, 351 insertions(+)
+
+commit c3a8c6bb8b0a44fb338b85014bd88615ecf5c79f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:38:24 2022 -0700
+
+    [paint] More docs
+
+ src/hb-paint.cc |  4 +++-
+ src/hb-paint.h  | 28 ++++++++++++++++++++++++++++
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+commit 5f168db884d2db7321cfbc251a98819a6ba0e4a4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 15:12:27 2022 -0700
+
+    [hb-view] Build with autotools if cairo-ft is not available
+    
+    Like with meson.
+
+ util/Makefile.am | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit ae208963dfd9bf3354b2eaa194bf2f4b5ec60c99
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 26 12:30:39 2022 -0700
+
+    Add hb-limits.hh
+
+ src/Makefile.sources           |   1 +
+ src/OT/glyf/Glyph.hh           |   5 --
+ src/hb-buffer.hh               |  20 --------
+ src/hb-cff-interp-cs-common.hh |   3 +-
+ src/hb-ft-colr.hh              |   9 +---
+ src/hb-limits.hh               | 105 +++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-color-colr-table.hh  |  14 ++----
+ src/hb-ot-layout-common.hh     |  36 --------------
+ src/hb.hh                      |   1 +
+ src/meson.build                |   1 +
+ 10 files changed, 113 insertions(+), 82 deletions(-)
+
+commit 5f5fa4b219320461a39c2d5c30a413574db6f628
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 13:47:35 2022 -0500
+
+    [ft-colr] Limit the size of the graph we follow
+    
+    This adds the same check that we already do in
+    the native implementation.
+
+ src/hb-ft-colr.hh | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+commit ea2892c30e6be7f073d2fc70237b7f6a77efff82
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 10:10:39 2022 -0500
+
+    [paint] Limit the size of the graph we follow
+    
+    In addition to checking the depth, also count
+    the number of edges in the graph we've followed,
+    and give up after 1024.
+
+ src/hb-ot-color-colr-table.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 1eb4d002f21354216c2fc7df973c7ca671e2af34
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 12:56:33 2022 -0500
+
+    Try to fix the build with msvc
+
+ test/api/test-paint.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 00e93102a63058aac9354edd87cdc16611e51168
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 08:31:22 2022 -0500
+
+    Add a test for hb_ot_color_glyph_has_paint
+
+ test/api/test-ot-color.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit e7b0947afd7caddbd865788f96af71a282eefdbc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 08:24:39 2022 -0500
+
+    Add a test for hb_ot_color_has_paint
+
+ test/api/test-ot-color.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 5dd69d81b0d2a1e2323dd780a684c041ffb310ed
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 08:23:55 2022 -0500
+
+    Fix hb_ot_color_has_paint
+    
+    We must no access v1 data without checking that
+    version is 1. A bit of a trap.
+
+ src/hb-ot-color-colr-table.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit b8f2281c6c1546853821d9b26bdb61f9fe5acd0a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 26 07:59:01 2022 -0500
+
+    Add hb_ot_color_glyph_has_paint
+
+ docs/harfbuzz-sections.txt    |  1 +
+ src/hb-ot-color-colr-table.hh | 13 +++++++++++++
+ src/hb-ot-color.cc            | 19 +++++++++++++++++++
+ src/hb-ot-color.h             |  4 ++++
+ 4 files changed, 37 insertions(+)
+
+commit 79c5bb92ce0609af093f23d8bfa5b092cfe09111
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 12:57:33 2022 -0700
+
+    [ft] Work around a freetype bug
+
+ src/hb-ft.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit a7a93b85e655dd947db23fd7350c2209729ab140
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 14:05:12 2022 -0500
+
+    Drop accidentally added ttx files
+
+ test/api/fonts/RocherColorGX.abc.ttx       | 2714 ---------
+ test/api/fonts/test_glyphs-glyf_colr_1.ttx | 8458 ----------------------------
+ 2 files changed, 11172 deletions(-)
+
+commit fa1cf15e5d53b3c7bd7e75c21ef3e9225f5b8b7d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:56:23 2022 -0700
+
+    [ft-colr] Whitespace
+
+ src/hb-ft-colr.hh | 102 +++++++++++++++++++++++++++---------------------------
+ 1 file changed, 51 insertions(+), 51 deletions(-)
+
+commit 5343eac16188e0cee6b50e452ea5590bc6cce2d2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:53:43 2022 -0700
+
+    [ft-colr] Minor use context instead of direct access
+
+ src/hb-ft-colr.hh | 45 ++++++++++++++++++++++++---------------------
+ 1 file changed, 24 insertions(+), 21 deletions(-)
+
+commit 0b6468b820d5f65259fc900e97e9e796cadbbd38
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:50:57 2022 -0700
+
+    [ft-colr] Minor
+
+ src/hb-ft-colr.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1c595ec17fe11288dd133db243ba5c5c75ed808d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:40:44 2022 -0700
+
+    [paint-extents] Lazy-load paint_extents funcs
+
+ src/hb-ft-colr.hh             |  2 --
+ src/hb-ot-color-colr-table.hh |  4 ----
+ src/hb-paint-extents.cc       | 53 ++++++++++++++++++++++++++++++-------------
+ 3 files changed, 37 insertions(+), 22 deletions(-)
+
+commit 4280ed290d4b773f94228f746688bde7be33971e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:38:32 2022 -0700
+
+    [paint-extents] Add missing file
+
+ src/hb-paint-extents.hh | 282 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 282 insertions(+)
+
+commit 2c0ab34d03477a5ad15bf8cddd4c99e61572efee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:37:59 2022 -0700
+
+    [paint-extents] Lazy-load draw-funcs
+
+ src/hb-machinery.hh     | 16 ++++++++++++++++
+ src/hb-paint-extents.cc | 37 +++++++++++++++++++++++++++++--------
+ 2 files changed, 45 insertions(+), 8 deletions(-)
+
+commit 11036ed71ed4fb6b7eb1cc365100be8628161727
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:30:45 2022 -0700
+
+    [paint] Add hb-paint-extents.cc
+
+ src/Makefile.sources                             |   1 +
+ src/harfbuzz-subset.cc                           |   1 +
+ src/harfbuzz.cc                                  |   1 +
+ src/{hb-paint-extents.hh => hb-paint-extents.cc} | 255 +----------------------
+ src/meson.build                                  |   1 +
+ 5 files changed, 6 insertions(+), 253 deletions(-)
+
+commit 959996d709dad7ce4a8087b2eef9dd4d6169493f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:22:16 2022 -0700
+
+    [paint-extents] Namespace
+
+ src/hb-paint-extents.hh | 52 ++++++++++++++++++++++---------------------------
+ 1 file changed, 23 insertions(+), 29 deletions(-)
+
+commit 62bd26dda3950bb879c1cf9907bb7e6f1b8a7b2c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 11:01:32 2022 -0700
+
+    [ft] Pick largest bitmap size
+
+ src/hb-ft.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit d35dff020f7852d4b3d48966b4bcb69b2452330b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:59:17 2022 -0700
+
+    [cbdt] Remove extra clip
+
+ src/hb-ot-color-cbdt-table.hh | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit f70c5d6f0da2cca2c2df4765ba45dbe5fee0cc79
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:56:06 2022 -0700
+
+    [paint] Continue returning bool from paint_image()
+    
+    https://github.com/harfbuzz/harfbuzz/commit/6ccbfabd4fcc5d4cca99be10552c270205fd7792#commitcomment-94127307
+
+ src/hb-ft.cc                  | 17 ++++++++++-------
+ src/hb-ot-color-cbdt-table.hh | 14 +++++++-------
+ src/hb-ot-color-sbix-table.hh | 14 +++++++-------
+ src/hb-paint.hh               |  8 ++++----
+ 4 files changed, 28 insertions(+), 25 deletions(-)
+
+commit 6ccbfabd4fcc5d4cca99be10552c270205fd7792
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:44:25 2022 -0700
+
+    [paint] Return bool from paint_image()
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3974
+
+ src/hb-paint-extents.hh   |  4 +++-
+ src/hb-paint.cc           |  4 ++--
+ src/hb-paint.h            | 20 +++++++++++---------
+ test/api/test-paint.c     |  8 ++++++--
+ util/hb-cairo-utils.c     | 12 +++++++-----
+ util/hb-cairo-utils.h     | 14 +++++++-------
+ util/helper-cairo-user.hh |  4 ++--
+ 7 files changed, 38 insertions(+), 28 deletions(-)
+
+commit 346331d37518f6de411f28bc09917fee475cad15
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:35:26 2022 -0700
+
+    [ft] Fix negative xscale
+
+ src/hb-ft.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 9376e7a93096b6eff1872063823278a569dbfdb0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:31:30 2022 -0700
+
+    [ft] Remove stale TODO
+
+ src/hb-ft.cc | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit a7fd48c408e13a0979a418739e73d5e196be1252
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:28:41 2022 -0700
+
+    [ft] Comment
+
+ src/hb-ft.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit bb45ba2f9f4469b8bf326118ffe8003fb487f1f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:25:43 2022 -0700
+
+    [ft] Fix negative y-scale
+
+ src/hb-ft.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit aba2063c22629308fac59bf91e3b4c9a8eaa2fa1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:15:47 2022 -0700
+
+    [paint-extents] Comments
+
+ src/hb-paint-extents.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 988ca459f33f1ac1b580d935fa0612ed985ae987
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:12:35 2022 -0700
+
+    [paint-extents] Minor refactor
+
+ src/hb-paint-extents.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit f8bf98798d8cba184c2a623c35d0b1202ded48bd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 10:04:48 2022 -0700
+
+    [paint-extents] Refactor code
+
+ src/hb-paint-extents.hh | 111 ++++++++++++++++++++++--------------------------
+ 1 file changed, 51 insertions(+), 60 deletions(-)
+
+commit f9081fc358f6673ce289992b6cdfb0b63068142c
+Merge: 1f3c042ff dfd371e97
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 24 09:51:11 2022 -0700
+
+    Merge pull request #3938 from harfbuzz/wip/matthiasc/paint-api
+    
+    hb-paint API
+
+commit 1f3c042ff50ca231441b006825aa089e3a54fab1
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Dec 24 17:03:57 2022 +0200
+
+    [doc] Don’t automatically skip building docs on Windows
+    
+    Respect the option setting.
+
+ .github/workflows/msys2-ci.yml | 1 +
+ docs/meson.build               | 5 -----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+commit dfd371e97653b704326e04c2436ee3edab6c9d64
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 09:57:48 2022 -0500
+
+    Cosmetics
+
+ util/helper-cairo-user.hh | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit d00e97f16cb72ce12ef8c93ccc34fb1be2023a10
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 06:58:44 2022 -0500
+
+    Add test-paint to the autotools build
+
+ test/api/Makefile.am                       |    7 +
+ test/api/fonts/RocherColorGX.abc.ttx       | 2714 +++++++++
+ test/api/fonts/test_glyphs-glyf_colr_1.ttx | 8458 ++++++++++++++++++++++++++++
+ 3 files changed, 11179 insertions(+)
+
+commit 3478728edb32787bcc52cf262563c140a958031e
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 08:51:23 2022 -0500
+
+    Fix test-paint build without freetype
+
+ test/api/test-paint.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 4816be9ab5c0afdc7019728620c6761838236bd3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 07:37:04 2022 -0500
+
+    Work around cairo limitations
+    
+    If we just draw an image, cairos recording surface
+    complains that it is unbounded. Its not true of course.
+    
+    To make things work, clip to the extents.
+
+ src/hb-ot-color-cbdt-table.hh |  7 +++++++
+ util/hb-cairo-utils.c         | 11 +++++++++++
+ 2 files changed, 18 insertions(+)
+
+commit 9b9d7c7b8eac99116eeb9cead68c9f926881841c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 05:34:47 2022 -0500
+
+    Plug a memory lek in paint tests
+
+ test/api/test-paint.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 76c16095fa9a15d719ce78e3adc6d890439e62e1
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 24 05:30:11 2022 -0500
+
+    Fix the build on Windows
+    
+    No __BYTE_ORDER there.
+
+ util/hb-cairo-utils.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f9c865a8998d6d41b756526f1053b7f55e3c2218
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 20:20:33 2022 -0500
+
+    Update test results
+    
+    These were changed by the introduction of
+    clip boxes.
+
+ test/api/results/hand-20-0-10   | 188 ++++++++++++++++++++--------------------
+ test/api/results/hand-20-0.2-10 | 188 ++++++++++++++++++++--------------------
+ test/api/results/test-20-0-10   |  30 ++++---
+ test/api/results/test-20-0-106  |  46 +++++-----
+ test/api/results/test-20-0-116  |  42 ++++-----
+ test/api/results/test-20-0-123  |  54 ++++++------
+ test/api/results/test-20-0-165  |  30 ++++---
+ test/api/results/test-20-0-175  |  54 ++++++------
+ test/api/results/test-20-0-6    |  28 +++---
+ test/api/results/test-20-0-92   |  28 +++---
+ 10 files changed, 354 insertions(+), 334 deletions(-)
+
+commit f7eebc397c87d4e8c14c5c0e9f892c0dc8b2e269
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 18:52:46 2022 -0700
+
+    [paint-extents] Shorten enum addressing
+
+ src/hb-paint-extents.hh | 42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+commit 0110bdb3eaa46a6a60f2d5bc0f9cd2f782c6d446
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 18:17:05 2022 -0700
+
+    [paint-extents] Streamline extents_t more
+
+ src/hb-paint-extents.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 9f3e050b990e7006a34648faa62a1fd912b8e3c1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 18:15:21 2022 -0700
+
+    [paint-extents] Streamline extents_t
+
+ src/hb-paint-extents.hh | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+commit 0d129ae308d7ac8d0d676b302118229e5add655d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 18:00:38 2022 -0700
+
+    Fix warning
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 73e48b9357ae8efb1526d64f6978efa8f22d80e3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 17:55:09 2022 -0700
+
+    [colr] Push clipbox or computed clip
+
+ src/hb-ot-color-colr-table.hh | 59 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 56 insertions(+), 3 deletions(-)
+
+commit 02684751bd6c4f76e6377862136611cf12f66762
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 17:33:13 2022 -0700
+
+    [paint-extents] Clean up
+
+ src/hb-ft-colr.hh             | 15 ++++++++++-----
+ src/hb-ot-color-colr-table.hh |  9 +++++----
+ src/hb-paint-extents.hh       | 10 ++++++++++
+ 3 files changed, 25 insertions(+), 9 deletions(-)
+
+commit dbea503a38878d8cab0d2106d5b7e44d6550ff5b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 17:28:46 2022 -0700
+
+    [colr] Return true extents
+
+ src/hb-ot-color-colr-table.hh | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+commit f9c2e30e0173f29ce5c05b3163561b1dab3889f7
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 17:13:35 2022 -0700
+
+    [paint-extents] Better handle empty glyphs
+
+ src/hb-paint-extents.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 885dbcfba0e1bbc22255ab54f8f76096cb35fdeb
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 19:07:32 2022 -0500
+
+    Skip empty outlines
+
+ src/hb-paint-extents.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit bd61e645ffea3fdc421f7dc17c0ac0c5fb0d2357
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 16:59:12 2022 -0700
+
+    [paint-extents] Use hb_min/hb_max
+
+ src/hb-paint-extents.hh | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+commit 56a48f8b0a881dd0c211f76668a36b477f22e100
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 16:44:06 2022 -0700
+
+    [paint] Don't use extents in hb-view
+    
+    Let the clipbox do its magic. Currently works for ft backend only.
+
+ src/hb-ft-colr.hh         | 1 -
+ util/helper-cairo-user.hh | 7 -------
+ 2 files changed, 8 deletions(-)
+
+commit 79229cea1743acaf12c5736f8d7d0e2a8308a961
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 18:33:53 2022 -0500
+
+    Get outline extents manually
+
+ src/hb-paint-extents.hh | 96 +++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 89 insertions(+), 7 deletions(-)
+
+commit 55b7af6b621daf2b02d49d4b43d54c67298865fd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 18:01:45 2022 -0500
+
+    Tweak paint-tests
+
+ test/api/test-paint.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 47c896f0040c4fd6b6c91cdbc0f4f0fa2e9f6582
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 16:20:44 2022 -0700
+
+    [paint-extents] Hook it up, kinda
+
+ src/hb-ft-colr.hh             | 25 +++++++++++++++++++------
+ src/hb-ot-color-colr-table.hh | 16 ++++++++++++++++
+ 2 files changed, 35 insertions(+), 6 deletions(-)
+
+commit 7fbaaebe8bf61523f1c69ba50c4c29c5e5230fa1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 15:37:16 2022 -0700
+
+    [paint-extents] Finish off
+    
+    Untested and unused.
+
+ src/hb-paint-extents.hh | 61 +++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 56 insertions(+), 5 deletions(-)
+
+commit 8ca78d1520cf9c4ee1720ed80abc3167cdf6f963
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 15:21:48 2022 -0700
+
+    [paint-extend] More
+
+ src/hb-paint-extents.hh | 56 +++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 50 insertions(+), 6 deletions(-)
+
+commit 23a2d4dbabf812c75dec6bfe7ceb3a4fbf0b039e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 15:10:26 2022 -0700
+
+    [paint-extents] More
+
+ src/hb-paint-extents.hh | 30 +++++++++++++++++++++++++++++-
+ 1 file changed, 29 insertions(+), 1 deletion(-)
+
+commit d7435b10095bf035f41539de5e1ddd39c14719ce
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 15:05:30 2022 -0700
+
+    [paint-extents] Flesh out more
+
+ src/hb-paint-extents.hh | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+commit c37a1eadef4c99d7c95cefb8341c40c7b3159246
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 14:57:12 2022 -0700
+
+    [paint-extents] Flesh out some more
+
+ src/hb-paint-extents.hh | 64 ++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 48 insertions(+), 16 deletions(-)
+
+commit 268d8b7dedf35b8c097075c2726753fb1462a04d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 14:45:56 2022 -0700
+
+    [paint-extents] Start out
+
+ src/Makefile.sources    |   1 +
+ src/hb-ft-colr.hh       |   2 +
+ src/hb-paint-extents.hh | 288 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/meson.build         |   1 +
+ 4 files changed, 292 insertions(+)
+
+commit 44b48845b7200a74f4ea01711f30a7c3ebe6fee4
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 16:26:05 2022 -0500
+
+    Add tests for hb_color_line_t
+    
+    Test a few things that were broken with the
+    ft implementation before.
+
+ test/api/test-paint.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 108 insertions(+)
+
+commit a4a86c0ec281e0e5ce0cd90822d6b6d633457342
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 13:52:22 2022 -0700
+
+    [test-paint] g_test_message
+
+ test/api/test-paint.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit dcab5679889ff47db6765e1ea853963cf9ee4286
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 13:47:37 2022 -0700
+
+    [test-paint] Don't use g_test_fail_print() for older glib
+
+ test/api/test-paint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8e197f50daf6d89a1e6f14cbd9836160d5d3d8c7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 15:31:16 2022 -0500
+
+    Add missing paint test results
+
+ test/api/results/rocher-120-0-3   | 12 ++++++++++++
+ test/api/results/rocher-120-0.3-1 | 12 ++++++++++++
+ test/api/results/rocher-120-0.3-2 | 12 ++++++++++++
+ 3 files changed, 36 insertions(+)
+
+commit d9875ddc9d7a6b7078906929d98e0606a49f5da4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 12:37:42 2022 -0700
+
+    [ft-colr] Add depth counter
+
+ src/hb-ft-colr.hh | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit 3b021c5568bf8fe26b9691075211dad2408ae3b9
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 14:30:29 2022 -0500
+
+    Run paint tests with ft font funcs
+
+ test/api/test-paint.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 56 insertions(+), 3 deletions(-)
+
+commit ca190aaba4878b00bfeda39ae4f8ba6b669e90d3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 14:03:03 2022 -0500
+
+    Split off the hb-paint tests
+    
+    They belong in their own file.
+
+ test/api/meson.build     |   1 +
+ test/api/test-ot-color.c | 370 -------------------------------------------
+ test/api/test-paint.c    | 400 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 401 insertions(+), 370 deletions(-)
+
+commit ecd7420456619dcfffd51b943468ed828c07d5a1
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 13:32:31 2022 -0500
+
+    Debug spew
+    
+    To get a dump of the hb-paint callbacks,
+    set HB_PAINT_DEBUG=1 when running hb-view.
+    
+    For now, leave this code in place, since it
+    comes in handy for various debugging.
+
+ util/helper-cairo-user.hh | 131 ++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 126 insertions(+), 5 deletions(-)
+
+commit 583f010b0506cec061e5a6849da649fe3d2cb22e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 12:10:22 2022 -0700
+
+    [ft] Move lock only around clip_glyph
+
+ src/hb-ft.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 276290390952d0ad26f77247675ad023e0651856
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 12:09:17 2022 -0700
+
+    [ft-colr] Minor
+
+ src/hb-ft-colr.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3a1385f019082575e93bb92be870e1b5d9c76134
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 12:06:18 2022 -0700
+
+    [ft-colr] Simplify color-stop callback
+
+ src/hb-ft-colr.hh | 98 +++++++++++++++++++++++++------------------------------
+ 1 file changed, 44 insertions(+), 54 deletions(-)
+
+commit 1cc3b10008a2ae52b83466bb0039e2b8d99f7a28
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 11:55:55 2022 -0700
+
+    [ft-colr] Ifdef build for older freetype
+
+ src/hb-ft-colr.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 882c2bca2dcc898b6aa884605013c2609dd775ba
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 11:48:41 2022 -0700
+
+    [ft-colr] Add a paint context
+
+ src/hb-ft-colr.hh | 167 +++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 95 insertions(+), 72 deletions(-)
+
+commit 7a4b4c64f2f71e3b66833222a153a3f7b56300b3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 11:36:04 2022 -0700
+
+    [ft-colr] Minor macro
+
+ src/hb-ft-colr.hh | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+commit c453c2fce990b066155ccb72d8a39eba55e42a2d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 11:33:23 2022 -0700
+
+    [ft-colr] Fix color-stop iteration
+
+ src/hb-ft-colr.hh | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+commit bbb89e62aa5f876dc0b9348f11ce6a24ab032e47
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 13:30:26 2022 -0500
+
+    [paint] Document color lines as transient
+    
+    Just so people don't get ideas.
+
+ src/hb-paint.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 15582d5fc164f8e0a4b5f2df5ef246e213cd85d2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 11:14:16 2022 -0700
+
+    [ft-colr] Apply slant to clipbox
+
+ src/hb-ft-colr.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7abd5dcf10ea06fb5ba48077734222e7acc41065
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 11:49:06 2022 -0500
+
+    [ft-paint] Fix handling of colorstop iters
+
+ src/hb-ft-colr.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 393bab4ba1e5938843f83cc824e4a4142b42ff56
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 11:02:38 2022 -0500
+
+    [ft-paint] Apply ClipBox to all glyphs
+
+ src/hb-ft-colr.hh | 41 +++++++++++++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
+
+commit c11ae85cbfa7b7a13577a058544a39146fc81bbf
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 09:20:45 2022 -0500
+
+    [ft-paint] Apply root transform
+
+ src/hb-ft-colr.hh | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 7fc3fdac761670d9c223768c128f5225a87b47df
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 09:16:26 2022 -0500
+
+    [ft-paint] Optimize away some transforms
+
+ src/hb-ft-colr.hh | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+commit 586d1758c1aecf995de85020cb608f3fe5d859cf
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 09:21:14 2022 -0500
+
+    [ft-paint] Fix an oversight
+
+ src/hb-ft-colr.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 092637f94c60bc56ba135bbce1905275bde0925d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 09:14:11 2022 -0500
+
+    [ft-paint] Fix rounding
+
+ src/hb-ft-colr.hh | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit fe08e956e0eb89ca26547b00d0a3191db9011af9
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 09:08:10 2022 -0500
+
+    [ft-paint] Fix a case of x/y confusion
+
+ src/hb-ft-colr.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 0d5256e5a729552a6c9b292c42928fc3734a95a7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 02:41:08 2022 -0500
+
+    [ft-paint] Fix some fixed->float conversions
+
+ src/hb-ft-colr.hh | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+commit 07ba5be393f43ea8584074c61a463717ef33d72f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 01:10:35 2022 -0500
+
+    [paint] Documentation tweaks
+
+ src/hb-paint.cc |  9 +++++----
+ src/hb-paint.h  | 15 +++++----------
+ 2 files changed, 10 insertions(+), 14 deletions(-)
+
+commit 13e0cb64f47f54c54651a239c8633f6d836ea9eb
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 00:54:05 2022 -0500
+
+    hb-view: Interpolate gradients premultiplied
+    
+    This is what the specs demand.
+
+ util/hb-cairo-utils.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+commit 21f78c87744c8a119f999f4b02c50009f681db33
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 00:30:40 2022 -0500
+
+    [paint] Document that colors are unpremultiplied
+    
+    And mention that gradient interpolation must happen
+    in premultiplied space.
+
+ src/hb-paint.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit b6e98cf758b8f38c14dee28b57d63514ace1a97d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 00:18:40 2022 -0500
+
+    [colr] Add more docs
+    
+    State explicitly that palette entries are
+    unpremultipled, and link to the spec.
+
+ src/hb-font.cc | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+commit 7a2dc5cf5b41058c6d598cd89f714d81ea325632
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 22:29:52 2022 -0700
+
+    [docs] Hook up a couple
+
+ docs/harfbuzz-sections.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a634f6b48699b72b3f5bc57aad0c88c713e138f8
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 00:18:40 2022 -0500
+
+    [colr] Add more docs
+    
+    State explicitly that palette entries are
+    unpremultipled, and link to the spec.
+
+ src/hb-ot-color.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit a02c2a911cc59985db00b86b09ed77b755238291
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 22:05:09 2022 -0700
+
+    [ft-paint] Apply alpha correctly
+
+ src/hb-ft-colr.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ee7bbdf372833a5705a0ba9e012d9665f5731726
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 00:01:20 2022 -0500
+
+    tests: Update expected results
+    
+    These were changed by fixes for glyph transforms.
+
+ test/api/results/hand-20-0-10    | 92 ++++++++++++++++++++++++----------------
+ test/api/results/hand-20-0.2-10  | 92 ++++++++++++++++++++++++----------------
+ test/api/results/rocher-20-0-2   | 12 ------
+ test/api/results/rocher-20-0-3   | 12 ------
+ test/api/results/rocher-20-0.3-1 | 12 ------
+ test/api/results/test-20-0-10    | 18 ++++----
+ test/api/results/test-20-0-106   |  8 +++-
+ test/api/results/test-20-0-116   |  8 +++-
+ test/api/results/test-20-0-123   | 12 ++++--
+ test/api/results/test-20-0-165   | 18 ++++----
+ test/api/results/test-20-0-175   | 20 +++++----
+ test/api/results/test-20-0-6     | 16 ++++---
+ test/api/results/test-20-0-92    | 16 ++++---
+ test/api/test-ot-color.c         |  6 +--
+ 14 files changed, 184 insertions(+), 158 deletions(-)
+
+commit 3993a407037477e384650a1394c27c15596c9a45
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 22 23:55:27 2022 -0500
+
+    test: Add some verification hints
+
+ test/api/test-ot-color.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+commit 6ebcc9d2e16ca4d7eaad2002ea8209dce5e9ed90
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 21:23:45 2022 -0700
+
+    [ft-paint] Hook up gradients
+
+ src/hb-ft-colr.hh | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 122 insertions(+), 3 deletions(-)
+
+commit fe4e9bd93070daa2b8ac3bb8201e3736faab752b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 20:14:19 2022 -0700
+
+    [colr] Add public vtable for hb_color_line_t
+
+ src/hb-ot-color-colr-table.cc | 47 ---------------------------------
+ src/hb-ot-color-colr-table.hh | 44 ++++++++++++++++++++++++-------
+ src/hb-paint.cc               | 49 +++++++++++++++++++++++++++++++++++
+ src/hb-paint.h                | 60 ++++++++++++++++++++++++++++++++-----------
+ 4 files changed, 129 insertions(+), 71 deletions(-)
+
+commit 7c9e42ed924d7e286b666e9206532cf1dac76955
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 19:49:06 2022 -0700
+
+    [colr] Fix transform hell
+
+ src/hb-ot-color-colr-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 569d5b436cff95fbd7753aebb443ecc682d248c8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 18:00:02 2022 -0700
+
+    [ft-paint] Remove dead code
+
+ src/hb-ft-colr.hh | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit cfdc34b44d97bedfe482612f885f52641452390f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:58:36 2022 -0700
+
+    [ft-paint] Implement FT_COLR_PAINTFORMAT_SKEW
+
+ src/hb-ft-colr.hh | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+commit 64cf17ec8b616dcf0a6254c56498b3b53cd4b933
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:55:25 2022 -0700
+
+    [ft-paint] Fix center translation
+
+ src/hb-ft-colr.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit ddbe4e52ec05bca0c284192af41df7479edd2ecd
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:54:01 2022 -0700
+
+    [ft-paint] Implement FT_COLR_PAINTFORMAT_ROTATE
+
+ src/hb-ft-colr.hh | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+commit 16598e024bd79796878650b9e723b02269e8f9d4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:51:35 2022 -0700
+
+    [ft-paint] Default
+
+ src/hb-ft-colr.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit a0f7f9e61cca50dfbf6969c1dfd088301ac89318
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:50:35 2022 -0700
+
+    [ft-paint] Implement FT_COLR_PAINTFORMAT_COMPOSITE
+
+ src/hb-ft-colr.hh | 67 ++++++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 57 insertions(+), 10 deletions(-)
+
+commit 0ec201446bf0f8b776a8820e97d76b4357036e2f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:40:53 2022 -0700
+
+    [ft] Implement FT_COLR_PAINTFORMAT_COLR_GLYPH
+
+ src/hb-ft-colr.hh | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+commit ac2682c610e64d47d9de0f5c742779a3b8f48f80
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 17:36:54 2022 -0700
+
+    [ft] Start of a COLRv1 renderer
+
+ src/hb-ft-colr.hh | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 161 insertions(+), 3 deletions(-)
+
+commit e2546f5ab0fa440206ef501b382c19e8409ada61
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 15:50:43 2022 -0700
+
+    [ft] Add hb-ft-colr.hh
+
+ src/Makefile.sources |   2 +-
+ src/hb-ft-colr.hh    | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ft.cc         |  60 ++++--------------------------
+ src/meson.build      |   2 +-
+ 4 files changed, 112 insertions(+), 54 deletions(-)
+
+commit 5bd3c07b5475dac69e33403f8c33b137cf9281d2
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 22 16:23:50 2022 -0500
+
+    [colr] Don't access baseGlyphList unless v1
+    
+    This was showing up sporadic crashes due to
+    invalid reads.
+
+ src/hb-ot-color-colr-table.hh | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+commit 47dbebff393dcb121f058b43977bf8d931b19b1e
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 22 16:06:51 2022 -0500
+
+    [paint] Add COLRv0 tests
+
+ test/api/fonts/RocherColorGX.abc.ttf | Bin 0 -> 7588 bytes
+ test/api/results/rocher-20-0-2       |  12 ++++++++++++
+ test/api/results/rocher-20-0-3       |  12 ++++++++++++
+ test/api/results/rocher-20-0.3-1     |  12 ++++++++++++
+ test/api/test-ot-color.c             |  35 +++++++++++++++++++++++------------
+ 5 files changed, 59 insertions(+), 12 deletions(-)
+
+commit 6909701b36e989a9bd0f581bf4959f8c706116a7
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 22 15:32:09 2022 -0500
+
+    [paint] Update docs
+
+ src/hb-paint.h | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 381d410b1eae1a292741a78920ff2e0fb436df55
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 13:21:48 2022 -0700
+
+    [paint] Add HB_PAINT_IMAGE_FORMAT_BGRA and use it in hb-ft
+    
+    Now hb-ft can render color emoji as well.
+    
+    Just left COLRv2.
+
+ docs/harfbuzz-sections.txt |  4 +++
+ src/hb-ft.cc               | 39 ++++++++++++++++++++++-
+ src/hb-paint.h             | 18 +++++++++--
+ util/hb-cairo-utils.c      | 78 +++++++++++++++++++++++++++++++++++++++-------
+ 4 files changed, 125 insertions(+), 14 deletions(-)
+
+commit 63db0d2aed3cda83470bae5c2c8128d1bc54ac46
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 12:19:33 2022 -0700
+
+    [util] Speculatively fix build against non-PNG builds
+
+ util/hb-cairo-utils.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit c5f903872fdb9d7221acd6910a9c5c5acabf99a9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 12:16:55 2022 -0700
+
+    [paint] Add bitmap width/height to paint_image callback
+    
+    Such that we can add raw data as well.
+
+ src/hb-ot-color-cbdt-table.hh | 45 ++++++++++++++++++++++++++++---------------
+ src/hb-ot-color-sbix-table.hh | 31 ++++++++++++++++-------------
+ src/hb-ot-color-svg-table.hh  |  7 ++++++-
+ src/hb-paint.cc               |  2 ++
+ src/hb-paint.h                |  8 ++++++--
+ src/hb-paint.hh               |  3 ++-
+ util/hb-cairo-utils.c         |  9 +++++++--
+ util/hb-cairo-utils.h         |  2 ++
+ util/helper-cairo-user.hh     |  4 +++-
+ 9 files changed, 75 insertions(+), 36 deletions(-)
+
+commit eef47f2379a3509a2f306fb3e6207f4541b96b73
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 22 14:16:02 2022 -0500
+
+    [paint] Fix the docs
+
+ src/hb-paint.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 3c972867b97a0fbca5bef25ebfd7cbdab008a102
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 11:40:06 2022 -0700
+
+    More s/hb_font_get_glyph_shape/hb_font_draw_glyph/
+
+ perf/benchmark-font.cc         |  2 +-
+ src/hb-draw.h                  | 10 ++---
+ test/api/test-draw.c           | 88 +++++++++++++++++++++---------------------
+ test/fuzzing/hb-draw-fuzzer.cc |  2 +-
+ 4 files changed, 51 insertions(+), 51 deletions(-)
+
+commit 72a169c846c9be92d5ac5d0b2bc051d6ef5e8e6f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 11:26:10 2022 -0700
+
+    [ft] Paint COLRv0 glyphs
+
+ src/hb-ft.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 64 insertions(+), 13 deletions(-)
+
+commit bb807f47d22f23a2da348f0498282c9ae7b81ab9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 10:51:26 2022 -0700
+
+    [ft] Implement paint_glyph() for outline glyphs
+
+ src/hb-ft.cc | 46 +++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 45 insertions(+), 1 deletion(-)
+
+commit 91c880503e7b194c9fc15cfe43eae4c70b1b19f9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 10:42:27 2022 -0700
+
+    [ft] Use new name for draw API
+
+ src/hb-ft.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit c27eefec1df85d1648106c3d0ae7d2e740c5cedc
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 10:41:13 2022 -0700
+
+    Revert "Drop the deprecation"
+    
+    This reverts commit 3904e66777339a3d420ece1c2b7d550949aa3946.
+
+ src/hb-font.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit f3985d948279c00518d5f3dea925a71a8e2be23f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 10:11:28 2022 -0700
+
+    [paint] Fix drawing non-color glyphs
+
+ src/OT/glyf/glyf.hh     | 6 +-----
+ src/hb-ot-cff1-table.cc | 6 +-----
+ src/hb-ot-cff2-table.cc | 6 +-----
+ 3 files changed, 3 insertions(+), 15 deletions(-)
+
+commit 237955dffca19bc320ca1b94808b52265ef653ed
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 08:12:47 2022 -0700
+
+    [paint] Add slant to image() callback
+    
+    And slant images in hb-view.
+
+ src/hb-ot-color-cbdt-table.hh | 2 +-
+ src/hb-ot-color-sbix-table.hh | 2 +-
+ src/hb-ot-color-svg-table.hh  | 2 +-
+ src/hb-paint.cc               | 1 +
+ src/hb-paint.h                | 1 +
+ src/hb-paint.hh               | 3 ++-
+ util/hb-cairo-utils.c         | 7 +++++++
+ util/hb-cairo-utils.h         | 1 +
+ util/helper-cairo-user.hh     | 3 ++-
+ 9 files changed, 17 insertions(+), 5 deletions(-)
+
+commit c221933977bdcf272fd9f2ded5e1182de8ae1939
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 18:39:27 2022 -0500
+
+    [paint] Preserve foreground information
+
+ src/OT/glyf/glyf.hh           |  2 +-
+ src/hb-ot-cff1-table.cc       |  2 +-
+ src/hb-ot-cff2-table.cc       |  2 +-
+ src/hb-ot-color-colr-table.hh | 23 +++++++++++++++++------
+ src/hb-paint.cc               |  1 +
+ src/hb-paint.h                |  4 ++++
+ src/hb-paint.hh               |  3 ++-
+ test/api/test-ot-color.c      |  1 +
+ util/helper-cairo-user.hh     |  1 +
+ 9 files changed, 29 insertions(+), 10 deletions(-)
+
+commit f146299a405b8338542a245b85e664de29f0c972
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 17:24:02 2022 -0500
+
+    [paint] Drop unnecessary api
+
+ docs/harfbuzz-sections.txt |  13 ---
+ src/hb-paint.cc            | 237 ---------------------------------------------
+ src/hb-paint.h             |  59 -----------
+ 3 files changed, 309 deletions(-)
+
+commit 6387004cadd8f5bc755f5b14c95fd71153bcc48b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 16:43:19 2022 -0500
+
+    [paint] Simplify api
+    
+    Drop the hb_paint_context_t struct from the API, and
+    only pass the font where we need it.
+
+ docs/harfbuzz-sections.txt    |   1 -
+ src/OT/glyf/glyf.hh           |  16 +--
+ src/hb-font.cc                |  12 +--
+ src/hb-ot-cff1-table.cc       |  16 +--
+ src/hb-ot-cff2-table.cc       |  16 +--
+ src/hb-ot-color-cbdt-table.hh |   7 +-
+ src/hb-ot-color-colr-table.cc |  12 +--
+ src/hb-ot-color-colr-table.hh | 242 +++++++++++++++++++++---------------------
+ src/hb-ot-color-sbix-table.hh |   3 +-
+ src/hb-ot-color-svg-table.hh  |   4 +-
+ src/hb-paint.cc               |  85 +++++----------
+ src/hb-paint.h                |  84 +++------------
+ src/hb-paint.hh               |  90 ++++------------
+ test/api/test-ot-color.c      |  13 +--
+ util/hb-cairo-utils.c         |  31 +-----
+ util/hb-cairo-utils.h         |   9 --
+ util/helper-cairo-user.hh     |  23 ++--
+ 17 files changed, 216 insertions(+), 448 deletions(-)
+
+commit 71bd5a0dfc34efdf61a641b8ba98303524adeb9a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 16:18:46 2022 -0500
+
+    [paint] Resolve colors
+    
+    We don't need to pass the index/alpha pairs to
+    client callbacks, and can just resolve the colors
+    internally.
+    
+    Update test results.
+
+ src/OT/glyf/glyf.hh             |  2 +-
+ src/hb-ot-cff1-table.cc         |  3 ++-
+ src/hb-ot-cff2-table.cc         |  2 +-
+ src/hb-ot-color-colr-table.cc   |  4 ++--
+ src/hb-ot-color-colr-table.hh   | 31 ++++++++++++++++++-------------
+ src/hb-paint.cc                 | 11 ++++-------
+ src/hb-paint.h                  | 33 +++++++--------------------------
+ src/hb-paint.hh                 | 27 ++++++++++++++++++++++++---
+ test/api/results/hand-20-0-10   | 34 +++++++++++++++++-----------------
+ test/api/results/hand-20-0.2-10 | 34 +++++++++++++++++-----------------
+ test/api/results/test-20-0-10   |  8 ++++----
+ test/api/results/test-20-0-106  |  4 ++--
+ test/api/results/test-20-0-116  |  4 ++--
+ test/api/results/test-20-0-123  |  6 +++---
+ test/api/results/test-20-0-165  |  6 +++---
+ test/api/results/test-20-0-175  |  6 +++---
+ test/api/results/test-20-0-6    |  4 ++--
+ test/api/results/test-20-0-92   |  6 +++---
+ test/api/test-ot-color.c        | 18 +++++++++++++-----
+ util/hb-cairo-utils.c           | 29 ++++++++++++++++++++++-------
+ util/helper-cairo-user.hh       | 11 ++++++-----
+ 21 files changed, 156 insertions(+), 127 deletions(-)
+
+commit bd1389bedf891311177b3aa9804aa4474c6758d0
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 15:23:43 2022 -0500
+
+    [paint] Add hb_paint_context_t to docs
+
+ docs/harfbuzz-sections.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 5d7553d38f178c1c071f356f98bbf43d21b4ce29
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 15:18:02 2022 -0500
+
+    view: Add a --font-palette option
+
+ util/font-options.hh      |  2 ++
+ util/helper-cairo-user.hh | 10 +++++++++-
+ util/helper-cairo.hh      |  3 +++
+ 3 files changed, 14 insertions(+), 1 deletion(-)
+
+commit d094e76cbc84dc13de35e2837ffe6d1a8aa51fab
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 15:02:41 2022 -0500
+
+    hb-view: Pass fg color to hb_font_paint_glyph
+
+ util/helper-cairo-user.hh | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+commit 9be01b6bff054e3edb516ca680a1e33b05a74e9b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 14:04:32 2022 -0500
+
+    [paint] Pass hb_paint_context_t along
+    
+    Replace the font argument with a hb_paint_context_t
+    that carries the font, the palette index and the
+    foreground color.
+    
+    The hb_font_paint_glyph() api now takes the palette
+    index and the foreground color as extra arguments.
+    
+    Update all callers and regenerate test results.
+
+ src/OT/glyf/glyf.hh             |  18 ++++--
+ src/hb-font.cc                  |  24 ++++++--
+ src/hb-font.h                   |   9 ++-
+ src/hb-font.hh                  |   5 +-
+ src/hb-ot-cff1-table.cc         |  19 ++++---
+ src/hb-ot-cff1-table.hh         |   2 +-
+ src/hb-ot-cff2-table.cc         |  20 ++++---
+ src/hb-ot-cff2-table.hh         |   2 +-
+ src/hb-ot-color-cbdt-table.hh   |   8 ++-
+ src/hb-ot-color-colr-table.cc   |   4 +-
+ src/hb-ot-color-colr-table.hh   | 119 ++++++++++++++++++++--------------------
+ src/hb-ot-color-sbix-table.hh   |   3 +-
+ src/hb-ot-color-svg-table.hh    |   4 +-
+ src/hb-ot-font.cc               |  10 ++--
+ src/hb-paint.cc                 |  98 ++++++++++++++++-----------------
+ src/hb-paint.h                  |  95 ++++++++++++++++++++------------
+ src/hb-paint.hh                 |  66 +++++++++++-----------
+ test/api/results/hand-20-0-10   |  18 +++---
+ test/api/results/hand-20-0.2-10 |  18 +++---
+ test/api/results/test-20-0-10   |   2 +-
+ test/api/results/test-20-0-106  |   4 +-
+ test/api/results/test-20-0-116  |   4 +-
+ test/api/results/test-20-0-123  |   6 +-
+ test/api/results/test-20-0-165  |   2 +-
+ test/api/results/test-20-0-175  |   4 +-
+ test/api/results/test-20-0-6    |   2 +-
+ test/api/results/test-20-0-92   |   2 +-
+ test/api/test-ot-color.c        |  26 ++++-----
+ util/hb-cairo-utils.c           |  51 +++++++----------
+ util/hb-cairo-utils.h           |  17 +++---
+ util/helper-cairo-user.hh       |  38 ++++++-------
+ 31 files changed, 384 insertions(+), 316 deletions(-)
+
+commit 6c71c530caaa40c0038ac1f33549a5a7f96266c3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 21 10:54:22 2022 -0700
+
+    [paint] Rename hb_paint_context_t to hb_ot_paint_context_t
+
+ src/hb-ot-color-colr-table.cc |  4 ++--
+ src/hb-ot-color-colr-table.hh | 56 +++++++++++++++++++++----------------------
+ 2 files changed, 30 insertions(+), 30 deletions(-)
+
+commit 8495395397e5a26dacad0cad689a41b06ef5314c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 21 09:03:13 2022 -0700
+
+    [paint] Fix slant
+
+ src/hb-paint.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b1500babaae38cb6d81bc4287adeb4678dfde1b3
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 09:49:42 2022 -0500
+
+    utils: Some cairo helper tweaks
+
+ util/hb-cairo-utils.c     | 64 +++++++++++++++++++++++------------------------
+ util/hb-cairo-utils.h     | 10 ++++----
+ util/helper-cairo-user.hh | 19 ++++++++------
+ 3 files changed, 48 insertions(+), 45 deletions(-)
+
+commit 97224f3b63e7d8ec74acabc1270ebf021c19afd6
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 02:11:36 2022 -0500
+
+    [paint] Pass font to all callbacks
+    
+    This will lead to easier implementations.
+    
+    At the same time, we change the push_clip_glyph
+    callback to use the font as-is, no unscaling needed.
+    
+    Update all callers and expected test results.
+
+ src/OT/glyf/glyf.hh                                |   8 +-
+ src/hb-font.cc                                     |   5 +-
+ src/hb-ot-cff1-table.cc                            |   8 +-
+ src/hb-ot-cff2-table.cc                            |   8 +-
+ src/hb-ot-color-cbdt-table.hh                      |   2 +-
+ src/hb-ot-color-colr-table.cc                      |   4 +-
+ src/hb-ot-color-colr-table.hh                      | 137 ++++++++++++---------
+ src/hb-ot-color-sbix-table.hh                      |   2 +-
+ src/hb-ot-color-svg-table.hh                       |   2 +-
+ src/hb-paint.cc                                    |  84 +++++++++----
+ src/hb-paint.h                                     |  65 +++++++---
+ src/hb-paint.hh                                    |  79 +++++++++---
+ src/hb.h                                           |   2 +-
+ test/api/results/hand-20-0-10                      |  97 +++++++++++++++
+ test/api/results/hand-20-0-10.txt                  |  79 ------------
+ test/api/results/hand-20-0.2-10                    |  97 +++++++++++++++
+ test/api/results/hand-20-0.2-10.txt                |  79 ------------
+ test/api/results/test-20-0-10                      |  14 +++
+ test/api/results/test-20-0-10.txt                  |  12 --
+ .../results/{test-20-0-106.txt => test-20-0-106}   |  16 ++-
+ test/api/results/test-20-0-116                     |  18 +++
+ test/api/results/test-20-0-116.txt                 |  14 ---
+ .../results/{test-20-0-123.txt => test-20-0-123}   |  24 ++--
+ test/api/results/test-20-0-165                     |  14 +++
+ test/api/results/test-20-0-165.txt                 |  12 --
+ test/api/results/test-20-0-175                     |  26 ++++
+ test/api/results/test-20-0-175.txt                 |  22 ----
+ test/api/results/test-20-0-6                       |  13 ++
+ test/api/results/test-20-0-6.txt                   |  11 --
+ test/api/results/test-20-0-92                      |  13 ++
+ test/api/results/test-20-0-92.txt                  |  11 --
+ test/api/test-ot-color.c                           |  40 +++---
+ util/helper-cairo-user.hh                          |  78 +++++-------
+ 33 files changed, 639 insertions(+), 457 deletions(-)
+
+commit 32ce29f99ea7387ce32de1114b1ce1c876fb6fbe
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 07:42:36 2022 -0500
+
+    [font] Move hb_font_t typedef
+    
+    This is needed to avoid circular header dependencies.
+
+ src/hb-common.h | 8 ++++++++
+ src/hb-font.h   | 9 ---------
+ src/hb-paint.h  | 3 +--
+ 3 files changed, 9 insertions(+), 11 deletions(-)
+
+commit 8364d9130f72a80802153efc7e22ac85bb38fe8f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 00:59:13 2022 -0500
+
+    Document hb_font_set_draw_glyph_func
+
+ src/hb-font.h | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit a20999b9df313702643f012845cee4e266236985
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 00:20:37 2022 -0500
+
+    [font] Fix a few documentation mistakes
+
+ src/hb-font.cc | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+commit 754528914d98db1e30192cc07de4e3df879d5d8a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 21 00:09:25 2022 -0500
+
+    [docs] Reorder paint section
+
+ docs/harfbuzz-sections.txt | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+commit 2333a566edbe99402d66086dd820a02335f56899
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Dec 20 22:43:04 2022 -0500
+
+    Drop the deprecation
+    
+    No need to drop hb_font_get_glyph_shape, just
+    because hb_font_draw_glyph does the same.
+    
+    Its fine to keep both around.
+
+ src/hb-font.h | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit cf02d13302941b964e2c3b63485eeb023698d26b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 20 11:52:39 2022 -0700
+
+    [cairo] Remove unused struct
+
+ util/hb-cairo-utils.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit 14b026ff86f55436897702e268cf6c7eddbb0859
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 13:53:49 2022 -0500
+
+    [draw] Add hb_font_draw_glyph
+    
+    hb_font_draw_glyph(), hb_font_draw_glyph_func_t and
+    hb_font_funcs_set_draw_glyph_func() are just alternative
+    names for hb_font_get_glyph_shape and friends, to better
+    align with hb_font_paint_glyph.
+
+ src/hb-draw.cc    |  2 ++
+ src/hb-font.cc    | 76 +++++++++++++++++++++++++++++++++++++++----------------
+ src/hb-font.h     | 46 ++++++++++++++++++++++++++++++++-
+ src/hb-font.hh    | 14 +++++-----
+ src/hb-ot-font.cc | 12 ++++-----
+ 5 files changed, 114 insertions(+), 36 deletions(-)
+
+commit 08da126523d1cdfdcd527f7bdf10c2d3525196e4
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 14:36:29 2022 -0500
+
+    [docs] Linkify links
+
+ src/hb-paint.h | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 9437f719a7217ddb2231709ead03c4b62cbdb42f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 14:29:39 2022 -0500
+
+    [paint] Document hb_paint_extend_t
+
+ src/hb-paint.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 3a2634e27cf6f1df164aacb70b2e107eab2a15e6
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 13:48:08 2022 -0500
+
+    [paint] Document hb_font_paint_glyph_func_t
+
+ docs/harfbuzz-sections.txt |  2 ++
+ src/hb-font.h              | 13 +++++++++++++
+ 2 files changed, 15 insertions(+)
+
+commit 0f287e75ece6364bc3fcdd752de837f8ef51529d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 13:45:45 2022 -0500
+
+    [paint] Rename hb_font_get_glyph_paint_func_t
+    
+    The 'get' was just there due to implementation
+    choices. Work around that and call the vfunc
+    what it should be: hb_font_paint_glyph_func_t.
+
+ src/hb-font.cc    | 40 ++++++++++++++++++++--------------------
+ src/hb-font.h     | 16 ++++++++--------
+ src/hb-font.hh    | 54 +++++++++++++++++++++++++++---------------------------
+ src/hb-ot-font.cc | 12 ++++++------
+ 4 files changed, 61 insertions(+), 61 deletions(-)
+
+commit b0fa40b2ece482818bfc9e71b2f173e43b9dd6dd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 13:16:10 2022 -0500
+
+    tests: More diagnostics
+
+ test/api/test-ot-color.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit ddd2039265e3bf20bb4809d57905f83c42e61b97
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 12:20:07 2022 -0500
+
+    [paint] Improve the docs
+
+ src/hb-paint.cc | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit 3a219cfa6a2bef8eb79dd86c2210485a71aece1d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 11:15:37 2022 -0500
+
+    [config] Make HB_LEAN imply HB_NO_PAINT
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0ef2dc9be557cc247621019933ca5151a4bd80cd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 10:02:17 2022 -0500
+
+    Drop a TODO
+    
+    This was addressed in 61bd602791d801
+
+ src/hb-font.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 96cda3886ceffc4264587576100d56f16c150ad0
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 09:59:33 2022 -0500
+
+    [paint] Clarify docs
+    
+    Spell out where the different datas originate.
+
+ src/hb-paint.h | 50 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 25 insertions(+), 25 deletions(-)
+
+commit 290bb338bf9a881e38899cd0391146ef7a52b2b1
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 02:39:14 2022 -0500
+
+    Dist test result files
+
+ test/api/Makefile.am | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit a3ba723876d4da299cd13d70a3accab1b0672ffb
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 02:22:34 2022 -0500
+
+    Drop an unneeded include
+
+ util/hb-cairo-utils.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 74ccc1e76df3dafbc48e02818403d0f0688cf8ca
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 00:49:02 2022 -0500
+
+    tests: Produce useful output on failure
+
+ test/api/test-ot-color.c | 32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+commit 084291108ac59a0a99b2cde58073ad4377dfdd82
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 01:08:41 2022 -0500
+
+    Tests: Fix memleak pointed out by valgrind
+
+ test/api/test-ot-color.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0800d1879c7aafb038e47793c9f3495da0221969
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 00:59:40 2022 -0500
+
+    Try to fix autotools build
+
+ src/Makefile.sources  | 3 +++
+ util/Makefile.sources | 2 ++
+ 2 files changed, 5 insertions(+)
+
+commit 5ac218865ad7df1643c8b70e527cc792415c28d0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 19 10:26:54 2022 -0700
+
+    [paint] A doc fix
+
+ src/hb-font.h   | 4 ++++
+ src/hb-paint.cc | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 5451b78f4a4d97277d3a411762844e97adda62cd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 00:07:18 2022 -0500
+
+    Don't use alloca
+    
+    It complicates things on Windows, for no
+    big win. Just preallocate a reasonable amount.
+
+ util/hb-cairo-utils.c | 58 +++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 45 insertions(+), 13 deletions(-)
+
+commit 7c12db46ff3fd771db4cc2d2cc6fea8937b34532
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 23:36:05 2022 -0500
+
+    Try to fix msvc build
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ util/hb-cairo-utils.c         | 5 +++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit d2b420589bb65e92385383966cf2a8c9865abc49
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 16:43:19 2022 -0500
+
+    [docs] Add hb-paint apis
+
+ docs/harfbuzz-docs.xml     |  1 +
+ docs/harfbuzz-sections.txt | 62 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+)
+
+commit d8cb7ceefb31600b288da05c2c09476953dafc91
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 14:35:36 2022 -0700
+
+    [test] Try fixing bots with old glib
+
+ test/api/test-ot-color.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5d1fc9ee9dcec13a45bfc19f53894ad83f42a2a0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 14:25:39 2022 -0700
+
+    [paint] Fix annotations
+
+ src/hb-paint.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 3590ee74f49fa571af145f788f2db6e122021116
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:59:56 2022 -0700
+
+    [util] Fix bot
+
+ util/helper-cairo-user.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ee2204469ebfe3a3e9c76e856a7e0c8aab1dd946
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:50:34 2022 -0700
+
+    [paint] Add get_empty / [sg]et_user_data
+
+ src/hb-cplusplus.hh |  2 +-
+ src/hb-draw.cc      |  1 -
+ src/hb-paint.cc     | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-paint.h      | 15 ++++++++++++++
+ 4 files changed, 74 insertions(+), 2 deletions(-)
+
+commit 21a9db875ed9204ac45093e97354158012b4b35f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:47:22 2022 -0700
+
+    [draw] Add get_empty / [sg]et_user_data
+
+ docs/harfbuzz-sections.txt |  3 +++
+ src/hb-cplusplus.hh        |  2 ++
+ src/hb-draw.cc             | 58 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-draw.h              | 15 ++++++++++++
+ 4 files changed, 78 insertions(+)
+
+commit 9a7422c5fb9eefa3c73cde387512e1de4adaa946
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:46:32 2022 -0700
+
+    [font] Minor doc fix
+
+ src/hb-font.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit a9b37206eb1e254b24226b5115932aa40f20f7d9
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:37:32 2022 -0700
+
+    [font] Minor rename
+
+ src/hb-font.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 815544a1f7ce0cd9da6cb632e7309ba31ed53faf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:33:54 2022 -0700
+
+    [font] Adapt paint_glyph to parent transform
+
+ src/hb-font.cc | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+commit 81bf08927361ae57563b02774523f7ce83903ea1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:15:49 2022 -0700
+
+    [hb-view] Use color render callback if HB_DRAW >= 2
+
+ util/helper-cairo-user.hh | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit c65f580b932daf7492d09c30462bf470247f794d
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 15:13:55 2022 -0500
+
+    Drop hb-test
+    
+    This was a test binary to assist in developing
+    the hb-paint code. Not needed anymore, now that
+    hb-view has the same code in the cairo userfont
+    backend.
+
+ util/hb-test.c   | 350 -------------------------------------------------------
+ util/meson.build |   7 --
+ 2 files changed, 357 deletions(-)
+
+commit 85917e5b2143e212224e7950d8ee97ccd14b9ee0
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 13:08:45 2022 -0700
+
+    [paint] Fix docs
+
+ src/hb-paint.h | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 14bf3aaa8d276470c826f095bc0f8d57ff930b38
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 12:59:35 2022 -0700
+
+    [colr] Make paint_image work again
+
+ src/hb-ot-color-cbdt-table.hh | 4 ----
+ src/hb-ot-color-sbix-table.hh | 4 ----
+ 2 files changed, 8 deletions(-)
+
+commit 9672aa8610d605617fc2465b0c5d5dc2fc33079f
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 12:57:42 2022 -0700
+
+    [util] Fix compiler warning
+
+ util/hb-cairo-utils.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 955bd30365d8bb7998515e0714c3aec94e284440
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 14:55:56 2022 -0500
+
+    Fix hb-cairo-utils
+    
+    This was a stupid mistake, and hard to track down.
+
+ util/hb-cairo-utils.c | 2 ++
+ util/hb-cairo-utils.h | 1 +
+ 2 files changed, 3 insertions(+)
+
+commit 35739567058b61a4545228ea5b832576f2824f63
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 12:56:01 2022 -0700
+
+    [util] Include stdio.h
+
+ util/hb-cairo-utils.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7accbe97d8dd0e55484fd4d1e76acea1c89c8ae1
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 12:51:26 2022 -0700
+
+    [util] Fix argument order and root transform PNGs
+
+ src/hb-ot-color-cbdt-table.hh | 6 +++++-
+ src/hb-ot-color-sbix-table.hh | 6 +++++-
+ util/hb-cairo-utils.c         | 9 +++------
+ 3 files changed, 13 insertions(+), 8 deletions(-)
+
+commit 529dc40d7db9bee1075fc16ba0971ad265ffac11
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 12:35:50 2022 -0700
+
+    [util] Adjust scaling
+    
+    Still doesn't render PNGs.
+    
+    Fix a few compiler warnings
+
+ util/hb-cairo-utils.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit bcc9ab27fcf02d57333a9bfc06261eede85c0746
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 11:59:54 2022 -0700
+
+    [hb-view] Fix transformation
+    
+    No need for cairo patch; that patch was wrong.
+
+ util/helper-cairo-user.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c996fc58ec8997242d853b8bfac4f4f9c3d96605
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 11:36:58 2022 -0700
+
+    [hb-view] Remove redundant check
+
+ util/helper-cairo-user.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit bec5354030e003e17aff2c0394c0b706d69cda73
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 11:26:46 2022 -0700
+
+    [hb-view] Fix render_color_glyph extents coordinate system
+    
+    Needs cairo fix:
+    https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/371
+
+ util/helper-cairo-user.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 95ccd66481768d443ac7aaeb1588823a79948944
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sun Dec 18 11:08:25 2022 -0700
+
+    [hb-view] Set glyph extents in render_color_glyph
+    
+    Works around limitation in cairo-recording-surface unboundedness.
+    
+    Extents are wrong but at least renders something now.
+
+ util/helper-cairo-user.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 6cadf280f286f5ad59466d71fd2b7f8c2fd5d267
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 09:42:18 2022 -0500
+
+    Use hb-cairo-utils in hb-test
+    
+    Just to prove that it works.
+
+ util/hb-test.c   | 1029 ++++++++----------------------------------------------
+ util/meson.build |    2 +-
+ 2 files changed, 144 insertions(+), 887 deletions(-)
+
+commit 8bcd13dd91916a436fa357fa73f9d4477d8a02ff
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 09:41:00 2022 -0500
+
+    small fixup to hb-cairo-utils
+
+ util/hb-cairo-utils.h | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit f1f8d1e855a4628a59bfc9b8b55d94a9e35e31de
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 02:43:25 2022 -0500
+
+    Small documentation addition
+
+ src/hb-font.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 6c49822cad38b071212823a303059e0917aeedfa
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 01:52:39 2022 -0500
+
+    wip: Use hb-paint in hb-view
+    
+    This doesn't paint anything yet.
+
+ util/hb-cairo-utils.c     | 727 ++++++++++++++++++++++++++++++++++++++++++++++
+ util/hb-cairo-utils.h     | 104 +++++++
+ util/helper-cairo-user.hh | 362 ++++++++++++++---------
+ util/meson.build          |   1 +
+ 4 files changed, 1061 insertions(+), 133 deletions(-)
+
+commit 021618e91ae26ef7af1fae4eb0693258e48a7d2a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sun Dec 18 00:12:32 2022 -0500
+
+    [colr] Add hb_ot_color_has_paint
+    
+    This is a counterpart to hb_ot_color_has_layers
+    for COLRv1 data.
+
+ src/hb-ot-color-colr-table.hh |  3 ++-
+ src/hb-ot-color.cc            | 30 ++++++++++++++++++++----------
+ src/hb-ot-color.h             |  5 +++++
+ 3 files changed, 27 insertions(+), 11 deletions(-)
+
+commit 63fcb26c9b771f6ab492dad896a4da911fb0427e
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 22:41:34 2022 -0500
+
+    Add some more docs
+
+ src/hb-ot-color.cc | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit 2d4678b6478874288312cfe773d735c351d04b0f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 22:30:31 2022 -0500
+
+    Add a comment
+
+ test/api/test-ot-color.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 3b32eab38e3212464239f32ad294d30d943a3ae2
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 17:13:30 2022 -0700
+
+    [colr] Fix compiler warning
+
+ util/hb-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 30a6fd04d00624129b13b20fb755d6c1c4982637
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 18:20:00 2022 -0500
+
+    [colr] Add some tests
+
+ test/api/fonts/noto_handwriting-cff2_colr_1.otf | Bin 0 -> 4172 bytes
+ test/api/fonts/test_glyphs-glyf_colr_1.ttf      | Bin 0 -> 16704 bytes
+ test/api/results/hand-20-0-10.txt               |  79 ++++++
+ test/api/results/hand-20-0.2-10.txt             |  79 ++++++
+ test/api/results/test-20-0-10.txt               |  12 +
+ test/api/results/test-20-0-106.txt              |  18 ++
+ test/api/results/test-20-0-116.txt              |  14 ++
+ test/api/results/test-20-0-123.txt              |  31 +++
+ test/api/results/test-20-0-165.txt              |  12 +
+ test/api/results/test-20-0-175.txt              |  22 ++
+ test/api/results/test-20-0-6.txt                |  11 +
+ test/api/results/test-20-0-92.txt               |  11 +
+ test/api/test-ot-color.c                        | 312 ++++++++++++++++++++++++
+ 13 files changed, 601 insertions(+)
+
+commit 451414a27eeee7b47bed7cd8c5bb88b81f7f5cca
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 18:14:31 2022 -0500
+
+    [paint] Documentation fixes
+
+ src/hb-ot-color-colr-table.cc | 42 ++++++++++++++++++++++++++++++++++--------
+ src/hb-paint.cc               |  4 +++-
+ 2 files changed, 37 insertions(+), 9 deletions(-)
+
+commit e3153654cbb5132a9b06231fb4402a3849a0fb68
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 13:56:22 2022 -0700
+
+    [colr] Fix PNG placement
+
+ util/hb-test.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+commit f07ce68f9cf8d5fd4eb37141a16e89cb0ec2bbae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 13:48:05 2022 -0700
+
+    Remove unused function
+
+ util/hb-test.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit 0c77f1d9abf5f8dcd931ca1ae5856039daf3e3fc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 14:10:28 2022 -0500
+
+    [paint] Documentation tweaks
+
+ src/hb-paint.cc | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-paint.h  |  25 ++++++++--
+ 2 files changed, 168 insertions(+), 6 deletions(-)
+
+commit 0a2f3673b9cbe340cdf329f3b303832b16f7d2ee
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 13:51:23 2022 -0500
+
+    [paint] Use tags for image formats
+    
+    This fits better with the rest of the
+    HarfBuzz API.
+
+ src/hb-ot-color-cbdt-table.hh |  2 +-
+ src/hb-ot-color-sbix-table.hh |  2 +-
+ src/hb-ot-color-svg-table.hh  |  2 +-
+ src/hb-paint.cc               |  6 +++---
+ src/hb-paint.h                | 30 +++++++++++++++++++++++-------
+ src/hb-paint.hh               |  4 ++--
+ util/hb-test.c                |  4 ++--
+ 7 files changed, 33 insertions(+), 17 deletions(-)
+
+commit 4c728e952b5f7fa29b6da6c674ac289fddaf875b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 13:33:56 2022 -0500
+
+    [colr] Add a todo
+
+ src/hb-ot-color-colr-table.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 4b0285bae60554c914f0b572fdaa5586be9f0611
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 11:18:42 2022 -0700
+
+    [colr] Use slant_xy
+
+ src/hb-paint.hh | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+commit b9314400eccb2dadce788f6af5d843d5341f2c11
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 10:58:52 2022 -0700
+
+    [colr] Hook up color-line variation
+
+ src/hb-ot-color-colr-table.cc |  4 ++--
+ src/hb-ot-color-colr-table.hh | 37 ++++++++++++++++++++++++-------------
+ 2 files changed, 26 insertions(+), 15 deletions(-)
+
+commit a935e4b0c256451f50b2c0886f4fed5152735b62
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 12:59:58 2022 -0500
+
+    [paint] Add synthetic slant to root transform
+
+ src/hb-paint.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit edf27382630a30070a33d9f65f005741fb15d95b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 10:47:55 2022 -0700
+
+    [colr] Try fixing bot build
+    
+    I don't get the error. Let's see.
+    
+    ../../src/harfbuzz/src/hb-ot-color-colr-table.hh:574:66: error: incomplete definition of type 'OT::NoVariable<OT::ColorLine<OT::NoVariable>>'
+
+ src/hb-ot-color-colr-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 686e627bdf1ef28f0ced44c146d0b3cd7f2def33
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 12:44:16 2022 -0500
+
+    [paint] Set up root transform in one place
+    
+    Instead of spreading this in all the tables,
+    make hb_paint_funcs_t provide a push/pop_root_transform
+    that does all the setup.
+
+ src/OT/glyf/glyf.hh           | 12 ++----------
+ src/hb-ot-cff1-table.cc       | 12 ++----------
+ src/hb-ot-cff2-table.cc       | 12 ++----------
+ src/hb-ot-color-colr-table.hh | 20 ++++----------------
+ src/hb-paint.hh               | 12 ++++++++++++
+ 5 files changed, 22 insertions(+), 46 deletions(-)
+
+commit c6dd56cc64d08defd661b3152a1ecd9b4b786db4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 10:38:23 2022 -0700
+
+    [colr] Simplify color-stop handling
+
+ src/hb-ot-color-colr-table.cc | 42 +++++++------------------------------
+ src/hb-ot-color-colr-table.hh | 49 ++++++++-----------------------------------
+ 2 files changed, 17 insertions(+), 74 deletions(-)
+
+commit 485ba9beb36d16f91330f50fa6f403cdb192f294
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 12:25:04 2022 -0500
+
+    [paint] Spell out rectangle in the API
+    
+    No need to abbreviate this.
+
+ src/hb-paint.cc | 12 ++++++------
+ src/hb-paint.h  | 32 ++++++++++++++++----------------
+ src/hb-paint.hh | 12 ++++++------
+ util/hb-test.c  | 12 ++++++------
+ 4 files changed, 34 insertions(+), 34 deletions(-)
+
+commit 37f3f0fcc25ed5cc0ea822b1a780705ab842d7bd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 11:49:18 2022 -0500
+
+    [paint] Change the image callback
+    
+    Instead of passing the glyph ID, give
+    it the image blob, a mimetype, and
+    glyph extents (if available).
+    
+    Update all callers.
+
+ src/hb-ot-color-cbdt-table.hh |  6 +++++-
+ src/hb-ot-color-sbix-table.hh |  6 +++++-
+ src/hb-ot-color-svg-table.hh  |  2 +-
+ src/hb-paint.cc               | 10 +++++++---
+ src/hb-paint.h                | 18 ++++++++++++++----
+ src/hb-paint.hh               |  6 ++++--
+ util/hb-test.c                | 16 ++++++++++------
+ 7 files changed, 46 insertions(+), 18 deletions(-)
+
+commit ea48d6c292bd248a6607a0cfe1d17f05fc4f018f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 11:51:37 2022 -0500
+
+    Move hb_glyph_extents_t definition
+
+ src/hb-common.h | 18 ++++++++++++++++++
+ src/hb-font.h   | 20 +-------------------
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+commit b722039c48b41c1e96c7a1bcbad072a2332d4e46
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 10:22:32 2022 -0700
+
+    [colr] Simplify
+
+ src/hb-ot-color-colr-table.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 452cfb95997cbc0a81f5533e1fa365cbf6888157
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 10:04:55 2022 -0700
+
+    [colr] Simplify loop using iterators
+    
+    Or complexify?!
+
+ src/hb-ot-color-colr-table.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit 601a596ca0837e36b45e117f70a5b7072c30d4e8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 09:22:55 2022 -0700
+
+    [paint] Fix include path
+
+ src/OT/glyf/glyf.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8a9069d55fdfe738103a2fea83317a7fd1857727
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 09:21:08 2022 -0700
+
+    [colr] Fix radial gradient
+    
+    Broke it when adding variations.
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e799c33bb59b8699a6c6b0f43e7e5854515c5075
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 09:00:20 2022 -0700
+
+    [paint] Fix function prototype
+
+ src/hb-paint.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1953d26a8a9cc0e70055c8cf5e8e876d7b6ac664
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 08:59:33 2022 -0700
+
+    [colr] Limit recursion depth
+
+ src/hb-ot-color-colr-table.hh | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit 378bbeea015f492756cbe7ffc39e6144a0ffe5ee
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 10:02:30 2022 -0500
+
+    Add more docs
+
+ src/hb-font.cc | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+commit 9876e30c6ee8fc53ae4d26692b9482e6011d04a5
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 02:46:37 2022 -0500
+
+    test: Support png images via paint_image
+
+ util/hb-test.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+commit 6079173a5229b8f51a0ee15f4e4ea957f1e2e722
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 01:04:35 2022 -0500
+
+    Try paint_glyph for more tables
+    
+    If the COLR table does not paint the glyph,
+    try SVG, CBDT and sbix too, before giving up
+    on color.
+
+ src/hb-ot-font.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit e6c5a616aaf081d0603a6f6e74be66d89c2b1832
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 02:13:38 2022 -0500
+
+    SVG Implement paint-glyph
+
+ src/hb-ot-color-svg-table.hh | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+commit 23c60fd9b293f09461926f47cdd0779af766aff8
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 01:04:23 2022 -0500
+
+    sbix: Implement paint_glyph
+
+ src/hb-ot-color-sbix-table.hh | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+commit 7996ae4c3d4d99066efa738a8ddca3851ff94ec5
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 01:04:00 2022 -0500
+
+    CBDT: Implement paint glyph
+
+ src/hb-ot-color-cbdt-table.hh | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+commit 82e23f322a5e58e8fe7e74069f90507c09694c93
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 00:33:59 2022 -0500
+
+    paint: Add a paint-image callback
+    
+    This will be used for image blobs like pngs and svgs.
+    
+    FIXME: nail down and document sizing.
+
+ src/hb-paint.cc | 12 ++++++++++++
+ src/hb-paint.h  | 43 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-paint.hh |  6 ++++++
+ 3 files changed, 61 insertions(+)
+
+commit 56b02b6599168aec8743145021fbc9cec0163113
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:58:37 2022 -0500
+
+    Update the docs
+    
+    Mention that the color index will always be 0xFFFF
+    when using hb_paint API with fonts that don't have
+    color palettes.
+    
+    And add an outline about which kinds of glyphs
+    require which callbacks.
+
+ src/hb-paint.h | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 9461ab70883c4fa0492f5f71c902cdabba627d4f
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:46:45 2022 -0500
+
+    Try paint_glyph for more tables
+    
+    If the COLR table can't paint the glyph,
+    try glyf, cff1 and cff2 too.
+
+ src/hb-ot-font.cc | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 3e39dd492bd566e55183ff4e2b136288dfd5458c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:46:15 2022 -0500
+
+    cff2: Implement paint_glyph
+
+ src/hb-ot-cff2-table.cc | 21 +++++++++++++++++++++
+ src/hb-ot-cff2-table.hh |  2 ++
+ 2 files changed, 23 insertions(+)
+
+commit df89b52130ce85ed481f8672f051744b947df6a5
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:46:05 2022 -0500
+
+    cff1: Implement paint_glyph
+
+ src/hb-ot-cff1-table.cc | 21 +++++++++++++++++++++
+ src/hb-ot-cff1-table.hh |  2 ++
+ 2 files changed, 23 insertions(+)
+
+commit 2edd771cf58de4348d6c760e4fbe77ea0f1ba16a
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:32:15 2022 -0500
+
+    glyf: Implement paint_glyph
+
+ src/OT/glyf/glyf.hh | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+commit 0b33b35eb0fc50045adc614dc60567fad837762b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:22:15 2022 -0500
+
+    COLRv1: Return bool from paint_glyph
+    
+    This will let hb_ot_font_paint_glyph() try
+    multiple tables in turn.
+
+ src/hb-ot-color-colr-table.hh | 41 ++++++++++++++++++++++++++++-------------
+ 1 file changed, 28 insertions(+), 13 deletions(-)
+
+commit 0d890061d139a9a8b59d8aef7e73a02bec1489ee
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Sat Dec 17 00:07:30 2022 -0500
+
+    Rename 'solid' to 'color'
+    
+    'solid' does not really describe well what
+    the function does, and there is no strong
+    reason to stick 1:1 to the terminology used
+    in the spec.
+
+ src/hb-ot-color-colr-table.hh   |   4 +-
+ src/hb-ot-color-colrv1-paint.hh | 286 ++++++++++++++++++++++++++++++++++++++++
+ src/hb-paint.cc                 |   6 +-
+ src/hb-paint.h                  |  18 +--
+ src/hb-paint.hh                 |   8 +-
+ util/hb-test.c                  |  58 ++++----
+ 6 files changed, 333 insertions(+), 47 deletions(-)
+
+commit 2c07828603847892fe2759d2397530910f3f42e2
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 23:23:51 2022 -0500
+
+    test: More debug spew
+
+ util/hb-test.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+commit 46286275f7f49149ef9e1db45d703880f094c1ee
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 15:27:18 2022 -0700
+
+    [colr] More dispatch functionality
+
+ src/hb-ot-color-colr-table.cc |  4 ++--
+ src/hb-ot-color-colr-table.hh | 39 ++++++++++++++++++---------------------
+ 2 files changed, 20 insertions(+), 23 deletions(-)
+
+commit 81f232afb509bf94d8d909236c5bc1f507b08b5e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 15:17:35 2022 -0700
+
+    [colr] Use dispatch machinery for paint_glyph context
+
+ src/hb-ot-color-colr-table.hh | 48 +++++++------------------------------------
+ 1 file changed, 7 insertions(+), 41 deletions(-)
+
+commit a96300d42cf0a85ba6fa84eacfe583d8faf9c906
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 15:11:35 2022 -0700
+
+    [colr] Hide internal symbols
+
+ src/harfbuzz-subset.cc        | 1 +
+ src/harfbuzz.cc               | 1 +
+ src/hb-ot-color-colr-table.hh | 4 ++--
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+commit fdf17dbf34666918979cb53c89e85b0c92fcf12b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 15:00:06 2022 -0700
+
+    Try fixing bots
+
+ util/hb-test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b4cab86d94affa5b610154623a393afffac9728c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 14:58:39 2022 -0700
+
+    Fix autotools build
+
+ src/Makefile.sources   | 1 +
+ src/harfbuzz-subset.cc | 1 -
+ src/harfbuzz.cc        | 1 -
+ 3 files changed, 1 insertion(+), 2 deletions(-)
+
+commit 07575190928ff7bcb72885943d9b7073a27e4e3c
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 12:45:02 2022 -0700
+
+    [colr] Add variation to rest of the paints
+
+ src/hb-ot-color-colr-table.hh | 80 +++++++++++++++++++++++++++++--------------
+ 1 file changed, 54 insertions(+), 26 deletions(-)
+
+commit 5bce0053463ff29386f1442f3720fd847d972263
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 12:31:08 2022 -0700
+
+    [colr] Flesh out variations for a few paints
+
+ src/hb-ot-color-colr-table.hh | 22 +++++++++++++++-------
+ 1 file changed, 15 insertions(+), 7 deletions(-)
+
+commit 9d3440b74299da8beb59c55e88aaf61fec39c507
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 16 12:12:21 2022 -0700
+
+    [colr] Add variation infrastructure to paint_glyph
+    
+    No paint applies variations yet.
+
+ src/hb-ot-color-colr-table.hh | 80 ++++++++++++++++++++++++-------------------
+ 1 file changed, 45 insertions(+), 35 deletions(-)
+
+commit 5c6329555e6171e82cdf151a119166666a08426b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 12:04:17 2022 -0500
+
+    Apply root transform
+    
+    This commit applies scale, slant is still missing.
+
+ src/hb-ot-color-colr-table.hh | 15 +++++++++++++--
+ util/hb-test.c                | 22 +++++++++++++---------
+ 2 files changed, 26 insertions(+), 11 deletions(-)
+
+commit 5afca91ff22c76fbe65da1f2084b5029a66bee14
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 06:43:43 2022 -0500
+
+    Add some docs
+
+ src/hb-paint.cc |  48 +++++++++++-
+ src/hb-paint.h  | 226 +++++++++++++++++++++++++++++++++++++-------------------
+ 2 files changed, 196 insertions(+), 78 deletions(-)
+
+commit 44c68594f197f325fd9c50c3ca3d8ca1dca0be01
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 16 00:48:28 2022 -0500
+
+    Some docs
+
+ src/hb-paint.cc |   9 +++
+ src/hb-paint.h  | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 239 insertions(+)
+
+commit d7c2eacf454e1345c15978bae9fff791d23effde
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 23:42:40 2022 -0500
+
+    Handle COLRv0 layers in paint_glyph
+
+ src/hb-ot-color-colr-table.hh | 26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+commit 55ca6ed230b74f84345258217e51d4865e763f2c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 23:16:54 2022 -0500
+
+    minor fixes
+
+ src/hb-ot-color-colr-table.cc | 73 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-color-colr-table.hh |  9 ++++--
+ 2 files changed, 80 insertions(+), 2 deletions(-)
+
+commit 794fa4c3c1d6564477a0885b95f80409f9272090
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 22:22:31 2022 -0500
+
+    sweep gradients etc
+
+ util/hb-test.c | 819 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 817 insertions(+), 2 deletions(-)
+
+commit 1880e547531a8f137564e9c5bf7421005e8cffbd
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 01:06:00 2022 -0500
+
+    Assorted fixes
+
+ src/hb-ot-color-colr-table.hh | 62 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 37 insertions(+), 25 deletions(-)
+
+commit 684df8a82a81e01412dc951c251abab77165ae66
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 00:32:48 2022 -0500
+
+    add some todos
+
+ src/hb-font.cc                | 1 +
+ src/hb-ot-color-colr-table.hh | 2 ++
+ 2 files changed, 3 insertions(+)
+
+commit a6f813b68009325f9b5cc478ed83b312b06ad996
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Thu Dec 15 00:05:27 2022 -0500
+
+    Implement hb_color_line_get_extend
+
+ src/hb-ot-color-colr-table.hh | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+commit d07fdc69dd66ad520f9ce24438fbef5c7c41f28e
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 23:58:59 2022 -0500
+
+    test: dump color lines
+
+ util/hb-test.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+commit 3937d6b0aaff5b5937bb513430e7df30f3517315
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 23:58:47 2022 -0500
+
+    Implement hb_color_line_t
+
+ src/hb-ot-color-colr-table.hh | 139 +++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 123 insertions(+), 16 deletions(-)
+
+commit 64f1b55d01afa0a8424b0336fcaad626d9814126
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 23:58:25 2022 -0500
+
+    api fixes: use floats consistently
+
+ src/hb-paint.cc | 14 +++++++-------
+ src/hb-paint.h  | 11 ++++++-----
+ src/hb-paint.hh |  8 ++++----
+ 3 files changed, 17 insertions(+), 16 deletions(-)
+
+commit 627c857f8b8ea5c5efab1525daef2d7e5ec04401
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 22:36:54 2022 -0500
+
+    rename pop_group_and_composite
+
+ src/hb-ot-color-colr-table.hh |  4 ++--
+ src/hb-paint.cc               | 12 ++++++------
+ src/hb-paint.h                | 28 ++++++++++++++--------------
+ src/hb-paint.hh               | 12 ++++++------
+ util/hb-test.c                | 10 +++++-----
+ 5 files changed, 33 insertions(+), 33 deletions(-)
+
+commit c9350838c7a039b87408ff2686759d0bd0c05377
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 22:32:40 2022 -0500
+
+    assorted fixes and changes
+
+ src/hb-ot-color-colr-table.hh |   4 +-
+ src/hb-paint.cc               | 112 +++++++++++++++++++++++-------------------
+ src/hb-paint.h                |  73 +++++++++++++++++----------
+ src/hb-paint.hh               |  37 ++++++++------
+ util/hb-test.c                |  43 ++++++++++------
+ 5 files changed, 158 insertions(+), 111 deletions(-)
+
+commit 5a123e8691ae839e6409fdcd51edab0c62c0e9a4
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 22:05:02 2022 -0500
+
+    quick testcase
+
+ util/hb-test.c   | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ util/meson.build |   7 +++
+ 2 files changed, 175 insertions(+)
+
+commit 42324aef2b18728d6318ffd4de08a21b54126c92
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 22:04:46 2022 -0500
+
+    hb-paint: annotation fix
+
+ src/hb-paint.h | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 8377341b289f47a8e63d448b5a3376dfdd464734
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 22:03:52 2022 -0500
+
+    wip: implement paint_glyph
+
+ src/harfbuzz-subset.cc        |   1 +
+ src/harfbuzz.cc               |   1 +
+ src/hb-ot-color-colr-table.hh | 204 ++++++++++++++++++++++++++++++++++++++++--
+ src/meson.build               |   1 +
+ 4 files changed, 199 insertions(+), 8 deletions(-)
+
+commit efe13a191df504df4a38f633c35a73477cf93b01
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 09:50:52 2022 -0500
+
+    fix introspection
+
+ src/hb-font.h             |  8 +++++-
+ src/hb-gobject-structs.cc |  1 +
+ src/hb-gobject-structs.h  |  4 +++
+ src/hb-paint.cc           |  5 ++++
+ src/hb-paint.h            | 70 +++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 87 insertions(+), 1 deletion(-)
+
+commit 6a48ac42f4f8404ecf64fda876141a0d1c48a56c
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 06:55:01 2022 -0500
+
+    COLR implementation
+
+ src/hb-ot-color-colr-table.hh |  5 +++++
+ src/hb-ot-font.cc             | 18 ++++++++++++++++++
+ 2 files changed, 23 insertions(+)
+
+commit 71efa0dcf12eb3924697f96d3a4ed203bb71962b
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Wed Dec 14 06:22:00 2022 -0500
+
+    wip: hb_font_paint_glyph
+
+ src/hb-font.cc | 30 ++++++++++++++++++++++++++++++
+ src/hb-font.h  | 16 ++++++++++++++++
+ src/hb-font.hh |  9 +++++++++
+ 3 files changed, 55 insertions(+)
+
+commit 83d0a49f7100008937fcf7e69e31fe9625365259
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Tue Dec 13 21:14:25 2022 -0500
+
+    wip: hb-paint
+
+ src/harfbuzz-subset.cc        |   1 +
+ src/harfbuzz.cc               |   1 +
+ src/hb-ot-color-colr-table.hh |   5 +
+ src/hb-paint.cc               | 311 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-paint.h                | 276 +++++++++++++++++++++++++++++++++++++
+ src/hb-paint.hh               | 125 +++++++++++++++++
+ src/hb.h                      |   1 +
+ src/meson.build               |   3 +
+ 8 files changed, 723 insertions(+)
+
+commit 0066e824f02efce79e026f60391f3fd95214e1ac
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 13:37:38 2022 -0700
+
+    [util] Fix vertical positioning with --glyphs
+
+ util/shape-options.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 265b699fbd3c74c1c4324d5f7044e7236d3b0b89
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 13:31:48 2022 -0700
+
+    [util] Improve --glyphs
+
+ util/shape-consumer.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit d45f7265e9dfbb053ae3ed88575136d75979c02b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Fri Dec 23 13:13:29 2022 -0700
+
+    [hb-view/hb-shape] Add --glyphs
+    
+    This makes hb-view take output of hb-shape and render it.
+
+ util/shape-consumer.hh |  2 +-
+ util/shape-options.hh  | 44 +++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 40 insertions(+), 6 deletions(-)
+
+commit 30c5402e3d0cc156fd5f04560864a88723173cf2
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Fri Dec 23 14:29:25 2022 -0500
+
+    Make hb-features.h usable standalone
+    
+    The intended use for hb-features.h is to
+    be included standalone, so we can't put
+    the single-include guards in here.
+
+ src/hb-features.h.in | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit d628aff9db826671b1612ed1865f5cdbd763c9f8
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 10:53:24 2022 -0700
+
+    [ft] Apply slant in get_glyph_extents
+
+ src/hb-ft.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 9a0ebd2b2ab4b7fa5e1463c0ac4549cb24b21896
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 10:21:07 2022 -0700
+
+    [glyf] Fix slant-scaling in GlyphHeader too
+
+ src/OT/glyf/GlyphHeader.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit 392463bff591fd0cec2ea2476b30427251f7c9f4
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 08:34:01 2022 -0700
+
+    [cff] Fix extent rounding
+    
+    I broke it in b0abbfd8684e9970ed2cac78781643edb7cce0ae.
+
+ src/hb-ot-cff1-table.cc | 8 ++++----
+ src/hb-ot-cff2-table.cc | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 897c102703e482f8ed0842e63c6fb96f15dface3
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 08:14:13 2022 -0700
+
+    [font] Fix scale_glyph_extents
+
+ src/hb-font.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 9194e13e25563f7170c68b0126f5852925c526ff
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 07:31:16 2022 -0700
+
+    [font] Apply slant to glyph extents
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/3952
+    
+    hb-ft not fixed since doesn't use this code.
+
+ src/hb-font.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit b0abbfd8684e9970ed2cac78781643edb7cce0ae
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Thu Dec 22 07:26:14 2022 -0700
+
+    [font] Centralize glyph-extents scaling
+    
+    Needs more testing...
+    
+    Some rounding was removed, namely in cff1 and cff2.
+
+ src/OT/glyf/glyf.hh           | 11 +++--------
+ src/hb-font.hh                |  8 ++++++++
+ src/hb-ot-cff1-table.cc       | 10 ++++++----
+ src/hb-ot-cff2-table.cc       | 10 ++++++----
+ src/hb-ot-color-cbdt-table.hh | 10 ++++++----
+ src/hb-ot-color-colr-table.hh |  5 +----
+ src/hb-ot-color-sbix-table.hh | 18 ++++++++++--------
+ 7 files changed, 40 insertions(+), 32 deletions(-)
+
+commit 4622be7f84b22ad3fb1c7141c0e4ec88dd5672c8
+Author: Chun-wei Fan <fanc999 at yahoo.com.tw>
+Date:   Thu Dec 22 12:05:11 2022 +0800
+
+    test/fuzzing: Fix dist
+    
+    We need to dist the repacker fuzzer test items into the tarball, along
+    with the items in graphs/ and sets/.
+
+ test/fuzzing/Makefile.am | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 97b8ada8652ef7ca7e33f6fe927ab8bf3c18396e
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Wed Dec 21 19:52:20 2022 -0700
+
+    [varc] Reset component coordinates to that of the font
+    
+    Fixes https://github.com/harfbuzz/boring-expansion-spec/issues/78
+
+ src/OT/glyf/Glyph.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 40342c9437712cd51e37dc54f1f535bb24ae7529
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 21 21:52:28 2022 +0000
+
+    [subset] check for addition overflow in hdmx size calculation.
+    
+    Fixes https://oss-fuzz.com/testcase-detail/4877336988483584.
+
+ src/hb-ot-hdmx-table.hh                                   |   1 +
+ ...z-testcase-minimized-hb-subset-fuzzer-4877336988483584 | Bin 0 -> 738 bytes
+ 2 files changed, 1 insertion(+)
+
+commit d77fca997ed0e9526e98eb78be2e469886123da0
+Author: Garret Rieger <grieger at google.com>
+Date:   Wed Dec 21 21:18:20 2022 +0000
+
+    [subset] when subsetting preprocessor fails, reference the returned face.
+    
+    The caller of the method is expected to destroy the returned result.
+
+ src/hb-subset-input.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fc8fa184183d7eaa49d789963d6ae9456e32680c
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Dec 20 19:04:41 2022 +0200
+
+    Revert "[doc] Don’t skip building on Windows"
+    
+    This reverts commit 196e739cf28456cd8b7989377c3df6a5fe468dd7.
+
+ docs/meson.build | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 6d80aba49e20f5915545dcc4116f5e68eab8c57f
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Dec 20 19:01:04 2022 +0200
+
+    Revert "[doc] Remove redundant check for gtkdoc-scan"
+    
+    This reverts commit 0409363f77cab416b34aab66d647a3d61f46d9d8.
+    
+    Broke lots of bots.
+
+ docs/meson.build | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 9b5b4da0e471a16be46ddc60b0e2a233a84abd8d
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Tue Dec 20 09:57:32 2022 -0700
+
+    [varc] Set coordinates as absolute values
+
+ src/OT/glyf/VarCompositeGlyph.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 0409363f77cab416b34aab66d647a3d61f46d9d8
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Dec 20 18:42:13 2022 +0200
+
+    [doc] Remove redundant check for gtkdoc-scan
+    
+    If docs are enabled, meson will fail earlier of gtkdoc-scan is missing.
+
+ docs/meson.build | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit 196e739cf28456cd8b7989377c3df6a5fe468dd7
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Tue Dec 20 18:41:01 2022 +0200
+
+    [doc] Don’t skip building on Windows
+    
+    We don’t enable building docs by default, so if one asked explicitly for
+    it we shouldn’t be overriding that.
+
+ docs/meson.build | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit 80e68f09c5daef0c3dfef4fb44ebfbd22899bf8a
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 19 19:15:44 2022 -0700
+
+    [VarC] Change rotation/skew representation
+    
+    Fixes https://github.com/harfbuzz/boring-expansion-spec/issues/77
+
+ src/OT/glyf/VarCompositeGlyph.hh | 12 ++++++------
+ src/hb-open-type.hh              |  3 +--
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+commit 1840b02e6a61d030cf485ea6c36126cd6dbd984e
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 19 20:06:32 2022 +0000
+
+    [subset] Don't gate access to the table repacker.
+    
+    Any table with an object graph should repack correctly.
+
+ src/hb-subset.cc | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit 03a1685693e59f0c31803daf6647a80b4a111e9b
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Mon Dec 19 17:11:34 2022 -0700
+
+    [VarC] Change representation of scale from 4.12 to 6.10
+    
+    Fixes https://github.com/harfbuzz/boring-expansion-spec/issues/76
+
+ src/OT/glyf/VarCompositeGlyph.hh | 12 ++++++------
+ src/hb-open-type.hh              |  4 ++--
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 1a51f71afd794a52a24cbcb7547000e0c563b0f6
+Author: Garret Rieger <grieger at google.com>
+Date:   Mon Dec 19 22:40:11 2022 +0000
+
+    [subset] don't segfault when --help-all is specified w/ instancing options.
+
+ util/hb-subset.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit c292e577ff7d6b6b9d98e95dabd7ed71a02021fc
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 12:40:11 2022 -0500
+
+    Fix a typo
+
+ src/hb-draw.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b795246fff2246266287a728475b97e8873f3f14
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 06:30:28 2022 -0500
+
+    [draw] Clarify the docs
+    
+    Disambiguate the origin of draw_data and user_data,
+    this had me confused a few times.
+    
+    Fixes: https://github.com/harfbuzz/harfbuzz/issues/3955
+
+ src/hb-draw.h | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit eddb408f9c9c42991c8b8427ca81e33a03fc9060
+Author: Matthias Clasen <mclasen at redhat.com>
+Date:   Mon Dec 19 12:19:48 2022 -0500
+
+    [draw] Small doc fix
+
+ src/hb-draw.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit bc4c290b7581bbcb7632d74a2ebebc24bd5df9f1
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Dec 19 00:39:35 2022 +0200
+
+    [doc] Workaround gtk-doc limitation with HB_DEPRECATED_FOR
+    
+    See https://github.com/harfbuzz/harfbuzz/issues/3957#issuecomment-1356890525
+
+ src/hb-deprecated.h    |  3 ++-
+ src/hb-graphite2.h     |  3 ++-
+ src/hb-ot-deprecated.h | 18 ++++++++++++------
+ 3 files changed, 16 insertions(+), 8 deletions(-)
+
+commit 734e5f7cf412e421568963e5a5fe3ee51365163e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Mon Dec 19 00:15:04 2022 +0200
+
+    [doc] Add HB_DEPRECATED_FOR to --ignore-decorators
+    
+    Does not make a difference, though.
+
+ docs/Makefile.am | 2 +-
+ docs/meson.build | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit f9e1192d58e54f6719993a1694aee0a73198d63d
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Dec 18 23:58:36 2022 +0200
+
+    [ot-tag] Document two deprecated symbols
+    
+    See https://github.com/harfbuzz/harfbuzz/issues/3957
+
+ src/hb-ot-tag.cc | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+commit 947e01a7c1bc7eede4077ced24923acd8f45e0f5
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Dec 18 23:40:01 2022 +0200
+
+    [subset] Suppress gtk-doc warning
+
+ src/hb-subset-input.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 9ca8e7564b52ae889961144d6533e8143a0f3771
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sun Dec 18 17:44:41 2022 +0200
+
+    Revert "[circleci] Make dist tarball with meson"
+    
+    This reverts commit 80157cc60baf0f1b26c442c336dc1854216468be.
+    
+    That was a thinko, meson generated dist tarballs are not usable for
+    autotools build as they will miss generated autotools files.
+
+ .circleci/config.yml | 33 +++++++++++----------------------
+ 1 file changed, 11 insertions(+), 22 deletions(-)
+
+commit c7dd63d1a04e797f21ba3fd7bb5aa5d08524c9dd
+Author: Nirbheek Chauhan <nirbheek at centricular.com>
+Date:   Sun Dec 18 09:28:47 2022 +0530
+
+    meson: Provide binaries when built as a subproject
+
+ util/meson.build | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 7be06f63779e3221333d3162f2025b1c497c5c8c
+Author: Nirbheek Chauhan <nirbheek at centricular.com>
+Date:   Sun Dec 18 07:10:32 2022 +0530
+
+    meson: Override dependencies to improve usage as a subproject
+    
+    With this change, harfbuzz can be consumed as a subproject without
+    making any changes to the build files of a project. All you need to do
+    is provide a wrap file with a `[provide]` section:
+    
+    https://mesonbuild.com/Wrap-dependency-system-manual.html#provide-section
+    
+    This is also necessary because otherwise projects need to hard-code
+    the subproject name, which might be `harfbuzz` when using `wrap-git` or
+    `harfbuzz-6.0.0` when using `wrap-file` (to build from a release
+    tarball). This can cause conflicts between different subprojects that
+    consume harfbuzz differently.
+    
+    Other projects like glib, cairo, pango, etc already do this.
+
+ src/meson.build | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 206957aee4a4479ca19a4065b2c5603e99379fcf
+Author: Behdad Esfahbod <behdad at behdad.org>
+Date:   Sat Dec 17 08:57:40 2022 -0700
+
+    [COLR] Change recursion limit back to 128
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 31ba950b71acbcb8d71a82bde0675785d24ff791
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Dec 17 01:11:20 2022 +0200
+
+    [circleci] Don’t run tests in dist
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f22e42d7376f980fbb32e35a194f1dc1bfc3af0e
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Dec 17 00:57:26 2022 +0200
+
+    [circleci] Remove cruft
+
+ .circleci/config.yml | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+commit 21e866b8b5006ee99f40077fe1c494faf9ccb014
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Dec 17 00:34:46 2022 +0200
+
+    [circleci] Unify meson commands a bit
+
+ .circleci/config.yml | 33 ++++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 15 deletions(-)
+
+commit 80157cc60baf0f1b26c442c336dc1854216468be
+Author: Khaled Hosny <khaled at aliftype.com>
+Date:   Sat Dec 17 00:19:27 2022 +0200
+
+    [circleci] Make dist tarball with meson
+
+ .circleci/config.yml | 33 ++++++++++++++++++++++-----------
+ 1 file changed, 22 insertions(+), 11 deletions(-)
+
 commit afcae83a064843d71d47624bc162e121cc56c08b
 Author: Khaled Hosny <khaled at aliftype.com>
 Date:   Fri Dec 16 23:14:57 2022 +0200

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/NEWS	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,3 +1,133 @@
+Overview of changes leading to 7.0.0
+Saturday, February 11, 2023
+====================================
+- New hb-paint API that is designed mainly to paint “COLRv1” glyphs, but can be
+  also used as a unified API to paint any of the glyph representations
+  supported by HarfBuzz (B/W outlines, color layers, or color bitmaps). 
+  (Behdad Esfahbod, Matthias Clasen)
+- New hb-cairo API for integrating with cairo graphics library. This is provided
+  as a separate harfbuzz-cairo library. (Behdad Esfahbod, Matthias Clasen)
+- Support for instancing “CFF2” table. (Behdad Esfahbod)
+- Support font emboldening. (Behdad Esfahbod)
+- Support feature ranges with AAT shaping. (Behdad Esfahbod)
+- Experimental support to cubic curves in “glyf” table, see
+  https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1-cubicOutlines.md
+  for spec. (Behdad Esfahbod)
+- Various subsetter improvements. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
+- Various documentation improvements. 
+  (Behdad Esfahbod, Matthias Clasen, Khaled Hosny)
+- Significantly reduced memory use during shaping. (Behdad Esfahbod)
+- Greatly reduced memory use during subsetting “CFF” table. (Behdad Esfahbod)
+- New command line utility, hb-info, for querying various font information.
+  (Behdad Esfahbod, Matthias Clasen)
+- New hb-shape/hb-view options: --glyphs, --color-palette, --font-bold,
+  --font-grade, and --named-instance. (Behdad Esfahbod)
+- Miscellaneous fixes and improvements.
+  (Amir Masoud Abdol, Andres Salomon, Behdad Esfahbod, Chun-wei Fan,
+  Garret Rieger, Jens Kutilek, Khaled Hosny, Konstantin Käfer, Matthias Clasen,
+  Nirbheek Chauhan, Pedro J. Estébanez, Qunxin Liu, Sergei Trofimovich)
+
+- New API:
++HB_FONT_NO_VAR_NAMED_INSTANCE
++HB_PAINT_IMAGE_FORMAT_BGRA
++HB_PAINT_IMAGE_FORMAT_PNG
++HB_PAINT_IMAGE_FORMAT_SVG
++hb_cairo_font_face_create_for_face
++hb_cairo_font_face_create_for_font
++hb_cairo_font_face_get_face
++hb_cairo_font_face_get_font
++hb_cairo_font_face_get_scale_factor
++hb_cairo_font_face_set_font_init_func
++hb_cairo_font_face_set_scale_factor
++hb_cairo_font_init_func_t
++hb_cairo_glyphs_from_buffer
++hb_cairo_scaled_font_get_font
++hb_color_line_get_color_stops
++hb_color_line_get_color_stops_func_t
++hb_color_line_get_extend
++hb_color_line_get_extend_func_t
++hb_color_line_t
++hb_color_stop_t
++hb_draw_funcs_get_empty
++hb_draw_funcs_get_user_data
++hb_draw_funcs_set_user_data
++hb_face_collect_nominal_glyph_mapping
++hb_font_draw_glyph
++hb_font_draw_glyph_func_t
++hb_font_funcs_set_draw_glyph_func
++hb_font_funcs_set_paint_glyph_func
++hb_font_get_synthetic_bold
++hb_font_get_var_named_instance
++hb_font_paint_glyph
++hb_font_paint_glyph_func_t
++hb_font_set_synthetic_bold
++hb_map_keys
++hb_map_next
++hb_map_update
++hb_map_values
++hb_ot_color_glyph_has_paint
++hb_ot_color_has_paint
++hb_ot_layout_script_select_language2
++hb_ot_name_id_predefined_t
++hb_paint_color
++hb_paint_color_func_t
++hb_paint_composite_mode_t
++hb_paint_custom_palette_color
++hb_paint_custom_palette_color_func_t
++hb_paint_extend_t
++hb_paint_funcs_create
++hb_paint_funcs_destroy
++hb_paint_funcs_get_empty
++hb_paint_funcs_get_user_data
++hb_paint_funcs_is_immutable
++hb_paint_funcs_make_immutable
++hb_paint_funcs_reference
++hb_paint_funcs_set_color_func
++hb_paint_funcs_set_custom_palette_color_func
++hb_paint_funcs_set_image_func
++hb_paint_funcs_set_linear_gradient_func
++hb_paint_funcs_set_pop_clip_func
++hb_paint_funcs_set_pop_group_func
++hb_paint_funcs_set_pop_transform_func
++hb_paint_funcs_set_push_clip_glyph_func
++hb_paint_funcs_set_push_clip_rectangle_func
++hb_paint_funcs_set_push_group_func
++hb_paint_funcs_set_push_transform_func
++hb_paint_funcs_set_radial_gradient_func
++hb_paint_funcs_set_sweep_gradient_func
++hb_paint_funcs_set_user_data
++hb_paint_funcs_t
++hb_paint_image
++hb_paint_image_func_t
++hb_paint_linear_gradient
++hb_paint_linear_gradient_func_t
++hb_paint_pop_clip
++hb_paint_pop_clip_func_t
++hb_paint_pop_group
++hb_paint_pop_group_func_t
++hb_paint_pop_transform
++hb_paint_pop_transform_func_t
++hb_paint_push_clip_glyph
++hb_paint_push_clip_glyph_func_t
++hb_paint_push_clip_rectangle
++hb_paint_push_clip_rectangle_func_t
++hb_paint_push_group
++hb_paint_push_group_func_t
++hb_paint_push_transform
++hb_paint_push_transform_func_t
++hb_paint_radial_gradient
++hb_paint_radial_gradient_func_t
++hb_paint_sweep_gradient
++hb_paint_sweep_gradient_func_t
++hb_set_is_inverted
++hb_subset_input_keep_everything
+
+- Deprecated API:
++hb_font_funcs_set_glyph_shape_func
++hb_font_get_glyph_shape_func_t
++hb_font_get_glyph_shape
+
+
 Overview of changes leading to 6.0.0
 Friday, December 16, 2022
 ====================================

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/RELEASING.md	2023-02-12 04:02:23 UTC (rev 65798)
@@ -17,7 +17,7 @@
 
 - [ ] Based on severity of changes, decide whether it's a minor or micro release number bump.
 
-- [ ] Search for REPLACEME on the repository and replace it with the chosen version for the release.
+- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
 
 - [ ] Make sure you have correct date and new version at the top of NEWS file.
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/configure.ac	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [6.0.0],
+        [7.0.0],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -45,7 +45,7 @@
 
 # Libtool version
 m4_define([hb_version_int],
-	  m4_eval(hb_version_major*10000 + hb_version_minor*100 + hb_version_micro))
+	  m4_eval(60000 + hb_version_major*100 + hb_version_minor*10 + hb_version_micro))
 HB_LIBTOOL_VERSION_INFO=hb_version_int:0:hb_version_int
 AC_SUBST(HB_LIBTOOL_VERSION_INFO)
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/meson.build	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,8 +1,9 @@
 project('harfbuzz', 'c', 'cpp',
   meson_version: '>= 0.55.0',
-  version: '6.0.0',
+  version: '7.0.0',
   default_options: [
-    'cpp_rtti=false',       # Just to support msvc, we are passing -fno-exceptions also anyway
+    'cpp_eh=none',          # Just to support msvc, we are passing -fno-exceptions also anyway
+    'cpp_rtti=false',       # Just to support msvc, we are passing -fno-rtti also anyway
     'cpp_std=c++11',
     'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
   ],
@@ -14,7 +15,7 @@
 hb_version_micro = hb_version_arr[2].to_int()
 
 # libtool versioning
-hb_version_int = hb_version_major*10000 + hb_version_minor*100 + hb_version_micro
+hb_version_int = 60000 + hb_version_major*100 + hb_version_minor*10 + hb_version_micro
 hb_libtool_version_info = '@0@:0:@0@'.format(hb_version_int)
 
 pkgmod = import('pkgconfig')
@@ -27,17 +28,12 @@
   # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
   # NOTE: Only add warnings here if you are sure they're spurious
   msvc_args = [
-    '/wd4018', # implicit signed/unsigned conversion
-    '/wd4146', # unary minus on unsigned (beware INT_MIN)
     '/wd4244', # lossy type conversion (e.g. double -> int)
-    '/wd4305', # truncating type conversion (e.g. double -> float)
     cpp.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
   ]
   add_project_arguments(msvc_args, language: ['c', 'cpp'])
   # Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
   # noseh_link_args = ['/SAFESEH:NO']
-  # disable exception handling
-  add_project_arguments(['/EHs-', '/EHc-'], language: 'cpp')
 endif
 
 add_project_link_arguments(cpp.get_supported_link_arguments([
@@ -209,10 +205,19 @@
 
 if cairo_dep.found()
   conf.set('HAVE_CAIRO', 1)
+  check_cairo_funcs = [
+    ['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}],
+    ['cairo_font_options_get_custom_palette_color', {'deps': cairo_dep}],
+    ['cairo_user_scaled_font_get_foreground_source', {'deps': cairo_dep}],
+  ]
+
   if cairo_dep.type_name() == 'internal'
-    conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
+    foreach func: check_cairo_funcs
+      name = func[0]
+      conf.set('HAVE_ at 0@'.format(name.to_upper()), 1)
+    endforeach
   else
-    check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
+    check_funcs += check_cairo_funcs
   endif
 endif
 
@@ -384,6 +389,9 @@
 
 configure_file(output: 'config.h', configuration: conf)
 
+alias_target('lib', libharfbuzz)
+alias_target('libs', libharfbuzz, libharfbuzz_subset)
+
 build_summary = {
   'Directories':
     {'prefix': get_option('prefix'),
@@ -398,7 +406,8 @@
      'ICU': conf.get('HAVE_ICU', 0) == 1,
     },
   'Font callbacks (the more the merrier)':
-    {'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
+    {'Builtin' : true,
+     'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
     },
   'Dependencies used for command-line utilities':
     {'Cairo': conf.get('HAVE_CAIRO', 0) == 1,
@@ -415,6 +424,7 @@
   'Other features':
     {'Documentation': conf.get('HAVE_GTK_DOC', 0) == 1,
      'GObject bindings': conf.get('HAVE_GOBJECT', 0) == 1,
+     'Cairo integration': conf.get('HAVE_CAIRO', 0) == 1,
      'Introspection': conf.get('HAVE_INTROSPECTION', 0) == 1,
      'Experimental APIs': conf.get('HB_EXPERIMENTAL_API', 0) == 1,
     },

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am	2023-02-12 04:02:23 UTC (rev 65798)
@@ -135,6 +135,8 @@
 harfbuzz_def_dependency = harfbuzz.def
 export_symbols_subset = -export-symbols harfbuzz-subset.def
 harfbuzz_subset_def_dependency = harfbuzz-subset.def
+export_symbols_cairo = -export-symbols harfbuzz-cairo.def
+harfbuzz_cairo_def_dependency = harfbuzz-cairo.def
 export_symbols_icu = -export-symbols harfbuzz-icu.def
 harfbuzz_icu_def_dependency = harfbuzz-icu.def
 export_symbols_gobject = -export-symbols harfbuzz-gobject.def
@@ -193,6 +195,17 @@
 	|| ($(RM) $(srcdir)/harfbuzz-subset.cc; false)
 BUILT_SOURCES += harfbuzz-subset.cc
 
+lib_LTLIBRARIES += libharfbuzz-cairo.la
+libharfbuzz_cairo_la_LINK = $(chosen_linker) $(libharfbuzz_cairo_la_LDFLAGS)
+libharfbuzz_cairo_la_SOURCES = $(HB_CAIRO_sources)
+libharfbuzz_cairo_la_CPPFLAGS = $(HBCFLAGS) $(CAIRO_CFLAGS) $(CODE_COVERAGE_CFLAGS)
+libharfbuzz_cairo_la_LDFLAGS = $(base_link_flags) $(export_symbols_cairo) $(CODE_COVERAGE_LDFLAGS)
+libharfbuzz_cairo_la_LIBADD = $(CAIRO_LIBS) libharfbuzz.la
+EXTRA_libharfbuzz_cairo_la_DEPENDENCIES = $(harfbuzz_cairo_def_dependency)
+pkginclude_HEADERS += $(HB_CAIRO_headers)
+pkgconfig_DATA += harfbuzz-cairo.pc
+EXTRA_DIST += harfbuzz-cairo.pc.in
+
 if HAVE_ICU
 if HAVE_ICU_BUILTIN
 HBCFLAGS += $(ICU_CFLAGS)
@@ -241,6 +254,9 @@
 		--template $^ | \
 	sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \
 	|| ($(RM) "$@"; false)
+HB_HAS_GOBJECT_DEF = define HB_HAS_GOBJECT 1
+else
+HB_HAS_GOBJECT_DEF = undef HB_HAS_GOBJECT
 endif
 EXTRA_DIST += \
 	harfbuzz-gobject.pc.in \
@@ -256,11 +272,13 @@
 
 hb-features.h: hb-features.h.in $(top_builddir)/config.status
 	$(AM_V_GEN) $(SED) \
+		-e 's/mesondefine HB_HAS_CAIRO/$(HB_HAS_CAIRO_DEF)/' \
 		-e 's/mesondefine HB_HAS_FREETYPE/$(HB_HAS_FREETYPE_DEF)/' \
 		-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
 		-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
 		-e 's/mesondefine HB_HAS_GRAPHITE/$(HB_HAS_GRAPHITE_DEF)/' \
 		-e 's/mesondefine HB_HAS_GLIB/$(HB_HAS_GLIB_DEF)/' \
+		-e 's/mesondefine HB_HAS_GOBJECT/$(HB_HAS_GOBJECT_DEF)/' \
 		-e 's/mesondefine HB_HAS_UNISCRIBE/$(HB_HAS_UNISCRIBE_DEF)/' \
 		-e 's/mesondefine HB_HAS_DIRECTWRITE/$(HB_HAS_DIRECTWRITE_DEF)/' \
 		-e 's/mesondefine HB_HAS_CORETEXT/$(HB_HAS_CORETEXT_DEF)/' \
@@ -294,6 +312,8 @@
 	$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
 harfbuzz-subset.def: $(HB_SUBSET_headers)
 	$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
+harfbuzz-cairo.def: $(HB_CAIRO_headers)
+	$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
 harfbuzz-icu.def: $(HB_ICU_headers)
 	$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
 harfbuzz-gobject.def: $(HB_GOBJECT_headers)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources	2023-02-12 04:02:23 UTC (rev 65798)
@@ -42,11 +42,13 @@
 	hb-draw.hh \
 	hb-face.cc \
 	hb-face.hh \
+	hb-face-builder.cc \
 	hb-fallback-shape.cc \
 	hb-font.cc \
 	hb-font.hh \
 	hb-iter.hh \
 	hb-kern.hh \
+	hb-limits.hh \
 	hb-machinery.hh \
 	hb-map.cc \
 	hb-map.hh \
@@ -67,11 +69,6 @@
 	hb-ot-cff2-table.cc \
 	hb-ot-cff2-table.hh \
 	hb-ot-cmap-table.hh \
-	hb-ot-color-cbdt-table.hh \
-	hb-ot-color-colr-table.hh \
-	hb-ot-color-cpal-table.hh \
-	hb-ot-color-sbix-table.hh \
-	hb-ot-color-svg-table.hh \
 	hb-ot-color.cc \
 	hb-ot-face-table-list.hh \
 	hb-ot-face.cc \
@@ -88,7 +85,18 @@
 	hb-ot-layout-common.hh \
 	hb-ot-layout-gdef-table.hh \
 	hb-ot-layout-gpos-table.hh \
+	hb-outline.hh \
+	hb-outline.cc \
+	hb-paint.cc \
+	hb-paint.hh \
+	hb-paint-extents.cc \
+	hb-paint-extents.hh \
 	hb-ot-layout-gsub-table.hh \
+	OT/Color/CBDT/CBDT.hh \
+	OT/Color/COLR/COLR.hh \
+	OT/Color/CPAL/CPAL.hh \
+	OT/Color/sbix/sbix.hh \
+	OT/Color/svg/svg.hh \
 	OT/glyf/glyf.hh \
 	OT/glyf/glyf-helpers.hh \
 	OT/glyf/loca.hh \
@@ -106,6 +114,7 @@
 	OT/Layout/Common/CoverageFormat1.hh \
 	OT/Layout/Common/CoverageFormat2.hh \
 	OT/Layout/Common/RangeRecord.hh \
+	OT/Layout/GDEF/GDEF.hh \
 	OT/Layout/GPOS/AnchorFormat1.hh \
 	OT/Layout/GPOS/AnchorFormat2.hh \
 	OT/Layout/GPOS/AnchorFormat3.hh \
@@ -160,6 +169,7 @@
 	OT/Layout/GSUB/SingleSubst.hh \
 	OT/Layout/GSUB/SubstLookup.hh \
 	OT/Layout/GSUB/SubstLookupSubTable.hh \
+	OT/name/name.hh \
 	hb-ot-layout-gsubgpos.hh \
 	hb-ot-layout-jstf-table.hh \
 	hb-ot-layout.cc \
@@ -250,7 +260,8 @@
 
 HB_BASE_RAGEL_GENERATED_sources = \
 	hb-buffer-deserialize-json.hh \
-	hb-buffer-deserialize-text.hh \
+	hb-buffer-deserialize-text-glyphs.hh \
+	hb-buffer-deserialize-text-unicode.hh \
 	hb-number-parser.hh \
 	hb-ot-shaper-indic-machine.hh \
 	hb-ot-shaper-khmer-machine.hh \
@@ -259,7 +270,8 @@
 	$(NULL)
 HB_BASE_RAGEL_sources = \
 	hb-buffer-deserialize-json.rl \
-	hb-buffer-deserialize-text.rl \
+	hb-buffer-deserialize-text-glyphs.rl \
+	hb-buffer-deserialize-text-unicode.rl \
 	hb-number-parser.rl \
 	hb-ot-shaper-indic-machine.rl \
 	hb-ot-shaper-khmer-machine.rl \
@@ -290,6 +302,7 @@
 	hb-ot-shape.h \
 	hb-ot-var.h \
 	hb-ot.h \
+	hb-paint.h \
 	hb-set.h \
 	hb-shape-plan.h \
 	hb-shape.h \
@@ -301,7 +314,7 @@
 
 # Optional Sources and Headers with external deps
 
-HB_FT_sources = hb-ft.cc
+HB_FT_sources = hb-ft.cc hb-ft-colr.hh
 HB_FT_headers = hb-ft.h
 
 HB_GLIB_sources = hb-glib.cc
@@ -334,7 +347,6 @@
 	hb-number.hh \
 	hb-ot-cff1-table.cc \
 	hb-ot-cff2-table.cc \
-	hb-ot-color-colrv1-closure.hh \
 	hb-ot-post-table-v2subset.hh \
 	hb-static.cc \
 	hb-subset-cff-common.cc \
@@ -345,6 +357,7 @@
 	hb-subset-cff2.hh \
 	hb-subset-input.cc \
 	hb-subset-input.hh \
+	hb-subset-instancer-solver.cc \
 	hb-subset-accelerator.hh \
 	hb-subset-plan.cc \
 	hb-subset-plan.hh \
@@ -362,6 +375,7 @@
 	graph/markbasepos-graph.hh \
 	graph/split-helpers.hh \
 	graph/serialize.hh \
+	OT/Color/COLR/colrv1-closure.hh \
 	$(NULL)
 
 HB_SUBSET_headers = \
@@ -369,6 +383,16 @@
 	hb-subset-repacker.h \
 	$(NULL)
 
+HB_CAIRO_sources = \
+	hb-cairo.cc \
+	hb-cairo-utils.cc \
+	hb-cairo-utils.hh \
+	hb-static.cc \
+	$(NULL)
+HB_CAIRO_headers = \
+	hb-cairo.h \
+	$(NULL)
+
 HB_GOBJECT_DIST_sources = hb-gobject-structs.cc
 HB_GOBJECT_DIST_headers = hb-gobject.h hb-gobject-structs.h
 HB_GOBJECT_ENUM_sources = hb-gobject-enums.cc

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CBDT/CBDT.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,1030 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Seigo Nonaka, Calder Kitagawa
+ */
+
+#ifndef OT_COLOR_CBDT_CBDT_HH
+#define OT_COLOR_CBDT_CBDT_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
+
+/*
+ * CBLC -- Color Bitmap Location
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc
+ * CBDT -- Color Bitmap Data
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt
+ */
+#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
+#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
+
+
+namespace OT {
+
+struct cblc_bitmap_size_subset_context_t
+{
+  const char *cbdt;
+  unsigned int cbdt_length;
+  hb_vector_t<char> *cbdt_prime;
+  unsigned int size;		/* INOUT
+				 *  Input: old size of IndexSubtable
+				 *  Output: new size of IndexSubtable
+				 */
+  unsigned int num_tables;	/* INOUT
+				 *  Input: old number of subtables.
+				 *  Output: new number of subtables.
+				 */
+  hb_codepoint_t start_glyph;	/* OUT */
+  hb_codepoint_t end_glyph;	/* OUT */
+};
+
+static inline bool
+_copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime,
+		    const void        *data,
+		    unsigned           length)
+{
+  unsigned int new_len = cbdt_prime->length + length;
+  if (unlikely (!cbdt_prime->alloc (new_len))) return false;
+  hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
+  cbdt_prime->length = new_len;
+  return true;
+}
+
+struct SmallGlyphMetrics
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scale) const
+  {
+    extents->x_bearing = bearingX;
+    extents->y_bearing = bearingY;
+    extents->width = width;
+    extents->height = -static_cast<int> (height);
+
+    if (scale)
+      font->scale_glyph_extents (extents);
+  }
+
+  HBUINT8	height;
+  HBUINT8	width;
+  HBINT8	bearingX;
+  HBINT8	bearingY;
+  HBUINT8	advance;
+  public:
+  DEFINE_SIZE_STATIC (5);
+};
+
+struct BigGlyphMetrics : SmallGlyphMetrics
+{
+  HBINT8	vertBearingX;
+  HBINT8	vertBearingY;
+  HBUINT8	vertAdvance;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct SBitLineMetrics
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBINT8	ascender;
+  HBINT8	decender;
+  HBUINT8	widthMax;
+  HBINT8	caretSlopeNumerator;
+  HBINT8	caretSlopeDenominator;
+  HBINT8	caretOffset;
+  HBINT8	minOriginSB;
+  HBINT8	minAdvanceSB;
+  HBINT8	maxBeforeBL;
+  HBINT8	minAfterBL;
+  HBINT8	padding1;
+  HBINT8	padding2;
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+
+/*
+ * Index Subtables.
+ */
+
+struct IndexSubtableHeader
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBUINT16	indexFormat;
+  HBUINT16	imageFormat;
+  HBUINT32	imageDataOffset;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+template <typename OffsetType>
+struct IndexSubtableFormat1Or3
+{
+  bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  offsetArrayZ.sanitize (c, glyph_count + 1));
+  }
+
+  bool get_image_data (unsigned int idx,
+		       unsigned int *offset,
+		       unsigned int *length) const
+  {
+    if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
+      return false;
+
+    *offset = header.imageDataOffset + offsetArrayZ[idx];
+    *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
+    return true;
+  }
+
+  bool add_offset (hb_serialize_context_t *c,
+		   unsigned int offset,
+		   unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+    Offset<OffsetType> embedded_offset;
+    embedded_offset = offset;
+    *size += sizeof (OffsetType);
+    auto *o = c->embed (embedded_offset);
+    return_trace ((bool) o);
+  }
+
+  IndexSubtableHeader	header;
+  UnsizedArrayOf<Offset<OffsetType>>
+			offsetArrayZ;
+  public:
+  DEFINE_SIZE_ARRAY (8, offsetArrayZ);
+};
+
+struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
+struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {};
+
+struct IndexSubtable
+{
+  bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.header.sanitize (c)) return_trace (false);
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.sanitize (c, glyph_count));
+    case 3: return_trace (u.format3.sanitize (c, glyph_count));
+    default:return_trace (true);
+    }
+  }
+
+  bool
+  finish_subtable (hb_serialize_context_t *c,
+		   unsigned int cbdt_prime_len,
+		   unsigned int num_glyphs,
+		   unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
+    case 3: {
+      if (!u.format3.add_offset (c, local_offset, size))
+	return_trace (false);
+      if (!(num_glyphs & 0x01))  // Pad to 32-bit alignment if needed.
+	return_trace (u.format3.add_offset (c, 0, size));
+      return_trace (true);
+    }
+    // TODO: implement 2, 4, 5.
+    case 2: case 4:  // No-op.
+    case 5:  // Pad to 32-bit aligned.
+    default: return_trace (false);
+    }
+  }
+
+  bool
+  fill_missing_glyphs (hb_serialize_context_t *c,
+		       unsigned int cbdt_prime_len,
+		       unsigned int num_missing,
+		       unsigned int *size /* OUT (accumulated) */,
+		       unsigned int *num_glyphs /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
+    switch (u.header.indexFormat)
+    {
+    case 1: {
+      for (unsigned int i = 0; i < num_missing; i++)
+      {
+	if (unlikely (!u.format1.add_offset (c, local_offset, size)))
+	  return_trace (false);
+	*num_glyphs += 1;
+      }
+      return_trace (true);
+    }
+    case 3: {
+      for (unsigned int i = 0; i < num_missing; i++)
+      {
+	if (unlikely (!u.format3.add_offset (c, local_offset, size)))
+	  return_trace (false);
+	*num_glyphs += 1;
+      }
+      return_trace (true);
+    }
+    // TODO: implement 2, 4, 5.
+    case 2:  // Add empty space in cbdt_prime?.
+    case 4: case 5:  // No-op as sparse is supported.
+    default: return_trace (false);
+    }
+  }
+
+  bool
+  copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx,
+		     const char *cbdt, unsigned int cbdt_length,
+		     hb_vector_t<char> *cbdt_prime /* INOUT */,
+		     IndexSubtable *subtable_prime /* INOUT */,
+		     unsigned int *size /* OUT (accumulated) */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int offset, length, format;
+    if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false);
+    if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false);
+
+    auto *header_prime = subtable_prime->get_header ();
+    unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset;
+    if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false);
+
+    return_trace (subtable_prime->add_offset (c, new_local_offset, size));
+  }
+
+  bool
+  add_offset (hb_serialize_context_t *c, unsigned int local_offset,
+	      unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
+    case 3: return_trace (u.format3.add_offset (c, local_offset, size));
+    // TODO: Implement tables 2, 4, 5
+    case 2:  // Should be a no-op.
+    case 4: case 5:  // Handle sparse cases.
+    default: return_trace (false);
+    }
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents HB_UNUSED, bool scale HB_UNUSED) const
+  {
+    switch (u.header.indexFormat)
+    {
+    case 2: case 5: /* TODO */
+    case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
+    default:return (false);
+    }
+  }
+
+  bool
+  get_image_data (unsigned int idx, unsigned int *offset,
+		  unsigned int *length, unsigned int *format) const
+  {
+    *format = u.header.imageFormat;
+    switch (u.header.indexFormat)
+    {
+    case 1: return u.format1.get_image_data (idx, offset, length);
+    case 3: return u.format3.get_image_data (idx, offset, length);
+    default: return false;
+    }
+  }
+
+  const IndexSubtableHeader* get_header () const { return &u.header; }
+
+  void populate_header (unsigned index_format,
+			unsigned image_format,
+			unsigned int image_data_offset,
+			unsigned int *size)
+  {
+    u.header.indexFormat = index_format;
+    u.header.imageFormat = image_format;
+    u.header.imageDataOffset = image_data_offset;
+    switch (u.header.indexFormat)
+    {
+    case 1: *size += IndexSubtableFormat1::min_size; break;
+    case 3: *size += IndexSubtableFormat3::min_size; break;
+    }
+  }
+
+  protected:
+  union {
+  IndexSubtableHeader	header;
+  IndexSubtableFormat1	format1;
+  IndexSubtableFormat3	format3;
+  /* TODO: Format 2, 4, 5. */
+  } u;
+  public:
+  DEFINE_SIZE_UNION (8, header);
+};
+
+struct IndexSubtableRecord
+{
+  /* XXX Remove this and fix by not inserting it into vector. */
+  IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
+  {
+    firstGlyphIndex = o.firstGlyphIndex;
+    lastGlyphIndex = o.lastGlyphIndex;
+    offsetToSubtable = (unsigned) o.offsetToSubtable;
+    assert (offsetToSubtable.is_null ());
+    return *this;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  firstGlyphIndex <= lastGlyphIndex &&
+		  offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
+  }
+
+  const IndexSubtable* get_subtable (const void *base) const
+  {
+    return &(base+offsetToSubtable);
+  }
+
+  bool add_new_subtable (hb_subset_context_t* c,
+			 cblc_bitmap_size_subset_context_t *bitmap_size_context,
+			 IndexSubtableRecord *record,
+			 const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
+			 const void *base,
+			 unsigned int *start /* INOUT */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *subtable = c->serializer->start_embed<IndexSubtable> ();
+    if (unlikely (!subtable)) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
+
+    auto *old_subtable = get_subtable (base);
+    auto *old_header = old_subtable->get_header ();
+
+    subtable->populate_header (old_header->indexFormat,
+			       old_header->imageFormat,
+			       bitmap_size_context->cbdt_prime->length,
+			       &bitmap_size_context->size);
+
+    unsigned int num_glyphs = 0;
+    bool early_exit = false;
+    for (unsigned int i = *start; i < lookup->length; i++)
+    {
+      hb_codepoint_t new_gid = (*lookup)[i].first;
+      const IndexSubtableRecord *next_record = (*lookup)[i].second;
+      const IndexSubtable *next_subtable = next_record->get_subtable (base);
+      auto *next_header = next_subtable->get_header ();
+      if (next_header != old_header)
+      {
+	*start = i;
+	early_exit = true;
+	break;
+      }
+      unsigned int num_missing = record->add_glyph_for_subset (new_gid);
+      if (unlikely (!subtable->fill_missing_glyphs (c->serializer,
+						    bitmap_size_context->cbdt_prime->length,
+						    num_missing,
+						    &bitmap_size_context->size,
+						    &num_glyphs)))
+	return_trace (false);
+
+      hb_codepoint_t old_gid = 0;
+      c->plan->old_gid_for_new_gid (new_gid, &old_gid);
+      if (old_gid < next_record->firstGlyphIndex)
+	return_trace (false);
+
+      unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex;
+      if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer,
+						       old_idx,
+						       bitmap_size_context->cbdt,
+						       bitmap_size_context->cbdt_length,
+						       bitmap_size_context->cbdt_prime,
+						       subtable,
+						       &bitmap_size_context->size)))
+	return_trace (false);
+      num_glyphs += 1;
+    }
+    if (!early_exit)
+      *start = lookup->length;
+    if (unlikely (!subtable->finish_subtable (c->serializer,
+					      bitmap_size_context->cbdt_prime->length,
+					      num_glyphs,
+					      &bitmap_size_context->size)))
+      return_trace (false);
+    return_trace (true);
+  }
+
+  bool add_new_record (hb_subset_context_t *c,
+		       cblc_bitmap_size_subset_context_t *bitmap_size_context,
+		       const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
+		       const void *base,
+		       unsigned int *start, /* INOUT */
+		       hb_vector_t<IndexSubtableRecord>* records /* INOUT */) const
+  {
+    TRACE_SERIALIZE (this);
+    auto snap = c->serializer->snapshot ();
+    unsigned int old_size = bitmap_size_context->size;
+    unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length;
+
+    // Set to invalid state to indicate filling glyphs is not yet started.
+    if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
+      return_trace (false);
+
+    records->tail ().firstGlyphIndex = 1;
+    records->tail ().lastGlyphIndex = 0;
+    bitmap_size_context->size += IndexSubtableRecord::min_size;
+
+    c->serializer->push ();
+
+    if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
+    {
+      c->serializer->pop_discard ();
+      c->serializer->revert (snap);
+      bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length);
+      bitmap_size_context->size = old_size;
+      records->resize (records->length - 1);
+      return_trace (false);
+    }
+
+    bitmap_size_context->num_tables += 1;
+    return_trace (true);
+  }
+
+  unsigned int add_glyph_for_subset (hb_codepoint_t gid)
+  {
+    if (firstGlyphIndex > lastGlyphIndex)
+    {
+      firstGlyphIndex = gid;
+      lastGlyphIndex = gid;
+      return 0;
+    }
+    // TODO maybe assert? this shouldn't occur.
+    if (lastGlyphIndex > gid)
+      return 0;
+    unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1);
+    lastGlyphIndex = gid;
+    return num_missing;
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents, const void *base, bool scale) const
+  { return (base+offsetToSubtable).get_extents (extents, scale); }
+
+  bool get_image_data (unsigned int  gid,
+		       const void   *base,
+		       unsigned int *offset,
+		       unsigned int *length,
+		       unsigned int *format) const
+  {
+    if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
+    return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
+						   offset, length, format);
+  }
+
+  HBGlyphID16			firstGlyphIndex;
+  HBGlyphID16			lastGlyphIndex;
+  Offset32To<IndexSubtable>	offsetToSubtable;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct IndexSubtableArray
+{
+  friend struct CBDT;
+
+  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (indexSubtablesZ.sanitize (c, count, this));
+  }
+
+  void
+  build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context,
+		hb_vector_t<hb_pair_t<hb_codepoint_t,
+		const IndexSubtableRecord*>> *lookup /* OUT */) const
+  {
+    bool start_glyph_is_set = false;
+    for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
+
+      const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables);
+      if (unlikely (!record)) continue;
+
+      // Don't add gaps to the lookup. The best way to determine if a glyph is a
+      // gap is that it has no image data.
+      unsigned int offset, length, format;
+      if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue;
+
+      lookup->push (hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*> (new_gid, record));
+
+      if (!start_glyph_is_set)
+      {
+	bitmap_size_context->start_glyph = new_gid;
+	start_glyph_is_set = true;
+      }
+
+      bitmap_size_context->end_glyph = new_gid;
+    }
+  }
+
+  bool
+  subset (hb_subset_context_t *c,
+	  cblc_bitmap_size_subset_context_t *bitmap_size_context) const
+  {
+    TRACE_SUBSET (this);
+
+    auto *dst = c->serializer->start_embed<IndexSubtableArray> ();
+    if (unlikely (!dst)) return_trace (false);
+
+    hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
+    build_lookup (c, bitmap_size_context, &lookup);
+    if (unlikely (!c->serializer->propagate_error (lookup)))
+      return false;
+
+    bitmap_size_context->size = 0;
+    bitmap_size_context->num_tables = 0;
+    hb_vector_t<IndexSubtableRecord> records;
+    for (unsigned int start = 0; start < lookup.length;)
+    {
+      if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records)))
+      {
+	// Discard any leftover pushes to the serializer from successful records.
+	for (unsigned int i = 0; i < records.length; i++)
+	  c->serializer->pop_discard ();
+	return_trace (false);
+      }
+    }
+
+    /* Workaround to ensure offset ordering is from least to greatest when
+     * resolving links. */
+    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
+    for (unsigned int i = 0; i < records.length; i++)
+      objidxs.push (c->serializer->pop_pack ());
+    for (unsigned int i = 0; i < records.length; i++)
+    {
+      IndexSubtableRecord* record = c->serializer->embed (records[i]);
+      if (unlikely (!record)) return_trace (false);
+      c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]);
+    }
+    return_trace (true);
+  }
+
+  public:
+  const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
+  {
+    for (unsigned int i = 0; i < numTables; ++i)
+    {
+      unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
+      unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
+      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
+	return &indexSubtablesZ[i];
+    }
+    return nullptr;
+  }
+
+  protected:
+  UnsizedArrayOf<IndexSubtableRecord>	indexSubtablesZ;
+};
+
+struct BitmapSizeTable
+{
+  friend struct CBLC;
+  friend struct CBDT;
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
+		  horizontal.sanitize (c) &&
+		  vertical.sanitize (c));
+  }
+
+  const IndexSubtableRecord *
+  find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const
+  {
+    *out_base = &(base+indexSubtableArrayOffset);
+    return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
+  }
+
+  bool
+  subset (hb_subset_context_t *c, const void *base,
+	  const char *cbdt, unsigned int cbdt_length,
+	  hb_vector_t<char> *cbdt_prime /* INOUT */) const
+  {
+    TRACE_SUBSET (this);
+    auto *out_table = c->serializer->embed (this);
+    if (unlikely (!out_table)) return_trace (false);
+
+    cblc_bitmap_size_subset_context_t bitmap_size_context;
+    bitmap_size_context.cbdt = cbdt;
+    bitmap_size_context.cbdt_length = cbdt_length;
+    bitmap_size_context.cbdt_prime = cbdt_prime;
+    bitmap_size_context.size = indexTablesSize;
+    bitmap_size_context.num_tables = numberOfIndexSubtables;
+    bitmap_size_context.start_glyph = 1;
+    bitmap_size_context.end_glyph = 0;
+
+    if (!out_table->indexSubtableArrayOffset.serialize_subset (c,
+							       indexSubtableArrayOffset,
+							       base,
+							       &bitmap_size_context))
+      return_trace (false);
+    if (!bitmap_size_context.size ||
+	!bitmap_size_context.num_tables ||
+	bitmap_size_context.start_glyph > bitmap_size_context.end_glyph)
+      return_trace (false);
+
+    out_table->indexTablesSize = bitmap_size_context.size;
+    out_table->numberOfIndexSubtables = bitmap_size_context.num_tables;
+    out_table->startGlyphIndex = bitmap_size_context.start_glyph;
+    out_table->endGlyphIndex = bitmap_size_context.end_glyph;
+    return_trace (true);
+  }
+
+  protected:
+  NNOffset32To<IndexSubtableArray>
+			indexSubtableArrayOffset;
+  HBUINT32		indexTablesSize;
+  HBUINT32		numberOfIndexSubtables;
+  HBUINT32		colorRef;
+  SBitLineMetrics	horizontal;
+  SBitLineMetrics	vertical;
+  HBGlyphID16		startGlyphIndex;
+  HBGlyphID16		endGlyphIndex;
+  HBUINT8		ppemX;
+  HBUINT8		ppemY;
+  HBUINT8		bitDepth;
+  HBINT8		flags;
+  public:
+  DEFINE_SIZE_STATIC (48);
+};
+
+
+/*
+ * Glyph Bitmap Data Formats.
+ */
+
+struct GlyphBitmapDataFormat17
+{
+  SmallGlyphMetrics	glyphMetrics;
+  Array32Of<HBUINT8>	data;
+  public:
+  DEFINE_SIZE_ARRAY (9, data);
+};
+
+struct GlyphBitmapDataFormat18
+{
+  BigGlyphMetrics	glyphMetrics;
+  Array32Of<HBUINT8>	data;
+  public:
+  DEFINE_SIZE_ARRAY (12, data);
+};
+
+struct GlyphBitmapDataFormat19
+{
+  Array32Of<HBUINT8>	data;
+  public:
+  DEFINE_SIZE_ARRAY (4, data);
+};
+
+struct CBLC
+{
+  friend struct CBDT;
+
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CBLC;
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  likely (version.major == 2 || version.major == 3) &&
+		  sizeTables.sanitize (c, this));
+  }
+
+  static bool
+  sink_cbdt (hb_subset_context_t *c, hb_vector_t<char>* cbdt_prime)
+  {
+    hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ,
+						 cbdt_prime->length,
+						 HB_MEMORY_MODE_WRITABLE,
+						 cbdt_prime->arrayZ,
+						 hb_free);
+    cbdt_prime->init ();  // Leak arrayZ to the blob.
+    bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob);
+    hb_blob_destroy (cbdt_prime_blob);
+    return ret;
+  }
+
+  bool
+  subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table,
+		     const char *cbdt /* IN */, unsigned int cbdt_length,
+		     CBLC *cblc_prime /* INOUT */, hb_vector_t<char> *cbdt_prime /* INOUT */) const
+  {
+    TRACE_SUBSET (this);
+    cblc_prime->sizeTables.len++;
+
+    auto snap = c->serializer->snapshot ();
+    auto cbdt_prime_len = cbdt_prime->length;
+
+    if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime))
+    {
+      cblc_prime->sizeTables.len--;
+      c->serializer->revert (snap);
+      cbdt_prime->shrink (cbdt_prime_len);
+      return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  // Implemented in cc file as it depends on definition of CBDT.
+  HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+
+  protected:
+  const BitmapSizeTable &choose_strike (hb_font_t *font) const
+  {
+    unsigned count = sizeTables.len;
+    if (unlikely (!count))
+      return Null (BitmapSizeTable);
+
+    unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
+    if (!requested_ppem)
+      requested_ppem = 1<<30; /* Choose largest strike. */
+    unsigned int best_i = 0;
+    unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY);
+
+    for (unsigned int i = 1; i < count; i++)
+    {
+      unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY);
+      if ((requested_ppem <= ppem && ppem < best_ppem) ||
+	  (requested_ppem > best_ppem && ppem > best_ppem))
+      {
+	best_i = i;
+	best_ppem = ppem;
+      }
+    }
+
+    return sizeTables[best_i];
+  }
+
+  protected:
+  FixedVersion<>		version;
+  Array32Of<BitmapSizeTable>	sizeTables;
+  public:
+  DEFINE_SIZE_ARRAY (8, sizeTables);
+};
+
+struct CBDT
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CBDT;
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
+      this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
+
+      upem = hb_face_get_upem (face);
+    }
+    ~accelerator_t ()
+    {
+      this->cblc.destroy ();
+      this->cbdt.destroy ();
+    }
+
+    bool
+    get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents, bool scale = true) const
+    {
+      const void *base;
+      const BitmapSizeTable &strike = this->cblc->choose_strike (font);
+      const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
+      if (!subtable_record || !strike.ppemX || !strike.ppemY)
+	return false;
+
+      if (subtable_record->get_extents (extents, base, scale))
+	return true;
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
+	return false;
+
+      unsigned int cbdt_len = cbdt.get_length ();
+      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+	return false;
+
+      switch (image_format)
+      {
+      case 17: {
+	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
+	  return false;
+	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	glyphFormat17.glyphMetrics.get_extents (font, extents, scale);
+	break;
+      }
+      case 18: {
+	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
+	  return false;
+	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	glyphFormat18.glyphMetrics.get_extents (font, extents, scale);
+	break;
+      }
+      default: return false; /* TODO: Support other image formats. */
+      }
+
+      /* Convert to font units. */
+      if (scale)
+      {
+	float x_scale = upem / (float) strike.ppemX;
+	float y_scale = upem / (float) strike.ppemY;
+	extents->x_bearing = roundf (extents->x_bearing * x_scale);
+	extents->y_bearing = roundf (extents->y_bearing * y_scale);
+	extents->width = roundf (extents->width * x_scale);
+	extents->height = roundf (extents->height * y_scale);
+      }
+
+      return true;
+    }
+
+    hb_blob_t*
+    reference_png (hb_font_t *font, hb_codepoint_t glyph) const
+    {
+      const void *base;
+      const BitmapSizeTable &strike = this->cblc->choose_strike (font);
+      const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
+      if (!subtable_record || !strike.ppemX || !strike.ppemY)
+	return hb_blob_get_empty ();
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
+	return hb_blob_get_empty ();
+
+      unsigned int cbdt_len = cbdt.get_length ();
+      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+	return hb_blob_get_empty ();
+
+      switch (image_format)
+      {
+      case 17:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat17::min_size,
+					glyphFormat17.data.len);
+      }
+      case 18:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat18::min_size,
+					glyphFormat18.data.len);
+      }
+      case 19:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat19::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat19::min_size,
+					glyphFormat19.data.len);
+      }
+      default: return hb_blob_get_empty (); /* TODO: Support other image formats. */
+      }
+    }
+
+    bool has_data () const { return cbdt.get_length (); }
+
+    bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      hb_glyph_extents_t extents;
+      hb_glyph_extents_t pixel_extents;
+      hb_blob_t *blob = reference_png (font, glyph);
+
+      if (unlikely (blob == hb_blob_get_empty ()))
+        return false;
+
+      if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents)))
+        return false;
+
+      if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+        return false;
+
+      bool ret = funcs->image (data,
+			       blob,
+			       pixel_extents.width, -pixel_extents.height,
+			       HB_PAINT_IMAGE_FORMAT_PNG,
+			       font->slant_xy,
+			       &extents);
+
+      hb_blob_destroy (blob);
+      return ret;
+    }
+
+    private:
+    hb_blob_ptr_t<CBLC> cblc;
+    hb_blob_ptr_t<CBDT> cbdt;
+
+    unsigned int upem;
+  };
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  likely (version.major == 2 || version.major == 3));
+  }
+
+  protected:
+  FixedVersion<>		version;
+  UnsizedArrayOf<HBUINT8>	dataZ;
+  public:
+  DEFINE_SIZE_ARRAY (4, dataZ);
+};
+
+inline bool
+CBLC::subset (hb_subset_context_t *c) const
+{
+  TRACE_SUBSET (this);
+
+  auto *cblc_prime = c->serializer->start_embed<CBLC> ();
+
+  // Use a vector as a secondary buffer as the tables need to be built in parallel.
+  hb_vector_t<char> cbdt_prime;
+
+  if (unlikely (!cblc_prime)) return_trace (false);
+  if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
+  cblc_prime->version = version;
+
+  hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table<CBDT> (c->plan->source);
+  unsigned int cbdt_length;
+  CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length);
+  if (unlikely (cbdt_length < CBDT::min_size))
+  {
+    hb_blob_destroy (cbdt_blob);
+    return_trace (false);
+  }
+  _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size);
+
+  for (const BitmapSizeTable& table : + sizeTables.iter ())
+    subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime);
+
+  hb_blob_destroy (cbdt_blob);
+
+  return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
+}
+
+struct CBDT_accelerator_t : CBDT::accelerator_t {
+  CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
+};
+
+
+} /* namespace OT */
+
+#endif /* OT_COLOR_CBDT_CBDT_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/COLR.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,2203 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Calder Kitagawa
+ */
+
+#ifndef OT_COLOR_COLR_COLR_HH
+#define OT_COLOR_COLR_COLR_HH
+
+#include "../../../hb.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-ot-var-common.hh"
+#include "../../../hb-paint.hh"
+#include "../../../hb-paint-extents.hh"
+
+/*
+ * COLR -- Color
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
+ */
+#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
+
+
+namespace OT {
+struct hb_paint_context_t;
+}
+
+namespace OT {
+
+struct COLR;
+
+struct Paint;
+
+struct hb_paint_context_t :
+       hb_dispatch_context_t<hb_paint_context_t>
+{
+  template <typename T>
+  return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
+
+  const COLR* get_colr_table () const
+  { return reinterpret_cast<const COLR *> (base); }
+
+public:
+  const void *base;
+  hb_paint_funcs_t *funcs;
+  void *data;
+  hb_font_t *font;
+  unsigned int palette_index;
+  hb_color_t foreground;
+  VarStoreInstancer &instancer;
+  int depth_left = HB_MAX_NESTING_LEVEL;
+  int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
+
+  hb_paint_context_t (const void *base_,
+		      hb_paint_funcs_t *funcs_,
+		      void *data_,
+                      hb_font_t *font_,
+                      unsigned int palette_,
+                      hb_color_t foreground_,
+		      VarStoreInstancer &instancer_) :
+    base (base_),
+    funcs (funcs_),
+    data (data_),
+    font (font_),
+    palette_index (palette_),
+    foreground (foreground_),
+    instancer (instancer_)
+  { }
+
+  hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground)
+  {
+    hb_color_t color = foreground;
+
+    *is_foreground = true;
+
+    if (color_index != 0xffff)
+    {
+      if (!funcs->custom_palette_color (data, color_index, &color))
+      {
+	unsigned int clen = 1;
+	hb_face_t *face = hb_font_get_face (font);
+
+	hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
+      }
+
+      *is_foreground = false;
+    }
+
+    return HB_COLOR (hb_color_get_blue (color),
+                     hb_color_get_green (color),
+                     hb_color_get_red (color),
+                     hb_color_get_alpha (color) * alpha);
+  }
+
+  inline void recurse (const Paint &paint);
+};
+
+struct hb_colrv1_closure_context_t :
+       hb_dispatch_context_t<hb_colrv1_closure_context_t>
+{
+  template <typename T>
+  return_t dispatch (const T &obj)
+  {
+    if (unlikely (nesting_level_left == 0))
+      return hb_empty_t ();
+
+    if (paint_visited (&obj))
+      return hb_empty_t ();
+
+    nesting_level_left--;
+    obj.closurev1 (this);
+    nesting_level_left++;
+    return hb_empty_t ();
+  }
+  static return_t default_return_value () { return hb_empty_t (); }
+
+  bool paint_visited (const void *paint)
+  {
+    hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
+    if (visited_paint.in_error() || visited_paint.has (delta))
+      return true;
+
+    visited_paint.add (delta);
+    return false;
+  }
+
+  const COLR* get_colr_table () const
+  { return reinterpret_cast<const COLR *> (base); }
+
+  void add_glyph (unsigned glyph_id)
+  { glyphs->add (glyph_id); }
+
+  void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
+  { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
+
+  void add_palette_index (unsigned palette_index)
+  { palette_indices->add (palette_index); }
+
+  public:
+  const void *base;
+  hb_set_t visited_paint;
+  hb_set_t *glyphs;
+  hb_set_t *layer_indices;
+  hb_set_t *palette_indices;
+  unsigned nesting_level_left;
+
+  hb_colrv1_closure_context_t (const void *base_,
+                               hb_set_t *glyphs_,
+                               hb_set_t *layer_indices_,
+                               hb_set_t *palette_indices_,
+                               unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+                          base (base_),
+                          glyphs (glyphs_),
+                          layer_indices (layer_indices_),
+                          palette_indices (palette_indices_),
+                          nesting_level_left (nesting_level_left_)
+  {}
+};
+
+struct LayerRecord
+{
+  operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBGlyphID16	glyphId;	/* Glyph ID of layer glyph */
+  Index		colorIdx;	/* Index value to use with a
+				 * selected color palette.
+				 * An index value of 0xFFFF
+				 * is a special case indicating
+				 * that the text foreground
+				 * color (defined by a
+				 * higher-level client) should
+				 * be used and shall not be
+				 * treated as actual index
+				 * into CPAL ColorRecord array. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct BaseGlyphRecord
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBGlyphID16	glyphId;	/* Glyph ID of reference glyph */
+  HBUINT16	firstLayerIdx;	/* Index (from beginning of
+				 * the Layer Records) to the
+				 * layer record. There will be
+				 * numLayers consecutive entries
+				 * for this base glyph. */
+  HBUINT16	numLayers;	/* Number of color layers
+				 * associated with this glyph */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+template <typename T>
+struct Variable
+{
+  static constexpr bool is_variable = true;
+
+  Variable<T>* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (!value.subset (c)) return_trace (false);
+    return_trace (c->serializer->embed (varIdxBase));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && value.sanitize (c));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    value.paint_glyph (c, varIdxBase);
+  }
+
+  void get_color_stop (hb_paint_context_t *c,
+                       hb_color_stop_t *stop,
+		       const VarStoreInstancer &instancer) const
+  {
+    value.get_color_stop (c, stop, varIdxBase, instancer);
+  }
+
+  hb_paint_extend_t get_extend () const
+  {
+    return value.get_extend ();
+  }
+
+  protected:
+  T      value;
+  public:
+  VarIdx varIdxBase;
+  public:
+  DEFINE_SIZE_STATIC (4 + T::static_size);
+};
+
+template <typename T>
+struct NoVariable
+{
+  static constexpr bool is_variable = false;
+
+  static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
+
+  NoVariable<T>* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    return_trace (value.subset (c));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && value.sanitize (c));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    value.paint_glyph (c, varIdxBase);
+  }
+
+  void get_color_stop (hb_paint_context_t *c,
+                       hb_color_stop_t *stop,
+		       const VarStoreInstancer &instancer) const
+  {
+    value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer);
+  }
+
+  hb_paint_extend_t get_extend () const
+  {
+    return value.get_extend ();
+  }
+
+  T      value;
+  public:
+  DEFINE_SIZE_STATIC (T::static_size);
+};
+
+// Color structures
+
+struct ColorStop
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { c->add_palette_index (paletteIndex); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_color_stop (hb_paint_context_t *c,
+                       hb_color_stop_t *out,
+		       uint32_t varIdx,
+		       const VarStoreInstancer &instancer) const
+  {
+    out->offset = stopOffset.to_float(instancer (varIdx, 0));
+    out->color = c->get_color (paletteIndex,
+                               alpha.to_float (instancer (varIdx, 1)),
+                               &out->is_foreground);
+  }
+
+  F2DOT14	stopOffset;
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
+  public:
+  DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size);
+};
+
+struct Extend : HBUINT8
+{
+  enum {
+    EXTEND_PAD     = 0,
+    EXTEND_REPEAT  = 1,
+    EXTEND_REFLECT = 2,
+  };
+  public:
+  DEFINE_SIZE_STATIC (1);
+};
+
+template <template<typename> class Var>
+struct ColorLine
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    for (const auto &stop : stops.iter ())
+      stop.closurev1 (c);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!out)) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+    if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false);
+
+    for (const auto& stop : stops.iter ())
+    {
+      if (!stop.subset (c)) return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  stops.sanitize (c));
+  }
+
+  /* get up to count stops from start */
+  unsigned int
+  get_color_stops (hb_paint_context_t *c,
+                   unsigned int start,
+		   unsigned int *count,
+		   hb_color_stop_t *color_stops,
+		   const VarStoreInstancer &instancer) const
+  {
+    unsigned int len = stops.len;
+
+    if (count && color_stops)
+    {
+      unsigned int i;
+      for (i = 0; i < *count && start + i < len; i++)
+        stops[start + i].get_color_stop (c, &color_stops[i], instancer);
+      *count = i;
+    }
+
+    return len;
+  }
+
+  HB_INTERNAL static unsigned int static_get_color_stops (hb_color_line_t *color_line,
+							  void *color_line_data,
+							  unsigned int start,
+							  unsigned int *count,
+							  hb_color_stop_t *color_stops,
+							  void *user_data)
+  {
+    const ColorLine *thiz = (const ColorLine *) color_line_data;
+    hb_paint_context_t *c = (hb_paint_context_t *) user_data;
+    return thiz->get_color_stops (c, start, count, color_stops, c->instancer);
+  }
+
+  hb_paint_extend_t get_extend () const
+  {
+    return (hb_paint_extend_t) (unsigned int) extend;
+  }
+
+  HB_INTERNAL static hb_paint_extend_t static_get_extend (hb_color_line_t *color_line,
+							  void *color_line_data,
+							  void *user_data)
+  {
+    const ColorLine *thiz = (const ColorLine *) color_line_data;
+    return thiz->get_extend ();
+  }
+
+  Extend	extend;
+  Array16Of<Var<ColorStop>>	stops;
+  public:
+  DEFINE_SIZE_ARRAY_SIZED (3, stops);
+};
+
+// Composition modes
+
+// Compositing modes are taken from https://www.w3.org/TR/compositing-1/
+// NOTE: a brief audit of major implementations suggests most support most
+// or all of the specified modes.
+struct CompositeMode : HBUINT8
+{
+  enum {
+    // Porter-Duff modes
+    // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators
+    COMPOSITE_CLEAR          =  0,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_clear
+    COMPOSITE_SRC            =  1,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_src
+    COMPOSITE_DEST           =  2,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dst
+    COMPOSITE_SRC_OVER       =  3,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcover
+    COMPOSITE_DEST_OVER      =  4,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstover
+    COMPOSITE_SRC_IN         =  5,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin
+    COMPOSITE_DEST_IN        =  6,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin
+    COMPOSITE_SRC_OUT        =  7,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout
+    COMPOSITE_DEST_OUT       =  8,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout
+    COMPOSITE_SRC_ATOP       =  9,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop
+    COMPOSITE_DEST_ATOP      = 10,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop
+    COMPOSITE_XOR            = 11,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor
+    COMPOSITE_PLUS           = 12,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus
+
+    // Blend modes
+    // https://www.w3.org/TR/compositing-1/#blending
+    COMPOSITE_SCREEN         = 13,  // https://www.w3.org/TR/compositing-1/#blendingscreen
+    COMPOSITE_OVERLAY        = 14,  // https://www.w3.org/TR/compositing-1/#blendingoverlay
+    COMPOSITE_DARKEN         = 15,  // https://www.w3.org/TR/compositing-1/#blendingdarken
+    COMPOSITE_LIGHTEN        = 16,  // https://www.w3.org/TR/compositing-1/#blendinglighten
+    COMPOSITE_COLOR_DODGE    = 17,  // https://www.w3.org/TR/compositing-1/#blendingcolordodge
+    COMPOSITE_COLOR_BURN     = 18,  // https://www.w3.org/TR/compositing-1/#blendingcolorburn
+    COMPOSITE_HARD_LIGHT     = 19,  // https://www.w3.org/TR/compositing-1/#blendinghardlight
+    COMPOSITE_SOFT_LIGHT     = 20,  // https://www.w3.org/TR/compositing-1/#blendingsoftlight
+    COMPOSITE_DIFFERENCE     = 21,  // https://www.w3.org/TR/compositing-1/#blendingdifference
+    COMPOSITE_EXCLUSION      = 22,  // https://www.w3.org/TR/compositing-1/#blendingexclusion
+    COMPOSITE_MULTIPLY       = 23,  // https://www.w3.org/TR/compositing-1/#blendingmultiply
+
+    // Modes that, uniquely, do not operate on components
+    // https://www.w3.org/TR/compositing-1/#blendingnonseparable
+    COMPOSITE_HSL_HUE        = 24,  // https://www.w3.org/TR/compositing-1/#blendinghue
+    COMPOSITE_HSL_SATURATION = 25,  // https://www.w3.org/TR/compositing-1/#blendingsaturation
+    COMPOSITE_HSL_COLOR      = 26,  // https://www.w3.org/TR/compositing-1/#blendingcolor
+    COMPOSITE_HSL_LUMINOSITY = 27,  // https://www.w3.org/TR/compositing-1/#blendingluminosity
+  };
+  public:
+  DEFINE_SIZE_STATIC (1);
+};
+
+struct Affine2x3
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    c->funcs->push_transform (c->data,
+			      xx.to_float (c->instancer (varIdxBase, 0)),
+			      yx.to_float (c->instancer (varIdxBase, 1)),
+                              xy.to_float (c->instancer (varIdxBase, 2)),
+			      yy.to_float (c->instancer (varIdxBase, 3)),
+                              dx.to_float (c->instancer (varIdxBase, 4)),
+			      dy.to_float (c->instancer (varIdxBase, 5)));
+  }
+
+  F16DOT16 xx;
+  F16DOT16 yx;
+  F16DOT16 xy;
+  F16DOT16 yy;
+  F16DOT16 dx;
+  F16DOT16 dy;
+  public:
+  DEFINE_SIZE_STATIC (6 * F16DOT16::static_size);
+};
+
+struct PaintColrLayers
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  inline void paint_glyph (hb_paint_context_t *c) const;
+
+  HBUINT8	format; /* format = 1 */
+  HBUINT8	numLayers;
+  HBUINT32	firstLayerIndex;  /* index into COLRv1::layerList */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct PaintSolid
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { c->add_palette_index (paletteIndex); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    hb_bool_t is_foreground;
+    hb_color_t color;
+
+    color = c->get_color (paletteIndex,
+                          alpha.to_float (c->instancer (varIdxBase, 0)),
+                          &is_foreground);
+    c->funcs->color (c->data, is_foreground, color);
+  }
+
+  HBUINT8	format; /* format = 2(noVar) or 3(Var)*/
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
+  public:
+  DEFINE_SIZE_STATIC (3 + F2DOT14::static_size);
+};
+
+template <template<typename> class Var>
+struct PaintLinearGradient
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    hb_color_line_t cl = {
+      (void *) &(this+colorLine),
+      (this+colorLine).static_get_color_stops, c,
+      (this+colorLine).static_get_extend, nullptr
+    };
+
+    c->funcs->linear_gradient (c->data, &cl,
+			       x0 + c->instancer (varIdxBase, 0),
+			       y0 + c->instancer (varIdxBase, 1),
+			       x1 + c->instancer (varIdxBase, 2),
+			       y1 + c->instancer (varIdxBase, 3),
+			       x2 + c->instancer (varIdxBase, 4),
+			       y2 + c->instancer (varIdxBase, 5));
+  }
+
+  HBUINT8			format; /* format = 4(noVar) or 5 (Var) */
+  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintLinearGradient
+                                            * table) to ColorLine subtable. */
+  FWORD			x0;
+  FWORD			y0;
+  FWORD			x1;
+  FWORD			y1;
+  FWORD			x2;
+  FWORD			y2;
+  public:
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
+};
+
+template <template<typename> class Var>
+struct PaintRadialGradient
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    hb_color_line_t cl = {
+      (void *) &(this+colorLine),
+      (this+colorLine).static_get_color_stops, c,
+      (this+colorLine).static_get_extend, nullptr
+    };
+
+    c->funcs->radial_gradient (c->data, &cl,
+			       x0 + c->instancer (varIdxBase, 0),
+			       y0 + c->instancer (varIdxBase, 1),
+			       radius0 + c->instancer (varIdxBase, 2),
+			       x1 + c->instancer (varIdxBase, 3),
+			       y1 + c->instancer (varIdxBase, 4),
+			       radius1 + c->instancer (varIdxBase, 5));
+  }
+
+  HBUINT8			format; /* format = 6(noVar) or 7 (Var) */
+  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintRadialGradient
+                                            * table) to ColorLine subtable. */
+  FWORD			x0;
+  FWORD			y0;
+  UFWORD		radius0;
+  FWORD			x1;
+  FWORD			y1;
+  UFWORD		radius1;
+  public:
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
+};
+
+template <template<typename> class Var>
+struct PaintSweepGradient
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { (this+colorLine).closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    hb_color_line_t cl = {
+      (void *) &(this+colorLine),
+      (this+colorLine).static_get_color_stops, c,
+      (this+colorLine).static_get_extend, nullptr
+    };
+
+    c->funcs->sweep_gradient (c->data, &cl,
+			      centerX + c->instancer (varIdxBase, 0),
+			      centerY + c->instancer (varIdxBase, 1),
+                              (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI,
+                              (endAngle.to_float   (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI);
+  }
+
+  HBUINT8			format; /* format = 8(noVar) or 9 (Var) */
+  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintSweepGradient
+                                            * table) to ColorLine subtable. */
+  FWORD			centerX;
+  FWORD			centerY;
+  F2DOT14		startAngle;
+  F2DOT14		endAngle;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size);
+};
+
+// Paint a non-COLR glyph, filled as indicated by paint.
+struct PaintGlyph
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) 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));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && paint.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    c->funcs->push_inverse_root_transform (c->data, c->font);
+    c->funcs->push_clip_glyph (c->data, gid, c->font);
+    c->funcs->push_root_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);
+  }
+
+  HBUINT8		format; /* format = 10 */
+  Offset24To<Paint>	paint;  /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
+  HBUINT16		gid;
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct PaintColrGlyph
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  inline void paint_glyph (hb_paint_context_t *c) const;
+
+  HBUINT8	format; /* format = 11 */
+  HBUINT16	gid;
+  public:
+  DEFINE_SIZE_STATIC (3);
+};
+
+template <template<typename> class Var>
+struct PaintTransform
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false);
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  src.sanitize (c, this) &&
+                  transform.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    (this+transform).paint_glyph (c);
+    c->recurse (this+src);
+    c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8			format; /* format = 12(noVar) or 13 (Var) */
+  Offset24To<Paint>		src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
+  Offset24To<Var<Affine2x3>>	transform;
+  public:
+  DEFINE_SIZE_STATIC (7);
+};
+
+struct PaintTranslate
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 14(noVar) or 15 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
+  FWORD		dx;
+  FWORD		dy;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size);
+};
+
+struct PaintScale
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
+  F2DOT14		scaleX;
+  F2DOT14		scaleY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
+};
+
+struct PaintScaleAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 18 (noVar) or 19(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
+  F2DOT14	scaleX;
+  F2DOT14	scaleY;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintScaleUniform
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 20 (noVar) or 21(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
+  F2DOT14		scale;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintScaleUniformAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 22 (noVar) or 23(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
+  F2DOT14	scale;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintRotate
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 24 (noVar) or 25(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
+  F2DOT14		angle;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintRotateAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 26 (noVar) or 27(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
+  F2DOT14	angle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintSkew
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 28(noVar) or 29 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
+  F2DOT14		xSkewAngle;
+  F2DOT14		ySkewAngle;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
+};
+
+struct PaintSkewAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->src.serialize_subset (c, src, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 30(noVar) or 31 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
+  F2DOT14	xSkewAngle;
+  F2DOT14	ySkewAngle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintComposite
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (!out->src.serialize_subset (c, src, this)) return_trace (false);
+    return_trace (out->backdrop.serialize_subset (c, backdrop, this));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  src.sanitize (c, this) &&
+                  backdrop.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    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);
+  }
+
+  HBUINT8		format; /* format = 32 */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
+  CompositeMode		mode;   /* If mode is unrecognized use COMPOSITE_CLEAR */
+  Offset24To<Paint>	backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct ClipBoxData
+{
+  int xMin, yMin, xMax, yMax;
+};
+
+struct ClipBoxFormat1
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const
+  {
+    clip_box.xMin = xMin;
+    clip_box.yMin = yMin;
+    clip_box.xMax = xMax;
+    clip_box.yMax = yMax;
+  }
+
+  public:
+  HBUINT8	format; /* format = 1(noVar) or 2(Var)*/
+  FWORD		xMin;
+  FWORD		yMin;
+  FWORD		xMax;
+  FWORD		yMax;
+  public:
+  DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
+};
+
+struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
+{
+  void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const
+  {
+    value.get_clip_box(clip_box, instancer);
+    if (instancer)
+    {
+      clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
+      clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
+      clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
+      clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+    }
+  }
+};
+
+struct ClipBox
+{
+  ClipBox* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.format) {
+    case 1: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format1)));
+    case 2: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format2)));
+    default:return_trace (nullptr);
+    }
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents,
+                    const VarStoreInstancer &instancer) const
+  {
+    ClipBoxData clip_box;
+    switch (u.format) {
+    case 1:
+      u.format1.get_clip_box (clip_box, instancer);
+      break;
+    case 2:
+      u.format2.get_clip_box (clip_box, instancer);
+      break;
+    default:
+      return false;
+    }
+
+    extents->x_bearing = clip_box.xMin;
+    extents->y_bearing = clip_box.yMax;
+    extents->width = clip_box.xMax - clip_box.xMin;
+    extents->height = clip_box.yMin - clip_box.yMax;
+    return true;
+  }
+
+  protected:
+  union {
+  HBUINT8		format;         /* Format identifier */
+  ClipBoxFormat1	format1;
+  ClipBoxFormat2	format2;
+  } u;
+};
+
+struct ClipRecord
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
+
+  ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr);
+    return_trace (out);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents,
+		    const void *base,
+		    const VarStoreInstancer &instancer) const
+  {
+    return (base+clipBox).get_extents (extents, instancer);
+  }
+
+  public:
+  HBUINT16		startGlyphID;  // first gid clip applies to
+  HBUINT16		endGlyphID;    // last gid clip applies to, inclusive
+  Offset24To<ClipBox>	clipBox;   // Box or VarBox
+  public:
+  DEFINE_SIZE_STATIC (7);
+};
+DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
+
+struct ClipList
+{
+  unsigned serialize_clip_records (hb_serialize_context_t *c,
+                                   const hb_set_t& gids,
+                                   const hb_map_t& gid_offset_map) const
+  {
+    TRACE_SERIALIZE (this);
+    if (gids.is_empty () ||
+        gid_offset_map.get_population () != gids.get_population ())
+      return_trace (0);
+
+    unsigned count  = 0;
+
+    hb_codepoint_t start_gid= gids.get_min ();
+    hb_codepoint_t prev_gid = start_gid;
+
+    unsigned offset = gid_offset_map.get (start_gid);
+    unsigned prev_offset = offset;
+    for (const hb_codepoint_t _ : gids.iter ())
+    {
+      if (_ == start_gid) continue;
+
+      offset = gid_offset_map.get (_);
+      if (_ == prev_gid + 1 &&  offset == prev_offset)
+      {
+        prev_gid = _;
+        continue;
+      }
+
+      ClipRecord record;
+      record.startGlyphID = start_gid;
+      record.endGlyphID = prev_gid;
+      record.clipBox = prev_offset;
+
+      if (!c->copy (record, this)) return_trace (0);
+      count++;
+
+      start_gid = _;
+      prev_gid = _;
+      prev_offset = offset;
+    }
+
+    //last one
+    {
+      ClipRecord record;
+      record.startGlyphID = start_gid;
+      record.endGlyphID = prev_gid;
+      record.clipBox = prev_offset;
+      if (!c->copy (record, this)) return_trace (0);
+      count++;
+    }
+    return_trace (count);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    const hb_set_t& glyphset = c->plan->_glyphset_colred;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    hb_map_t new_gid_offset_map;
+    hb_set_t new_gids;
+    for (const ClipRecord& record : clips.iter ())
+    {
+      unsigned start_gid = record.startGlyphID;
+      unsigned end_gid = record.endGlyphID;
+      for (unsigned gid = start_gid; gid <= end_gid; gid++)
+      {
+        if (!glyphset.has (gid) || !glyph_map.has (gid)) continue;
+        unsigned new_gid = glyph_map.get (gid);
+        new_gid_offset_map.set (new_gid, record.clipBox);
+        new_gids.add (new_gid);
+      }
+    }
+
+    unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map);
+    if (!count) return_trace (false);
+    return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    // TODO Make a formatted struct!
+    return_trace (c->check_struct (this) && clips.sanitize (c, this));
+  }
+
+  bool
+  get_extents (hb_codepoint_t gid,
+	       hb_glyph_extents_t *extents,
+	       const VarStoreInstancer &instancer) const
+  {
+    auto *rec = clips.as_array ().bsearch (gid);
+    if (rec)
+    {
+      rec->get_extents (extents, this, instancer);
+      return true;
+    }
+    return false;
+  }
+
+  HBUINT8			format;  // Set to 1.
+  SortedArray32Of<ClipRecord>	clips;  // Clip records, sorted by startGlyphID
+  public:
+  DEFINE_SIZE_ARRAY_SIZED (5, clips);
+};
+
+struct Paint
+{
+
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
+  {
+    TRACE_SANITIZE (this);
+
+    if (unlikely (!c->check_start_recursion (HB_MAX_NESTING_LEVEL)))
+      return_trace (c->no_dispatch_return_value ());
+
+    return_trace (c->end_recursion (this->dispatch (c, std::forward<Ts> (ds)...)));
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.paintformat1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.paintformat3, std::forward<Ts> (ds)...));
+    case 4: return_trace (c->dispatch (u.paintformat4, std::forward<Ts> (ds)...));
+    case 5: return_trace (c->dispatch (u.paintformat5, std::forward<Ts> (ds)...));
+    case 6: return_trace (c->dispatch (u.paintformat6, std::forward<Ts> (ds)...));
+    case 7: return_trace (c->dispatch (u.paintformat7, std::forward<Ts> (ds)...));
+    case 8: return_trace (c->dispatch (u.paintformat8, std::forward<Ts> (ds)...));
+    case 9: return_trace (c->dispatch (u.paintformat9, std::forward<Ts> (ds)...));
+    case 10: return_trace (c->dispatch (u.paintformat10, std::forward<Ts> (ds)...));
+    case 11: return_trace (c->dispatch (u.paintformat11, std::forward<Ts> (ds)...));
+    case 12: return_trace (c->dispatch (u.paintformat12, std::forward<Ts> (ds)...));
+    case 13: return_trace (c->dispatch (u.paintformat13, std::forward<Ts> (ds)...));
+    case 14: return_trace (c->dispatch (u.paintformat14, std::forward<Ts> (ds)...));
+    case 15: return_trace (c->dispatch (u.paintformat15, std::forward<Ts> (ds)...));
+    case 16: return_trace (c->dispatch (u.paintformat16, std::forward<Ts> (ds)...));
+    case 17: return_trace (c->dispatch (u.paintformat17, std::forward<Ts> (ds)...));
+    case 18: return_trace (c->dispatch (u.paintformat18, std::forward<Ts> (ds)...));
+    case 19: return_trace (c->dispatch (u.paintformat19, std::forward<Ts> (ds)...));
+    case 20: return_trace (c->dispatch (u.paintformat20, std::forward<Ts> (ds)...));
+    case 21: return_trace (c->dispatch (u.paintformat21, std::forward<Ts> (ds)...));
+    case 22: return_trace (c->dispatch (u.paintformat22, std::forward<Ts> (ds)...));
+    case 23: return_trace (c->dispatch (u.paintformat23, std::forward<Ts> (ds)...));
+    case 24: return_trace (c->dispatch (u.paintformat24, std::forward<Ts> (ds)...));
+    case 25: return_trace (c->dispatch (u.paintformat25, std::forward<Ts> (ds)...));
+    case 26: return_trace (c->dispatch (u.paintformat26, std::forward<Ts> (ds)...));
+    case 27: return_trace (c->dispatch (u.paintformat27, std::forward<Ts> (ds)...));
+    case 28: return_trace (c->dispatch (u.paintformat28, std::forward<Ts> (ds)...));
+    case 29: return_trace (c->dispatch (u.paintformat29, std::forward<Ts> (ds)...));
+    case 30: return_trace (c->dispatch (u.paintformat30, std::forward<Ts> (ds)...));
+    case 31: return_trace (c->dispatch (u.paintformat31, std::forward<Ts> (ds)...));
+    case 32: return_trace (c->dispatch (u.paintformat32, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  HBUINT8					format;
+  PaintColrLayers				paintformat1;
+  NoVariable<PaintSolid>			paintformat2;
+  Variable<PaintSolid>				paintformat3;
+  NoVariable<PaintLinearGradient<NoVariable>>	paintformat4;
+  Variable<PaintLinearGradient<Variable>>	paintformat5;
+  NoVariable<PaintRadialGradient<NoVariable>>	paintformat6;
+  Variable<PaintRadialGradient<Variable>>	paintformat7;
+  NoVariable<PaintSweepGradient<NoVariable>>	paintformat8;
+  Variable<PaintSweepGradient<Variable>>	paintformat9;
+  PaintGlyph					paintformat10;
+  PaintColrGlyph				paintformat11;
+  PaintTransform<NoVariable>			paintformat12;
+  PaintTransform<Variable>			paintformat13;
+  NoVariable<PaintTranslate>			paintformat14;
+  Variable<PaintTranslate>			paintformat15;
+  NoVariable<PaintScale>			paintformat16;
+  Variable<PaintScale>				paintformat17;
+  NoVariable<PaintScaleAroundCenter>		paintformat18;
+  Variable<PaintScaleAroundCenter>		paintformat19;
+  NoVariable<PaintScaleUniform>			paintformat20;
+  Variable<PaintScaleUniform>			paintformat21;
+  NoVariable<PaintScaleUniformAroundCenter>	paintformat22;
+  Variable<PaintScaleUniformAroundCenter>	paintformat23;
+  NoVariable<PaintRotate>			paintformat24;
+  Variable<PaintRotate>				paintformat25;
+  NoVariable<PaintRotateAroundCenter>		paintformat26;
+  Variable<PaintRotateAroundCenter>		paintformat27;
+  NoVariable<PaintSkew>				paintformat28;
+  Variable<PaintSkew>				paintformat29;
+  NoVariable<PaintSkewAroundCenter>		paintformat30;
+  Variable<PaintSkewAroundCenter>		paintformat31;
+  PaintComposite				paintformat32;
+  } u;
+  public:
+  DEFINE_SIZE_MIN (2);
+};
+
+struct BaseGlyphPaintRecord
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
+
+  bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
+                  const void* src_base, hb_subset_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = s->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    if (!s->check_assign (out->glyphId, glyph_map->get (glyphId),
+                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+
+    return_trace (out->paint.serialize_subset (c, paint, src_base));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && paint.sanitize (c, base)));
+  }
+
+  public:
+  HBGlyphID16		glyphId;    /* Glyph ID of reference glyph */
+  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint,
+                                     * Typically PaintColrLayers */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
+{
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
+    const hb_set_t* glyphset = &c->plan->_glyphset_colred;
+
+    for (const auto& _ : as_array ())
+    {
+      unsigned gid = _.glyphId;
+      if (!glyphset->has (gid)) continue;
+
+      if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
+      else return_trace (false);
+    }
+
+    return_trace (out->len != 0);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this));
+  }
+};
+
+struct LayerList : Array32OfOffset32To<Paint>
+{
+  const Paint& get_paint (unsigned i) const
+  { return this+(*this)[i]; }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
+
+    for (const auto& _ : + hb_enumerate (*this)
+                         | hb_filter (c->plan->colrv1_layers, hb_first))
+
+    {
+      auto *o = out->serialize_append (c->serializer);
+      if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
+        return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (Array32OfOffset32To<Paint>::sanitize (c, this));
+  }
+};
+
+struct COLR
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
+
+  bool has_v0_data () const { return numBaseGlyphs; }
+  bool has_v1_data () const
+  {
+    if (version == 1)
+      return (this+baseGlyphList).len > 0;
+
+    return false;
+  }
+
+  unsigned int get_glyph_layers (hb_codepoint_t       glyph,
+				 unsigned int         start_offset,
+				 unsigned int        *count, /* IN/OUT.  May be NULL. */
+				 hb_ot_color_layer_t *layers /* OUT.     May be NULL. */) const
+  {
+    const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
+
+    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
+    hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
+								       record.numLayers);
+    if (count)
+    {
+      + glyph_layers.sub_array (start_offset, count)
+      | hb_sink (hb_array (layers, *count))
+      ;
+    }
+    return glyph_layers.length;
+  }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    { colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
+    ~accelerator_t () { this->colr.destroy (); }
+
+    bool is_valid () { return colr.get_blob ()->length; }
+
+    void closure_glyphs (hb_codepoint_t glyph,
+			 hb_set_t *related_ids /* OUT */) const
+    { colr->closure_glyphs (glyph, related_ids); }
+
+    void closure_V0palette_indices (const hb_set_t *glyphs,
+				    hb_set_t *palettes /* OUT */) const
+    { colr->closure_V0palette_indices (glyphs, palettes); }
+
+    void closure_forV1 (hb_set_t *glyphset,
+                        hb_set_t *layer_indices,
+                        hb_set_t *palette_indices) const
+    { colr->closure_forV1 (glyphset, layer_indices, palette_indices); }
+
+    private:
+    hb_blob_ptr_t<COLR> colr;
+  };
+
+  void closure_glyphs (hb_codepoint_t glyph,
+		       hb_set_t *related_ids /* OUT */) const
+  {
+    const BaseGlyphRecord *record = get_base_glyph_record (glyph);
+    if (!record) return;
+
+    auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx,
+								       record->numLayers);
+    if (!glyph_layers.length) return;
+    related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
+  }
+
+  void closure_V0palette_indices (const hb_set_t *glyphs,
+				  hb_set_t *palettes /* OUT */) const
+  {
+    if (!numBaseGlyphs || !numLayers) return;
+    hb_array_t<const BaseGlyphRecord> baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs);
+    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
+
+    for (const BaseGlyphRecord record : baseGlyphs)
+    {
+      if (!glyphs->has (record.glyphId)) continue;
+      hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
+                                                                   record.numLayers);
+      for (const LayerRecord layer : glyph_layers)
+        palettes->add (layer.colorIdx);
+    }
+  }
+
+  void closure_forV1 (hb_set_t *glyphset,
+                      hb_set_t *layer_indices,
+                      hb_set_t *palette_indices) const
+  {
+    if (version != 1) return;
+    hb_set_t visited_glyphs;
+
+    hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices);
+    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
+
+    for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ())
+    {
+      unsigned gid = baseglyph_paintrecord.glyphId;
+      if (!glyphset->has (gid)) continue;
+
+      const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint;
+      paint.dispatch (&c);
+    }
+    hb_set_union (glyphset, &visited_glyphs);
+  }
+
+  const LayerList& get_layerList () const
+  { return (this+layerList); }
+
+  const BaseGlyphList& get_baseglyphList () const
+  { return (this+baseGlyphList); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
+                  (this+layersZ).sanitize (c, numLayers) &&
+                  (version == 0 ||
+		   (version == 1 &&
+		    baseGlyphList.sanitize (c, this) &&
+		    layerList.sanitize (c, this) &&
+		    clipList.sanitize (c, this) &&
+		    varIdxMap.sanitize (c, this) &&
+		    varStore.sanitize (c, this))));
+  }
+
+  template<typename BaseIterator, typename LayerIterator,
+	   hb_requires (hb_is_iterator (BaseIterator)),
+	   hb_requires (hb_is_iterator (LayerIterator))>
+  bool serialize_V0 (hb_serialize_context_t *c,
+		     unsigned version,
+		     BaseIterator base_it,
+		     LayerIterator layer_it)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (base_it.len () != layer_it.len ()))
+      return_trace (false);
+
+    this->version = version;
+    numLayers = 0;
+    numBaseGlyphs = base_it.len ();
+    if (numBaseGlyphs == 0)
+    {
+      baseGlyphsZ = 0;
+      layersZ = 0;
+      return_trace (true);
+    }
+
+    c->push ();
+    for (const hb_item_type<BaseIterator> _ : + base_it.iter ())
+    {
+      auto* record = c->embed (_);
+      if (unlikely (!record)) return_trace (false);
+      record->firstLayerIdx = numLayers;
+      numLayers += record->numLayers;
+    }
+    c->add_link (baseGlyphsZ, c->pop_pack ());
+
+    c->push ();
+    for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ())
+      _.as_array ().copy (c);
+
+    c->add_link (layersZ, c->pop_pack ());
+
+    return_trace (true);
+  }
+
+  const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const
+  {
+    const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid);
+    if (record == &Null (BaseGlyphRecord) ||
+        (record && (hb_codepoint_t) record->glyphId != gid))
+      record = nullptr;
+    return record;
+  }
+
+  const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const
+  {
+    const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid);
+    if ((record && (hb_codepoint_t) record->glyphId != gid))
+      record = nullptr;
+    return record;
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
+    const hb_set_t& glyphset = c->plan->_glyphset_colred;
+
+    auto base_it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_filter ([&](hb_codepoint_t new_gid)
+		 {
+		    hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
+		    if (glyphset.has (old_gid)) return true;
+		    return false;
+		 })
+    | hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
+			      {
+				hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
+
+				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
+				if (unlikely (!old_record))
+				  return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
+				BaseGlyphRecord new_record = {};
+				new_record.glyphId = new_gid;
+				new_record.numLayers = old_record->numLayers;
+				return hb_pair_t<bool, BaseGlyphRecord> (true, new_record);
+			      })
+    | hb_filter (hb_first)
+    | hb_map_retains_sorting (hb_second)
+    ;
+
+    auto layer_it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_map (reverse_glyph_map)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
+			      {
+				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
+				hb_vector_t<LayerRecord> out_layers;
+
+				if (unlikely (!old_record ||
+					      old_record->firstLayerIdx >= numLayers ||
+					      old_record->firstLayerIdx + old_record->numLayers > numLayers))
+				  return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
+
+				auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx,
+											     old_record->numLayers);
+				out_layers.resize (layers.length);
+				for (unsigned int i = 0; i < layers.length; i++) {
+				  out_layers[i] = layers[i];
+				  hb_codepoint_t new_gid = 0;
+				  if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
+				    return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
+				  out_layers[i].glyphId = new_gid;
+				  out_layers[i].colorIdx = c->plan->colr_palettes.get (layers[i].colorIdx);
+				}
+
+				return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers);
+			      })
+    | hb_filter (hb_first)
+    | hb_map_retains_sorting (hb_second)
+    ;
+
+    if (version == 0 && (!base_it || !layer_it))
+      return_trace (false);
+
+    COLR *colr_prime = c->serializer->start_embed<COLR> ();
+    if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
+
+    if (version == 0)
+    return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it));
+
+    auto snap = c->serializer->snapshot ();
+    if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
+    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
+    {
+      if (c->serializer->in_error ()) return_trace (false);
+      //no more COLRv1 glyphs: downgrade to version 0
+      c->serializer->revert (snap);
+      return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
+    }
+
+    if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
+
+    colr_prime->layerList.serialize_subset (c, layerList, this);
+    colr_prime->clipList.serialize_subset (c, clipList, this);
+    colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
+    colr_prime->varStore.serialize_copy (c->serializer, varStore, this);
+    return_trace (true);
+  }
+
+  const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const
+  {
+    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
+    const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph);
+    if (record)
+    {
+      const Paint &paint = &baseglyph_paintrecords+record->paint;
+      return &paint;
+    }
+    else
+      return nullptr;
+  }
+
+  bool
+  get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+  {
+    if (version != 1)
+      return false;
+
+    VarStoreInstancer instancer (this+varStore,
+				 this+varIdxMap,
+				 hb_array (font->coords, font->num_coords));
+
+    if (get_clip (glyph, extents, instancer))
+    {
+      font->scale_glyph_extents (extents);
+      return true;
+    }
+
+    auto *extents_funcs = hb_paint_extents_get_funcs ();
+    hb_paint_extents_context_t extents_data;
+    bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
+
+    hb_extents_t e = extents_data.get_extents ();
+    if (e.is_void ())
+    {
+      extents->x_bearing = 0;
+      extents->y_bearing = 0;
+      extents->width = 0;
+      extents->height = 0;
+    }
+    else
+    {
+      extents->x_bearing = e.xmin;
+      extents->y_bearing = e.ymax;
+      extents->width = e.xmax - e.xmin;
+      extents->height = e.ymin - e.ymax;
+    }
+
+    return ret;
+  }
+
+  bool
+  has_paint_for_glyph (hb_codepoint_t glyph) const
+  {
+    if (version == 1)
+    {
+      const Paint *paint = get_base_glyph_paint (glyph);
+
+      return paint != nullptr;
+    }
+
+    return false;
+  }
+
+  bool get_clip (hb_codepoint_t glyph,
+		 hb_glyph_extents_t *extents,
+		 const VarStoreInstancer instancer) const
+  {
+    return (this+clipList).get_extents (glyph,
+					extents,
+					instancer);
+  }
+
+  bool
+  paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
+  {
+    VarStoreInstancer instancer (this+varStore,
+	                         this+varIdxMap,
+	                         hb_array (font->coords, font->num_coords));
+    hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
+
+    if (version == 1)
+    {
+      const Paint *paint = get_base_glyph_paint (glyph);
+      if (paint)
+      {
+        // COLRv1 glyph
+
+	VarStoreInstancer instancer (this+varStore,
+				     this+varIdxMap,
+				     hb_array (font->coords, font->num_coords));
+
+	bool is_bounded = true;
+	if (clip)
+	{
+	  hb_glyph_extents_t extents;
+	  if (get_clip (glyph, &extents, instancer))
+	  {
+	    font->scale_glyph_extents (&extents);
+	    c.funcs->push_clip_rectangle (c.data,
+					  extents.x_bearing,
+					  extents.y_bearing + extents.height,
+					  extents.x_bearing + extents.width,
+					  extents.y_bearing);
+	  }
+	  else
+	  {
+	    auto *extents_funcs = hb_paint_extents_get_funcs ();
+	    hb_paint_extents_context_t extents_data;
+
+	    paint_glyph (font, glyph,
+			 extents_funcs, &extents_data,
+			 palette_index, foreground,
+			 false);
+
+	    hb_extents_t extents = extents_data.get_extents ();
+	    is_bounded = extents_data.is_bounded ();
+
+	    c.funcs->push_clip_rectangle (c.data,
+					  extents.xmin,
+					  extents.ymin,
+					  extents.xmax,
+					  extents.ymax);
+	  }
+	}
+
+	c.funcs->push_root_transform (c.data, font);
+
+	if (is_bounded)
+	  c.recurse (*paint);
+
+	c.funcs->pop_transform (c.data);
+
+	if (clip)
+	  c.funcs->pop_clip (c.data);
+
+        return true;
+      }
+    }
+
+    const BaseGlyphRecord *record = get_base_glyph_record (glyph);
+    if (record && ((hb_codepoint_t) record->glyphId == glyph))
+    {
+      // COLRv0 glyph
+      for (const auto &r : (this+layersZ).as_array (numLayers)
+			   .sub_array (record->firstLayerIdx, record->numLayers))
+      {
+        hb_bool_t is_foreground;
+        hb_color_t color = c.get_color (r.colorIdx, 1., &is_foreground);
+        c.funcs->push_clip_glyph (c.data, r.glyphId, c.font);
+        c.funcs->color (c.data, is_foreground, color);
+        c.funcs->pop_clip (c.data);
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  protected:
+  HBUINT16	version;	/* Table version number (starts at 0). */
+  HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */
+  NNOffset32To<SortedUnsizedArrayOf<BaseGlyphRecord>>
+		baseGlyphsZ;	/* Offset to Base Glyph records. */
+  NNOffset32To<UnsizedArrayOf<LayerRecord>>
+		layersZ;	/* Offset to Layer Records. */
+  HBUINT16	numLayers;	/* Number of Layer Records. */
+  // Version-1 additions
+  Offset32To<BaseGlyphList>		baseGlyphList;
+  Offset32To<LayerList>			layerList;
+  Offset32To<ClipList>			clipList;   // Offset to ClipList table (may be NULL)
+  Offset32To<DeltaSetIndexMap>		varIdxMap;  // Offset to DeltaSetIndexMap table (may be NULL)
+  Offset32To<VariationStore>		varStore;
+  public:
+  DEFINE_SIZE_MIN (14);
+};
+
+struct COLR_accelerator_t : COLR::accelerator_t {
+  COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
+};
+
+void
+hb_paint_context_t::recurse (const Paint &paint)
+{
+  if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
+  depth_left--;
+  edge_count--;
+  paint.dispatch (this);
+  depth_left++;
+}
+
+void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
+{
+  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
+  for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
+  {
+    const Paint &paint = paint_offset_lists.get_paint (i);
+    c->funcs->push_group (c->data);
+    c->recurse (paint);
+    c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+  }
+}
+
+void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
+{
+  const COLR *colr_table = c->get_colr_table ();
+  const Paint *paint = colr_table->get_base_glyph_paint (gid);
+
+  hb_glyph_extents_t extents = {0};
+  bool has_clip_box = colr_table->get_clip (gid, &extents, c->instancer);
+
+  if (has_clip_box)
+    c->funcs->push_clip_rectangle (c->data,
+				   extents.x_bearing,
+				   extents.y_bearing + extents.height,
+				   extents.x_bearing + extents.width,
+				   extents.y_bearing);
+
+  if (paint)
+    c->recurse (*paint);
+
+  if (has_clip_box)
+    c->funcs->pop_clip (c->data);
+}
+
+} /* namespace OT */
+
+#endif /* OT_COLOR_COLR_COLR_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/colrv1-closure.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/colrv1-closure.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/COLR/colrv1-closure.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#ifndef OT_COLOR_COLR_COLRV1_CLOSURE_HH
+#define OT_COLOR_COLR_COLRV1_CLOSURE_HH
+
+#include "../../../hb-open-type.hh"
+#include "COLR.hh"
+
+/*
+ * COLR -- Color
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
+ */
+namespace OT {
+
+HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  c->add_layer_indices (firstLayerIndex, numLayers);
+  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
+  for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
+  {
+    const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
+    paint.dispatch (c);
+  }
+}
+
+HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  c->add_glyph (gid);
+  (this+paint).dispatch (c);
+}
+
+HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  const COLR *colr_table = c->get_colr_table ();
+  const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
+  if (!baseglyph_paintrecord) return;
+  c->add_glyph (gid);
+
+  const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
+  (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
+}
+
+template <template<typename> class Var>
+HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{ (this+src).dispatch (c); }
+
+HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  (this+backdrop).dispatch (c);
+}
+
+} /* namespace OT */
+
+
+#endif /* OT_COLOR_COLR_COLRV1_CLOSURE_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/CPAL/CPAL.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,322 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Sascha Brawer
+ */
+
+#ifndef OT_COLOR_CPAL_CPAL_HH
+#define OT_COLOR_CPAL_CPAL_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-ot-color.h"
+#include "../../../hb-ot-name.h"
+
+
+/*
+ * CPAL -- Color Palette
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
+ */
+#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
+
+namespace OT {
+
+
+struct CPALV1Tail
+{
+  friend struct CPAL;
+
+  private:
+  hb_ot_color_palette_flags_t get_palette_flags (const void *base,
+						 unsigned int palette_index,
+						 unsigned int palette_count) const
+  {
+    if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
+    return (hb_ot_color_palette_flags_t) (uint32_t)
+	   (base+paletteFlagsZ).as_array (palette_count)[palette_index];
+  }
+
+  hb_ot_name_id_t get_palette_name_id (const void *base,
+				       unsigned int palette_index,
+				       unsigned int palette_count) const
+  {
+    if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID;
+    return (base+paletteLabelsZ).as_array (palette_count)[palette_index];
+  }
+
+  hb_ot_name_id_t get_color_name_id (const void *base,
+				     unsigned int color_index,
+				     unsigned int color_count) const
+  {
+    if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID;
+    return (base+colorLabelsZ).as_array (color_count)[color_index];
+  }
+
+  public:
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned palette_count,
+                  unsigned color_count,
+                  const void *base,
+                  const hb_map_t *color_index_map) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->allocate_size<CPALV1Tail> (static_size);
+    if (unlikely (!out)) return_trace (false);
+
+    out->paletteFlagsZ = 0;
+    if (paletteFlagsZ)
+      out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
+
+    out->paletteLabelsZ = 0;
+    if (paletteLabelsZ)
+      out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
+
+    const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
+    if (colorLabelsZ)
+    {
+      c->push ();
+      for (const auto _ : colorLabels)
+      {
+	const hb_codepoint_t *v;
+        if (!color_index_map->has (_, &v)) continue;
+        NameID new_color_idx;
+	new_color_idx = *v;
+        if (!c->copy<NameID> (new_color_idx))
+        {
+          c->pop_discard ();
+          return_trace (false);
+        }
+      }
+      c->add_link (out->colorLabelsZ, c->pop_pack ());
+    }
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c,
+		 const void *base,
+		 unsigned int palette_count,
+		 unsigned int color_count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  (!paletteFlagsZ  || (base+paletteFlagsZ).sanitize (c, palette_count)) &&
+		  (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) &&
+		  (!colorLabelsZ   || (base+colorLabelsZ).sanitize (c, color_count)));
+  }
+
+  protected:
+  // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
+  //                     here. Currently they are needed since UnsizedArrayOf doesn't define null_size
+  NNOffset32To<UnsizedArrayOf<HBUINT32>>
+		paletteFlagsZ;		/* Offset from the beginning of CPAL table to
+					 * the Palette Type Array. Set to 0 if no array
+					 * is provided. */
+  NNOffset32To<UnsizedArrayOf<NameID>>
+		paletteLabelsZ;		/* Offset from the beginning of CPAL table to
+					 * the palette labels array. Set to 0 if no
+					 * array is provided. */
+  NNOffset32To<UnsizedArrayOf<NameID>>
+		colorLabelsZ;		/* Offset from the beginning of CPAL table to
+					 * the color labels array. Set to 0
+					 * if no array is provided. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+typedef HBUINT32 BGRAColor;
+
+struct CPAL
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL;
+
+  bool has_data () const { return numPalettes; }
+
+  unsigned int get_size () const
+  { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
+
+  unsigned int get_palette_count () const { return numPalettes; }
+  unsigned int   get_color_count () const { return numColors; }
+
+  hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
+  { return v1 ().get_palette_flags (this, palette_index, numPalettes); }
+
+  hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const
+  { return v1 ().get_palette_name_id (this, palette_index, numPalettes); }
+
+  hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
+  { return v1 ().get_color_name_id (this, color_index, numColors); }
+
+  unsigned int get_palette_colors (unsigned int  palette_index,
+				   unsigned int  start_offset,
+				   unsigned int *color_count, /* IN/OUT.  May be NULL. */
+				   hb_color_t   *colors       /* OUT.     May be NULL. */) const
+  {
+    if (unlikely (palette_index >= numPalettes))
+    {
+      if (color_count) *color_count = 0;
+      return 0;
+    }
+    unsigned int start_index = colorRecordIndicesZ[palette_index];
+    hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
+    hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index,
+								       numColors);
+    if (color_count)
+    {
+      + palette_colors.sub_array (start_offset, color_count)
+      | hb_sink (hb_array (colors, *color_count))
+      ;
+    }
+    return numColors;
+  }
+
+  private:
+  const CPALV1Tail& v1 () const
+  {
+    if (version == 0) return Null (CPALV1Tail);
+    return StructAfter<CPALV1Tail> (*this);
+  }
+
+  public:
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_array_t<const HBUINT16> &color_record_indices,
+                  const hb_array_t<const BGRAColor> &color_records,
+                  const hb_vector_t<unsigned>& first_color_index_for_layer,
+                  const hb_map_t& first_color_to_layer_index,
+                  const hb_set_t &retained_color_indices) const
+  {
+    TRACE_SERIALIZE (this);
+
+    // TODO(grieger): limit total final size.
+
+    for (const auto idx : color_record_indices)
+    {
+      hb_codepoint_t layer_index = first_color_to_layer_index[idx];
+
+      HBUINT16 new_idx;
+      new_idx = layer_index * retained_color_indices.get_population ();
+      if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
+    }
+
+    c->push ();
+    for (unsigned first_color_index : first_color_index_for_layer)
+    {
+      for (hb_codepoint_t color_index : retained_color_indices)
+      {
+        if (!c->copy<BGRAColor> (color_records[first_color_index + color_index]))
+        {
+          c->pop_discard ();
+          return_trace (false);
+        }
+      }
+    }
+
+    c->add_link (colorRecordsZ, c->pop_pack ());
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (!numPalettes) return_trace (false);
+
+    const hb_map_t *color_index_map = &c->plan->colr_palettes;
+    if (color_index_map->is_empty ()) return_trace (false);
+
+    hb_set_t retained_color_indices;
+    for (const auto _ : color_index_map->keys ())
+    {
+      if (_ == 0xFFFF) continue;
+      retained_color_indices.add (_);
+    }
+    if (retained_color_indices.is_empty ()) return_trace (false);
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+
+    out->version = version;
+    out->numColors = retained_color_indices.get_population ();
+    out->numPalettes = numPalettes;
+
+    hb_vector_t<unsigned> first_color_index_for_layer;
+    hb_map_t first_color_to_layer_index;
+
+    const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
+    for (const auto first_color_record_idx : colorRecordIndices)
+    {
+      if (first_color_to_layer_index.has (first_color_record_idx)) continue;
+
+      first_color_index_for_layer.push (first_color_record_idx);
+      first_color_to_layer_index.set (first_color_record_idx,
+                                      first_color_index_for_layer.length - 1);
+    }
+
+    out->numColorRecords = first_color_index_for_layer.length
+                           * retained_color_indices.get_population ();
+
+    const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
+    if (!out->serialize (c->serializer,
+                         colorRecordIndices,
+                         color_records,
+                         first_color_index_for_layer,
+                         first_color_to_layer_index,
+                         retained_color_indices))
+      return_trace (false);
+
+    if (version == 1)
+      return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
+
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  (this+colorRecordsZ).sanitize (c, numColorRecords) &&
+		  colorRecordIndicesZ.sanitize (c, numPalettes) &&
+		  (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors)));
+  }
+
+  protected:
+  HBUINT16	version;		/* Table version number */
+  /* Version 0 */
+  HBUINT16	numColors;		/* Number of colors in each palette. */
+  HBUINT16	numPalettes;		/* Number of palettes in the table. */
+  HBUINT16	numColorRecords;	/* Total number of color records, combined for
+					 * all palettes. */
+  NNOffset32To<UnsizedArrayOf<BGRAColor>>
+		colorRecordsZ;		/* Offset from the beginning of CPAL table to
+					 * the first ColorRecord. */
+  UnsizedArrayOf<HBUINT16>
+		colorRecordIndicesZ;	/* Index of each palette’s first color record in
+					 * the combined color record array. */
+/*CPALV1Tail	v1;*/
+  public:
+  DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_COLOR_CPAL_CPAL_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/sbix/sbix.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/sbix/sbix.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/sbix/sbix.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,452 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Calder Kitagawa
+ */
+
+#ifndef OT_COLOR_SBIX_SBIX_HH
+#define OT_COLOR_SBIX_SBIX_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
+
+/*
+ * sbix -- Standard Bitmap Graphics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
+ */
+#define HB_OT_TAG_sbix HB_TAG('s','b','i','x')
+
+
+namespace OT {
+
+
+struct SBIXGlyph
+{
+  SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const
+  {
+    TRACE_SERIALIZE (this);
+    SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
+    if (unlikely (!new_glyph)) return_trace (nullptr);
+    if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
+
+    new_glyph->xOffset = xOffset;
+    new_glyph->yOffset = yOffset;
+    new_glyph->graphicType = graphicType;
+    data.copy (c, data_length);
+    return_trace (new_glyph);
+  }
+
+  HBINT16	xOffset;	/* The horizontal (x-axis) offset from the left
+				 * edge of the graphic to the glyph’s origin.
+				 * That is, the x-coordinate of the point on the
+				 * baseline at the left edge of the glyph. */
+  HBINT16	yOffset;	/* The vertical (y-axis) offset from the bottom
+				 * edge of the graphic to the glyph’s origin.
+				 * That is, the y-coordinate of the point on the
+				 * baseline at the left edge of the glyph. */
+  Tag		graphicType;	/* Indicates the format of the embedded graphic
+				 * data: one of 'jpg ', 'png ' or 'tiff', or the
+				 * special format 'dupe'. */
+  UnsizedArrayOf<HBUINT8>
+		data;		/* The actual embedded graphic data. The total
+				 * length is inferred from sequential entries in
+				 * the glyphDataOffsets array and the fixed size
+				 * (8 bytes) of the preceding fields. */
+  public:
+  DEFINE_SIZE_ARRAY (8, data);
+};
+
+struct SBIXStrike
+{
+  static unsigned int get_size (unsigned num_glyphs)
+  { return min_size + num_glyphs * HBUINT32::static_size; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
+  }
+
+  hb_blob_t *get_glyph_blob (unsigned int  glyph_id,
+			     hb_blob_t    *sbix_blob,
+			     hb_tag_t      file_type,
+			     int          *x_offset,
+			     int          *y_offset,
+			     unsigned int  num_glyphs,
+			     unsigned int *strike_ppem) const
+  {
+    if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */
+
+    unsigned int retry_count = 8;
+    unsigned int sbix_len = sbix_blob->length;
+    unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data;
+    assert (strike_offset < sbix_len);
+
+  retry:
+    if (unlikely (glyph_id >= num_glyphs ||
+		  imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] ||
+		  imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size ||
+		  (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset))
+      return hb_blob_get_empty ();
+
+    unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size;
+    unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
+
+    const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
+
+    if (glyph->graphicType == HB_TAG ('d','u','p','e'))
+    {
+      if (glyph_length >= 2)
+      {
+	glyph_id = *((HBUINT16 *) &glyph->data);
+	if (retry_count--)
+	  goto retry;
+      }
+      return hb_blob_get_empty ();
+    }
+
+    if (unlikely (file_type != glyph->graphicType))
+      return hb_blob_get_empty ();
+
+    if (strike_ppem) *strike_ppem = ppem;
+    if (x_offset) *x_offset = glyph->xOffset;
+    if (y_offset) *y_offset = glyph->yOffset;
+    return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
+  }
+
+  bool subset (hb_subset_context_t *c, unsigned int available_len) const
+  {
+    TRACE_SUBSET (this);
+    unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
+
+    auto* out = c->serializer->start_embed<SBIXStrike> ();
+    if (unlikely (!out)) return_trace (false);
+    auto snap = c->serializer->snapshot ();
+    if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
+    out->ppem = ppem;
+    out->resolution = resolution;
+    HBUINT32 head;
+    head = get_size (num_output_glyphs + 1);
+
+    bool has_glyphs = false;
+    for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
+	  unlikely (imageOffsetsZ[old_gid].is_null () ||
+		    imageOffsetsZ[old_gid + 1].is_null () ||
+		    imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
+		    imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) ||
+		    (unsigned int) imageOffsetsZ[old_gid + 1] > available_len)
+      {
+	out->imageOffsetsZ[new_gid] = head;
+	continue;
+      }
+      has_glyphs = true;
+      unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
+      unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
+      if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length))
+	return_trace (false);
+      out->imageOffsetsZ[new_gid] = head;
+      head += delta;
+    }
+    if (has_glyphs)
+      out->imageOffsetsZ[num_output_glyphs] = head;
+    else
+      c->serializer->revert (snap);
+    return_trace (has_glyphs);
+  }
+
+  public:
+  HBUINT16	ppem;		/* The PPEM size for which this strike was designed. */
+  HBUINT16	resolution;	/* The device pixel density (in PPI) for which this
+				 * strike was designed. (E.g., 96 PPI, 192 PPI.) */
+  protected:
+  UnsizedArrayOf<Offset32To<SBIXGlyph>>
+		imageOffsetsZ;	/* Offset from the beginning of the strike data header
+				 * to bitmap data for an individual glyph ID. */
+  public:
+  DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
+};
+
+struct sbix
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix;
+
+  bool has_data () const { return version; }
+
+  const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      table = hb_sanitize_context_t ().reference_table<sbix> (face);
+      num_glyphs = face->get_num_glyphs ();
+    }
+    ~accelerator_t () { table.destroy (); }
+
+    bool has_data () const { return table->has_data (); }
+
+    bool get_extents (hb_font_t          *font,
+		      hb_codepoint_t      glyph,
+		      hb_glyph_extents_t *extents,
+		      bool                scale = true) const
+    {
+      /* We only support PNG right now, and following function checks type. */
+      return get_png_extents (font, glyph, extents, scale);
+    }
+
+    hb_blob_t *reference_png (hb_font_t      *font,
+			      hb_codepoint_t  glyph_id,
+			      int            *x_offset,
+			      int            *y_offset,
+			      unsigned int   *available_ppem) const
+    {
+      return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (),
+						  HB_TAG ('p','n','g',' '),
+						  x_offset, y_offset,
+						  num_glyphs, available_ppem);
+    }
+
+    bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      if (!has_data ())
+        return false;
+
+      int x_offset = 0, y_offset = 0;
+      unsigned int strike_ppem = 0;
+      hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
+      hb_glyph_extents_t extents;
+      hb_glyph_extents_t pixel_extents;
+
+      if (blob == hb_blob_get_empty ())
+        return false;
+
+      if (!hb_font_get_glyph_extents (font, glyph, &extents))
+        return false;
+
+      if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+        return false;
+
+      bool ret = funcs->image (data,
+			       blob,
+			       pixel_extents.width, -pixel_extents.height,
+			       HB_PAINT_IMAGE_FORMAT_PNG,
+			       font->slant_xy,
+			       &extents);
+
+      hb_blob_destroy (blob);
+      return ret;
+    }
+
+    private:
+
+    const SBIXStrike &choose_strike (hb_font_t *font) const
+    {
+      unsigned count = table->strikes.len;
+      if (unlikely (!count))
+	return Null (SBIXStrike);
+
+      unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
+      if (!requested_ppem)
+	requested_ppem = 1<<30; /* Choose largest strike. */
+      /* TODO Add DPI sensitivity as well? */
+      unsigned int best_i = 0;
+      unsigned int best_ppem = table->get_strike (0).ppem;
+
+      for (unsigned int i = 1; i < count; i++)
+      {
+	unsigned int ppem = (table->get_strike (i)).ppem;
+	if ((requested_ppem <= ppem && ppem < best_ppem) ||
+	    (requested_ppem > best_ppem && ppem > best_ppem))
+	{
+	  best_i = i;
+	  best_ppem = ppem;
+	}
+      }
+
+      return table->get_strike (best_i);
+    }
+
+    struct PNGHeader
+    {
+      HBUINT8	signature[8];
+      struct
+      {
+	struct
+	{
+	  HBUINT32	length;
+	  Tag		type;
+	}		header;
+	HBUINT32	width;
+	HBUINT32	height;
+	HBUINT8		bitDepth;
+	HBUINT8		colorType;
+	HBUINT8		compressionMethod;
+	HBUINT8		filterMethod;
+	HBUINT8		interlaceMethod;
+      } IHDR;
+
+      public:
+      DEFINE_SIZE_STATIC (29);
+    };
+
+    bool get_png_extents (hb_font_t          *font,
+			  hb_codepoint_t      glyph,
+			  hb_glyph_extents_t *extents,
+			  bool                scale = true) const
+    {
+      /* Following code is safe to call even without data.
+       * But faster to short-circuit. */
+      if (!has_data ())
+	return false;
+
+      int x_offset = 0, y_offset = 0;
+      unsigned int strike_ppem = 0;
+      hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
+
+      const PNGHeader &png = *blob->as<PNGHeader>();
+
+      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;
+      extents->height    = -1 * png.IHDR.height;
+
+      /* Convert to font units. */
+      if (strike_ppem && scale)
+      {
+	float scale = font->face->get_upem () / (float) strike_ppem;
+	extents->x_bearing = roundf (extents->x_bearing * scale);
+	extents->y_bearing = roundf (extents->y_bearing * scale);
+	extents->width = roundf (extents->width * scale);
+	extents->height = roundf (extents->height * scale);
+      }
+
+      if (scale)
+	font->scale_glyph_extents (extents);
+
+      hb_blob_destroy (blob);
+
+      return strike_ppem;
+    }
+
+    private:
+    hb_blob_ptr_t<sbix> table;
+
+    unsigned int num_glyphs;
+  };
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  version >= 1 &&
+			  strikes.sanitize (c, this)));
+  }
+
+  bool
+  add_strike (hb_subset_context_t *c, unsigned i) const
+  {
+    if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i])
+      return false;
+
+    return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]);
+  }
+
+  bool serialize_strike_offsets (hb_subset_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
+    if (unlikely (!out)) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
+    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
+    for (int i = strikes.len - 1; i >= 0; --i)
+    {
+      auto* o = out->serialize_append (c->serializer);
+      if (unlikely (!o)) return_trace (false);
+      *o = 0;
+      auto snap = c->serializer->snapshot ();
+      c->serializer->push ();
+      bool ret = add_strike (c, i);
+      if (!ret)
+      {
+	c->serializer->pop_discard ();
+	out->pop ();
+	c->serializer->revert (snap);
+      }
+      else
+      {
+	objidxs.push (c->serializer->pop_pack ());
+	new_strikes.push (o);
+      }
+    }
+    for (unsigned int i = 0; i < new_strikes.length; ++i)
+      c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]);
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t* c) const
+  {
+    TRACE_SUBSET (this);
+
+    sbix *sbix_prime = c->serializer->start_embed<sbix> ();
+    if (unlikely (!sbix_prime)) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
+
+    return_trace (serialize_strike_offsets (c));
+  }
+
+  protected:
+  HBUINT16	version;	/* Table version number — set to 1 */
+  HBUINT16	flags;		/* Bit 0: Set to 1. Bit 1: Draw outlines.
+				 * Bits 2 to 15: reserved (set to 0). */
+  Array32OfOffset32To<SBIXStrike>
+		strikes;	/* Offsets from the beginning of the 'sbix'
+				 * table to data for each individual bitmap strike. */
+  public:
+  DEFINE_SIZE_ARRAY (8, strikes);
+};
+
+struct sbix_accelerator_t : sbix::accelerator_t {
+  sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
+};
+
+
+} /* namespace OT */
+
+#endif /* OT_COLOR_SBIX_SBIX_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/svg/svg.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/svg/svg.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Color/svg/svg.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef OT_COLOR_SVG_SVG_HH
+#define OT_COLOR_SVG_SVG_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-blob.hh"
+#include "../../../hb-paint.hh"
+
+/*
+ * SVG -- SVG (Scalable Vector Graphics)
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
+ */
+
+#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
+
+
+namespace OT {
+
+
+struct SVGDocumentIndexEntry
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
+
+  hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
+  {
+    return hb_blob_create_sub_blob (svg_blob,
+				    index_offset + (unsigned int) svgDoc,
+				    svgDocLength);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  svgDoc.sanitize (c, base, svgDocLength));
+  }
+
+  protected:
+  HBUINT16	startGlyphID;	/* The first glyph ID in the range described by
+				 * this index entry. */
+  HBUINT16	endGlyphID;	/* The last glyph ID in the range described by
+				 * this index entry. Must be >= startGlyphID. */
+  NNOffset32To<UnsizedArrayOf<HBUINT8>>
+		svgDoc;		/* Offset from the beginning of the SVG Document Index
+				 * to an SVG document. Must be non-zero. */
+  HBUINT32	svgDocLength;	/* Length of the SVG document.
+				 * Must be non-zero. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct SVG
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG;
+
+  bool has_data () const { return svgDocEntries; }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    { table = hb_sanitize_context_t ().reference_table<SVG> (face); }
+    ~accelerator_t () { table.destroy (); }
+
+    hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
+    {
+      return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (),
+							       table->svgDocEntries);
+    }
+
+    bool has_data () const { return table->has_data (); }
+
+    bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      if (!has_data ())
+        return false;
+
+      hb_blob_t *blob = reference_blob_for_glyph (glyph);
+
+      if (blob == hb_blob_get_empty ())
+        return false;
+
+      funcs->image (data,
+		    blob,
+		    0, 0,
+		    HB_PAINT_IMAGE_FORMAT_SVG,
+		    font->slant_xy,
+		    nullptr);
+
+      hb_blob_destroy (blob);
+      return true;
+    }
+
+    private:
+    hb_blob_ptr_t<SVG> table;
+    public:
+    DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t<SVG>));
+  };
+
+  const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
+  { return (this+svgDocEntries).bsearch (glyph_id); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  (this+svgDocEntries).sanitize_shallow (c)));
+  }
+
+  protected:
+  HBUINT16	version;	/* Table version (starting at 0). */
+  Offset32To<SortedArray16Of<SVGDocumentIndexEntry>>
+		svgDocEntries;	/* Offset (relative to the start of the SVG table) to the
+				 * SVG Documents Index. Must be non-zero. */
+				/* Array of SVG Document Index Entries. */
+  HBUINT32	reserved;	/* Set to 0. */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+struct SVG_accelerator_t : SVG::accelerator_t {
+  SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_COLOR_SVG_SVG_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/Common/Coverage.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -147,6 +147,7 @@
     TRACE_SUBSET (this);
     auto it =
     + iter ()
+    | hb_take (c->plan->source->get_num_glyphs ())
     | hb_filter (c->plan->glyph_map_gsub)
     | hb_map_retains_sorting (c->plan->glyph_map_gsub)
     ;

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GDEF/GDEF.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,918 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2011,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef OT_LAYOUT_GDEF_GDEF_HH
+#define OT_LAYOUT_GDEF_GDEF_HH
+
+#include "../../../hb-ot-layout-common.hh"
+
+#include "../../../hb-font.hh"
+
+
+namespace OT {
+
+
+/*
+ * Attachment List Table
+ */
+
+/* Array of contour point indices--in increasing numerical order */
+struct AttachPoint : Array16Of<HBUINT16>
+{
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->serialize (c->serializer, + iter ()));
+  }
+};
+
+struct AttachList
+{
+  unsigned int get_attach_points (hb_codepoint_t glyph_id,
+				  unsigned int start_offset,
+				  unsigned int *point_count /* IN/OUT */,
+				  unsigned int *point_array /* OUT */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (index == NOT_COVERED)
+    {
+      if (point_count)
+	*point_count = 0;
+      return 0;
+    }
+
+    const AttachPoint &points = this+attachPoint[index];
+
+    if (point_count)
+    {
+      + points.as_array ().sub_array (start_offset, point_count)
+      | hb_sink (hb_array (point_array, *point_count))
+      ;
+    }
+
+    return points.len;
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, attachPoint)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
+  }
+
+  protected:
+  Offset16To<Coverage>
+		coverage;		/* Offset to Coverage table -- from
+					 * beginning of AttachList table */
+  Array16OfOffset16To<AttachPoint>
+		attachPoint;		/* Array of AttachPoint tables
+					 * in Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (4, attachPoint);
+};
+
+/*
+ * Ligature Caret Table
+ */
+
+struct CaretValueFormat1
+{
+  friend struct CaretValue;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
+
+  private:
+  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16	caretValueFormat;	/* Format identifier--format = 1 */
+  FWORD		coordinate;		/* X or Y value, in design units */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat2
+{
+  friend struct CaretValue;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
+
+  private:
+  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  {
+    hb_position_t x, y;
+    font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16	caretValueFormat;	/* Format identifier--format = 2 */
+  HBUINT16	caretValuePoint;	/* Contour point index on glyph */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat3
+{
+  friend struct CaretValue;
+
+  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction,
+				 const VariationStore &var_store) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ?
+	   font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
+	   font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    if (!c->serializer->embed (caretValueFormat)) return_trace (false);
+    if (!c->serializer->embed (coordinate)) return_trace (false);
+
+    unsigned varidx = (this+deviceTable).get_variation_index ();
+    if (c->plan->layout_variation_idx_delta_map.has (varidx))
+    {
+      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
+      if (delta != 0)
+      {
+        if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+          return_trace (false);
+      }
+    }
+
+    if (c->plan->all_axes_pinned)
+      return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+
+    if (!c->serializer->embed (deviceTable))
+      return_trace (false);
+
+    return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out),
+						   hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  { (this+deviceTable).collect_variation_indices (c); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+  }
+
+  protected:
+  HBUINT16	caretValueFormat;	/* Format identifier--format = 3 */
+  FWORD		coordinate;		/* X or Y value, in design units */
+  Offset16To<Device>
+		deviceTable;		/* Offset to Device table for X or Y
+					 * value--from beginning of CaretValue
+					 * table */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct CaretValue
+{
+  hb_position_t get_caret_value (hb_font_t *font,
+				 hb_direction_t direction,
+				 hb_codepoint_t glyph_id,
+				 const VariationStore &var_store) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_caret_value (font, direction);
+    case 2: return u.format2.get_caret_value (font, direction, glyph_id);
+    case 3: return u.format3.get_caret_value (font, direction, var_store);
+    default:return 0;
+    }
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    switch (u.format) {
+    case 1:
+    case 2:
+      return;
+    case 3:
+      u.format3.collect_variation_indices (c);
+      return;
+    default: return;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    switch (u.format) {
+    case 1: return_trace (u.format1.sanitize (c));
+    case 2: return_trace (u.format2.sanitize (c));
+    case 3: return_trace (u.format3.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  HBUINT16		format;		/* Format identifier */
+  CaretValueFormat1	format1;
+  CaretValueFormat2	format2;
+  CaretValueFormat3	format3;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+struct LigGlyph
+{
+  unsigned get_lig_carets (hb_font_t            *font,
+			   hb_direction_t        direction,
+			   hb_codepoint_t        glyph_id,
+			   const VariationStore &var_store,
+			   unsigned              start_offset,
+			   unsigned             *caret_count /* IN/OUT */,
+			   hb_position_t        *caret_array /* OUT */) const
+  {
+    if (caret_count)
+    {
+      + carets.as_array ().sub_array (start_offset, caret_count)
+      | hb_map (hb_add (this))
+      | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
+      | hb_sink (hb_array (caret_array, *caret_count))
+      ;
+    }
+
+    return carets.len;
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    + hb_iter (carets)
+    | hb_apply (subset_offset_array (c, out->carets, this))
+    ;
+
+    return_trace (bool (out->carets));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    for (const Offset16To<CaretValue>& offset : carets.iter ())
+      (this+offset).collect_variation_indices (c);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (carets.sanitize (c, this));
+  }
+
+  protected:
+  Array16OfOffset16To<CaretValue>
+		carets;			/* Offset array of CaretValue tables
+					 * --from beginning of LigGlyph table
+					 * --in increasing coordinate order */
+  public:
+  DEFINE_SIZE_ARRAY (2, carets);
+};
+
+struct LigCaretList
+{
+  unsigned int get_lig_carets (hb_font_t *font,
+			       hb_direction_t direction,
+			       hb_codepoint_t glyph_id,
+			       const VariationStore &var_store,
+			       unsigned int start_offset,
+			       unsigned int *caret_count /* IN/OUT */,
+			       hb_position_t *caret_array /* OUT */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (index == NOT_COVERED)
+    {
+      if (caret_count)
+	*caret_count = 0;
+      return 0;
+    }
+    const LigGlyph &lig_glyph = this+ligGlyph[index];
+    return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, ligGlyph)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    + hb_zip (this+coverage, ligGlyph)
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); })
+    ;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
+  }
+
+  protected:
+  Offset16To<Coverage>
+		coverage;		/* Offset to Coverage table--from
+					 * beginning of LigCaretList table */
+  Array16OfOffset16To<LigGlyph>
+		ligGlyph;		/* Array of LigGlyph tables
+					 * in Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (4, ligGlyph);
+};
+
+
+struct MarkGlyphSetsFormat1
+{
+  bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    bool ret = true;
+    for (const Offset32To<Coverage>& offset : coverage.iter ())
+    {
+      auto *o = out->coverage.serialize_append (c->serializer);
+      if (unlikely (!o))
+      {
+	ret = false;
+	break;
+      }
+
+      //not using o->serialize_subset (c, offset, this, out) here because
+      //OTS doesn't allow null offset.
+      //See issue: https://github.com/khaledhosny/ots/issues/172
+      c->serializer->push ();
+      c->dispatch (this+offset);
+      c->serializer->add_link (*o, c->serializer->pop_pack ());
+    }
+
+    return_trace (ret && out->coverage.len);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this));
+  }
+
+  protected:
+  HBUINT16	format;			/* Format identifier--format = 1 */
+  Array16Of<Offset32To<Coverage>>
+		coverage;		/* Array of long offsets to mark set
+					 * coverage tables */
+  public:
+  DEFINE_SIZE_ARRAY (4, coverage);
+};
+
+struct MarkGlyphSets
+{
+  bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.covers (set_index, glyph_id);
+    default:return false;
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    switch (u.format) {
+    case 1: return_trace (u.format1.subset (c));
+    default:return_trace (false);
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    switch (u.format) {
+    case 1: return_trace (u.format1.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  HBUINT16		format;		/* Format identifier */
+  MarkGlyphSetsFormat1	format1;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * GDEF -- Glyph Definition
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
+ */
+
+
+template <typename Types>
+struct GDEFVersion1_2
+{
+  friend struct GDEF;
+
+  protected:
+  FixedVersion<>version;		/* Version of the GDEF table--currently
+					 * 0x00010003u */
+  typename Types::template OffsetTo<ClassDef>
+		glyphClassDef;		/* Offset to class definition table
+					 * for glyph type--from beginning of
+					 * GDEF header (may be Null) */
+  typename Types::template OffsetTo<AttachList>
+		attachList;		/* Offset to list of glyphs with
+					 * attachment points--from beginning
+					 * of GDEF header (may be Null) */
+  typename Types::template OffsetTo<LigCaretList>
+		ligCaretList;		/* Offset to list of positioning points
+					 * for ligature carets--from beginning
+					 * of GDEF header (may be Null) */
+  typename Types::template OffsetTo<ClassDef>
+		markAttachClassDef;	/* Offset to class definition table for
+					 * mark attachment type--from beginning
+					 * of GDEF header (may be Null) */
+  typename Types::template OffsetTo<MarkGlyphSets>
+		markGlyphSetsDef;	/* Offset to the table of mark set
+					 * definitions--from beginning of GDEF
+					 * header (may be NULL).  Introduced
+					 * in version 0x00010002. */
+  Offset32To<VariationStore>
+		varStore;		/* Offset to the table of Item Variation
+					 * Store--from beginning of GDEF
+					 * header (may be NULL).  Introduced
+					 * in version 0x00010003. */
+  public:
+  DEFINE_SIZE_MIN (4 + 4 * Types::size);
+
+  unsigned int get_size () const
+  {
+    return min_size +
+	   (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) +
+	   (version.to_int () >= 0x00010003u ? varStore.static_size : 0);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (version.sanitize (c) &&
+		  glyphClassDef.sanitize (c, this) &&
+		  attachList.sanitize (c, this) &&
+		  ligCaretList.sanitize (c, this) &&
+		  markAttachClassDef.sanitize (c, this) &&
+		  (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
+		  (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
+    bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
+    bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
+    bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
+
+    bool subset_markglyphsetsdef = false;
+    if (version.to_int () >= 0x00010002u)
+    {
+      subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
+    }
+
+    bool subset_varstore = false;
+    if (version.to_int () >= 0x00010003u)
+    {
+      if (c->plan->all_axes_pinned)
+        out->varStore = 0;
+      else
+        subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
+    }
+
+    if (subset_varstore)
+    {
+      out->version.minor = 3;
+    } else if (subset_markglyphsetsdef) {
+      out->version.minor = 2;
+    } else  {
+      out->version.minor = 0;
+    }
+
+    return_trace (subset_glyphclassdef || subset_attachlist ||
+		  subset_ligcaretlist || subset_markattachclassdef ||
+		  (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
+		  (out->version.to_int () >= 0x00010003u && subset_varstore));
+  }
+};
+
+struct GDEF
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF;
+
+  enum GlyphClasses {
+    UnclassifiedGlyph	= 0,
+    BaseGlyph		= 1,
+    LigatureGlyph	= 2,
+    MarkGlyph		= 3,
+    ComponentGlyph	= 4
+  };
+
+  unsigned int get_size () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.get_size ();
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.get_size ();
+#endif
+    default: return u.version.static_size;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!u.version.sanitize (c))) return_trace (false);
+    switch (u.version.major) {
+    case 1: return_trace (u.version1.sanitize (c));
+#ifndef HB_NO_BEYOND_64K
+    case 2: return_trace (u.version2.sanitize (c));
+#endif
+    default: return_trace (true);
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.subset (c);
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.subset (c);
+#endif
+    default: return false;
+    }
+  }
+
+  bool has_glyph_classes () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.glyphClassDef != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.glyphClassDef != 0;
+#endif
+    default: return false;
+    }
+  }
+  const ClassDef &get_glyph_class_def () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.glyphClassDef;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.glyphClassDef;
+#endif
+    default: return Null(ClassDef);
+    }
+  }
+  bool has_attach_list () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.attachList != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.attachList != 0;
+#endif
+    default: return false;
+    }
+  }
+  const AttachList &get_attach_list () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.attachList;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.attachList;
+#endif
+    default: return Null(AttachList);
+    }
+  }
+  bool has_lig_carets () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.ligCaretList != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.ligCaretList != 0;
+#endif
+    default: return false;
+    }
+  }
+  const LigCaretList &get_lig_caret_list () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.ligCaretList;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.ligCaretList;
+#endif
+    default: return Null(LigCaretList);
+    }
+  }
+  bool has_mark_attachment_types () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.markAttachClassDef != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.markAttachClassDef != 0;
+#endif
+    default: return false;
+    }
+  }
+  const ClassDef &get_mark_attach_class_def () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.markAttachClassDef;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.markAttachClassDef;
+#endif
+    default: return Null(ClassDef);
+    }
+  }
+  bool has_mark_glyph_sets () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.markGlyphSetsDef != 0;
+#endif
+    default: return false;
+    }
+  }
+  const MarkGlyphSets &get_mark_glyph_sets () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets);
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.markGlyphSetsDef;
+#endif
+    default: return Null(MarkGlyphSets);
+    }
+  }
+  bool has_var_store () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.varStore != 0;
+#endif
+    default: return false;
+    }
+  }
+  const VariationStore &get_var_store () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore);
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.varStore;
+#endif
+    default: return Null(VariationStore);
+    }
+  }
+
+
+  bool has_data () const { return u.version.to_int (); }
+  unsigned int get_glyph_class (hb_codepoint_t glyph) const
+  { return get_glyph_class_def ().get_class (glyph); }
+  void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
+  { get_glyph_class_def ().collect_class (glyphs, klass); }
+
+  unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
+  { return get_mark_attach_class_def ().get_class (glyph); }
+
+  unsigned int get_attach_points (hb_codepoint_t glyph_id,
+				  unsigned int start_offset,
+				  unsigned int *point_count /* IN/OUT */,
+				  unsigned int *point_array /* OUT */) const
+  { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); }
+
+  unsigned int get_lig_carets (hb_font_t *font,
+			       hb_direction_t direction,
+			       hb_codepoint_t glyph_id,
+			       unsigned int start_offset,
+			       unsigned int *caret_count /* IN/OUT */,
+			       hb_position_t *caret_array /* OUT */) const
+  { return get_lig_caret_list ().get_lig_carets (font,
+						 direction, glyph_id, get_var_store(),
+						 start_offset, caret_count, caret_array); }
+
+  bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  { return get_mark_glyph_sets ().covers (set_index, glyph_id); }
+
+  /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
+   * glyph class and other bits, and high 8-bit the mark attachment type (if any).
+   * Not to be confused with lookup_props which is very similar. */
+  unsigned int get_glyph_props (hb_codepoint_t glyph) const
+  {
+    unsigned int klass = get_glyph_class (glyph);
+
+    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), "");
+    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), "");
+    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
+
+    switch (klass) {
+    default:			return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
+    case BaseGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+    case LigatureGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+    case MarkGlyph:
+	  klass = get_mark_attachment_type (glyph);
+	  return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
+    }
+  }
+
+  HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
+				   hb_face_t *face) const;
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      table = hb_sanitize_context_t ().reference_table<GDEF> (face);
+      if (unlikely (table->is_blocklisted (table.get_blob (), face)))
+      {
+	hb_blob_destroy (table.get_blob ());
+	table = hb_blob_get_empty ();
+      }
+    }
+    ~accelerator_t () { table.destroy (); }
+
+    hb_blob_ptr_t<GDEF> table;
+  };
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  { get_lig_caret_list ().collect_variation_indices (c); }
+
+  void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
+				       hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
+  {
+    if (!has_var_store ()) return;
+    if (layout_variation_indices->is_empty ()) return;
+
+    unsigned new_major = 0, new_minor = 0;
+    unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
+    for (unsigned idx : layout_variation_indices->iter ())
+    {
+      uint16_t major = idx >> 16;
+      if (major >= get_var_store ().get_sub_table_count ()) break;
+      if (major != last_major)
+      {
+	new_minor = 0;
+	++new_major;
+      }
+
+      unsigned new_idx = (new_major << 16) + new_minor;
+      if (!layout_variation_idx_delta_map->has (idx))
+        continue;
+      int delta = hb_second (layout_variation_idx_delta_map->get (idx));
+
+      layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
+      ++new_minor;
+      last_major = major;
+    }
+  }
+
+  protected:
+  union {
+  FixedVersion<>		version;	/* Version identifier */
+  GDEFVersion1_2<SmallTypes>	version1;
+#ifndef HB_NO_BEYOND_64K
+  GDEFVersion1_2<MediumTypes>	version2;
+#endif
+  } u;
+  public:
+  DEFINE_SIZE_MIN (4);
+};
+
+struct GDEF_accelerator_t : GDEF::accelerator_t {
+  GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_LAYOUT_GDEF_GDEF_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/AnchorFormat3.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -51,9 +51,9 @@
     if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
 
     unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map->has (x_varidx))
+    if (c->plan->layout_variation_idx_delta_map.has (x_varidx))
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map->get (x_varidx));
+      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx));
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
@@ -63,9 +63,9 @@
     }
 
     unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map->has (y_varidx))
+    if (c->plan->layout_variation_idx_delta_map.has (y_varidx))
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map->get (y_varidx));
+      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx));
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
@@ -80,8 +80,8 @@
     if (!c->serializer->embed (xDeviceTable)) return_trace (false);
     if (!c->serializer->embed (yDeviceTable)) return_trace (false);
 
-    out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, c->plan->layout_variation_idx_delta_map);
-    out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, c->plan->layout_variation_idx_delta_map);
+    out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
+    out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
     return_trace (out);
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -19,8 +19,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/CursivePosFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -143,7 +143,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "cursive attaching glyph at %d to glyph at %d",
+			  "cursive attaching glyph at %u to glyph at %u",
 			  i, j);
     }
 
@@ -241,7 +241,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "cursive attached glyph at %d to glyph at %d",
+			  "cursive attached glyph at %u to glyph at %u",
 			  i, j);
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkArray.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -42,7 +42,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "attaching mark glyph at %d to glyph at %d",
+			  "attaching mark glyph at %u to glyph at %u",
 			  c->buffer->idx, glyph_pos);
     }
 
@@ -56,7 +56,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "attached mark glyph at %d to glyph at %d",
+			  "attached mark glyph at %u to glyph at %u",
 			  c->buffer->idx, glyph_pos);
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -22,8 +22,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
 #ifndef HB_NO_BEYOND_64K

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkBasePosFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -90,6 +90,25 @@
 
   const Coverage &get_coverage () const { return this+markCoverage; }
 
+  static inline bool accept (hb_buffer_t *buffer, unsigned idx)
+  {
+    /* We only want to attach to the first of a MultipleSubst sequence.
+     * https://github.com/harfbuzz/harfbuzz/issues/740
+     * Reject others...
+     * ...but stop if we find a mark in the MultipleSubst sequence:
+     * https://github.com/harfbuzz/harfbuzz/issues/1020 */
+    return !_hb_glyph_info_multiplied (&buffer->info[idx]) ||
+	   0 == _hb_glyph_info_get_lig_comp (&buffer->info[idx]) ||
+	   (idx == 0 ||
+	    _hb_glyph_info_is_mark (&buffer->info[idx - 1]) ||
+	    !_hb_glyph_info_multiplied (&buffer->info[idx - 1]) ||
+	    _hb_glyph_info_get_lig_id (&buffer->info[idx]) !=
+	    _hb_glyph_info_get_lig_id (&buffer->info[idx - 1]) ||
+	    _hb_glyph_info_get_lig_comp (&buffer->info[idx]) !=
+	    _hb_glyph_info_get_lig_comp (&buffer->info[idx - 1]) + 1
+	    );
+  }
+
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
@@ -97,48 +116,52 @@
     unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
     if (likely (mark_index == NOT_COVERED)) return_trace (false);
 
-    /* Now we search backwards for a non-mark glyph */
+    /* Now we search backwards for a non-mark glyph.
+     * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */
+
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
-    do {
-      unsigned unsafe_from;
-      if (!skippy_iter.prev (&unsafe_from))
+
+    if (c->last_base_until > buffer->idx)
+    {
+      c->last_base_until = 0;
+      c->last_base = -1;
+    }
+    unsigned j;
+    for (j = buffer->idx; j > c->last_base_until; j--)
+    {
+      auto match = skippy_iter.match (buffer->info[j - 1]);
+      if (match == skippy_iter.MATCH)
       {
-        buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
-        return_trace (false);
+	if (!accept (buffer, j - 1))
+	  match = skippy_iter.SKIP;
       }
+      if (match == skippy_iter.MATCH)
+      {
+	c->last_base = (signed) j - 1;
+	break;
+      }
+    }
+    c->last_base_until = buffer->idx;
+    if (c->last_base == -1)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
+      return_trace (false);
+    }
 
-      /* We only want to attach to the first of a MultipleSubst sequence.
-       * https://github.com/harfbuzz/harfbuzz/issues/740
-       * Reject others...
-       * ...but stop if we find a mark in the MultipleSubst sequence:
-       * https://github.com/harfbuzz/harfbuzz/issues/1020 */
-      if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
-          0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
-          (skippy_iter.idx == 0 ||
-           _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) ||
-           !_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx - 1]) ||
-           _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
-           _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
-           _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
-           _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1
-           ))
-        break;
-      skippy_iter.reject ();
-    } while (true);
+    unsigned idx = (unsigned) c->last_base;
 
     /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
-    //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+    //if (!_hb_glyph_info_is_base_glyph (&buffer->info[idx])) { return_trace (false); }
 
-    unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint);
+    unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[idx].codepoint);
     if (base_index == NOT_COVERED)
     {
-      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
       return_trace (false);
     }
 
-    return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
+    return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, idx));
   }
 
   bool subset (hb_subset_context_t *c) const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -22,8 +22,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
 #ifndef HB_NO_BEYOND_64K

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -100,20 +100,37 @@
     if (likely (mark_index == NOT_COVERED)) return_trace (false);
 
     /* Now we search backwards for a non-mark glyph */
+
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
-    unsigned unsafe_from;
-    if (!skippy_iter.prev (&unsafe_from))
+
+    if (c->last_base_until > buffer->idx)
     {
-      buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+      c->last_base_until = 0;
+      c->last_base = -1;
+    }
+    unsigned j;
+    for (j = buffer->idx; j > c->last_base_until; j--)
+    {
+      auto match = skippy_iter.match (buffer->info[j - 1]);
+      if (match == skippy_iter.MATCH)
+      {
+	c->last_base = (signed) j - 1;
+	break;
+      }
+    }
+    c->last_base_until = buffer->idx;
+    if (c->last_base == -1)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
       return_trace (false);
     }
 
+    j = (unsigned) c->last_base;
+
     /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
-    //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+    //if (!_hb_glyph_info_is_ligature (&buffer->info[j])) { return_trace (false); }
 
-    unsigned int j = skippy_iter.idx;
     unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[j].codepoint);
     if (lig_index == NOT_COVERED)
     {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/MarkMarkPos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -22,8 +22,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
 #ifndef HB_NO_BEYOND_64K

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -25,8 +25,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -43,7 +43,7 @@
     {
       valueFormat,
       len1,
-      1 + len1 + len2
+      PairSet::get_size (len1, len2)
     };
 
     return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
@@ -177,9 +177,7 @@
 
   hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
   {
-    unsigned len1 = valueFormat[0].get_len ();
-    unsigned len2 = valueFormat[1].get_len ();
-    unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+    unsigned record_size = PairSet::get_size (valueFormat);
 
     unsigned format1 = 0;
     unsigned format2 = 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairPosFormat2.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -49,7 +49,7 @@
 
     unsigned int len1 = valueFormat1.get_len ();
     unsigned int len2 = valueFormat2.get_len ();
-    unsigned int stride = len1 + len2;
+    unsigned int stride = HBUINT16::static_size * (len1 + len2);
     unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
     unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
     return_trace (c->check_range ((const void *) values,
@@ -220,7 +220,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "try kerning glyphs at %d,%d",
+			  "try kerning glyphs at %u,%u",
 			  c->buffer->idx, skippy_iter.idx);
     }
 
@@ -231,7 +231,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "kerned glyphs at %d,%d",
+			    "kerned glyphs at %u,%u",
 			    c->buffer->idx, skippy_iter.idx);
       }
 
@@ -238,7 +238,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "tried kerning glyphs at %d,%d",
+			  "tried kerning glyphs at %u,%u",
 			  c->buffer->idx, skippy_iter.idx);
     }
 
@@ -298,8 +298,8 @@
       for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
       {
         unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
-        valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], c->plan->layout_variation_idx_delta_map);
-        valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], c->plan->layout_variation_idx_delta_map);
+        valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], &c->plan->layout_variation_idx_delta_map);
+        valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], &c->plan->layout_variation_idx_delta_map);
       }
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/PairSet.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -24,11 +24,22 @@
   public:
   DEFINE_SIZE_MIN (2);
 
+  static unsigned get_size (unsigned len1, unsigned len2)
+  {
+    return Types::HBGlyphID::static_size + Value::static_size * (len1 + len2);
+  }
+  static unsigned get_size (const ValueFormat valueFormats[2])
+  {
+    unsigned len1 = valueFormats[0].get_len ();
+    unsigned len2 = valueFormats[1].get_len ();
+    return get_size (len1, len2);
+  }
+
   struct sanitize_closure_t
   {
     const ValueFormat *valueFormats;
     unsigned int len1; /* valueFormats[0].get_len() */
-    unsigned int stride; /* 1 + len1 + len2 */
+    unsigned int stride; /* bytes */
   };
 
   bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
@@ -37,7 +48,6 @@
     if (!(c->check_struct (this)
        && c->check_range (&firstPairValueRecord,
                           len,
-                          HBUINT16::static_size,
                           closure->stride))) return_trace (false);
 
     unsigned int count = len;
@@ -49,9 +59,7 @@
   bool intersects (const hb_set_t *glyphs,
                    const ValueFormat *valueFormats) const
   {
-    unsigned int len1 = valueFormats[0].get_len ();
-    unsigned int len2 = valueFormats[1].get_len ();
-    unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+    unsigned record_size = get_size (valueFormats);
 
     const PairValueRecord *record = &firstPairValueRecord;
     unsigned int count = len;
@@ -67,9 +75,7 @@
   void collect_glyphs (hb_collect_glyphs_context_t *c,
                        const ValueFormat *valueFormats) const
   {
-    unsigned int len1 = valueFormats[0].get_len ();
-    unsigned int len2 = valueFormats[1].get_len ();
-    unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+    unsigned record_size = get_size (valueFormats);
 
     const PairValueRecord *record = &firstPairValueRecord;
     c->input->add_array (&record->secondGlyph, len, record_size);
@@ -78,9 +84,7 @@
   void collect_variation_indices (hb_collect_variation_indices_context_t *c,
                                   const ValueFormat *valueFormats) const
   {
-    unsigned len1 = valueFormats[0].get_len ();
-    unsigned len2 = valueFormats[1].get_len ();
-    unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
+    unsigned record_size = get_size (valueFormats);
 
     const PairValueRecord *record = &firstPairValueRecord;
     unsigned count = len;
@@ -101,7 +105,7 @@
     hb_buffer_t *buffer = c->buffer;
     unsigned int len1 = valueFormats[0].get_len ();
     unsigned int len2 = valueFormats[1].get_len ();
-    unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+    unsigned record_size = get_size (len1, len2);
 
     const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
                                                 &firstPairValueRecord,
@@ -112,7 +116,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "try kerning glyphs at %d,%d",
+			    "try kerning glyphs at %u,%u",
 			    c->buffer->idx, pos);
       }
 
@@ -123,7 +127,7 @@
 	if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
 	{
 	  c->buffer->message (c->font,
-			      "kerned glyphs at %d,%d",
+			      "kerned glyphs at %u,%u",
 			      c->buffer->idx, pos);
 	}
 
@@ -130,7 +134,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "tried kerning glyphs at %d,%d",
+			    "tried kerning glyphs at %u,%u",
 			    c->buffer->idx, pos);
       }
 
@@ -168,7 +172,7 @@
 
     unsigned len1 = valueFormats[0].get_len ();
     unsigned len2 = valueFormats[1].get_len ();
-    unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+    unsigned record_size = get_size (len1, len2);
 
     typename PairValueRecord::context_t context =
     {
@@ -177,7 +181,7 @@
       newFormats,
       len1,
       &glyph_map,
-      c->plan->layout_variation_idx_delta_map
+      &c->plan->layout_variation_idx_delta_map
     };
 
     const PairValueRecord *record = &firstPairValueRecord;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -72,8 +72,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -63,7 +63,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "positioning glyph at %d",
+			  "positioning glyph at %u",
 			  c->buffer->idx);
     }
 
@@ -72,7 +72,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "positioned glyph at %d",
+			  "positioned glyph at %u",
 			  c->buffer->idx);
     }
 
@@ -144,7 +144,7 @@
     ;
 
     bool ret = bool (it);
-    SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
+    SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
     return_trace (ret);
   }
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/SinglePosFormat2.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -73,7 +73,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "positioning glyph at %d",
+			  "positioning glyph at %u",
 			  c->buffer->idx);
     }
 
@@ -84,7 +84,7 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "positioned glyph at %d",
+			  "positioned glyph at %u",
 			  c->buffer->idx);
     }
 
@@ -163,7 +163,7 @@
     ;
 
     bool ret = bool (it);
-    SinglePos_serialize (c->serializer, this, it, c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
+    SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
     return_trace (ret);
   }
 };

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GPOS/ValueFormat.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -371,7 +371,7 @@
     for (unsigned int i = 0; i < count; i++) {
       if (!sanitize_value_devices (c, base, values))
         return_trace (false);
-      values += stride;
+      values = &StructAtOffset<const Value> (values, stride);
     }
 
     return_trace (true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSet.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -61,7 +61,7 @@
     {
       c->buffer->sync_so_far ();
       c->buffer->message (c->font,
-			  "replacing glyph at %d (alternate substitution)",
+			  "replacing glyph at %u (alternate substitution)",
 			  c->buffer->idx);
     }
 
@@ -70,8 +70,8 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "replaced glyph at %d (alternate substitution)",
-			  c->buffer->idx - 1);
+			  "replaced glyph at %u (alternate substitution)",
+			  c->buffer->idx - 1u);
     }
 
     return_trace (true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/AlternateSubst.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -23,8 +23,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
 #ifndef HB_NO_BEYOND_64K

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Ligature.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -69,7 +69,7 @@
       {
 	c->buffer->sync_so_far ();
 	c->buffer->message (c->font,
-			    "replacing glyph at %d (ligature substitution)",
+			    "replacing glyph at %u (ligature substitution)",
 			    c->buffer->idx);
       }
 
@@ -78,8 +78,8 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "replaced glyph at %d (ligature substitution)",
-			    c->buffer->idx - 1);
+			    "replaced glyph at %u (ligature substitution)",
+			    c->buffer->idx - 1u);
       }
 
       return_trace (true);
@@ -138,7 +138,7 @@
     {
       c->buffer->sync_so_far ();
       c->buffer->message (c->font,
-			  "ligated glyph at %d",
+			  "ligated glyph at %u",
 			  pos);
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/LigatureSubst.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -23,8 +23,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
 #ifndef HB_NO_BEYOND_64K

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/MultipleSubst.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -24,8 +24,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
 #ifndef HB_NO_BEYOND_64K

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -20,8 +20,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -135,7 +135,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "replacing glyph at %d (reverse chaining substitution)",
+			    "replacing glyph at %u (reverse chaining substitution)",
 			    c->buffer->idx);
       }
 
@@ -144,7 +144,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "replaced glyph at %d (reverse chaining substitution)",
+			    "replaced glyph at %u (reverse chaining substitution)",
 			    c->buffer->idx);
       }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/Sequence.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -44,7 +44,7 @@
       {
 	c->buffer->sync_so_far ();
 	c->buffer->message (c->font,
-			    "replacing glyph at %d (multiple substitution)",
+			    "replacing glyph at %u (multiple substitution)",
 			    c->buffer->idx);
       }
 
@@ -53,8 +53,8 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
 	c->buffer->message (c->font,
-			    "replaced glyph at %d (multiple subtitution)",
-			    c->buffer->idx - 1);
+			    "replaced glyph at %u (multiple subtitution)",
+			    c->buffer->idx - 1u);
       }
 
       return_trace (true);
@@ -67,7 +67,7 @@
       {
 	c->buffer->sync_so_far ();
 	c->buffer->message (c->font,
-			    "deleting glyph at %d (multiple substitution)",
+			    "deleting glyph at %u (multiple substitution)",
 			    c->buffer->idx);
       }
 
@@ -77,7 +77,7 @@
       {
 	c->buffer->sync_so_far ();
 	c->buffer->message (c->font,
-			    "deleted glyph at %d (multiple substitution)",
+			    "deleted glyph at %u (multiple substitution)",
 			    c->buffer->idx);
       }
 
@@ -88,7 +88,7 @@
     {
       c->buffer->sync_so_far ();
       c->buffer->message (c->font,
-			  "multiplying glyph at %d",
+			  "multiplying glyph at %u",
 			  c->buffer->idx);
     }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubst.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -27,8 +27,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat1.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -103,7 +103,7 @@
     {
       c->buffer->sync_so_far ();
       c->buffer->message (c->font,
-			  "replacing glyph at %d (single substitution)",
+			  "replacing glyph at %u (single substitution)",
 			  c->buffer->idx);
     }
 
@@ -112,8 +112,8 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "replaced glyph at %d (single substitution)",
-			  c->buffer->idx - 1);
+			  "replaced glyph at %u (single substitution)",
+			  c->buffer->idx - 1u);
     }
 
     return_trace (true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/Layout/GSUB/SingleSubstFormat2.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -87,7 +87,7 @@
     {
       c->buffer->sync_so_far ();
       c->buffer->message (c->font,
-			  "replacing glyph at %d (single substitution)",
+			  "replacing glyph at %u (single substitution)",
 			  c->buffer->idx);
     }
 
@@ -96,8 +96,8 @@
     if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
     {
       c->buffer->message (c->font,
-			  "replaced glyph at %d (single substitution)",
-			  c->buffer->idx - 1);
+			  "replaced glyph at %u (single substitution)",
+			  c->buffer->idx - 1u);
     }
 
     return_trace (true);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/Glyph.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -18,11 +18,6 @@
 namespace glyf_impl {
 
 
-#ifndef HB_GLYF_MAX_POINTS
-#define HB_GLYF_MAX_POINTS 10000
-#endif
-
-
 enum phantom_point_index_t
 {
   PHANTOM_LEFT   = 0,
@@ -85,7 +80,8 @@
   }
 
   void update_mtx (const hb_subset_plan_t *plan,
-                   int xMin, int yMax,
+                   int xMin, int xMax,
+                   int yMin, int yMax,
                    const contour_point_vector_t &all_points) const
   {
     hb_codepoint_t new_gid = 0;
@@ -92,6 +88,12 @@
     if (!plan->new_gid_for_old_gid (gid, &new_gid))
       return;
 
+    if (type != EMPTY)
+    {
+      plan->bounds_width_map.set (new_gid, xMax - xMin);
+      plan->bounds_height_map.set (new_gid, yMax - yMin);
+    }
+
     unsigned len = all_points.length;
     float leftSideX = all_points[len - 4].x;
     float rightSideX = all_points[len - 3].x;
@@ -98,15 +100,18 @@
     float topSideY = all_points[len - 2].y;
     float bottomSideY = all_points[len - 1].y;
 
-    int hori_aw = roundf (rightSideX - leftSideX);
+    signed hori_aw = roundf (rightSideX - leftSideX);
     if (hori_aw < 0) hori_aw = 0;
     int lsb = roundf (xMin - leftSideX);
-    plan->hmtx_map->set (new_gid, hb_pair (hori_aw, lsb));
+    plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
+    //flag value should be computed using non-empty glyphs
+    if (type != EMPTY && lsb != xMin)
+      plan->head_maxp_info.allXMinIsLsb = false;
 
-    int vert_aw = roundf (topSideY - bottomSideY);
+    signed vert_aw = roundf (topSideY - bottomSideY);
     if (vert_aw < 0) vert_aw = 0;
     int tsb = roundf (topSideY - yMax);
-    plan->vmtx_map->set (new_gid, hb_pair (vert_aw, tsb));
+    plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
   }
 
   bool compile_header_bytes (const hb_subset_plan_t *plan,
@@ -114,7 +119,7 @@
                              hb_bytes_t &dest_bytes /* OUT */) const
   {
     GlyphHeader *glyph_header = nullptr;
-    if (type != EMPTY && all_points.length > 4)
+    if (!plan->pinned_at_default && type != EMPTY && all_points.length >= 4)
     {
       glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
       if (unlikely (!glyph_header)) return false;
@@ -138,19 +143,34 @@
       yMax = hb_max (yMax, y);
     }
 
-    update_mtx (plan, roundf (xMin), roundf (yMax), all_points);
+    update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points);
+ 
+    int rounded_xMin = roundf (xMin);
+    int rounded_xMax = roundf (xMax);
+    int rounded_yMin = roundf (yMin);
+    int rounded_yMax = roundf (yMax);
 
-    /*for empty glyphs: all_points only include phantom points.
-     *just update metrics and then return */
+    if (type != EMPTY)
+    {
+      plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, rounded_xMin);
+      plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, rounded_yMin);
+      plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, rounded_xMax);
+      plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, rounded_yMax);
+    }
+
+    /* when pinned at default, no need to compile glyph header
+     * and for empty glyphs: all_points only include phantom points.
+     * just update metrics and then return */
     if (!glyph_header)
       return true;
 
     glyph_header->numberOfContours = header->numberOfContours;
-    glyph_header->xMin = roundf (xMin);
-    glyph_header->yMin = roundf (yMin);
-    glyph_header->xMax = roundf (xMax);
-    glyph_header->yMax = roundf (yMax);
 
+    glyph_header->xMin = rounded_xMin;
+    glyph_header->yMin = rounded_yMin;
+    glyph_header->xMax = rounded_xMax;
+    glyph_header->yMax = rounded_yMax;
+
     dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size);
     return true;
   }
@@ -162,7 +182,20 @@
                                   hb_bytes_t &dest_end /* OUT */)
   {
     contour_point_vector_t all_points, deltas;
-    if (!get_points (font, glyf, all_points, &deltas, false, false))
+    unsigned composite_contours = 0;
+    head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
+    unsigned *composite_contours_p = &composite_contours;
+
+    // don't compute head/maxp values when glyph has no contours(type is EMPTY)
+    // also ignore .notdef glyph when --notdef-outline is not enabled
+    if (type == EMPTY ||
+        (gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)))
+    {
+      head_maxp_info_p = nullptr;
+      composite_contours_p = nullptr;
+    }
+
+    if (!get_points (font, glyf, all_points, &deltas, head_maxp_info_p, composite_contours_p, false, false))
       return false;
 
     // .notdef, set type to empty so we only update metrics and don't compile bytes for
@@ -169,29 +202,36 @@
     // it
     if (gid == 0 &&
         !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+    {
       type = EMPTY;
-
-    switch (type) {
-    case COMPOSITE:
-      if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
-                                                                      deltas,
-                                                                      dest_end))
-        return false;
-      break;
-    case SIMPLE:
-      if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points,
-                                                                   plan->flags & HB_SUBSET_FLAGS_NO_HINTING,
-                                                                   dest_end))
-        return false;
-      break;
-    default:
-      /* set empty bytes for empty glyph
-       * do not use source glyph's pointers */
       dest_start = hb_bytes_t ();
       dest_end = hb_bytes_t ();
-      break;
     }
 
+    //dont compile bytes when pinned at default, just recalculate bounds
+    if (!plan->pinned_at_default) {
+      switch (type) {
+      case COMPOSITE:
+        if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
+                                                                        deltas,
+                                                                        dest_end))
+          return false;
+        break;
+      case SIMPLE:
+        if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points,
+                                                                     plan->flags & HB_SUBSET_FLAGS_NO_HINTING,
+                                                                     dest_end))
+          return false;
+        break;
+      default:
+        /* set empty bytes for empty glyph
+         * do not use source glyph's pointers */
+        dest_start = hb_bytes_t ();
+        dest_end = hb_bytes_t ();
+        break;
+      }
+    }
+
     if (!compile_header_bytes (plan, all_points, dest_start))
     {
       dest_end.fini ();
@@ -208,13 +248,25 @@
   bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
 		   contour_point_vector_t &all_points /* OUT */,
 		   contour_point_vector_t *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<int> coords = hb_array_t<int> (),
-		   unsigned int depth = 0) const
+		   unsigned int depth = 0,
+		   unsigned *edge_count = nullptr) 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_GLYF_MAX_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);
@@ -226,6 +278,10 @@
 
     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 (points, phantom_only)))
 	return false;
       break;
@@ -301,6 +357,8 @@
 
     switch (type) {
     case SIMPLE:
+      if (depth == 0 && head_maxp_info)
+        head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, points.length - 4);
       if (!inplace)
 	all_points.extend (points.as_array ());
       break;
@@ -311,17 +369,19 @@
       for (auto &item : get_composite_iterator ())
       {
         comp_points.reset ();
-
 	if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
 				       .get_points (font,
 						    glyf_accelerator,
 						    comp_points,
 						    deltas,
+						    head_maxp_info,
+						    composite_contours,
 						    shift_points_hori,
 						    use_my_metrics,
 						    phantom_only,
 						    coords,
-						    depth + 1)))
+						    depth + 1,
+						    edge_count)))
 	  return false;
 
 	/* Copy phantom points from component if USE_MY_METRICS flag set */
@@ -357,6 +417,13 @@
 	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);
     } break;
 #ifndef HB_NO_VAR_COMPOSITES
@@ -370,7 +437,11 @@
 
         comp_points.reset ();
 
-	coord_setter_t coord_setter (coords);
+	auto component_coords = coords;
+	if (item.is_reset_unspecified_axes ())
+	  component_coords = hb_array<int> ();
+
+	coord_setter_t coord_setter (component_coords);
 	item.set_variations (coord_setter, record_points);
 
 	if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
@@ -378,11 +449,14 @@
 						    glyf_accelerator,
 						    comp_points,
 						    deltas,
+						    head_maxp_info,
+						    nullptr,
 						    shift_points_hori,
 						    use_my_metrics,
 						    phantom_only,
 						    coord_setter.get_coords (),
-						    depth + 1)))
+						    depth + 1,
+						    edge_count)))
 	  return false;
 
 	/* Apply component transformation */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/GlyphHeader.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -21,11 +21,13 @@
     /* 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 = font->em_scale_x (lsb);
-    extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax));
-    extents->width     = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
-    extents->height    = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));
+    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;
   }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SimpleGlyph.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -20,7 +20,7 @@
     FLAG_X_SAME         = 0x10,
     FLAG_Y_SAME         = 0x20,
     FLAG_OVERLAP_SIMPLE = 0x40,
-    FLAG_RESERVED2      = 0x80
+    FLAG_CUBIC          = 0x80
   };
 
   const GlyphHeader &header;
@@ -184,7 +184,7 @@
     if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false;
     unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
 
-    points_.alloc (num_points + 4); // Allocate for phantom points, to avoid a possible copy
+    points_.alloc (num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
     if (!points_.resize (num_points)) return false;
     if (phantom_only) return true;
 
@@ -272,9 +272,9 @@
     unsigned num_points = all_points.length - 4;
 
     hb_vector_t<uint8_t> flags, x_coords, y_coords;
-    if (unlikely (!flags.alloc (num_points))) return false;
-    if (unlikely (!x_coords.alloc (2*num_points))) return false;
-    if (unlikely (!y_coords.alloc (2*num_points))) return false;
+    if (unlikely (!flags.alloc (num_points, true))) return false;
+    if (unlikely (!x_coords.alloc (2*num_points, true))) return false;
+    if (unlikely (!y_coords.alloc (2*num_points, true))) return false;
 
     uint8_t lastflag = 255, repeat = 0;
     int prev_x = 0, prev_y = 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/SubsetGlyph.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -21,22 +21,14 @@
 
   bool serialize (hb_serialize_context_t *c,
 		  bool use_short_loca,
-		  const hb_subset_plan_t *plan,
-		  hb_font_t *font)
+		  const hb_subset_plan_t *plan)
   {
     TRACE_SERIALIZE (this);
 
-    if (font)
-    {
-      const OT::glyf_accelerator_t &glyf = *font->face->table.glyf;
-      if (!this->compile_bytes_with_deltas (plan, font, glyf))
-        return_trace (false);
-    }
-
     hb_bytes_t dest_glyph = dest_start.copy (c);
     dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
     unsigned int pad_length = use_short_loca ? padding () : 0;
-    DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
+    DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
 
     HBUINT8 pad;
     pad = 0;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/VarCompositeGlyph.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -29,6 +29,7 @@
     HAVE_TCENTER_Y		= 0x0800,
     GID_IS_24			= 0x1000,
     AXES_HAVE_VARIATION		= 0x2000,
+    RESET_UNSPECIFIED_AXES	= 0x4000,
   };
 
   public:
@@ -60,6 +61,7 @@
   bool has_more () const { return true; }
 
   bool is_use_my_metrics () const { return flags & USE_MY_METRICS; }
+  bool is_reset_unspecified_axes () const { return flags & RESET_UNSPECIFIED_AXES; }
 
   hb_codepoint_t get_gid () const
   {
@@ -165,8 +167,8 @@
     float translateX = 0.f;
     float translateY = 0.f;
     float rotation = 0.f;
-    float scaleX = 1.f * (1 << 12);
-    float scaleY = 1.f * (1 << 12);
+    float scaleX = 1.f * (1 << 10);
+    float scaleY = 1.f * (1 << 10);
     float skewX = 0.f;
     float skewY = 0.f;
     float tCenterX = 0.f;
@@ -187,7 +189,7 @@
     if (flags & AXES_HAVE_VARIATION)
     {
       for (unsigned i = 0; i < count; i++)
-	rec_points[i].x = *q++;
+	rec_points[i].x = q++->to_int ();
       rec_points += count;
     }
     else
@@ -197,11 +199,11 @@
 
     if (flags & HAVE_TRANSLATE_X)	translateX = * (const FWORD *) p++;
     if (flags & HAVE_TRANSLATE_Y)	translateY = * (const FWORD *) p++;
-    if (flags & HAVE_ROTATION)		rotation = * (const F2DOT14 *) p++;
-    if (flags & HAVE_SCALE_X)		scaleX = * (const F4DOT12 *) p++;
-    if (flags & HAVE_SCALE_Y)		scaleY = * (const F4DOT12 *) p++;
-    if (flags & HAVE_SKEW_X)		skewX = * (const F2DOT14 *) p++;
-    if (flags & HAVE_SKEW_Y)		skewY = * (const F2DOT14 *) p++;
+    if (flags & HAVE_ROTATION)		rotation = ((const F4DOT12 *) p++)->to_int ();
+    if (flags & HAVE_SCALE_X)		scaleX = ((const F6DOT10 *) p++)->to_int ();
+    if (flags & HAVE_SCALE_Y)		scaleY = ((const F6DOT10 *) p++)->to_int ();
+    if (flags & HAVE_SKEW_X)		skewX = ((const F4DOT12 *) p++)->to_int ();
+    if (flags & HAVE_SKEW_Y)		skewY = ((const F4DOT12 *) p++)->to_int ();
     if (flags & HAVE_TCENTER_X)		tCenterX = * (const FWORD *) p++;
     if (flags & HAVE_TCENTER_Y)		tCenterY = * (const FWORD *) p++;
 
@@ -270,19 +272,19 @@
     }
     if (flags & HAVE_ROTATION)
     {
-      rotation = rec_points[0].x / (1 << 14);
+      rotation = rec_points[0].x / (1 << 12);
       rec_points++;
     }
     if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
     {
-      scaleX = rec_points[0].x / (1 << 12);
-      scaleY = rec_points[0].y / (1 << 12);
+      scaleX = rec_points[0].x / (1 << 10);
+      scaleY = rec_points[0].y / (1 << 10);
       rec_points++;
     }
     if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
     {
-      skewX = rec_points[0].x / (1 << 14);
-      skewY = rec_points[0].y / (1 << 14);
+      skewX = rec_points[0].x / (1 << 12);
+      skewY = rec_points[0].y / (1 << 12);
       rec_points++;
     }
     if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
@@ -316,9 +318,8 @@
     {
       unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
 
-      signed v = have_variations ? rec_points[i].x : *a++;
+      signed v = have_variations ? rec_points[i].x : a++->to_int ();
 
-      v += setter[axis_index];
       v = hb_clamp (v, -(1<<14), (1<<14));
       setter[axis_index] = v;
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf-helpers.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -25,7 +25,7 @@
   | hb_map ([=, &offset] (unsigned int padded_size)
 	    {
 	      offset += padded_size;
-	      DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
+	      DEBUG_MSG (SUBSET, nullptr, "loca entry offset %u", offset);
 	      return offset >> right_shift;
 	    })
   | hb_sink (dest)
@@ -44,6 +44,20 @@
 
   head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
   head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
+  if (plan->normalized_coords)
+  {
+    head_prime->xMin = plan->head_maxp_info.xMin;
+    head_prime->xMax = plan->head_maxp_info.xMax;
+    head_prime->yMin = plan->head_maxp_info.yMin;
+    head_prime->yMax = plan->head_maxp_info.yMax;
+
+    unsigned orig_flag = head_prime->flags;
+    if (plan->head_maxp_info.allXMinIsLsb)
+      orig_flag |= 1 << 1;
+    else
+      orig_flag &= ~(1 << 1);
+    head_prime->flags = orig_flag;
+  }
   bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
 
   hb_blob_destroy (head_prime_blob);
@@ -61,7 +75,7 @@
 
   if (unlikely (!loca_prime_data)) return false;
 
-  DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d",
+  DEBUG_MSG (SUBSET, nullptr, "loca entry_size %u num_offsets %u size %u",
 	     entry_size, num_offsets, entry_size * num_offsets);
 
   if (use_short_loca)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/glyf.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -7,6 +7,7 @@
 #include "../../hb-ot-hmtx-table.hh"
 #include "../../hb-ot-var-gvar-table.hh"
 #include "../../hb-draw.hh"
+#include "../../hb-paint.hh"
 
 #include "glyf-helpers.hh"
 #include "Glyph.hh"
@@ -42,14 +43,13 @@
   bool serialize (hb_serialize_context_t *c,
 		  Iterator it,
                   bool use_short_loca,
-		  const hb_subset_plan_t *plan,
-		  hb_font_t *font)
+		  const hb_subset_plan_t *plan)
   {
     TRACE_SERIALIZE (this);
 
     unsigned init_len = c->length ();
     for (auto &_ : it)
-      if (unlikely (!_.serialize (c, use_short_loca, plan, font)))
+      if (unlikely (!_.serialize (c, use_short_loca, plan)))
         return false;
 
     /* As a special case when all glyph in the font are empty, add a zero byte
@@ -75,59 +75,66 @@
     glyf *glyf_prime = c->serializer->start_embed <glyf> ();
     if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
 
-    hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
-    _populate_subset_glyphs (c->plan, glyphs);
-
     hb_font_t *font = nullptr;
-    if (!c->plan->pinned_at_default)
+    if (c->plan->normalized_coords)
     {
       font = _create_font_for_instancing (c->plan);
       if (unlikely (!font)) return false;
     }
 
-    auto padded_offsets =
-    + hb_iter (glyphs)
-    | hb_map (&glyf_impl::SubsetGlyph::padded_size)
-    ;
+    hb_vector_t<unsigned> padded_offsets;
+    unsigned num_glyphs = c->plan->num_output_glyphs ();
+    if (unlikely (!padded_offsets.resize (num_glyphs)))
+      return false;
 
+    hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
+    if (!_populate_subset_glyphs (c->plan, font, glyphs))
+      return false;
+
+    if (font)
+      hb_font_destroy (font);
+
+    unsigned max_offset = 0;
+    for (unsigned i = 0; i < num_glyphs; i++)
+    {
+      padded_offsets[i] = glyphs[i].padded_size ();
+      max_offset += padded_offsets[i];
+    }
+
     bool use_short_loca = false;
     if (likely (!c->plan->force_long_loca))
-    {
-      unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
       use_short_loca = max_offset < 0x1FFFF;
-    }
 
-    glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan, font);
     if (!use_short_loca) {
-      padded_offsets =
-          + hb_iter (glyphs)
-          | hb_map (&glyf_impl::SubsetGlyph::length)
-          ;
+      for (unsigned i = 0; i < num_glyphs; i++)
+        padded_offsets[i] = glyphs[i].length ();
     }
 
-    if (font)
-    {
-      _free_compiled_subset_glyphs (&glyphs);
-      hb_font_destroy (font);
-    }
+    bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan);
+    if (c->plan->normalized_coords && !c->plan->pinned_at_default)
+      _free_compiled_subset_glyphs (glyphs, glyphs.length - 1);
 
+    if (!result) return false;
+
     if (unlikely (c->serializer->in_error ())) return_trace (false);
+
     return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
-									       padded_offsets,
+									       padded_offsets.iter (),
 									       use_short_loca)));
   }
 
-  void
+  bool
   _populate_subset_glyphs (const hb_subset_plan_t   *plan,
+			   hb_font_t                *font,
 			   hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
 
   hb_font_t *
   _create_font_for_instancing (const hb_subset_plan_t *plan) const;
 
-  void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> *glyphs) const
+  void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs, unsigned index) const
   {
-    for (auto _ : *glyphs)
-      _.free_compiled_bytes ();
+    for (unsigned i = 0; i <= index && i < glyphs.length; i++)
+      glyphs[i].free_compiled_bytes ();
   }
 
   protected:
@@ -193,7 +200,7 @@
     contour_point_vector_t all_points;
 
     bool phantom_only = !consumer.is_consuming_contour_points ();
-    if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, true, phantom_only)))
+    if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only)))
       return false;
 
     if (consumer.is_consuming_contour_points ())
@@ -247,19 +254,14 @@
 	  extents->y_bearing = 0;
 	  return;
 	}
-	if (scaled)
 	{
-	  extents->x_bearing = font->em_scalef_x (min_x);
-	  extents->width = font->em_scalef_x (max_x) - extents->x_bearing;
-	  extents->y_bearing = font->em_scalef_y (max_y);
-	  extents->height = font->em_scalef_y (min_y) - extents->y_bearing;
-	}
-	else
-	{
 	  extents->x_bearing = roundf (min_x);
 	  extents->width = roundf (max_x - extents->x_bearing);
 	  extents->y_bearing = roundf (max_y);
 	  extents->height = roundf (min_y - extents->y_bearing);
+
+	  if (scaled)
+	    font->scale_glyph_extents (extents);
 	}
       }
 
@@ -337,6 +339,15 @@
     return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents);
   }
 
+  bool paint_glyph (hb_font_t *font, hb_codepoint_t gid, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
+  {
+    funcs->push_clip_glyph (data, gid, font);
+    funcs->color (data, true, foreground);
+    funcs->pop_clip (data);
+
+    return true;
+  }
+
   const glyf_impl::Glyph
   glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
   {
@@ -385,14 +396,16 @@
 };
 
 
-inline void
+inline bool
 glyf::_populate_subset_glyphs (const hb_subset_plan_t   *plan,
+			       hb_font_t *font,
 			       hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
 {
   OT::glyf_accelerator_t glyf (plan->source);
   unsigned num_glyphs = plan->num_output_glyphs ();
-  if (!glyphs.resize (num_glyphs)) return;
+  if (!glyphs.resize (num_glyphs)) return false;
 
+  unsigned idx = 0;
   for (auto p : plan->glyph_map->iter ())
   {
     unsigned new_gid = p.second;
@@ -401,7 +414,7 @@
 
     if (unlikely (new_gid == 0 &&
                   !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
-                  plan->pinned_at_default)
+                  !plan->normalized_coords)
       subset_glyph.source_glyph = glyf_impl::Glyph ();
     else
     {
@@ -414,7 +427,20 @@
       subset_glyph.drop_hints_bytes ();
     else
       subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
+
+    if (font)
+    {
+      if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf)))
+      {
+        // when pinned at default, only bounds are updated, thus no need to free
+        if (!plan->pinned_at_default && idx > 0)
+          _free_compiled_subset_glyphs (glyphs, idx - 1);
+        return false;
+      }
+      idx++;
+    }
   }
+  return true;
 }
 
 inline hb_font_t *
@@ -424,10 +450,10 @@
   if (unlikely (font == hb_font_get_empty ())) return nullptr;
 
   hb_vector_t<hb_variation_t> vars;
-  if (unlikely (!vars.alloc (plan->user_axes_location->get_population ())))
+  if (unlikely (!vars.alloc (plan->user_axes_location.get_population (), true)))
     return nullptr;
 
-  for (auto _ : *plan->user_axes_location)
+  for (auto _ : plan->user_axes_location)
   {
     hb_variation_t var;
     var.tag = _.first;
@@ -436,7 +462,7 @@
   }
 
 #ifndef HB_NO_VAR
-  hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
+  hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location.get_population ());
 #endif
   return font;
 }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/glyf/path-builder.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -26,22 +26,29 @@
 
     optional_point_t lerp (optional_point_t p, float t)
     { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
-  } first_oncurve, first_offcurve, last_offcurve;
+  } first_oncurve, first_offcurve, last_offcurve, last_offcurve2;
 
   path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
   {
     font = font_;
     draw_session = &draw_session_;
-    first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
+    first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
   }
 
   /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
      See also:
      * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
-     * https://stackoverflow.com/a/20772557 */
+     * https://stackoverflow.com/a/20772557
+     *
+     * Cubic support added (incomplete). */
   void consume_point (const contour_point_t &point)
   {
     bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
+#ifdef HB_NO_CUBIC_GLYF
+    bool is_cubic = false;
+#else
+    bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
+#endif
     optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
     if (!first_oncurve)
     {
@@ -69,16 +76,41 @@
       {
 	if (is_on_curve)
 	{
-	  draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
-				     p.x, p.y);
+	  if (last_offcurve2)
+	  {
+	    draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
+				    last_offcurve.x, last_offcurve.y,
+				    p.x, p.y);
+	    last_offcurve2 = optional_point_t ();
+	  }
+	  else
+	    draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+				       p.x, p.y);
 	  last_offcurve = optional_point_t ();
 	}
 	else
 	{
-	  optional_point_t mid = last_offcurve.lerp (p, .5f);
-	  draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
-				     mid.x, mid.y);
-	  last_offcurve = p;
+	  if (is_cubic && !last_offcurve2)
+	  {
+	    last_offcurve2 = last_offcurve;
+	    last_offcurve = p;
+	  }
+	  else
+	  {
+	    optional_point_t mid = last_offcurve.lerp (p, .5f);
+
+	    if (is_cubic)
+	    {
+	      draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
+				      last_offcurve.x, last_offcurve.y,
+				      mid.x, mid.y);
+	      last_offcurve2 = optional_point_t ();
+	    }
+	    else
+	      draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+					 mid.x, mid.y);
+	    last_offcurve = p;
+	  }
 	}
       }
       else
@@ -105,8 +137,15 @@
 	draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
 				   first_oncurve.x, first_oncurve.y);
       else if (last_offcurve && first_oncurve)
-	draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
-				   first_oncurve.x, first_oncurve.y);
+      {
+	if (last_offcurve2)
+	  draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
+				  last_offcurve.x, last_offcurve.y,
+				  first_oncurve.x, first_oncurve.y);
+	else
+	  draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
+				     first_oncurve.x, first_oncurve.y);
+      }
       else if (first_oncurve)
 	draw_session->line_to (first_oncurve.x, first_oncurve.y);
       else if (first_offcurve)
@@ -117,7 +156,7 @@
       }
 
       /* Getting ready for the next contour */
-      first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
+      first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
       draw_session->close_path ();
     }
   }

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/OT/name/name.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,589 @@
+/*
+ * Copyright © 2011,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef OT_NAME_NAME_HH
+#define OT_NAME_NAME_HH
+
+#include "../../hb-open-type.hh"
+#include "../../hb-ot-name-language.hh"
+#include "../../hb-aat-layout.hh"
+#include "../../hb-utf.hh"
+
+
+namespace OT {
+
+template <typename in_utf_t, typename out_utf_t>
+inline unsigned int
+hb_ot_name_convert_utf (hb_bytes_t                       bytes,
+			unsigned int                    *text_size /* IN/OUT */,
+			typename out_utf_t::codepoint_t *text /* OUT */)
+{
+  unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
+  const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
+  const typename in_utf_t::codepoint_t *src_end = src + src_len;
+
+  typename out_utf_t::codepoint_t *dst = text;
+
+  hb_codepoint_t unicode;
+  const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+
+  if (text_size && *text_size)
+  {
+    (*text_size)--; /* Save room for NUL-termination. */
+    const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
+
+    while (src < src_end && dst < dst_end)
+    {
+      const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
+      typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
+      if (dst_next == dst)
+	break; /* Out-of-room. */
+
+      dst = dst_next;
+      src = src_next;
+    }
+
+    *text_size = dst - text;
+    *dst = 0; /* NUL-terminate. */
+  }
+
+  /* Accumulate length of rest. */
+  unsigned int dst_len = dst - text;
+  while (src < src_end)
+  {
+    src = in_utf_t::next (src, src_end, &unicode, replacement);
+    dst_len += out_utf_t::encode_len (unicode);
+  }
+  return dst_len;
+}
+
+#define entry_score var.u16[0]
+#define entry_index var.u16[1]
+
+
+/*
+ * name -- Naming
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/name
+ */
+#define HB_OT_TAG_name HB_TAG('n','a','m','e')
+
+#define UNSUPPORTED	42
+
+struct NameRecord
+{
+  hb_language_t language (hb_face_t *face) const
+  {
+#ifndef HB_NO_OT_NAME_LANGUAGE
+    unsigned int p = platformID;
+    unsigned int l = languageID;
+
+    if (p == 3)
+      return _hb_ot_name_language_for_ms_code (l);
+
+    if (p == 1)
+      return _hb_ot_name_language_for_mac_code (l);
+
+#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
+    if (p == 0)
+      return face->table.ltag->get_language (l);
+#endif
+
+#endif
+    return HB_LANGUAGE_INVALID;
+  }
+
+  uint16_t score () const
+  {
+    /* Same order as in cmap::find_best_subtable(). */
+    unsigned int p = platformID;
+    unsigned int e = encodingID;
+
+    /* 32-bit. */
+    if (p == 3 && e == 10) return 0;
+    if (p == 0 && e ==  6) return 1;
+    if (p == 0 && e ==  4) return 2;
+
+    /* 16-bit. */
+    if (p == 3 && e ==  1) return 3;
+    if (p == 0 && e ==  3) return 4;
+    if (p == 0 && e ==  2) return 5;
+    if (p == 0 && e ==  1) return 6;
+    if (p == 0 && e ==  0) return 7;
+
+    /* Symbol. */
+    if (p == 3 && e ==  0) return 8;
+
+    /* We treat all Mac Latin names as ASCII only. */
+    if (p == 1 && e ==  0) return 10; /* 10 is magic number :| */
+
+    return UNSUPPORTED;
+  }
+
+  NameRecord* copy (hb_serialize_context_t *c, const void *base
+#ifdef HB_EXPERIMENTAL_API
+                    , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
+#endif
+		    ) const
+  {
+    TRACE_SERIALIZE (this);
+    HB_UNUSED auto snap = c->snapshot ();
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+#ifdef HB_EXPERIMENTAL_API
+    hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID);
+    hb_bytes_t* name_bytes;
+
+    if (name_table_overrides->has (record_ids, &name_bytes)) {
+      hb_bytes_t encoded_bytes = *name_bytes;
+      char *name_str_utf16_be = nullptr;
+
+      if (platformID != 1)
+      {
+        unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
+  
+        text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
+        unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
+        name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
+        if (!name_str_utf16_be)
+        {
+          c->revert (snap);
+          return_trace (nullptr);
+        }
+        hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
+                                                          (hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
+  
+        unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
+        if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
+          c->revert (snap);
+          hb_free (name_str_utf16_be);
+          return_trace (nullptr);
+        }
+  
+        encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
+      }
+      else
+      {
+        // mac platform, copy the UTF-8 string(all ascii characters) as is
+        if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
+          c->revert (snap);
+          return_trace (nullptr);
+        }
+      }
+
+      out->offset = 0;
+      c->push ();
+      encoded_bytes.copy (c);
+      c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0);
+      hb_free (name_str_utf16_be);
+    }
+    else
+#endif
+    {
+      out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
+    }
+    return_trace (out);
+  }
+
+  bool isUnicode () const
+  {
+    unsigned int p = platformID;
+    unsigned int e = encodingID;
+
+    return (p == 0 ||
+	    (p == 3 && (e == 0 || e == 1 || e == 10)));
+  }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const NameRecord *a = (const NameRecord *)pa;
+    const NameRecord *b = (const NameRecord *)pb;
+
+    if (a->platformID != b->platformID)
+      return a->platformID - b->platformID;
+
+    if (a->encodingID != b->encodingID)
+      return a->encodingID - b->encodingID;
+
+    if (a->languageID != b->languageID)
+      return a->languageID - b->languageID;
+
+    if (a->nameID != b->nameID)
+      return a->nameID - b->nameID;
+
+    if (a->length != b->length)
+      return a->length - b->length;
+
+    return 0;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
+  }
+
+  HBUINT16	platformID;	/* Platform ID. */
+  HBUINT16	encodingID;	/* Platform-specific encoding ID. */
+  HBUINT16	languageID;	/* Language ID. */
+  HBUINT16	nameID;		/* Name ID. */
+  HBUINT16	length;		/* String length (in bytes). */
+  NNOffset16To<UnsizedArrayOf<HBUINT8>>
+		offset;		/* String offset from start of storage area (in bytes). */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+static int
+_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
+{
+  const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
+  const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
+
+  /* Compare by name_id, then language. */
+
+  if (a->name_id != b->name_id)
+    return a->name_id - b->name_id;
+
+  if (a->language == b->language) return 0;
+  if (!a->language) return -1;
+  if (!b->language) return +1;
+
+  const char *astr = hb_language_to_string (a->language);
+  const char *bstr = hb_language_to_string (b->language);
+
+  signed c = strcmp (astr, bstr);
+
+  // 'a' is the user request, and 'b' is string in the font.
+  // If eg. user asks for "en-us" and font has "en", approve.
+  if (!exact && c &&
+      hb_language_matches (b->language, a->language))
+    return 0;
+
+  return c;
+}
+
+static int
+_hb_ot_name_entry_cmp (const void *pa, const void *pb)
+{
+  /* Compare by name_id, then language, then score, then index. */
+
+  int v = _hb_ot_name_entry_cmp_key (pa, pb, true);
+  if (v)
+    return v;
+
+  const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
+  const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
+
+  if (a->entry_score != b->entry_score)
+    return a->entry_score - b->entry_score;
+
+  if (a->entry_index != b->entry_index)
+    return a->entry_index - b->entry_index;
+
+  return 0;
+}
+
+struct name
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_name;
+
+  unsigned int get_size () const
+  { return min_size + count * nameRecordZ.item_size; }
+
+  template <typename Iterator,
+	    hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
+  bool serialize (hb_serialize_context_t *c,
+		  Iterator it,
+		  const void *src_string_pool
+#ifdef HB_EXPERIMENTAL_API
+                  , const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records
+		  , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
+#endif
+		  )
+  {
+    TRACE_SERIALIZE (this);
+
+    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
+
+    unsigned total_count = it.len ()
+#ifdef HB_EXPERIMENTAL_API
+        + insert_name_records.length
+#endif
+        ;
+    this->format = 0;
+    if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return false;
+
+    NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size);
+    if (unlikely (!name_records)) return_trace (false);
+
+    hb_array_t<NameRecord> records (name_records, total_count);
+
+    for (const NameRecord& record : it)
+    {
+      hb_memcpy (name_records, &record, NameRecord::static_size);
+      name_records++;
+    }
+
+#ifdef HB_EXPERIMENTAL_API
+    for (unsigned i = 0; i < insert_name_records.length; i++)
+    {
+      const hb_ot_name_record_ids_t& ids = insert_name_records[i];
+      NameRecord record;
+      record.platformID = ids.platform_id;
+      record.encodingID = ids.encoding_id;
+      record.languageID = ids.language_id;
+      record.nameID = ids.name_id;
+      record.length = 0; // handled in NameRecord copy()
+      record.offset = 0;
+      memcpy (name_records, &record, NameRecord::static_size);
+      name_records++;
+    }
+#endif
+
+    records.qsort ();
+
+    c->copy_all (records,
+		 src_string_pool
+#ifdef HB_EXPERIMENTAL_API
+		 , name_table_overrides
+#endif
+		 );
+    hb_free (records.arrayZ);
+
+
+    if (unlikely (c->ran_out_of_room ())) return_trace (false);
+
+    this->stringOffset = c->length ();
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    name *name_prime = c->serializer->start_embed<name> ();
+    if (unlikely (!name_prime)) return_trace (false);
+
+#ifdef HB_EXPERIMENTAL_API
+    const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
+        &c->plan->name_table_overrides;
+#endif
+    
+    auto it =
+    + nameRecordZ.as_array (count)
+    | hb_filter (c->plan->name_ids, &NameRecord::nameID)
+    | hb_filter (c->plan->name_languages, &NameRecord::languageID)
+    | hb_filter ([&] (const NameRecord& namerecord) {
+      return
+          (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY)
+          || namerecord.isUnicode ();
+    })
+#ifdef HB_EXPERIMENTAL_API
+    | hb_filter ([&] (const NameRecord& namerecord) {
+      if (name_table_overrides->is_empty ())
+        return true;
+      hb_ot_name_record_ids_t rec_ids (namerecord.platformID,
+                                       namerecord.encodingID,
+                                       namerecord.languageID,
+                                       namerecord.nameID);
+
+      hb_bytes_t *p;
+      if (name_table_overrides->has (rec_ids, &p) &&
+          (*p).length == 0)
+        return false;
+      return true;
+    })
+#endif
+    ;
+
+#ifdef HB_EXPERIMENTAL_API
+    hb_hashmap_t<hb_ot_name_record_ids_t, unsigned> retained_name_record_ids;
+    for (const NameRecord& rec : it)
+    {
+      hb_ot_name_record_ids_t rec_ids (rec.platformID,
+                                       rec.encodingID,
+                                       rec.languageID,
+                                       rec.nameID);
+      retained_name_record_ids.set (rec_ids, 1);
+    }
+
+    hb_vector_t<hb_ot_name_record_ids_t> insert_name_records;
+    if (!name_table_overrides->is_empty ())
+    {
+      if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true)))
+        return_trace (false);
+      for (const auto& record_ids : name_table_overrides->keys ())
+      {
+        if (name_table_overrides->get (record_ids).length == 0)
+          continue;
+        if (retained_name_record_ids.has (record_ids))
+          continue;
+        insert_name_records.push (record_ids);
+      }
+    }
+#endif
+
+    return (name_prime->serialize (c->serializer, it,
+                                   std::addressof (this + stringOffset)
+#ifdef HB_EXPERIMENTAL_API
+                                   , insert_name_records
+                                   , name_table_overrides
+#endif
+                                   ));
+  }
+
+  bool sanitize_records (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    const void *string_pool = (this+stringOffset).arrayZ;
+    return_trace (nameRecordZ.sanitize (c, count, string_pool));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  likely (format == 0 || format == 1) &&
+		  c->check_array (nameRecordZ.arrayZ, count) &&
+		  c->check_range (this, stringOffset) &&
+		  sanitize_records (c));
+  }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      this->table = hb_sanitize_context_t ().reference_table<name> (face);
+      assert (this->table.get_length () >= this->table->stringOffset);
+      this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
+      this->pool_len = this->table.get_length () - this->table->stringOffset;
+      const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
+						    this->table->count);
+
+      this->names.alloc (all_names.length, true);
+
+      for (unsigned int i = 0; i < all_names.length; i++)
+      {
+	hb_ot_name_entry_t *entry = this->names.push ();
+
+	entry->name_id = all_names[i].nameID;
+	entry->language = all_names[i].language (face);
+	entry->entry_score =  all_names[i].score ();
+	entry->entry_index = i;
+      }
+
+      this->names.qsort (_hb_ot_name_entry_cmp);
+      /* Walk and pick best only for each name_id,language pair,
+       * while dropping unsupported encodings. */
+      unsigned int j = 0;
+      for (unsigned int i = 0; i < this->names.length; i++)
+      {
+	if (this->names[i].entry_score == UNSUPPORTED ||
+	    this->names[i].language == HB_LANGUAGE_INVALID)
+	  continue;
+	if (i &&
+	    this->names[i - 1].name_id  == this->names[i].name_id &&
+	    this->names[i - 1].language == this->names[i].language)
+	  continue;
+	this->names[j++] = this->names[i];
+      }
+      this->names.resize (j);
+    }
+    ~accelerator_t ()
+    {
+      this->table.destroy ();
+    }
+
+    int get_index (hb_ot_name_id_t  name_id,
+		   hb_language_t    language,
+		   unsigned int    *width=nullptr) const
+    {
+      const hb_ot_name_entry_t key = {name_id, {0}, language};
+      const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
+						    this->names.length,
+						    sizeof (hb_ot_name_entry_t),
+						    _hb_ot_name_entry_cmp_key,
+						    true);
+
+      if (!entry)
+      {
+	entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
+			    this->names.length,
+			    sizeof (hb_ot_name_entry_t),
+			    _hb_ot_name_entry_cmp_key,
+			    false);
+      }
+
+      if (!entry)
+	return -1;
+
+      if (width)
+	*width = entry->entry_score < 10 ? 2 : 1;
+
+      return entry->entry_index;
+    }
+
+    hb_bytes_t get_name (unsigned int idx) const
+    {
+      const hb_array_t<const NameRecord> all_names (table->nameRecordZ.arrayZ, table->count);
+      const NameRecord &record = all_names[idx];
+      const hb_bytes_t string_pool (pool, pool_len);
+      return string_pool.sub_array (record.offset, record.length);
+    }
+
+    private:
+    const char *pool;
+    unsigned int pool_len;
+    public:
+    hb_blob_ptr_t<name> table;
+    hb_vector_t<hb_ot_name_entry_t> names;
+  };
+
+  public:
+  /* We only implement format 0 for now. */
+  HBUINT16	format;		/* Format selector (=0/1). */
+  HBUINT16	count;		/* Number of name records. */
+  NNOffset16To<UnsizedArrayOf<HBUINT8>>
+		stringOffset;	/* Offset to start of string storage (from start of table). */
+  UnsizedArrayOf<NameRecord>
+		nameRecordZ;	/* The name records where count is the number of records. */
+  public:
+  DEFINE_SIZE_ARRAY (6, nameRecordZ);
+};
+
+#undef entry_index
+#undef entry_score
+
+struct name_accelerator_t : name::accelerator_t {
+  name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_NAME_NAME_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.py	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-libstdc++.py	2023-02-12 04:02:23 UTC (rev 65798)
@@ -19,7 +19,7 @@
 tested = False
 
 # harfbuzz-icu links to libstdc++ because icu does.
-for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-gobject']:
+for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-gobject', 'harfbuzz-cairo']:
 	for suffix in ['so', 'dylib']:
 		so = os.path.join (libs, 'lib%s.%s' % (soname, suffix))
 		if not os.path.exists (so): continue

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/check-symbols.py	2023-02-12 04:02:23 UTC (rev 65798)
@@ -22,7 +22,7 @@
 tested = False
 stat = 0
 
-for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject']:
+for soname in ['harfbuzz', 'harfbuzz-subset', 'harfbuzz-icu', 'harfbuzz-gobject', 'harfbuzz-cairo']:
 	for suffix in ['so', 'dylib']:
 		so = os.path.join (builddir, libs, 'lib%s.%s' % (soname, suffix))
 		if not os.path.exists (so): continue

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/graph.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -123,7 +123,7 @@
         while (a || b)
         {
           DEBUG_MSG (SUBSET_REPACK, nullptr,
-                     "  0x%x %s 0x%x", *a, (*a == *b) ? "==" : "!=", *b);
+                     "  0x%x %s 0x%x", (unsigned) *a, (*a == *b) ? "==" : "!=", (unsigned) *b);
           a++;
           b++;
         }
@@ -700,6 +700,9 @@
       }
     }
 
+    if (in_error ())
+      return false;
+
     if (!made_changes)
       return false;
 
@@ -833,7 +836,11 @@
     if (index_map.has (node_idx))
       return;
 
-    index_map.set (node_idx, duplicate (node_idx));
+    unsigned clone_idx = duplicate (node_idx);
+    if (!check_success (clone_idx != (unsigned) -1))
+      return;
+
+    index_map.set (node_idx, clone_idx);
     for (const auto& l : object (node_idx).all_links ()) {
       duplicate_subgraph (l.objidx, index_map);
     }
@@ -918,12 +925,12 @@
     {
       // Can't duplicate this node, doing so would orphan the original one as all remaining links
       // to child are from parent.
-      DEBUG_MSG (SUBSET_REPACK, nullptr, "  Not duplicating %d => %d",
+      DEBUG_MSG (SUBSET_REPACK, nullptr, "  Not duplicating %u => %u",
                  parent_idx, child_idx);
       return -1;
     }
 
-    DEBUG_MSG (SUBSET_REPACK, nullptr, "  Duplicating %d => %d",
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "  Duplicating %u => %u",
                parent_idx, child_idx);
 
     unsigned clone_idx = duplicate (child_idx);
@@ -981,7 +988,7 @@
    */
   bool raise_childrens_priority (unsigned parent_idx)
   {
-    DEBUG_MSG (SUBSET_REPACK, nullptr, "  Raising priority of all children of %d",
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "  Raising priority of all children of %u",
                parent_idx);
     // This operation doesn't change ordering until a sort is run, so no need
     // to invalidate positions. It does not change graph structure so no need

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/graph/serialize.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -153,8 +153,8 @@
     const auto& child = graph.vertices_[o.child];
     DEBUG_MSG (SUBSET_REPACK, nullptr,
                "  overflow from "
-               "%4d (%4d in, %4d out, space %2d) => "
-               "%4d (%4d in, %4d out, space %2d)",
+               "%4u (%4u in, %4u out, space %2u) => "
+               "%4u (%4u in, %4u out, space %2u)",
                o.parent,
                parent.incoming_edges (),
                parent.obj.real_links.length + parent.obj.virtual_links.length,
@@ -165,7 +165,7 @@
                graph.space_for (o.child));
   }
   if (overflows.length > 10) {
-    DEBUG_MSG (SUBSET_REPACK, nullptr, "  ... plus %d more overflows.", overflows.length - 10);
+    DEBUG_MSG (SUBSET_REPACK, nullptr, "  ... plus %u more overflows.", overflows.length - 10);
   }
 }
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-cairo.pc.in	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,12 @@
+prefix=%prefix%
+exec_prefix=%exec_prefix%
+libdir=%libdir%
+includedir=%includedir%
+
+Name: harfbuzz cairo integration
+Description: HarfBuzz cairo integration
+Version: %VERSION%
+
+Requires: harfbuzz = %VERSION%
+Libs: -L${libdir} -lharfbuzz-cairo
+Cflags: -I${includedir}/harfbuzz

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz-subset.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -7,6 +7,7 @@
 #include "hb-buffer.cc"
 #include "hb-common.cc"
 #include "hb-draw.cc"
+#include "hb-face-builder.cc"
 #include "hb-face.cc"
 #include "hb-fallback-shape.cc"
 #include "hb-font.cc"
@@ -40,6 +41,9 @@
 #include "hb-ot-shaper-vowel-constraints.cc"
 #include "hb-ot-tag.cc"
 #include "hb-ot-var.cc"
+#include "hb-outline.cc"
+#include "hb-paint-extents.cc"
+#include "hb-paint.cc"
 #include "hb-set.cc"
 #include "hb-shape-plan.cc"
 #include "hb-shape.cc"
@@ -50,6 +54,7 @@
 #include "hb-subset-cff1.cc"
 #include "hb-subset-cff2.cc"
 #include "hb-subset-input.cc"
+#include "hb-subset-instancer-solver.cc"
 #include "hb-subset-plan.cc"
 #include "hb-subset-repacker.cc"
 #include "hb-subset.cc"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/harfbuzz.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -8,6 +8,7 @@
 #include "hb-coretext.cc"
 #include "hb-directwrite.cc"
 #include "hb-draw.cc"
+#include "hb-face-builder.cc"
 #include "hb-face.cc"
 #include "hb-fallback-shape.cc"
 #include "hb-font.cc"
@@ -45,6 +46,9 @@
 #include "hb-ot-shaper-vowel-constraints.cc"
 #include "hb-ot-tag.cc"
 #include "hb-ot-var.cc"
+#include "hb-outline.cc"
+#include "hb-paint-extents.cc"
+#include "hb-paint.cc"
 #include "hb-set.cc"
 #include "hb-shape-plan.cc"
 #include "hb-shape.cc"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -28,6 +28,7 @@
 #define HB_AAT_LAYOUT_COMMON_HH
 
 #include "hb-aat-layout.hh"
+#include "hb-aat-map.hh"
 #include "hb-open-type.hh"
 
 namespace OT {
@@ -39,6 +40,43 @@
 using namespace OT;
 
 
+struct ankr;
+
+struct hb_aat_apply_context_t :
+       hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
+{
+  const char *get_name () { return "APPLY"; }
+  template <typename T>
+  return_t dispatch (const T &obj) { return obj.apply (this); }
+  static return_t default_return_value () { return false; }
+  bool stop_sublookup_iteration (return_t r) const { return r; }
+
+  const hb_ot_shape_plan_t *plan;
+  hb_font_t *font;
+  hb_face_t *face;
+  hb_buffer_t *buffer;
+  hb_sanitize_context_t sanitizer;
+  const ankr *ankr_table;
+  const OT::GDEF *gdef_table;
+  const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
+  hb_mask_t subtable_flags = 0;
+
+  /* Unused. For debug tracing only. */
+  unsigned int lookup_index;
+
+  HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
+				      hb_font_t *font_,
+				      hb_buffer_t *buffer_,
+				      hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
+
+  HB_INTERNAL ~hb_aat_apply_context_t ();
+
+  HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
+
+  void set_lookup_index (unsigned int i) { lookup_index = i; }
+};
+
+
 /*
  * Lookup Table
  */
@@ -740,16 +778,44 @@
 	      num_glyphs (face_->get_num_glyphs ()) {}
 
   template <typename context_t>
-  void drive (context_t *c)
+  void drive (context_t *c, hb_aat_apply_context_t *ac)
   {
     if (!c->in_place)
       buffer->clear_output ();
 
     int state = StateTableT::STATE_START_OF_TEXT;
+    // If there's only one range, we already checked the flag.
+    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
     for (buffer->idx = 0; buffer->successful;)
     {
+      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
+      if (last_range)
+      {
+	auto *range = last_range;
+	if (buffer->idx < buffer->len)
+	{
+	  unsigned cluster = buffer->cur().cluster;
+	  while (cluster < range->cluster_first)
+	    range--;
+	  while (cluster > range->cluster_last)
+	    range++;
+
+
+	  last_range = range;
+	}
+	if (!(range->flags & ac->subtable_flags))
+	{
+	  if (buffer->idx == buffer->len || unlikely (!buffer->successful))
+	    break;
+
+	  state = StateTableT::STATE_START_OF_TEXT;
+	  (void) buffer->next_glyph ();
+	  continue;
+	}
+      }
+
       unsigned int klass = buffer->idx < buffer->len ?
-			   machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
+			   machine.get_class (buffer->cur().codepoint, num_glyphs) :
 			   (unsigned) StateTableT::CLASS_END_OF_TEXT;
       DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
       const EntryT &entry = machine.get_entry (state, klass);
@@ -845,41 +911,6 @@
 };
 
 
-struct ankr;
-
-struct hb_aat_apply_context_t :
-       hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
-{
-  const char *get_name () { return "APPLY"; }
-  template <typename T>
-  return_t dispatch (const T &obj) { return obj.apply (this); }
-  static return_t default_return_value () { return false; }
-  bool stop_sublookup_iteration (return_t r) const { return r; }
-
-  const hb_ot_shape_plan_t *plan;
-  hb_font_t *font;
-  hb_face_t *face;
-  hb_buffer_t *buffer;
-  hb_sanitize_context_t sanitizer;
-  const ankr *ankr_table;
-  const OT::GDEF *gdef_table;
-
-  /* Unused. For debug tracing only. */
-  unsigned int lookup_index;
-
-  HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
-				      hb_font_t *font_,
-				      hb_buffer_t *buffer_,
-				      hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
-
-  HB_INTERNAL ~hb_aat_apply_context_t ();
-
-  HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
-
-  void set_lookup_index (unsigned int i) { lookup_index = i; }
-};
-
-
 } /* namespace AAT */
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -350,7 +350,7 @@
     driver_context_t dc (this, c);
 
     StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face);
-    driver.drive (&dc);
+    driver.drive (&dc, c);
 
     return_trace (true);
   }
@@ -594,7 +594,7 @@
     driver_context_t dc (this, c);
 
     StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face);
-    driver.drive (&dc);
+    driver.drive (&dc, c);
 
     return_trace (true);
   }
@@ -869,6 +869,8 @@
 
   bool apply (AAT::hb_aat_apply_context_t *c) const
   {
+    c->buffer->unsafe_to_concat ();
+
     typedef typename T::SubTable SubTable;
 
     bool ret = false;
@@ -889,7 +891,7 @@
       reverse = bool (st->u.header.coverage & st->u.header.Backwards) !=
 		HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
 
-      if (!c->buffer->message (c->font, "start subtable %d", c->lookup_index))
+      if (!c->buffer->message (c->font, "start subtable %u", c->lookup_index))
 	goto skip;
 
       if (!seenCrossStream &&
@@ -921,7 +923,7 @@
       if (reverse)
 	c->buffer->reverse ();
 
-      (void) c->buffer->message (c->font, "end subtable %d", c->lookup_index);
+      (void) c->buffer->message (c->font, "end subtable %u", c->lookup_index);
 
     skip:
       st = &StructAfter<SubTable> (*st);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -169,7 +169,7 @@
     driver_context_t dc (this);
 
     StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
-    driver.drive (&dc);
+    driver.drive (&dc, c);
 
     return_trace (dc.ret);
   }
@@ -325,7 +325,7 @@
     driver_context_t dc (this, c);
 
     StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
-    driver.drive (&dc);
+    driver.drive (&dc, c);
 
     return_trace (dc.ret);
   }
@@ -525,7 +525,7 @@
 	  if (unlikely (!componentData.sanitize (&c->sanitizer))) break;
 	  ligature_idx += componentData;
 
-	  DEBUG_MSG (APPLY, nullptr, "Action store %u last %u",
+	  DEBUG_MSG (APPLY, nullptr, "Action store %d last %d",
 		     bool (action & LigActionStore),
 		     bool (action & LigActionLast));
 	  if (action & (LigActionStore | LigActionLast))
@@ -577,7 +577,7 @@
     driver_context_t dc (this, c);
 
     StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
-    driver.drive (&dc);
+    driver.drive (&dc, c);
 
     return_trace (dc.ret);
   }
@@ -618,8 +618,27 @@
 
     hb_glyph_info_t *info = c->buffer->info;
     unsigned int count = c->buffer->len;
+    // If there's only one range, we already checked the flag.
+    auto *last_range = c->range_flags && (c->range_flags->length > 1) ? &(*c->range_flags)[0] : nullptr;
     for (unsigned int i = 0; i < count; i++)
     {
+      /* This block copied from StateTableDriver::drive. Keep in sync. */
+      if (last_range)
+      {
+	auto *range = last_range;
+	{
+	  unsigned cluster = info[i].cluster;
+	  while (cluster < range->cluster_first)
+	    range--;
+	  while (cluster > range->cluster_last)
+	    range++;
+
+	  last_range = range;
+	}
+	if (!(range->flags & c->subtable_flags))
+	  continue;
+      }
+
       const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
       if (replacement)
       {
@@ -820,7 +839,7 @@
     driver_context_t dc (this, c);
 
     StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
-    driver.drive (&dc);
+    driver.drive (&dc, c);
 
     return_trace (dc.ret);
   }
@@ -968,7 +987,7 @@
 	// Check whether this type/setting pair was requested in the map, and if so, apply its flags.
 	// (The search here only looks at the type and setting fields of feature_info_t.)
 	hb_aat_map_builder_t::feature_info_t info = { type, setting, false, 0 };
-	if (map->features.bsearch (info))
+	if (map->current_features.bsearch (info))
 	{
 	  flags &= feature.disableFlags;
 	  flags |= feature.enableFlags;
@@ -994,8 +1013,7 @@
     return flags;
   }
 
-  void apply (hb_aat_apply_context_t *c,
-	      hb_mask_t flags) const
+  void apply (hb_aat_apply_context_t *c) const
   {
     const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
     unsigned int count = subtableCount;
@@ -1003,8 +1021,10 @@
     {
       bool reverse;
 
-      if (!(subtable->subFeatureFlags & flags))
+      if (hb_none (hb_iter (c->range_flags) |
+		   hb_map ([&subtable] (const hb_aat_map_t::range_flags_t _) -> bool { return subtable->subFeatureFlags & (_.flags); })))
 	goto skip;
+      c->subtable_flags = subtable->subFeatureFlags;
 
       if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) &&
 	  HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
@@ -1043,7 +1063,7 @@
 		bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) !=
 		HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
 
-      if (!c->buffer->message (c->font, "start chainsubtable %d", c->lookup_index))
+      if (!c->buffer->message (c->font, "start chainsubtable %u", c->lookup_index))
 	goto skip;
 
       if (reverse)
@@ -1054,7 +1074,7 @@
       if (reverse)
 	c->buffer->reverse ();
 
-      (void) c->buffer->message (c->font, "end chainsubtable %d", c->lookup_index);
+      (void) c->buffer->message (c->font, "end chainsubtable %u", c->lookup_index);
 
       if (unlikely (!c->buffer->successful)) return;
 
@@ -1120,22 +1140,31 @@
   {
     const Chain<Types> *chain = &firstChain;
     unsigned int count = chainCount;
+    if (unlikely (!map->chain_flags.resize (count)))
+      return;
     for (unsigned int i = 0; i < count; i++)
     {
-      map->chain_flags.push (chain->compile_flags (mapper));
+      map->chain_flags[i].push (hb_aat_map_t::range_flags_t {chain->compile_flags (mapper),
+							     mapper->range_first,
+							     mapper->range_last});
       chain = &StructAfter<Chain<Types>> (*chain);
     }
   }
 
-  void apply (hb_aat_apply_context_t *c) const
+  void apply (hb_aat_apply_context_t *c,
+	      const hb_aat_map_t &map) const
   {
     if (unlikely (!c->buffer->successful)) return;
+
+    c->buffer->unsafe_to_concat ();
+
     c->set_lookup_index (0);
     const Chain<Types> *chain = &firstChain;
     unsigned int count = chainCount;
     for (unsigned int i = 0; i < count; i++)
     {
-      chain->apply (c, c->plan->aat_map.chain_flags[i]);
+      c->range_flags = &map.chain_flags[i];
+      chain->apply (c);
       if (unlikely (!c->buffer->successful)) return;
       chain = &StructAfter<Chain<Types>> (*chain);
     }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -244,8 +244,16 @@
 void
 hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
 			  hb_font_t *font,
-			  hb_buffer_t *buffer)
+			  hb_buffer_t *buffer,
+			  const hb_feature_t *features,
+			  unsigned num_features)
 {
+  hb_aat_map_builder_t builder (font->face, plan->props);
+  for (unsigned i = 0; i < num_features; i++)
+    builder.add_feature (features[i]);
+  hb_aat_map_t map;
+  builder.compile (map);
+
   hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
   const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
   if (morx.has_data ())
@@ -252,7 +260,7 @@
   {
     AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob);
     if (!buffer->message (font, "start table morx")) return;
-    morx.apply (&c);
+    morx.apply (&c, map);
     (void) buffer->message (font, "end table morx");
     return;
   }
@@ -263,7 +271,7 @@
   {
     AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob);
     if (!buffer->message (font, "start table mort")) return;
-    mort.apply (&c);
+    mort.apply (&c, map);
     (void) buffer->message (font, "end table mort");
     return;
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -53,7 +53,9 @@
 HB_INTERNAL void
 hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
 			  hb_font_t *font,
-			  hb_buffer_t *buffer);
+			  hb_buffer_t *buffer,
+			  const hb_feature_t *features,
+			  unsigned num_features);
 
 HB_INTERNAL void
 hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -36,27 +36,29 @@
 #include "hb-aat-layout-feat-table.hh"
 
 
-void hb_aat_map_builder_t::add_feature (hb_tag_t tag, unsigned value)
+void hb_aat_map_builder_t::add_feature (const hb_feature_t &feature)
 {
   if (!face->table.feat->has_data ()) return;
 
-  if (tag == HB_TAG ('a','a','l','t'))
+  if (feature.tag == HB_TAG ('a','a','l','t'))
   {
     if (!face->table.feat->exposes_feature (HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES))
       return;
-    feature_info_t *info = features.push();
-    info->type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES;
-    info->setting = (hb_aat_layout_feature_selector_t) value;
-    info->seq = features.length;
-    info->is_exclusive = true;
+    feature_range_t *range = features.push();
+    range->start = feature.start;
+    range->end = feature.end;
+    range->info.type = HB_AAT_LAYOUT_FEATURE_TYPE_CHARACTER_ALTERNATIVES;
+    range->info.setting = (hb_aat_layout_feature_selector_t) feature.value;
+    range->info.seq = features.length;
+    range->info.is_exclusive = true;
     return;
   }
 
-  const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (tag);
+  const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (feature.tag);
   if (!mapping) return;
 
-  const AAT::FeatureName* feature = &face->table.feat->get_feature (mapping->aatFeatureType);
-  if (!feature->has_data ())
+  const AAT::FeatureName* feature_name = &face->table.feat->get_feature (mapping->aatFeatureType);
+  if (!feature_name->has_data ())
   {
     /* Special case: Chain::compile_flags will fall back to the deprecated version of
      * small-caps if necessary, so we need to check for that possibility.
@@ -64,38 +66,106 @@
     if (mapping->aatFeatureType == HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE &&
 	mapping->selectorToEnable == HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS)
     {
-      feature = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE);
-      if (!feature->has_data ()) return;
+      feature_name = &face->table.feat->get_feature (HB_AAT_LAYOUT_FEATURE_TYPE_LETTER_CASE);
+      if (!feature_name->has_data ()) return;
     }
     else return;
   }
 
-  feature_info_t *info = features.push();
-  info->type = mapping->aatFeatureType;
-  info->setting = value ? mapping->selectorToEnable : mapping->selectorToDisable;
-  info->seq = features.length;
-  info->is_exclusive = feature->is_exclusive ();
+  feature_range_t *range = features.push();
+  range->start = feature.start;
+  range->end = feature.end;
+  range->info.type = mapping->aatFeatureType;
+  range->info.setting = feature.value ? mapping->selectorToEnable : mapping->selectorToDisable;
+  range->info.seq = features.length;
+  range->info.is_exclusive = feature_name->is_exclusive ();
 }
 
 void
 hb_aat_map_builder_t::compile (hb_aat_map_t  &m)
 {
-  /* Sort features and merge duplicates */
-  if (features.length)
+  /* Compute active features per range, and compile each. */
+
+  /* Sort features by start/end events. */
+  hb_vector_t<feature_event_t> feature_events;
+  for (unsigned int i = 0; i < features.length; i++)
   {
-    features.qsort ();
-    unsigned int j = 0;
-    for (unsigned int i = 1; i < features.length; i++)
-      if (features[i].type != features[j].type ||
-	  /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
-	   * respectively, so we mask out the low-order bit when checking for "duplicates"
-	   * (selectors referring to the same feature setting) here. */
-	  (!features[i].is_exclusive && ((features[i].setting & ~1) != (features[j].setting & ~1))))
-	features[++j] = features[i];
-    features.shrink (j + 1);
+    auto &feature = features[i];
+
+    if (features[i].start == features[i].end)
+      continue;
+
+    feature_event_t *event;
+
+    event = feature_events.push ();
+    event->index = features[i].start;
+    event->start = true;
+    event->feature = feature.info;
+
+    event = feature_events.push ();
+    event->index = features[i].end;
+    event->start = false;
+    event->feature = feature.info;
   }
+  feature_events.qsort ();
+  /* Add a strategic final event. */
+  {
+    feature_info_t feature;
+    feature.seq = features.length + 1;
 
-  hb_aat_layout_compile_map (this, &m);
+    feature_event_t *event = feature_events.push ();
+    event->index = -1; /* This value does magic. */
+    event->start = false;
+    event->feature = feature;
+  }
+
+  /* Scan events and save features for each range. */
+  hb_sorted_vector_t<feature_info_t> active_features;
+  unsigned int last_index = 0;
+  for (unsigned int i = 0; i < feature_events.length; i++)
+  {
+    feature_event_t *event = &feature_events[i];
+
+    if (event->index != last_index)
+    {
+      /* Save a snapshot of active features and the range. */
+
+      /* Sort features and merge duplicates */
+      current_features = active_features;
+      range_first = last_index;
+      range_last = event->index - 1;
+      if (current_features.length)
+      {
+	current_features.qsort ();
+	unsigned int j = 0;
+	for (unsigned int i = 1; i < current_features.length; i++)
+	  if (current_features[i].type != current_features[j].type ||
+	      /* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
+	       * respectively, so we mask out the low-order bit when checking for "duplicates"
+	       * (selectors referring to the same feature setting) here. */
+	      (!current_features[i].is_exclusive && ((current_features[i].setting & ~1) != (current_features[j].setting & ~1))))
+	    current_features[++j] = current_features[i];
+	current_features.shrink (j + 1);
+      }
+
+      hb_aat_layout_compile_map (this, &m);
+
+      last_index = event->index;
+    }
+
+    if (event->start)
+    {
+      active_features.push (event->feature);
+    } else {
+      feature_info_t *feature = active_features.lsearch (event->feature);
+      if (feature)
+	active_features.remove_ordered (feature - active_features.arrayZ);
+    }
+  }
+
+  for (auto &chain_flags : m.chain_flags)
+    // With our above setup this value is one less than desired; adjust it.
+    chain_flags.tail().cluster_last = HB_FEATURE_GLOBAL_END;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -35,16 +35,15 @@
   friend struct hb_aat_map_builder_t;
 
   public:
-
-  void init ()
+  struct range_flags_t
   {
-    hb_memset (this, 0, sizeof (*this));
-    chain_flags.init ();
-  }
-  void fini () { chain_flags.fini (); }
+    hb_mask_t flags;
+    unsigned cluster_first;
+    unsigned cluster_last; // end - 1
+  };
 
   public:
-  hb_vector_t<hb_mask_t> chain_flags;
+  hb_vector_t<hb_sorted_vector_t<range_flags_t>> chain_flags;
 };
 
 struct hb_aat_map_builder_t
@@ -56,7 +55,7 @@
 				      face (face_),
 				      props (props_) {}
 
-  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1);
+  HB_INTERNAL void add_feature (const hb_feature_t &feature);
 
   HB_INTERNAL void compile (hb_aat_map_t  &m);
 
@@ -78,7 +77,7 @@
 	    return (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
     }
 
-    /* compares type & setting only, not is_exclusive flag or seq number */
+    /* compares type & setting only */
     int cmp (const feature_info_t& f) const
     {
       return (f.type != type) ? (f.type < type ? -1 : 1) :
@@ -86,12 +85,38 @@
     }
   };
 
+  struct feature_range_t
+  {
+    feature_info_t info;
+    unsigned start;
+    unsigned end;
+  };
+
+  private:
+  struct feature_event_t
+  {
+    unsigned int index;
+    bool start;
+    feature_info_t feature;
+
+    HB_INTERNAL static int cmp (const void *pa, const void *pb) {
+      const feature_event_t *a = (const feature_event_t *) pa;
+      const feature_event_t *b = (const feature_event_t *) pb;
+      return a->index < b->index ? -1 : a->index > b->index ? 1 :
+	     a->start < b->start ? -1 : a->start > b->start ? 1 :
+	     feature_info_t::cmp (&a->feature, &b->feature);
+    }
+  };
+
   public:
   hb_face_t *face;
   hb_segment_properties_t props;
 
   public:
-  hb_sorted_vector_t<feature_info_t> features;
+  hb_sorted_vector_t<feature_range_t> features;
+  hb_sorted_vector_t<feature_info_t> current_features;
+  unsigned range_first = HB_FEATURE_GLOBAL_START;
+  unsigned range_last = HB_FEATURE_GLOBAL_END;
 };
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-algs.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -875,7 +875,7 @@
 static inline bool
 hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
 {
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && (__clang_major__ >= 8))
   unsigned stack_result;
   if (!result)
     result = &stack_result;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-array.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -304,6 +304,9 @@
   unsigned int backwards_length = 0;
 };
 template <typename T> inline hb_array_t<T>
+hb_array ()
+{ return hb_array_t<T> (); }
+template <typename T> inline hb_array_t<T>
 hb_array (T *array, unsigned int length)
 { return hb_array_t<T> (array, length); }
 template <typename T, unsigned int length_> inline hb_array_t<T>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -84,11 +84,11 @@
 #define _hb_memory_r_barrier()			std::atomic_thread_fence(std::memory_order_acquire)
 #define _hb_memory_w_barrier()			std::atomic_thread_fence(std::memory_order_release)
 
-#define hb_atomic_int_impl_add(AI, V)		(reinterpret_cast<std::atomic<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
-#define hb_atomic_int_impl_set_relaxed(AI, V)	(reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed))
-#define hb_atomic_int_impl_set(AI, V)		(reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_release))
-#define hb_atomic_int_impl_get_relaxed(AI)	(reinterpret_cast<std::atomic<int> const *> (AI)->load (std::memory_order_relaxed))
-#define hb_atomic_int_impl_get(AI)		(reinterpret_cast<std::atomic<int> const *> (AI)->load (std::memory_order_acquire))
+#define hb_atomic_int_impl_add(AI, V)		(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
+#define hb_atomic_int_impl_set_relaxed(AI, V)	(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_relaxed))
+#define hb_atomic_int_impl_set(AI, V)		(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> *> (AI)->store ((V), std::memory_order_release))
+#define hb_atomic_int_impl_get_relaxed(AI)	(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_relaxed))
+#define hb_atomic_int_impl_get(AI)		(reinterpret_cast<std::atomic<std::decay<decltype (*(AI))>::type> const *> (AI)->load (std::memory_order_acquire))
 
 #define hb_atomic_ptr_impl_set_relaxed(P, V)	(reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed))
 #define hb_atomic_ptr_impl_get_relaxed(P)	(reinterpret_cast<std::atomic<void*> const *> (P)->load (std::memory_order_relaxed))
@@ -145,9 +145,11 @@
 #endif
 #ifndef hb_atomic_int_impl_set
 inline void hb_atomic_int_impl_set (int *AI, int v)	{ _hb_memory_w_barrier (); *AI = v; }
+inline void hb_atomic_int_impl_set (short *AI, short v)	{ _hb_memory_w_barrier (); *AI = v; }
 #endif
 #ifndef hb_atomic_int_impl_get
 inline int hb_atomic_int_impl_get (const int *AI)	{ int v = *AI; _hb_memory_r_barrier (); return v; }
+inline short hb_atomic_int_impl_get (const short *AI)	{ short v = *AI; _hb_memory_r_barrier (); return v; }
 #endif
 #ifndef hb_atomic_ptr_impl_get
 inline void *hb_atomic_ptr_impl_get (void ** const P)	{ void *v = *P; _hb_memory_r_barrier (); return v; }
@@ -154,6 +156,24 @@
 #endif
 
 
+struct hb_atomic_short_t
+{
+  hb_atomic_short_t () = default;
+  constexpr hb_atomic_short_t (short v) : v (v) {}
+
+  hb_atomic_short_t& operator = (short v_) { set_relaxed (v_); return *this; }
+  operator short () const { return get_relaxed (); }
+
+  void set_relaxed (short v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
+  void set_release (short v_) { hb_atomic_int_impl_set (&v, v_); }
+  short get_relaxed () const { return hb_atomic_int_impl_get_relaxed (&v); }
+  short get_acquire () const { return hb_atomic_int_impl_get (&v); }
+  short inc () { return hb_atomic_int_impl_add (&v,  1); }
+  short dec () { return hb_atomic_int_impl_add (&v, -1); }
+
+  short v = 0;
+};
+
 struct hb_atomic_int_t
 {
   hb_atomic_int_t () = default;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-page.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -34,7 +34,8 @@
 /* Compiler-assisted vectorization. */
 
 /* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
- * basically a fixed-size bitset. */
+ * basically a fixed-size bitset. We can't use the compiler type because hb_vector_t cannot
+ * guarantee alignment requirements. */
 template <typename elt_t, unsigned int byte_size>
 struct hb_vector_size_t
 {
@@ -41,7 +42,16 @@
   elt_t& operator [] (unsigned int i) { return v[i]; }
   const elt_t& operator [] (unsigned int i) const { return v[i]; }
 
-  void clear (unsigned char v = 0) { hb_memset (this, v, sizeof (*this)); }
+  void init0 ()
+  {
+    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+      v[i] = 0;
+  }
+  void init1 ()
+  {
+    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+      v[i] = (elt_t) -1;
+  }
 
   template <typename Op>
   hb_vector_size_t process (const Op& op) const
@@ -79,10 +89,10 @@
 
 struct hb_bit_page_t
 {
-  void init0 () { v.clear (); }
-  void init1 () { v.clear (0xFF); }
+  void init0 () { v.init0 (); }
+  void init1 () { v.init1 (); }
 
-  constexpr unsigned len () const
+  static inline constexpr unsigned len ()
   { return ARRAY_LENGTH_CONST (v); }
 
   bool is_empty () const
@@ -300,10 +310,10 @@
   static constexpr hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
 
   typedef unsigned long long elt_t;
-  static constexpr unsigned PAGE_BITS = 512;
+  static constexpr unsigned PAGE_BITS_LOG_2 = 9; // 512 bits
+  static constexpr unsigned PAGE_BITS = 1 << PAGE_BITS_LOG_2;
+  static_assert (1 << PAGE_BITS_LOG_2 == PAGE_BITS, "");
   static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
-  static constexpr unsigned PAGE_BITS_LOG_2 = 9;
-  static_assert (1 << PAGE_BITS_LOG_2 == PAGE_BITS, "");
   static constexpr unsigned PAGE_BITMASK = PAGE_BITS - 1;
 
   static unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set-invertible.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -74,6 +74,11 @@
       inverted = !inverted;
   }
 
+  bool is_inverted () const
+  {
+    return inverted;
+  }
+
   bool is_empty () const
   {
     hb_codepoint_t v = INVALID;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-bit-set.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -38,7 +38,7 @@
   hb_bit_set_t () = default;
   ~hb_bit_set_t () = default;
 
-  hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other); }
+  hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other, true); }
   hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); }
   hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; }
   hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; }
@@ -85,12 +85,16 @@
   void err () { if (successful) successful = false; } /* TODO Remove */
   bool in_error () const { return !successful; }
 
-  bool resize (unsigned int count, bool clear = true)
+  bool resize (unsigned int count, bool clear = true, bool exact_size = false)
   {
     if (unlikely (!successful)) return false;
-    if (unlikely (!pages.resize (count, clear) || !page_map.resize (count, clear)))
+
+    if (pages.length == 0 && count == 1)
+      exact_size = true; // Most sets are small and local
+
+    if (unlikely (!pages.resize (count, clear, exact_size) || !page_map.resize (count, clear, exact_size)))
     {
-      pages.resize (page_map.length);
+      pages.resize (page_map.length, clear, exact_size);
       successful = false;
       return false;
     }
@@ -346,11 +350,11 @@
     hb_codepoint_t c = first - 1;
     return next (&c) && c <= last;
   }
-  void set (const hb_bit_set_t &other)
+  void set (const hb_bit_set_t &other, bool exact_size = false)
   {
     if (unlikely (!successful)) return;
     unsigned int count = other.pages.length;
-    if (unlikely (!resize (count, false)))
+    if (unlikely (!resize (count, false, exact_size)))
       return;
     population = other.population;
 
@@ -422,7 +426,7 @@
   private:
   bool allocate_compact_workspace (hb_vector_t<unsigned>& workspace)
   {
-    if (unlikely (!workspace.resize (pages.length)))
+    if (unlikely (!workspace.resize_exact (pages.length)))
     {
       successful = false;
       return false;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -676,7 +676,7 @@
   wchar_t * wchar_file_name = (wchar_t *) hb_malloc (sizeof (wchar_t) * size);
   if (unlikely (!wchar_file_name)) goto fail_without_close;
   mbstowcs (wchar_file_name, file_name, size);
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
   {
     CREATEFILE2_EXTENDED_PARAMETERS ceparams = { 0 };
     ceparams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
@@ -697,7 +697,7 @@
 
   if (unlikely (fd == INVALID_HANDLE_VALUE)) goto fail_without_close;
 
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
   {
     LARGE_INTEGER length;
     GetFileSizeEx (fd, &length);
@@ -710,7 +710,7 @@
 #endif
   if (unlikely (!file->mapping)) goto fail;
 
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
   file->contents = (char *) MapViewOfFileFromApp (file->mapping, FILE_MAP_READ, 0, 0);
 #else
   file->contents = (char *) MapViewOfFile (file->mapping, FILE_MAP_READ, 0, 0, 0);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -35,34 +35,34 @@
 #line 33 "hb-buffer-deserialize-json.hh"
 static const unsigned char _deserialize_json_trans_keys[] = {
 	0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 
-	48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 
-	9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 
-	120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 
-	9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 
-	9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, 
-	34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 93u, 
+	48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 
+	48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 
+	9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 
+	34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 
+	9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 
+	9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 
 	9u, 123u, 0u, 0u, 0
 };
 
 static const char _deserialize_json_key_spans[] = {
 	0, 115, 26, 21, 2, 1, 50, 49, 
-	10, 117, 117, 117, 1, 50, 49, 10, 
-	117, 117, 1, 1, 50, 49, 117, 117, 
-	2, 1, 50, 49, 10, 117, 117, 1, 
-	50, 49, 10, 117, 117, 1, 1, 50, 
-	49, 117, 117, 1, 50, 49, 59, 117, 
-	59, 117, 117, 1, 50, 49, 117, 85, 
+	10, 117, 117, 85, 117, 1, 50, 49, 
+	10, 117, 117, 1, 1, 50, 49, 117, 
+	117, 2, 1, 50, 49, 10, 117, 117, 
+	1, 50, 49, 10, 117, 117, 1, 1, 
+	50, 49, 117, 117, 1, 50, 49, 59, 
+	117, 59, 117, 117, 1, 50, 49, 117, 
 	115, 0
 };
 
 static const short _deserialize_json_index_offsets[] = {
 	0, 0, 116, 143, 165, 168, 170, 221, 
-	271, 282, 400, 518, 636, 638, 689, 739, 
-	750, 868, 986, 988, 990, 1041, 1091, 1209, 
-	1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680, 
-	1682, 1733, 1783, 1794, 1912, 2030, 2032, 2034, 
-	2085, 2135, 2253, 2371, 2373, 2424, 2474, 2534, 
-	2652, 2712, 2830, 2948, 2950, 3001, 3051, 3169, 
+	271, 282, 400, 518, 604, 722, 724, 775, 
+	825, 836, 954, 1072, 1074, 1076, 1127, 1177, 
+	1295, 1413, 1416, 1418, 1469, 1519, 1530, 1648, 
+	1766, 1768, 1819, 1869, 1880, 1998, 2116, 2118, 
+	2120, 2171, 2221, 2339, 2457, 2459, 2510, 2560, 
+	2620, 2738, 2798, 2916, 3034, 3036, 3087, 3137, 
 	3255, 3371
 };
 
@@ -131,230 +131,228 @@
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 24, 1, 20, 
-	20, 20, 20, 20, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 24, 1, 25, 
+	25, 25, 25, 25, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 20, 1, 
+	1, 1, 1, 1, 1, 1, 25, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 21, 1, 1, 1, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
+	1, 1, 26, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 27, 1, 20, 20, 20, 
+	20, 20, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 20, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	21, 1, 1, 1, 19, 19, 19, 19, 
+	19, 19, 19, 19, 19, 19, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 22, 1, 25, 1, 25, 
-	25, 25, 25, 25, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 25, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	26, 1, 26, 26, 26, 26, 26, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 26, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 27, 1, 
-	1, 28, 29, 29, 29, 29, 29, 29, 
-	29, 29, 29, 1, 30, 31, 31, 31, 
-	31, 31, 31, 31, 31, 31, 1, 32, 
-	32, 32, 32, 32, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 32, 1, 
+	1, 22, 1, 28, 1, 28, 28, 28, 
+	28, 28, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 33, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 28, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 29, 1, 
+	29, 29, 29, 29, 29, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 29, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 30, 1, 1, 31, 
+	32, 32, 32, 32, 32, 32, 32, 32, 
+	32, 1, 33, 34, 34, 34, 34, 34, 
+	34, 34, 34, 34, 1, 35, 35, 35, 
+	35, 35, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 35, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	36, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 34, 1, 32, 32, 32, 
-	32, 32, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 32, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	33, 1, 1, 1, 31, 31, 31, 31, 
-	31, 31, 31, 31, 31, 31, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 37, 1, 35, 35, 35, 35, 35, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 34, 1, 35, 1, 36, 1, 36, 
-	36, 36, 36, 36, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 35, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 36, 1, 
+	1, 1, 34, 34, 34, 34, 34, 34, 
+	34, 34, 34, 34, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	37, 1, 37, 37, 37, 37, 37, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 37, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 38, 39, 39, 39, 39, 39, 39, 
-	39, 39, 39, 1, 40, 40, 40, 40, 
-	40, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 40, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 41, 
+	1, 1, 1, 1, 1, 1, 1, 37, 
+	1, 38, 1, 39, 1, 39, 39, 39, 
+	39, 39, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 39, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 40, 1, 
+	40, 40, 40, 40, 40, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 40, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 41, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 1, 43, 43, 43, 43, 43, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 43, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 44, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	42, 1, 40, 40, 40, 40, 40, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 40, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 41, 1, 1, 
-	1, 43, 43, 43, 43, 43, 43, 43, 
-	43, 43, 43, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 45, 1, 
+	43, 43, 43, 43, 43, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 43, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 44, 1, 1, 1, 46, 
+	46, 46, 46, 46, 46, 46, 46, 46, 
+	46, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 42, 1, 
-	44, 45, 1, 46, 1, 46, 46, 46, 
-	46, 46, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 46, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 47, 1, 
-	47, 47, 47, 47, 47, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 47, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 48, 1, 1, 49, 
-	50, 50, 50, 50, 50, 50, 50, 50, 
-	50, 1, 51, 52, 52, 52, 52, 52, 
-	52, 52, 52, 52, 1, 53, 53, 53, 
-	53, 53, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 53, 1, 1, 1, 
+	1, 1, 1, 1, 45, 1, 47, 48, 
+	1, 49, 1, 49, 49, 49, 49, 49, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	54, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 49, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 50, 1, 50, 50, 
+	50, 50, 50, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 50, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 51, 1, 1, 52, 53, 53, 
+	53, 53, 53, 53, 53, 53, 53, 1, 
+	54, 55, 55, 55, 55, 55, 55, 55, 
+	55, 55, 1, 56, 56, 56, 56, 56, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 56, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 57, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 55, 1, 53, 53, 53, 53, 53, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 53, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 54, 1, 
-	1, 1, 52, 52, 52, 52, 52, 52, 
-	52, 52, 52, 52, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 58, 
+	1, 56, 56, 56, 56, 56, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 55, 
-	1, 56, 1, 56, 56, 56, 56, 56, 
+	56, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 57, 1, 1, 1, 
+	55, 55, 55, 55, 55, 55, 55, 55, 
+	55, 55, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 56, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 57, 1, 57, 57, 
-	57, 57, 57, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 57, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 58, 1, 1, 59, 60, 60, 
-	60, 60, 60, 60, 60, 60, 60, 1, 
-	61, 62, 62, 62, 62, 62, 62, 62, 
-	62, 62, 1, 63, 63, 63, 63, 63, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 58, 1, 59, 
+	1, 59, 59, 59, 59, 59, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 63, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 64, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	59, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 60, 1, 60, 60, 60, 60, 
+	60, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 60, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	61, 1, 1, 62, 63, 63, 63, 63, 
+	63, 63, 63, 63, 63, 1, 64, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
+	1, 66, 66, 66, 66, 66, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	66, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 67, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 65, 
-	1, 63, 63, 63, 63, 63, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	63, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 64, 1, 1, 1, 
-	62, 62, 62, 62, 62, 62, 62, 62, 
-	62, 62, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 68, 1, 66, 
+	66, 66, 66, 66, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 66, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 65, 1, 66, 
-	1, 67, 1, 67, 67, 67, 67, 67, 
+	1, 1, 67, 1, 1, 1, 65, 65, 
+	65, 65, 65, 65, 65, 65, 65, 65, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 67, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 68, 1, 68, 68, 
-	68, 68, 68, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 68, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 69, 70, 70, 
-	70, 70, 70, 70, 70, 70, 70, 1, 
-	71, 71, 71, 71, 71, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 71, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 72, 1, 1, 1, 1, 
+	1, 1, 1, 68, 1, 69, 1, 70, 
+	1, 70, 70, 70, 70, 70, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	70, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 71, 1, 71, 71, 71, 71, 
+	71, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 71, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 72, 73, 73, 73, 73, 
+	73, 73, 73, 73, 73, 1, 74, 74, 
+	74, 74, 74, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 74, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 75, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 73, 1, 71, 71, 
-	71, 71, 71, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 71, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 72, 1, 1, 1, 74, 74, 74, 
-	74, 74, 74, 74, 74, 74, 74, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
@@ -361,119 +359,121 @@
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 76, 1, 74, 74, 74, 74, 
+	74, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 74, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 75, 
+	1, 1, 1, 77, 77, 77, 77, 77, 
+	77, 77, 77, 77, 77, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 73, 1, 75, 1, 75, 75, 
-	75, 75, 75, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 75, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 76, 
-	1, 76, 76, 76, 76, 76, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	76, 1, 77, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	78, 79, 79, 79, 79, 79, 79, 79, 
-	79, 79, 1, 81, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 80, 80, 80, 
-	80, 80, 80, 80, 80, 82, 80, 83, 
-	83, 83, 83, 83, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 83, 1, 
+	76, 1, 78, 1, 78, 78, 78, 78, 
+	78, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 84, 1, 1, 1, 1, 1, 
+	1, 1, 1, 78, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 79, 1, 79, 
+	79, 79, 79, 79, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 79, 1, 
+	80, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 81, 82, 
+	82, 82, 82, 82, 82, 82, 82, 82, 
+	1, 84, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 83, 83, 83, 83, 83, 
+	83, 83, 83, 85, 83, 86, 86, 86, 
+	86, 86, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 86, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	87, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 85, 1, 80, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 88, 1, 83, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 80, 
-	1, 86, 86, 86, 86, 86, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	86, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 87, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 83, 1, 89, 
+	89, 89, 89, 89, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 89, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 90, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 88, 1, 86, 
-	86, 86, 86, 86, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 86, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 87, 1, 1, 1, 89, 89, 
-	89, 89, 89, 89, 89, 89, 89, 89, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 91, 1, 89, 89, 89, 
+	89, 89, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 89, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	90, 1, 1, 1, 92, 92, 92, 92, 
+	92, 92, 92, 92, 92, 92, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 88, 1, 90, 1, 90, 
-	90, 90, 90, 90, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 90, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	91, 1, 91, 91, 91, 91, 91, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 91, 1, 93, 1, 93, 93, 93, 
+	93, 93, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 91, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 93, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 92, 93, 93, 93, 93, 93, 93, 
-	93, 93, 93, 1, 86, 86, 86, 86, 
-	86, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 86, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 87, 
-	1, 1, 1, 94, 94, 94, 94, 94, 
+	1, 1, 1, 1, 1, 1, 94, 1, 
 	94, 94, 94, 94, 94, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 94, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 95, 
+	96, 96, 96, 96, 96, 96, 96, 96, 
+	96, 1, 89, 89, 89, 89, 89, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 89, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 90, 1, 1, 
+	1, 97, 97, 97, 97, 97, 97, 97, 
+	97, 97, 97, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	88, 1, 95, 95, 95, 95, 95, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 95, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 96, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 97, 1, 
+	1, 1, 1, 1, 1, 1, 91, 1, 
 	0, 0, 0, 0, 0, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 0, 
@@ -492,19 +492,19 @@
 };
 
 static const char _deserialize_json_trans_targs[] = {
-	1, 0, 2, 2, 3, 4, 18, 24, 
-	37, 43, 51, 5, 12, 6, 7, 8, 
-	9, 11, 9, 11, 10, 2, 55, 10, 
-	55, 13, 14, 15, 16, 17, 16, 17, 
-	10, 2, 55, 19, 20, 21, 22, 23, 
-	10, 2, 55, 23, 25, 31, 26, 27, 
-	28, 29, 30, 29, 30, 10, 2, 55, 
-	32, 33, 34, 35, 36, 35, 36, 10, 
-	2, 55, 38, 39, 40, 41, 42, 10, 
-	2, 55, 42, 44, 45, 46, 49, 50, 
-	46, 47, 48, 10, 2, 55, 10, 2, 
-	55, 50, 52, 53, 49, 54, 54, 55, 
-	56, 57
+	1, 0, 2, 2, 3, 4, 19, 25, 
+	38, 44, 52, 5, 13, 6, 7, 8, 
+	9, 12, 9, 12, 10, 2, 11, 10, 
+	11, 11, 56, 57, 14, 15, 16, 17, 
+	18, 17, 18, 10, 2, 11, 20, 21, 
+	22, 23, 24, 10, 2, 11, 24, 26, 
+	32, 27, 28, 29, 30, 31, 30, 31, 
+	10, 2, 11, 33, 34, 35, 36, 37, 
+	36, 37, 10, 2, 11, 39, 40, 41, 
+	42, 43, 10, 2, 11, 43, 45, 46, 
+	47, 50, 51, 47, 48, 49, 10, 2, 
+	11, 10, 2, 11, 51, 53, 54, 50, 
+	55, 55
 };
 
 static const char _deserialize_json_trans_actions[] = {
@@ -511,20 +511,20 @@
 	0, 0, 1, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 2, 
 	2, 2, 0, 0, 3, 3, 4, 0, 
-	5, 0, 0, 2, 2, 2, 0, 0, 
-	6, 6, 7, 0, 0, 0, 2, 2, 
-	8, 8, 9, 0, 0, 0, 0, 0, 
-	2, 2, 2, 0, 0, 10, 10, 11, 
-	0, 0, 2, 2, 2, 0, 0, 12, 
-	12, 13, 0, 0, 0, 2, 2, 14, 
-	14, 15, 0, 0, 0, 2, 16, 16, 
-	0, 17, 0, 18, 18, 19, 20, 20, 
-	21, 17, 0, 0, 22, 22, 23, 0, 
-	0, 0
+	5, 0, 0, 0, 0, 0, 2, 2, 
+	2, 0, 0, 6, 6, 7, 0, 0, 
+	0, 2, 2, 8, 8, 9, 0, 0, 
+	0, 0, 0, 2, 2, 2, 0, 0, 
+	10, 10, 11, 0, 0, 2, 2, 2, 
+	0, 0, 12, 12, 13, 0, 0, 0, 
+	2, 2, 14, 14, 15, 0, 0, 0, 
+	2, 16, 16, 0, 17, 0, 18, 18, 
+	19, 20, 20, 21, 17, 0, 0, 22, 
+	22, 23
 };
 
 static const int deserialize_json_start = 1;
-static const int deserialize_json_first_final = 55;
+static const int deserialize_json_first_final = 56;
 static const int deserialize_json_error = 0;
 
 static const int deserialize_json_en_main = 1;
@@ -548,9 +548,7 @@
   while (p < pe && ISSPACE (*p))
     p++;
   if (p < pe && *p == (buffer->len ? ',' : '['))
-  {
     *end_ptr = ++p;
-  }
 
   const char *tok = nullptr;
   int cs;
@@ -557,12 +555,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
   
-#line 554 "hb-buffer-deserialize-json.hh"
+#line 552 "hb-buffer-deserialize-json.hh"
 	{
 	cs = deserialize_json_start;
 	}
 
-#line 557 "hb-buffer-deserialize-json.hh"
+#line 555 "hb-buffer-deserialize-json.hh"
 	{
 	int _slen;
 	int _trans;
@@ -774,7 +772,7 @@
 	*end_ptr = p;
 }
 	break;
-#line 735 "hb-buffer-deserialize-json.hh"
+#line 733 "hb-buffer-deserialize-json.hh"
 	}
 
 _again:
@@ -786,7 +784,7 @@
 	_out: {}
 	}
 
-#line 139 "hb-buffer-deserialize-json.rl"
+#line 137 "hb-buffer-deserialize-json.rl"
 
 
   *end_ptr = p;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-json.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -106,7 +106,7 @@
 	@add_item
 	;
 
-main := space* item (comma item)* space* (','|']')?;
+main := space* item (comma item)* space* (','|']');
 
 }%%
 
@@ -125,9 +125,7 @@
   while (p < pe && ISSPACE (*p))
     p++;
   if (p < pe && *p == (buffer->len ? ',' : '['))
-  {
     *end_ptr = ++p;
-  }
 
   const char *tok = nullptr;
   int cs;

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,692 @@
+
+#line 1 "hb-buffer-deserialize-text-glyphs.rl"
+/*
+ * Copyright © 2013  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
+
+#include "hb.hh"
+
+
+#line 33 "hb-buffer-deserialize-text-glyphs.hh"
+static const unsigned char _deserialize_text_glyphs_trans_keys[] = {
+	0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 
+	48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, 
+	9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 
+	9u, 124u, 9u, 124u, 9u, 124u, 0
+};
+
+static const char _deserialize_text_glyphs_key_spans[] = {
+	0, 10, 13, 10, 13, 10, 10, 13, 
+	10, 1, 13, 10, 14, 82, 116, 116, 
+	116, 116, 116, 116, 116, 116, 116, 116, 
+	116, 116, 116
+};
+
+static const short _deserialize_text_glyphs_index_offsets[] = {
+	0, 0, 11, 25, 36, 50, 61, 72, 
+	86, 97, 99, 113, 124, 139, 222, 339, 
+	456, 573, 690, 807, 924, 1041, 1158, 1275, 
+	1392, 1509, 1626
+};
+
+static const char _deserialize_text_glyphs_indicies[] = {
+	0, 2, 2, 2, 2, 2, 2, 
+	2, 2, 2, 1, 3, 1, 1, 4, 
+	5, 5, 5, 5, 5, 5, 5, 5, 
+	5, 1, 6, 7, 7, 7, 7, 7, 
+	7, 7, 7, 7, 1, 8, 1, 1, 
+	9, 10, 10, 10, 10, 10, 10, 10, 
+	10, 10, 1, 11, 12, 12, 12, 12, 
+	12, 12, 12, 12, 12, 1, 13, 14, 
+	14, 14, 14, 14, 14, 14, 14, 14, 
+	1, 15, 1, 1, 16, 17, 17, 17, 
+	17, 17, 17, 17, 17, 17, 1, 18, 
+	19, 19, 19, 19, 19, 19, 19, 19, 
+	19, 1, 20, 1, 21, 1, 1, 22, 
+	23, 23, 23, 23, 23, 23, 23, 23, 
+	23, 1, 24, 25, 25, 25, 25, 25, 
+	25, 25, 25, 25, 1, 20, 1, 1, 
+	1, 19, 19, 19, 19, 19, 19, 19, 
+	19, 19, 19, 1, 26, 26, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 26, 1, 
+	1, 26, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 26, 26, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 26, 1, 28, 
+	28, 28, 28, 28, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 28, 27, 
+	27, 29, 27, 27, 27, 27, 27, 27, 
+	27, 30, 1, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 27, 31, 27, 27, 32, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 33, 1, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 27, 27, 27, 27, 27, 27, 
+	27, 27, 28, 27, 34, 34, 34, 34, 
+	34, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 34, 26, 26, 35, 26, 
+	26, 26, 26, 26, 26, 26, 36, 1, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	37, 26, 26, 38, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 39, 
+	1, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 26, 
+	26, 26, 26, 26, 26, 26, 26, 40, 
+	26, 41, 41, 41, 41, 41, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	41, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 42, 1, 43, 43, 
+	43, 43, 43, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 43, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 44, 1, 41, 41, 41, 41, 41, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 41, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 45, 45, 45, 45, 45, 45, 
+	45, 45, 45, 45, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 42, 1, 
+	46, 46, 46, 46, 46, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 46, 
+	1, 1, 47, 1, 1, 1, 1, 1, 
+	1, 1, 1, 48, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 49, 1, 50, 50, 50, 
+	50, 50, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 50, 1, 1, 51, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	52, 1, 50, 50, 50, 50, 50, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 50, 1, 1, 51, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 12, 12, 12, 12, 12, 12, 12, 
+	12, 12, 12, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 52, 1, 46, 
+	46, 46, 46, 46, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 46, 1, 
+	1, 47, 1, 1, 1, 1, 1, 1, 
+	1, 1, 48, 1, 1, 1, 7, 7, 
+	7, 7, 7, 7, 7, 7, 7, 7, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 49, 1, 53, 53, 53, 53, 
+	53, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 53, 1, 1, 54, 1, 
+	1, 1, 1, 1, 1, 1, 55, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 56, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 57, 
+	1, 58, 58, 58, 58, 58, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	58, 1, 1, 59, 1, 1, 1, 1, 
+	1, 1, 1, 60, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 61, 1, 58, 58, 
+	58, 58, 58, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 58, 1, 1, 
+	59, 1, 1, 1, 1, 1, 1, 1, 
+	60, 1, 1, 1, 1, 25, 25, 25, 
+	25, 25, 25, 25, 25, 25, 25, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 61, 1, 53, 53, 53, 53, 53, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 53, 1, 1, 54, 1, 1, 
+	1, 1, 1, 1, 1, 55, 1, 1, 
+	1, 1, 62, 62, 62, 62, 62, 62, 
+	62, 62, 62, 62, 1, 1, 1, 1, 
+	1, 1, 56, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 57, 1, 
+	0
+};
+
+static const char _deserialize_text_glyphs_trans_targs[] = {
+	16, 0, 18, 3, 19, 22, 19, 22, 
+	5, 20, 21, 20, 21, 23, 26, 8, 
+	9, 12, 9, 12, 10, 11, 24, 25, 
+	24, 25, 15, 15, 14, 1, 2, 6, 
+	7, 13, 15, 1, 2, 6, 7, 13, 
+	14, 17, 14, 17, 14, 18, 17, 1, 
+	4, 14, 17, 1, 14, 17, 1, 2, 
+	7, 14, 17, 1, 2, 14, 26
+};
+
+static const char _deserialize_text_glyphs_trans_actions[] = {
+	1, 0, 1, 1, 1, 1, 0, 0, 
+	1, 1, 1, 0, 0, 1, 1, 1, 
+	1, 1, 0, 0, 2, 1, 1, 1, 
+	0, 0, 0, 4, 3, 5, 5, 5, 
+	5, 4, 6, 7, 7, 7, 7, 0, 
+	6, 8, 8, 0, 0, 0, 9, 10, 
+	10, 9, 11, 12, 11, 13, 14, 14, 
+	14, 13, 15, 16, 16, 15, 0
+};
+
+static const char _deserialize_text_glyphs_eof_actions[] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 
+	0, 0, 0, 0, 0, 0, 3, 6, 
+	8, 0, 8, 9, 11, 11, 9, 13, 
+	15, 15, 13
+};
+
+static const int deserialize_text_glyphs_start = 14;
+static const int deserialize_text_glyphs_first_final = 14;
+static const int deserialize_text_glyphs_error = 0;
+
+static const int deserialize_text_glyphs_en_main = 14;
+
+
+#line 98 "hb-buffer-deserialize-text-glyphs.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
+				    const char *buf,
+				    unsigned int buf_len,
+				    const char **end_ptr,
+				    hb_font_t *font)
+{
+  const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
+
+  /* Ensure we have positions. */
+  (void) hb_buffer_get_glyph_positions (buffer, nullptr);
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+  if (p < pe && *p == (buffer->len ? '|' : '['))
+    *end_ptr = ++p;
+
+  const char *end = strchr ((char *) p, ']');
+  if (end)
+    pe = eof = end;
+  else
+  {
+    end = strrchr ((char *) p, '|');
+    if (end)
+      pe = eof = end;
+    else
+      pe = eof = p;
+  }
+
+  const char *tok = nullptr;
+  int cs;
+  hb_glyph_info_t info = {0};
+  hb_glyph_position_t pos = {0};
+  
+#line 346 "hb-buffer-deserialize-text-glyphs.hh"
+	{
+	cs = deserialize_text_glyphs_start;
+	}
+
+#line 349 "hb-buffer-deserialize-text-glyphs.hh"
+	{
+	int _slen;
+	int _trans;
+	const unsigned char *_keys;
+	const char *_inds;
+	if ( p == pe )
+		goto _test_eof;
+	if ( cs == 0 )
+		goto _out;
+_resume:
+	_keys = _deserialize_text_glyphs_trans_keys + (cs<<1);
+	_inds = _deserialize_text_glyphs_indicies + _deserialize_text_glyphs_index_offsets[cs];
+
+	_slen = _deserialize_text_glyphs_key_spans[cs];
+	_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+		(*p) <= _keys[1] ?
+		(*p) - _keys[0] : _slen ];
+
+	cs = _deserialize_text_glyphs_trans_targs[_trans];
+
+	if ( _deserialize_text_glyphs_trans_actions[_trans] == 0 )
+		goto _again;
+
+	switch ( _deserialize_text_glyphs_trans_actions[_trans] ) {
+	case 1:
+#line 51 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	tok = p;
+}
+	break;
+	case 7:
+#line 55 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+	break;
+	case 14:
+#line 63 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+	break;
+	case 2:
+#line 64 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
+	break;
+	case 16:
+#line 65 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+	break;
+	case 10:
+#line 66 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+	break;
+	case 12:
+#line 67 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+	break;
+	case 4:
+#line 38 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	tok = p;
+}
+	break;
+	case 6:
+#line 55 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 13:
+#line 63 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 15:
+#line 65 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 9:
+#line 66 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 11:
+#line 67 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 8:
+#line 68 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 5:
+#line 38 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	tok = p;
+}
+#line 55 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+	break;
+	case 3:
+#line 38 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	tok = p;
+}
+#line 55 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+#line 516 "hb-buffer-deserialize-text-glyphs.hh"
+	}
+
+_again:
+	if ( cs == 0 )
+		goto _out;
+	if ( ++p != pe )
+		goto _resume;
+	_test_eof: {}
+	if ( p == eof )
+	{
+	switch ( _deserialize_text_glyphs_eof_actions[cs] ) {
+	case 6:
+#line 55 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 13:
+#line 63 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 15:
+#line 65 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 9:
+#line 66 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 11:
+#line 67 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 8:
+#line 68 "hb-buffer-deserialize-text-glyphs.rl"
+	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 3:
+#line 38 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	tok = p;
+}
+#line 55 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+#line 43 "hb-buffer-deserialize-text-glyphs.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+#line 616 "hb-buffer-deserialize-text-glyphs.hh"
+	}
+	}
+
+	_out: {}
+	}
+
+#line 136 "hb-buffer-deserialize-text-glyphs.rl"
+
+
+  if (pe < orig_pe && *pe == ']')
+  {
+    pe++;
+    if (p == pe)
+      p++;
+  }
+
+  *end_ptr = p;
+
+  return p == pe;
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-glyphs.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,150 @@
+/*
+ * Copyright © 2013  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH
+
+#include "hb.hh"
+
+%%{
+
+machine deserialize_text_glyphs;
+alphtype unsigned char;
+write data;
+
+action clear_item {
+	hb_memset (&info, 0, sizeof (info));
+	hb_memset (&pos , 0, sizeof (pos ));
+}
+
+action add_item {
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+
+action tok {
+	tok = p;
+}
+
+action parse_glyph {
+	/* TODO Unescape delimiters. */
+	if (!hb_font_glyph_from_string (font,
+					tok, p - tok,
+					&info.codepoint))
+	  return false;
+}
+
+action parse_cluster	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+action parse_x_offset	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
+action parse_y_offset	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+action parse_x_advance	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+action parse_y_advance	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+action parse_glyph_flags{ if (!parse_uint (tok, p, &info.mask    )) return false; }
+
+unum  = '0' | [1-9] digit*;
+num	= '-'? unum;
+
+glyph_id = unum;
+glyph_name = ([^\\\]=@+,#|] | '\\' [\\\]=@+,|]) *;
+
+glyph	= (glyph_id | glyph_name) >tok %parse_glyph;
+cluster	= '=' (unum >tok %parse_cluster);
+offsets	= '@' (num >tok %parse_x_offset)   ',' (num >tok %parse_y_offset );
+advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?;
+glyphflags= '#' (unum >tok %parse_glyph_flags);
+
+glyph_item	=
+	(
+		glyph
+		cluster?
+		offsets?
+		advances?
+		glyphflags?
+	)
+	>clear_item
+	%add_item
+	;
+
+glyphs = glyph_item (space* '|' space* glyph_item)* space*;
+
+main := space* glyphs;
+
+}%%
+
+static hb_bool_t
+_hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
+				    const char *buf,
+				    unsigned int buf_len,
+				    const char **end_ptr,
+				    hb_font_t *font)
+{
+  const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
+
+  /* Ensure we have positions. */
+  (void) hb_buffer_get_glyph_positions (buffer, nullptr);
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+  if (p < pe && *p == (buffer->len ? '|' : '['))
+    *end_ptr = ++p;
+
+  const char *end = strchr ((char *) p, ']');
+  if (end)
+    pe = eof = end;
+  else
+  {
+    end = strrchr ((char *) p, '|');
+    if (end)
+      pe = eof = end;
+    else
+      pe = eof = p;
+  }
+
+  const char *tok = nullptr;
+  int cs;
+  hb_glyph_info_t info = {0};
+  hb_glyph_position_t pos = {0};
+  %%{
+    write init;
+    write exec;
+  }%%
+
+  if (pe < orig_pe && *pe == ']')
+  {
+    pe++;
+    if (p == pe)
+      p++;
+  }
+
+  *end_ptr = p;
+
+  return p == pe;
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_GLYPHS_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,332 @@
+
+#line 1 "hb-buffer-deserialize-text-unicode.rl"
+/*
+ * Copyright © 2013  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
+
+#include "hb.hh"
+
+
+#line 33 "hb-buffer-deserialize-text-unicode.hh"
+static const unsigned char _deserialize_text_unicode_trans_keys[] = {
+	0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u, 
+	9u, 124u, 0
+};
+
+static const char _deserialize_text_unicode_key_spans[] = {
+	0, 109, 60, 55, 10, 116, 116, 116, 
+	116
+};
+
+static const short _deserialize_text_unicode_index_offsets[] = {
+	0, 0, 110, 171, 227, 238, 355, 472, 
+	589
+};
+
+static const char _deserialize_text_unicode_indicies[] = {
+	0, 0, 0, 0, 0, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	0, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 2, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 2, 1, 3, 
+	1, 1, 1, 1, 4, 4, 4, 4, 
+	4, 4, 4, 4, 4, 4, 1, 1, 
+	1, 1, 1, 1, 1, 4, 4, 4, 
+	4, 4, 4, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 4, 4, 4, 
+	4, 4, 4, 1, 4, 4, 4, 4, 
+	4, 4, 4, 4, 4, 4, 1, 1, 
+	1, 1, 1, 1, 1, 4, 4, 4, 
+	4, 4, 4, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 4, 4, 4, 
+	4, 4, 4, 1, 5, 6, 6, 6, 
+	6, 6, 6, 6, 6, 6, 1, 7, 
+	7, 7, 7, 7, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 7, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 8, 8, 
+	8, 8, 8, 8, 8, 8, 8, 8, 
+	1, 1, 1, 9, 1, 1, 1, 8, 
+	8, 8, 8, 8, 8, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 8, 
+	8, 8, 8, 8, 8, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 10, 1, 11, 11, 11, 11, 
+	11, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 11, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 0, 
+	1, 12, 12, 12, 12, 12, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	12, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 13, 1, 12, 12, 
+	12, 12, 12, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 12, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 14, 14, 14, 
+	14, 14, 14, 14, 14, 14, 14, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 13, 1, 0
+};
+
+static const char _deserialize_text_unicode_trans_targs[] = {
+	1, 0, 2, 3, 5, 7, 8, 6, 
+	5, 4, 1, 6, 6, 1, 8
+};
+
+static const char _deserialize_text_unicode_trans_actions[] = {
+	0, 0, 1, 0, 2, 2, 2, 3, 
+	0, 4, 3, 0, 5, 5, 0
+};
+
+static const char _deserialize_text_unicode_eof_actions[] = {
+	0, 0, 0, 0, 0, 3, 0, 5, 
+	5
+};
+
+static const int deserialize_text_unicode_start = 1;
+static const int deserialize_text_unicode_first_final = 5;
+static const int deserialize_text_unicode_error = 0;
+
+static const int deserialize_text_unicode_en_main = 1;
+
+
+#line 79 "hb-buffer-deserialize-text-unicode.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer,
+				     const char *buf,
+				     unsigned int buf_len,
+				     const char **end_ptr,
+				     hb_font_t *font)
+{
+  const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+  if (p < pe && *p == (buffer->len ? '|' : '<'))
+    *end_ptr = ++p;
+
+  const char *end = strchr ((char *) p, '>');
+  if (end)
+    pe = eof = end;
+  else
+  {
+    end = strrchr ((char *) p, '|');
+    if (end)
+      pe = eof = end;
+    else
+      pe = eof = p;
+  }
+
+
+  const char *tok = nullptr;
+  int cs;
+  hb_glyph_info_t info = {0};
+  const hb_glyph_position_t pos = {0};
+  
+#line 194 "hb-buffer-deserialize-text-unicode.hh"
+	{
+	cs = deserialize_text_unicode_start;
+	}
+
+#line 197 "hb-buffer-deserialize-text-unicode.hh"
+	{
+	int _slen;
+	int _trans;
+	const unsigned char *_keys;
+	const char *_inds;
+	if ( p == pe )
+		goto _test_eof;
+	if ( cs == 0 )
+		goto _out;
+_resume:
+	_keys = _deserialize_text_unicode_trans_keys + (cs<<1);
+	_inds = _deserialize_text_unicode_indicies + _deserialize_text_unicode_index_offsets[cs];
+
+	_slen = _deserialize_text_unicode_key_spans[cs];
+	_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+		(*p) <= _keys[1] ?
+		(*p) - _keys[0] : _slen ];
+
+	cs = _deserialize_text_unicode_trans_targs[_trans];
+
+	if ( _deserialize_text_unicode_trans_actions[_trans] == 0 )
+		goto _again;
+
+	switch ( _deserialize_text_unicode_trans_actions[_trans] ) {
+	case 1:
+#line 38 "hb-buffer-deserialize-text-unicode.rl"
+	{
+	hb_memset (&info, 0, sizeof (info));
+}
+	break;
+	case 2:
+#line 51 "hb-buffer-deserialize-text-unicode.rl"
+	{
+	tok = p;
+}
+	break;
+	case 4:
+#line 55 "hb-buffer-deserialize-text-unicode.rl"
+	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
+	break;
+	case 3:
+#line 55 "hb-buffer-deserialize-text-unicode.rl"
+	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
+#line 42 "hb-buffer-deserialize-text-unicode.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	if (buffer->have_positions)
+	  buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 5:
+#line 57 "hb-buffer-deserialize-text-unicode.rl"
+	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 42 "hb-buffer-deserialize-text-unicode.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	if (buffer->have_positions)
+	  buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+#line 256 "hb-buffer-deserialize-text-unicode.hh"
+	}
+
+_again:
+	if ( cs == 0 )
+		goto _out;
+	if ( ++p != pe )
+		goto _resume;
+	_test_eof: {}
+	if ( p == eof )
+	{
+	switch ( _deserialize_text_unicode_eof_actions[cs] ) {
+	case 3:
+#line 55 "hb-buffer-deserialize-text-unicode.rl"
+	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
+#line 42 "hb-buffer-deserialize-text-unicode.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	if (buffer->have_positions)
+	  buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+	case 5:
+#line 57 "hb-buffer-deserialize-text-unicode.rl"
+	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 42 "hb-buffer-deserialize-text-unicode.rl"
+	{
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	if (buffer->have_positions)
+	  buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+	break;
+#line 289 "hb-buffer-deserialize-text-unicode.hh"
+	}
+	}
+
+	_out: {}
+	}
+
+#line 115 "hb-buffer-deserialize-text-unicode.rl"
+
+
+  if (pe < orig_pe && *pe == '>')
+  {
+    pe++;
+    if (p == pe)
+      p++;
+  }
+
+  *end_ptr = p;
+
+  return p == pe;
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text-unicode.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,129 @@
+/*
+ * Copyright © 2013  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH
+
+#include "hb.hh"
+
+%%{
+
+machine deserialize_text_unicode;
+alphtype unsigned char;
+write data;
+
+action clear_item {
+	hb_memset (&info, 0, sizeof (info));
+}
+
+action add_item {
+	buffer->add_info (info);
+	if (unlikely (!buffer->successful))
+	  return false;
+	if (buffer->have_positions)
+	  buffer->pos[buffer->len - 1] = pos;
+	*end_ptr = p;
+}
+
+action tok {
+	tok = p;
+}
+
+action parse_hexdigits  {if (!parse_hex (tok, p, &info.codepoint )) return false; }
+
+action parse_cluster	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+
+unum  = '0' | [1-9] digit*;
+num	= '-'? unum;
+
+cluster	= '=' (unum >tok %parse_cluster);
+
+unicode = [Uu] '+'? xdigit+ >tok %parse_hexdigits;
+
+unicode_item	=
+	(
+		unicode
+		cluster?
+	)
+	>clear_item
+	%add_item
+	;
+
+unicodes = unicode_item (space* '|' space* unicode_item)* space*;
+
+main := space* unicodes;
+
+}%%
+
+static hb_bool_t
+_hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer,
+				     const char *buf,
+				     unsigned int buf_len,
+				     const char **end_ptr,
+				     hb_font_t *font)
+{
+  const char *p = buf, *pe = buf + buf_len, *eof = pe, *orig_pe = pe;
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+  if (p < pe && *p == (buffer->len ? '|' : '<'))
+    *end_ptr = ++p;
+
+  const char *end = strchr ((char *) p, '>');
+  if (end)
+    pe = eof = end;
+  else
+  {
+    end = strrchr ((char *) p, '|');
+    if (end)
+      pe = eof = end;
+    else
+      pe = eof = p;
+  }
+
+
+  const char *tok = nullptr;
+  int cs;
+  hb_glyph_info_t info = {0};
+  const hb_glyph_position_t pos = {0};
+  %%{
+    write init;
+    write exec;
+  }%%
+
+  if (pe < orig_pe && *pe == '>')
+  {
+    pe++;
+    if (p == pe)
+      p++;
+  }
+
+  *end_ptr = p;
+
+  return p == pe;
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_UNICODE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,917 +0,0 @@
-
-#line 1 "hb-buffer-deserialize-text.rl"
-/*
- * Copyright © 2013  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
-#define HB_BUFFER_DESERIALIZE_TEXT_HH
-
-#include "hb.hh"
-
-
-#line 33 "hb-buffer-deserialize-text.hh"
-static const unsigned char _deserialize_text_trans_keys[] = {
-	0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 48u, 57u, 
-	45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 
-	45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 
-	9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 
-	9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 
-	0
-};
-
-static const char _deserialize_text_key_spans[] = {
-	0, 83, 1, 1, 55, 77, 10, 10, 
-	13, 10, 13, 10, 10, 13, 10, 1, 
-	13, 10, 14, 82, 116, 116, 0, 77, 
-	116, 116, 116, 116, 116, 116, 116, 116, 
-	116, 116, 116, 116, 116, 116, 116, 116
-};
-
-static const short _deserialize_text_index_offsets[] = {
-	0, 0, 84, 86, 88, 144, 222, 233, 
-	244, 258, 269, 283, 294, 305, 319, 330, 
-	332, 346, 357, 372, 455, 572, 689, 690, 
-	768, 885, 1002, 1119, 1236, 1353, 1470, 1587, 
-	1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523
-};
-
-static const char _deserialize_text_indicies[] = {
-	0, 0, 0, 0, 0, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	0, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 2, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 3, 1, 4, 1, 5, 
-	1, 6, 6, 6, 6, 6, 6, 6, 
-	6, 6, 6, 1, 1, 1, 1, 1, 
-	1, 1, 6, 6, 6, 6, 6, 6, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 6, 6, 6, 6, 6, 6, 
-	1, 7, 7, 7, 7, 7, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	7, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 4, 1, 8, 
-	9, 9, 9, 9, 9, 9, 9, 9, 
-	9, 1, 10, 11, 11, 11, 11, 11, 
-	11, 11, 11, 11, 1, 12, 1, 1, 
-	13, 14, 14, 14, 14, 14, 14, 14, 
-	14, 14, 1, 15, 16, 16, 16, 16, 
-	16, 16, 16, 16, 16, 1, 17, 1, 
-	1, 18, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 1, 20, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 1, 22, 
-	23, 23, 23, 23, 23, 23, 23, 23, 
-	23, 1, 24, 1, 1, 25, 26, 26, 
-	26, 26, 26, 26, 26, 26, 26, 1, 
-	27, 28, 28, 28, 28, 28, 28, 28, 
-	28, 28, 1, 29, 1, 30, 1, 1, 
-	31, 32, 32, 32, 32, 32, 32, 32, 
-	32, 32, 1, 33, 34, 34, 34, 34, 
-	34, 34, 34, 34, 34, 1, 29, 1, 
-	1, 1, 28, 28, 28, 28, 28, 28, 
-	28, 28, 28, 28, 1, 35, 35, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 35, 
-	1, 1, 35, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 35, 35, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 35, 1, 
-	36, 36, 36, 36, 36, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 36, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 37, 
-	37, 37, 37, 37, 37, 37, 37, 37, 
-	37, 1, 1, 1, 38, 39, 1, 1, 
-	37, 37, 37, 37, 37, 37, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	37, 37, 37, 37, 37, 37, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 40, 1, 41, 41, 41, 
-	41, 41, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 41, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 42, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	43, 1, 1, 7, 7, 7, 7, 7, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 7, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 4, 
-	1, 44, 44, 44, 44, 44, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	44, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 45, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 46, 1, 44, 44, 
-	44, 44, 44, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 44, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 47, 47, 47, 
-	47, 47, 47, 47, 47, 47, 47, 1, 
-	1, 1, 1, 45, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 46, 1, 49, 49, 49, 49, 49, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 49, 48, 48, 50, 48, 48, 
-	48, 48, 48, 48, 48, 51, 1, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 52, 
-	48, 48, 53, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 54, 55, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 56, 48, 
-	57, 57, 57, 57, 57, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 57, 
-	35, 35, 58, 35, 35, 35, 35, 35, 
-	35, 35, 59, 1, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 60, 35, 35, 61, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 62, 63, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 35, 35, 35, 35, 35, 
-	35, 35, 35, 64, 35, 65, 65, 65, 
-	65, 65, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 65, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 66, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	67, 1, 68, 68, 68, 68, 68, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 68, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 42, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 69, 1, 70, 
-	70, 70, 70, 70, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 70, 48, 
-	48, 50, 48, 48, 48, 48, 48, 48, 
-	48, 51, 1, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 52, 48, 48, 53, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 54, 55, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 48, 48, 48, 48, 48, 48, 
-	48, 48, 56, 48, 71, 71, 71, 71, 
-	71, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 71, 1, 1, 72, 1, 
-	1, 1, 1, 1, 1, 1, 1, 73, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	74, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 75, 
-	1, 76, 76, 76, 76, 76, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	76, 1, 1, 77, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 78, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 79, 1, 76, 76, 
-	76, 76, 76, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 76, 1, 1, 
-	77, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 21, 21, 21, 
-	21, 21, 21, 21, 21, 21, 21, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 78, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 79, 1, 71, 71, 71, 71, 71, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 71, 1, 1, 72, 1, 1, 
-	1, 1, 1, 1, 1, 1, 73, 1, 
-	1, 1, 16, 16, 16, 16, 16, 16, 
-	16, 16, 16, 16, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 74, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 75, 1, 
-	80, 80, 80, 80, 80, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 80, 
-	1, 1, 81, 1, 1, 1, 1, 1, 
-	1, 1, 82, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 83, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 45, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 84, 1, 85, 85, 85, 
-	85, 85, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 85, 1, 1, 86, 
-	1, 1, 1, 1, 1, 1, 1, 87, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 88, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	89, 1, 85, 85, 85, 85, 85, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 85, 1, 1, 86, 1, 1, 1, 
-	1, 1, 1, 1, 87, 1, 1, 1, 
-	1, 34, 34, 34, 34, 34, 34, 34, 
-	34, 34, 34, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 88, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 89, 1, 80, 
-	80, 80, 80, 80, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 80, 1, 
-	1, 81, 1, 1, 1, 1, 1, 1, 
-	1, 82, 1, 1, 1, 1, 90, 90, 
-	90, 90, 90, 90, 90, 90, 90, 90, 
-	1, 1, 1, 1, 1, 1, 83, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 45, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 84, 1, 65, 65, 65, 65, 
-	65, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 65, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 91, 91, 91, 91, 91, 
-	91, 91, 91, 91, 91, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	66, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 1, 67, 
-	1, 0
-};
-
-static const char _deserialize_text_trans_targs[] = {
-	1, 0, 2, 26, 3, 4, 20, 5, 
-	24, 25, 28, 39, 9, 31, 34, 31, 
-	34, 11, 32, 33, 32, 33, 35, 38, 
-	14, 15, 18, 15, 18, 16, 17, 36, 
-	37, 36, 37, 27, 21, 20, 6, 22, 
-	23, 21, 22, 23, 21, 22, 23, 25, 
-	27, 27, 7, 8, 12, 13, 19, 22, 
-	30, 27, 7, 8, 12, 13, 19, 22, 
-	30, 29, 22, 30, 29, 30, 30, 29, 
-	7, 10, 22, 30, 29, 7, 22, 30, 
-	29, 7, 8, 13, 30, 29, 7, 8, 
-	22, 30, 38, 39
-};
-
-static const char _deserialize_text_trans_actions[] = {
-	0, 0, 0, 0, 1, 0, 2, 0, 
-	2, 2, 3, 3, 4, 3, 3, 5, 
-	5, 4, 3, 3, 5, 5, 3, 3, 
-	4, 4, 4, 0, 0, 6, 4, 3, 
-	3, 5, 5, 5, 7, 8, 9, 7, 
-	7, 0, 0, 0, 10, 10, 10, 8, 
-	12, 13, 14, 14, 14, 14, 15, 11, 
-	11, 17, 18, 18, 18, 18, 0, 16, 
-	16, 19, 19, 19, 0, 0, 13, 20, 
-	21, 21, 20, 20, 22, 23, 22, 22, 
-	10, 24, 24, 24, 10, 25, 26, 26, 
-	25, 25, 5, 5
-};
-
-static const char _deserialize_text_eof_actions[] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0, 7, 0, 0, 0, 
-	10, 10, 11, 16, 19, 0, 11, 20, 
-	22, 22, 20, 10, 25, 25, 10, 19
-};
-
-static const int deserialize_text_start = 1;
-static const int deserialize_text_first_final = 20;
-static const int deserialize_text_error = 0;
-
-static const int deserialize_text_en_main = 1;
-
-
-#line 117 "hb-buffer-deserialize-text.rl"
-
-
-static hb_bool_t
-_hb_buffer_deserialize_text (hb_buffer_t *buffer,
-				    const char *buf,
-				    unsigned int buf_len,
-				    const char **end_ptr,
-				    hb_font_t *font)
-{
-  const char *p = buf, *pe = buf + buf_len;
-
-  /* Ensure we have positions. */
-  (void) hb_buffer_get_glyph_positions (buffer, nullptr);
-
-  while (p < pe && ISSPACE (*p))
-    p++;
-
-  const char *eof = pe, *tok = nullptr;
-  int cs;
-  hb_glyph_info_t info = {0};
-  hb_glyph_position_t pos = {0};
-  
-#line 457 "hb-buffer-deserialize-text.hh"
-	{
-	cs = deserialize_text_start;
-	}
-
-#line 460 "hb-buffer-deserialize-text.hh"
-	{
-	int _slen;
-	int _trans;
-	const unsigned char *_keys;
-	const char *_inds;
-	if ( p == pe )
-		goto _test_eof;
-	if ( cs == 0 )
-		goto _out;
-_resume:
-	_keys = _deserialize_text_trans_keys + (cs<<1);
-	_inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
-
-	_slen = _deserialize_text_key_spans[cs];
-	_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
-		(*p) <= _keys[1] ?
-		(*p) - _keys[0] : _slen ];
-
-	cs = _deserialize_text_trans_targs[_trans];
-
-	if ( _deserialize_text_trans_actions[_trans] == 0 )
-		goto _again;
-
-	switch ( _deserialize_text_trans_actions[_trans] ) {
-	case 1:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-	break;
-	case 4:
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-	break;
-	case 5:
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-	break;
-	case 8:
-#line 56 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_unicode ())) return false; }
-	break;
-	case 18:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-	break;
-	case 9:
-#line 66 "hb-buffer-deserialize-text.rl"
-	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
-	break;
-	case 24:
-#line 68 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
-	break;
-	case 6:
-#line 69 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
-	break;
-	case 26:
-#line 70 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
-	break;
-	case 21:
-#line 71 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
-	break;
-	case 23:
-#line 72 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
-	break;
-	case 15:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-	break;
-	case 3:
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-	break;
-	case 2:
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 56 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_unicode ())) return false; }
-	break;
-	case 16:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 7:
-#line 66 "hb-buffer-deserialize-text.rl"
-	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 10:
-#line 68 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 25:
-#line 70 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 20:
-#line 71 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 22:
-#line 72 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 19:
-#line 73 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 12:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-	break;
-	case 14:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-	break;
-	case 17:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 11:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 13:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 55 "hb-buffer-deserialize-text.rl"
-	{ if (unlikely (!buffer->ensure_glyphs ())) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-#line 715 "hb-buffer-deserialize-text.hh"
-	}
-
-_again:
-	if ( cs == 0 )
-		goto _out;
-	if ( ++p != pe )
-		goto _resume;
-	_test_eof: {}
-	if ( p == eof )
-	{
-	switch ( _deserialize_text_eof_actions[cs] ) {
-	case 16:
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 7:
-#line 66 "hb-buffer-deserialize-text.rl"
-	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 10:
-#line 68 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 25:
-#line 70 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 20:
-#line 71 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 22:
-#line 72 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 19:
-#line 73 "hb-buffer-deserialize-text.rl"
-	{ if (!parse_uint (tok, p, &info.mask    )) return false; }
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-	case 11:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-#line 51 "hb-buffer-deserialize-text.rl"
-	{
-	tok = p;
-}
-#line 58 "hb-buffer-deserialize-text.rl"
-	{
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-#line 43 "hb-buffer-deserialize-text.rl"
-	{
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-	break;
-#line 825 "hb-buffer-deserialize-text.hh"
-	}
-	}
-
-	_out: {}
-	}
-
-#line 141 "hb-buffer-deserialize-text.rl"
-
-
-  *end_ptr = p;
-
-  return p == pe && *(p-1) != ']';
-}
-
-#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-deserialize-text.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,148 +0,0 @@
-/*
- * Copyright © 2013  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH
-#define HB_BUFFER_DESERIALIZE_TEXT_HH
-
-#include "hb.hh"
-
-%%{
-
-machine deserialize_text;
-alphtype unsigned char;
-write data;
-
-action clear_item {
-	hb_memset (&info, 0, sizeof (info));
-	hb_memset (&pos , 0, sizeof (pos ));
-}
-
-action add_item {
-	buffer->add_info (info);
-	if (unlikely (!buffer->successful))
-	  return false;
-	buffer->pos[buffer->len - 1] = pos;
-	*end_ptr = p;
-}
-
-action tok {
-	tok = p;
-}
-
-action ensure_glyphs { if (unlikely (!buffer->ensure_glyphs ())) return false; }
-action ensure_unicode { if (unlikely (!buffer->ensure_unicode ())) return false; }
-
-action parse_glyph {
-	/* TODO Unescape delimiters. */
-	if (!hb_font_glyph_from_string (font,
-					tok, p - tok,
-					&info.codepoint))
-	  return false;
-}
-
-action parse_hexdigits  {if (!parse_hex (tok, p, &info.codepoint )) return false; }
-
-action parse_cluster	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
-action parse_x_offset	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
-action parse_y_offset	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
-action parse_x_advance	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
-action parse_y_advance	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
-action parse_glyph_flags{ if (!parse_uint (tok, p, &info.mask    )) return false; }
-
-unum  = '0' | [1-9] digit*;
-num	= '-'? unum;
-
-glyph_id = unum;
-glyph_name = ([^\\\]=@+,#|] | '\\' [\\\]=@+,|]) *;
-
-glyph	= (glyph_id | glyph_name) >tok %parse_glyph;
-cluster	= '=' (unum >tok %parse_cluster);
-offsets	= '@' (num >tok %parse_x_offset)   ',' (num >tok %parse_y_offset );
-advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?;
-glyphflags= '#' (unum >tok %parse_glyph_flags);
-
-glyph_item	=
-	(
-		glyph
-		cluster?
-		offsets?
-		advances?
-		glyphflags?
-	)
-	>clear_item
-	@ensure_glyphs
-	%add_item
-	;
-
-unicode = 'U' '+' xdigit+ >tok %parse_hexdigits;
-
-unicode_item	=
-	(
-		unicode
-		cluster?
-	)
-	>clear_item
-	@ensure_unicode
-	%add_item
-	;
-
-glyphs = glyph_item (space* '|' space* glyph_item)* space* ('|'|']')?;
-unicodes = unicode_item (space* '|' space* unicode_item)* space* ('|'|'>')?;
-
-main := space* ( ('[' glyphs) | ('<' unicodes) );
-
-}%%
-
-static hb_bool_t
-_hb_buffer_deserialize_text (hb_buffer_t *buffer,
-				    const char *buf,
-				    unsigned int buf_len,
-				    const char **end_ptr,
-				    hb_font_t *font)
-{
-  const char *p = buf, *pe = buf + buf_len;
-
-  /* Ensure we have positions. */
-  (void) hb_buffer_get_glyph_positions (buffer, nullptr);
-
-  while (p < pe && ISSPACE (*p))
-    p++;
-
-  const char *eof = pe, *tok = nullptr;
-  int cs;
-  hb_glyph_info_t info = {0};
-  hb_glyph_position_t pos = {0};
-  %%{
-    write init;
-    write exec;
-  }%%
-
-  *end_ptr = p;
-
-  return p == pe && *(p-1) != ']';
-}
-
-#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-serialize.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -721,7 +721,8 @@
 }
 
 #include "hb-buffer-deserialize-json.hh"
-#include "hb-buffer-deserialize-text.hh"
+#include "hb-buffer-deserialize-text-glyphs.hh"
+#include "hb-buffer-deserialize-text-unicode.hh"
 
 /**
  * hb_buffer_deserialize_glyphs:
@@ -736,7 +737,8 @@
  * Deserializes glyphs @buffer from textual representation in the format
  * produced by hb_buffer_serialize_glyphs().
  *
- * Return value: `true` if @buf is not fully consumed, `false` otherwise.
+ * Return value: `true` if parse was successful, `false` if an error
+ * occurred.
  *
  * Since: 0.9.7
  **/
@@ -779,9 +781,9 @@
   switch (format)
   {
     case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
-      return _hb_buffer_deserialize_text (buffer,
-                                          buf, buf_len, end_ptr,
-                                          font);
+      return _hb_buffer_deserialize_text_glyphs (buffer,
+						 buf, buf_len, end_ptr,
+						 font);
 
     case HB_BUFFER_SERIALIZE_FORMAT_JSON:
       return _hb_buffer_deserialize_json (buffer,
@@ -808,7 +810,8 @@
  * Deserializes Unicode @buffer from textual representation in the format
  * produced by hb_buffer_serialize_unicode().
  *
- * Return value: `true` if @buf is not fully consumed, `false` otherwise.
+ * Return value: `true` if parse was successful, `false` if an error
+ * occurred.
  *
  * Since: 2.7.3
  **/
@@ -849,9 +852,9 @@
   switch (format)
   {
     case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
-      return _hb_buffer_deserialize_text (buffer,
-                                          buf, buf_len, end_ptr,
-                                          font);
+      return _hb_buffer_deserialize_text_unicode (buffer,
+						  buf, buf_len, end_ptr,
+						  font);
 
     case HB_BUFFER_SERIALIZE_FORMAT_JSON:
       return _hb_buffer_deserialize_json (buffer,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer-verify.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -150,7 +150,7 @@
     assert (text_start < text_end);
 
     if (0)
-      printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end);
+      printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end);
 
     hb_buffer_clear_contents (fragment);
 
@@ -292,7 +292,7 @@
       assert (text_start < text_end);
 
       if (0)
-	printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end);
+	printf("start %u end %u text start %u end %u\n", start, end, text_start, text_end);
 
 #if 0
       hb_buffer_flags_t flags = hb_buffer_get_flags (fragment);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -522,15 +522,17 @@
     cluster = hb_min (cluster, info[i].cluster);
 
   /* Extend end */
-  while (end < len && info[end - 1].cluster == info[end].cluster)
-    end++;
+  if (cluster != info[end - 1].cluster)
+    while (end < len && info[end - 1].cluster == info[end].cluster)
+      end++;
 
   /* Extend start */
-  while (idx < start && info[start - 1].cluster == info[start].cluster)
-    start--;
+  if (cluster != info[start].cluster)
+    while (idx < start && info[start - 1].cluster == info[start].cluster)
+      start--;
 
   /* If we hit the start of buffer, continue in out-buffer. */
-  if (idx == start)
+  if (idx == start && info[start].cluster != cluster)
     for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
       set_cluster (out_info[i - 1], cluster);
 
@@ -893,6 +895,32 @@
  * Sets the type of @buffer contents. Buffers are either empty, contain
  * characters (before shaping), or contain glyphs (the result of shaping).
  *
+ * You rarely need to call this function, since a number of other
+ * functions transition the content type for you. Namely:
+ *
+ * - A newly created buffer starts with content type
+ *   %HB_BUFFER_CONTENT_TYPE_INVALID. Calling hb_buffer_reset(),
+ *   hb_buffer_clear_contents(), as well as calling hb_buffer_set_length()
+ *   with an argument of zero all set the buffer content type to invalid
+ *   as well.
+ *
+ * - Calling hb_buffer_add_utf8(), hb_buffer_add_utf16(),
+ *   hb_buffer_add_utf32(), hb_buffer_add_codepoints() and
+ *   hb_buffer_add_latin1() expect that buffer is either empty and
+ *   have a content type of invalid, or that buffer content type is
+ *   %HB_BUFFER_CONTENT_TYPE_UNICODE, and they also set the content
+ *   type to Unicode if they added anything to an empty buffer.
+ *
+ * - Finally hb_shape() and hb_shape_full() expect that the buffer
+ *   is either empty and have content type of invalid, or that buffer
+ *   content type is %HB_BUFFER_CONTENT_TYPE_UNICODE, and upon
+ *   success they set the buffer content type to
+ *   %HB_BUFFER_CONTENT_TYPE_GLYPHS.
+ *
+ * The above transitions are designed such that one can use a buffer
+ * in a loop of "reset : add-text : shape" without needing to ever
+ * modify the content type manually.
+ *
  * Since: 0.9.5
  **/
 void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -763,7 +763,7 @@
 
 
 /*
- * Debugging.
+ * Tracing.
  */
 
 /**

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-buffer.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -35,26 +35,6 @@
 #include "hb-set-digest.hh"
 
 
-#ifndef HB_BUFFER_MAX_LEN_FACTOR
-#define HB_BUFFER_MAX_LEN_FACTOR 64
-#endif
-#ifndef HB_BUFFER_MAX_LEN_MIN
-#define HB_BUFFER_MAX_LEN_MIN 16384
-#endif
-#ifndef HB_BUFFER_MAX_LEN_DEFAULT
-#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
-#endif
-
-#ifndef HB_BUFFER_MAX_OPS_FACTOR
-#define HB_BUFFER_MAX_OPS_FACTOR 1024
-#endif
-#ifndef HB_BUFFER_MAX_OPS_MIN
-#define HB_BUFFER_MAX_OPS_MIN 16384
-#endif
-#ifndef HB_BUFFER_MAX_OPS_DEFAULT
-#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
-#endif
-
 static_assert ((sizeof (hb_glyph_info_t) == 20), "");
 static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), "");
 
@@ -601,21 +581,59 @@
 			  unsigned int cluster,
 			  hb_mask_t mask)
   {
-    for (unsigned int i = start; i < end; i++)
-      if (cluster != infos[i].cluster)
+    if (unlikely (start == end))
+      return;
+
+    unsigned cluster_first = infos[start].cluster;
+    unsigned cluster_last = infos[end - 1].cluster;
+
+    if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS ||
+	(cluster != cluster_first && cluster != cluster_last))
+    {
+      for (unsigned int i = start; i < end; i++)
+	if (cluster != infos[i].cluster)
+	{
+	  scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
+	  infos[i].mask |= mask;
+	}
+      return;
+    }
+
+    /* Monotone clusters */
+
+    if (cluster == cluster_first)
+    {
+      for (unsigned int i = end; start < i && infos[i - 1].cluster != cluster_first; i--)
       {
 	scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
+	infos[i - 1].mask |= mask;
+      }
+    }
+    else /* cluster == cluster_last */
+    {
+      for (unsigned int i = start; i < end && infos[i].cluster != cluster_last; i++)
+      {
+	scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
 	infos[i].mask |= mask;
       }
+    }
   }
-  static unsigned
+  unsigned
   _infos_find_min_cluster (const hb_glyph_info_t *infos,
 			   unsigned start, unsigned end,
 			   unsigned cluster = UINT_MAX)
   {
-    for (unsigned int i = start; i < end; i++)
-      cluster = hb_min (cluster, infos[i].cluster);
-    return cluster;
+    if (unlikely (start == end))
+      return cluster;
+
+    if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+    {
+      for (unsigned int i = start; i < end; i++)
+	cluster = hb_min (cluster, infos[i].cluster);
+      return cluster;
+    }
+
+    return hb_min (cluster, hb_min (infos[start].cluster, infos[end - 1].cluster));
   }
 
   void clear_glyph_flags (hb_mask_t mask = 0)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cache.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -39,8 +39,10 @@
 struct hb_cache_t
 {
   using item_t = typename std::conditional<thread_safe,
-					   hb_atomic_int_t,
 					   typename std::conditional<key_bits + value_bits - cache_bits <= 16,
+								     hb_atomic_short_t,
+								     hb_atomic_int_t>::type,
+					   typename std::conditional<key_bits + value_bits - cache_bits <= 16,
 								     short,
 								     int>::type
 					  >::type;
@@ -48,8 +50,9 @@
   static_assert ((key_bits >= cache_bits), "");
   static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
 
+  hb_cache_t () { init (); }
+
   void init () { clear (); }
-  void fini () {}
 
   void clear ()
   {

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,869 @@
+/*
+ * Copyright © 2022  Red Hat, Inc
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Matthias Clasen
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_CAIRO
+
+#include "hb-cairo-utils.hh"
+
+#include <cairo.h>
+
+#define PREALLOCATED_COLOR_STOPS 16
+
+#define _2_M_PIf (2.f * float (M_PI))
+
+typedef struct {
+  float r, g, b, a;
+} hb_cairo_color_t;
+
+static inline cairo_extend_t
+hb_cairo_extend (hb_paint_extend_t extend)
+{
+  switch (extend)
+    {
+    case HB_PAINT_EXTEND_PAD: return CAIRO_EXTEND_PAD;
+    case HB_PAINT_EXTEND_REPEAT: return CAIRO_EXTEND_REPEAT;
+    case HB_PAINT_EXTEND_REFLECT: return CAIRO_EXTEND_REFLECT;
+    default: break;
+    }
+
+  return CAIRO_EXTEND_PAD;
+}
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+typedef struct
+{
+  hb_blob_t *blob;
+  unsigned int offset;
+} hb_cairo_read_blob_data_t;
+
+static cairo_status_t
+hb_cairo_read_blob (void *closure,
+		    unsigned char *data,
+		    unsigned int length)
+{
+  hb_cairo_read_blob_data_t *r = (hb_cairo_read_blob_data_t *) closure;
+  const char *d;
+  unsigned int size;
+
+  d = hb_blob_get_data (r->blob, &size);
+
+  if (r->offset + length > size)
+    return CAIRO_STATUS_READ_ERROR;
+
+  memcpy (data, d + r->offset, length);
+  r->offset += length;
+
+  return CAIRO_STATUS_SUCCESS;
+}
+#endif
+
+static const cairo_user_data_key_t *_hb_cairo_surface_blob_user_data_key = {0};
+
+static void
+_hb_cairo_destroy_blob (void *p)
+{
+  hb_blob_destroy ((hb_blob_t *) p);
+}
+
+hb_bool_t
+_hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
+			     hb_blob_t *blob,
+			     unsigned width,
+			     unsigned height,
+			     hb_tag_t format,
+			     float slant,
+			     hb_glyph_extents_t *extents)
+{
+  cairo_t *cr = c->cr;
+
+  if (!extents) /* SVG currently. */
+    return false;
+
+  cairo_surface_t *surface = nullptr;
+
+#ifdef CAIRO_HAS_PNG_FUNCTIONS
+  if (format == HB_PAINT_IMAGE_FORMAT_PNG)
+  {
+    hb_cairo_read_blob_data_t r;
+    r.blob = blob;
+    r.offset = 0;
+    surface = cairo_image_surface_create_from_png_stream (hb_cairo_read_blob, &r);
+
+    /* For PNG, width,height can be unreliable, as is the case for NotoColorEmoji :(.
+     * Just pull them out of the surface. */
+    width = cairo_image_surface_get_width (surface);
+    height = cairo_image_surface_get_width (surface);
+  }
+  else
+#endif
+  if (format == HB_PAINT_IMAGE_FORMAT_BGRA)
+  {
+    /* Byte-endian conversion. */
+    unsigned data_size = hb_blob_get_length (blob);
+    if (data_size < width * height * 4)
+      return false;
+
+    unsigned char *data;
+#ifdef __BYTE_ORDER
+    if (__BYTE_ORDER == __BIG_ENDIAN)
+    {
+      data = (unsigned char *) hb_blob_get_data_writable (blob, nullptr);
+      if (!data)
+        return false;
+
+      unsigned count = width * height * 4;
+      for (unsigned i = 0; i < count; i += 4)
+      {
+        unsigned char b;
+	b = data[i];
+	data[i] = data[i+3];
+	data[i+3] = b;
+	b = data[i+1];
+	data[i+1] = data[i+2];
+	data[i+2] = b;
+      }
+    }
+    else
+#endif
+      data = (unsigned char *) hb_blob_get_data (blob, nullptr);
+
+    surface = cairo_image_surface_create_for_data (data,
+						   CAIRO_FORMAT_ARGB32,
+						   width, height,
+						   width * 4);
+
+    cairo_surface_set_user_data (surface,
+				 _hb_cairo_surface_blob_user_data_key,
+				 hb_blob_reference (blob),
+				 _hb_cairo_destroy_blob);
+  }
+
+  if (!surface)
+    return false;
+
+  cairo_save (cr);
+  /* this clip is here to work around recording surface limitations */
+  cairo_rectangle (cr,
+                   extents->x_bearing,
+                   extents->y_bearing,
+                   extents->width,
+                   extents->height);
+  cairo_clip (cr);
+
+  cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
+  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
+
+  cairo_matrix_t matrix = {(double) width, 0, 0, (double) height, 0, 0};
+  cairo_pattern_set_matrix (pattern, &matrix);
+
+  /* Undo slant in the extents and apply it in the context. */
+  extents->width -= extents->height * slant;
+  extents->x_bearing -= extents->y_bearing * slant;
+  cairo_matrix_t cairo_matrix = {1., 0., (double) slant, 1., 0., 0.};
+  cairo_transform (cr, &cairo_matrix);
+
+  cairo_translate (cr, extents->x_bearing, extents->y_bearing);
+  cairo_scale (cr, extents->width, extents->height);
+  cairo_set_source (cr, pattern);
+
+  cairo_paint (cr);
+
+  cairo_pattern_destroy (pattern);
+  cairo_surface_destroy (surface);
+
+  cairo_restore (cr);
+
+  return true;
+}
+
+static void
+_hb_cairo_reduce_anchors (float x0, float y0,
+			  float x1, float y1,
+			  float x2, float y2,
+			  float *xx0, float *yy0,
+			  float *xx1, float *yy1)
+{
+  float q1x, q1y, q2x, q2y;
+  float s;
+  float k;
+
+  q2x = x2 - x0;
+  q2y = y2 - y0;
+  q1x = x1 - x0;
+  q1y = y1 - y0;
+
+  s = q2x * q2x + q2y * q2y;
+  if (s < 0.000001f)
+    {
+      *xx0 = x0; *yy0 = y0;
+      *xx1 = x1; *yy1 = y1;
+      return;
+    }
+
+  k = (q2x * q1x + q2y * q1y) / s;
+  *xx0 = x0;
+  *yy0 = y0;
+  *xx1 = x1 - k * q2x;
+  *yy1 = y1 - k * q2y;
+}
+
+static int
+_hb_cairo_cmp_color_stop (const void *p1,
+			  const void *p2)
+{
+  const hb_color_stop_t *c1 = (const hb_color_stop_t *) p1;
+  const hb_color_stop_t *c2 = (const hb_color_stop_t *) p2;
+
+  if (c1->offset < c2->offset)
+    return -1;
+  else if (c1->offset > c2->offset)
+    return 1;
+  else
+    return 0;
+}
+
+static void
+_hb_cairo_normalize_color_line (hb_color_stop_t *stops,
+				unsigned int len,
+				float *omin,
+				float *omax)
+{
+  float min, max;
+
+  hb_qsort (stops, len, sizeof (hb_color_stop_t), _hb_cairo_cmp_color_stop);
+
+  min = max = stops[0].offset;
+  for (unsigned int i = 0; i < len; i++)
+    {
+      min = hb_min (min, stops[i].offset);
+      max = hb_max (max, stops[i].offset);
+    }
+
+  if (min != max)
+    {
+      for (unsigned int i = 0; i < len; i++)
+        stops[i].offset = (stops[i].offset - min) / (max - min);
+    }
+
+  *omin = min;
+  *omax = max;
+}
+
+static bool
+_hb_cairo_get_color_stops (hb_cairo_context_t *c,
+			   hb_color_line_t *color_line,
+			   unsigned *count,
+			   hb_color_stop_t **stops)
+{
+  unsigned len = hb_color_line_get_color_stops (color_line, 0, nullptr, nullptr);
+  if (len > *count)
+  {
+    *stops = (hb_color_stop_t *) hb_malloc (len * sizeof (hb_color_stop_t));
+    if (unlikely (!stops))
+      return false;
+  }
+  hb_color_line_get_color_stops (color_line, 0, &len, *stops);
+  for (unsigned i = 0; i < len; i++)
+    if ((*stops)[i].is_foreground)
+    {
+#ifdef HAVE_CAIRO_USER_SCALED_FONT_GET_FOREGROUND_SOURCE
+      double r, g, b, a;
+      cairo_pattern_t *foreground = cairo_user_scaled_font_get_foreground_source (c->scaled_font);
+      if (cairo_pattern_get_rgba (foreground, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
+        (*stops)[i].color = HB_COLOR (round (b * 255.), round (g * 255.), round (r * 255.),
+                                      round (a * hb_color_get_alpha ((*stops)[i].color)));
+      else
+#endif
+        (*stops)[i].color = HB_COLOR (0, 0, 0, hb_color_get_alpha ((*stops)[i].color));
+    }
+
+  *count = len;
+  return true;
+}
+
+void
+_hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
+				 hb_color_line_t *color_line,
+				 float x0, float y0,
+				 float x1, float y1,
+				 float x2, float y2)
+{
+  cairo_t *cr = c->cr;
+
+  unsigned int len = PREALLOCATED_COLOR_STOPS;
+  hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
+  hb_color_stop_t *stops = stops_;
+  float xx0, yy0, xx1, yy1;
+  float xxx0, yyy0, xxx1, yyy1;
+  float min, max;
+  cairo_pattern_t *pattern;
+
+  if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
+    return;
+  _hb_cairo_normalize_color_line (stops, len, &min, &max);
+
+  _hb_cairo_reduce_anchors (x0, y0, x1, y1, x2, y2, &xx0, &yy0, &xx1, &yy1);
+
+  xxx0 = xx0 + min * (xx1 - xx0);
+  yyy0 = yy0 + min * (yy1 - yy0);
+  xxx1 = xx0 + max * (xx1 - xx0);
+  yyy1 = yy0 + max * (yy1 - yy0);
+
+  pattern = cairo_pattern_create_linear ((double) xxx0, (double) yyy0, (double) xxx1, (double) yyy1);
+  cairo_pattern_set_extend (pattern, hb_cairo_extend (hb_color_line_get_extend (color_line)));
+  for (unsigned int i = 0; i < len; i++)
+    {
+      double r, g, b, a;
+      r = hb_color_get_red (stops[i].color) / 255.;
+      g = hb_color_get_green (stops[i].color) / 255.;
+      b = hb_color_get_blue (stops[i].color) / 255.;
+      a = hb_color_get_alpha (stops[i].color) / 255.;
+      cairo_pattern_add_color_stop_rgba (pattern, (double) stops[i].offset, r, g, b, a);
+    }
+
+  cairo_set_source (cr, pattern);
+  cairo_paint (cr);
+
+  cairo_pattern_destroy (pattern);
+
+  if (stops != stops_)
+    hb_free (stops);
+}
+
+void
+_hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
+				 hb_color_line_t *color_line,
+				 float x0, float y0, float r0,
+				 float x1, float y1, float r1)
+{
+  cairo_t *cr = c->cr;
+
+  unsigned int len = PREALLOCATED_COLOR_STOPS;
+  hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
+  hb_color_stop_t *stops = stops_;
+  float min, max;
+  float xx0, yy0, xx1, yy1;
+  float rr0, rr1;
+  cairo_pattern_t *pattern;
+
+  if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
+    return;
+  _hb_cairo_normalize_color_line (stops, len, &min, &max);
+
+  xx0 = x0 + min * (x1 - x0);
+  yy0 = y0 + min * (y1 - y0);
+  xx1 = x0 + max * (x1 - x0);
+  yy1 = y0 + max * (y1 - y0);
+  rr0 = r0 + min * (r1 - r0);
+  rr1 = r0 + max * (r1 - r0);
+
+  pattern = cairo_pattern_create_radial ((double) xx0, (double) yy0, (double) rr0, (double) xx1, (double) yy1, (double) rr1);
+  cairo_pattern_set_extend (pattern, hb_cairo_extend (hb_color_line_get_extend (color_line)));
+
+  for (unsigned int i = 0; i < len; i++)
+    {
+      double r, g, b, a;
+      r = hb_color_get_red (stops[i].color) / 255.;
+      g = hb_color_get_green (stops[i].color) / 255.;
+      b = hb_color_get_blue (stops[i].color) / 255.;
+      a = hb_color_get_alpha (stops[i].color) / 255.;
+      cairo_pattern_add_color_stop_rgba (pattern, (double) stops[i].offset, r, g, b, a);
+    }
+
+  cairo_set_source (cr, pattern);
+  cairo_paint (cr);
+
+  cairo_pattern_destroy (pattern);
+
+  if (stops != stops_)
+    hb_free (stops);
+}
+
+typedef struct {
+  float x, y;
+} hb_cairo_point_t;
+
+static inline float
+_hb_cairo_interpolate (float f0, float f1, float f)
+{
+  return f0 + f * (f1 - f0);
+}
+
+static inline void
+_hb_cairo_premultiply (hb_cairo_color_t *c)
+{
+  c->r *= c->a;
+  c->g *= c->a;
+  c->b *= c->a;
+}
+
+static inline void
+_hb_cairo_unpremultiply (hb_cairo_color_t *c)
+{
+  if (c->a != 0.f)
+  {
+     c->r /= c->a;
+     c->g /= c->a;
+     c->b /= c->a;
+  }
+}
+
+static void
+_hb_cairo_interpolate_colors (hb_cairo_color_t *c0, hb_cairo_color_t *c1, float k, hb_cairo_color_t *c)
+{
+  // According to the COLR specification, gradients
+  // should be interpolated in premultiplied form
+  _hb_cairo_premultiply (c0);
+  _hb_cairo_premultiply (c1);
+  c->r = c0->r + k * (c1->r - c0->r);
+  c->g = c0->g + k * (c1->g - c0->g);
+  c->b = c0->b + k * (c1->b - c0->b);
+  c->a = c0->a + k * (c1->a - c0->a);
+  _hb_cairo_unpremultiply (c);
+}
+
+static inline float
+_hb_cairo_dot (hb_cairo_point_t p, hb_cairo_point_t q)
+{
+  return p.x * q.x + p.y * q.y;
+}
+
+static inline hb_cairo_point_t
+_hb_cairo_normalize (hb_cairo_point_t p)
+{
+  float len = sqrtf (_hb_cairo_dot (p, p));
+
+  return hb_cairo_point_t { p.x / len, p.y / len };
+}
+
+static inline hb_cairo_point_t
+_hb_cairo_sum (hb_cairo_point_t p, hb_cairo_point_t q)
+{
+  return hb_cairo_point_t { p.x + q.x, p.y + q.y };
+}
+
+static inline hb_cairo_point_t
+_hb_cairo_difference (hb_cairo_point_t p, hb_cairo_point_t q)
+{
+  return hb_cairo_point_t { p.x - q.x, p.y - q.y };
+}
+
+static inline hb_cairo_point_t
+_hb_cairo_scale (hb_cairo_point_t p, float f)
+{
+  return hb_cairo_point_t { p.x * f, p.y * f };
+}
+
+typedef struct {
+  hb_cairo_point_t center, p0, c0, c1, p1;
+  hb_cairo_color_t color0, color1;
+} hb_cairo_patch_t;
+
+static void
+_hb_cairo_add_patch (cairo_pattern_t *pattern, hb_cairo_point_t *center, hb_cairo_patch_t *p)
+{
+  cairo_mesh_pattern_begin_patch (pattern);
+  cairo_mesh_pattern_move_to (pattern, (double) center->x, (double) center->y);
+  cairo_mesh_pattern_line_to (pattern, (double) p->p0.x, (double) p->p0.y);
+  cairo_mesh_pattern_curve_to (pattern,
+                               (double) p->c0.x, (double) p->c0.y,
+                               (double) p->c1.x, (double) p->c1.y,
+                               (double) p->p1.x, (double) p->p1.y);
+  cairo_mesh_pattern_line_to (pattern, (double) center->x, (double) center->y);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 0,
+                                            (double) p->color0.r,
+                                            (double) p->color0.g,
+                                            (double) p->color0.b,
+                                            (double) p->color0.a);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 1,
+                                            (double) p->color0.r,
+                                            (double) p->color0.g,
+                                            (double) p->color0.b,
+                                            (double) p->color0.a);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 2,
+                                            (double) p->color1.r,
+                                            (double) p->color1.g,
+                                            (double) p->color1.b,
+                                            (double) p->color1.a);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 3,
+                                            (double) p->color1.r,
+                                            (double) p->color1.g,
+                                            (double) p->color1.b,
+                                            (double) p->color1.a);
+  cairo_mesh_pattern_end_patch (pattern);
+}
+
+#define MAX_ANGLE ((float) M_PI / 8.f)
+
+static void
+_hb_cairo_add_sweep_gradient_patches1 (float cx, float cy, float radius,
+				       float a0, hb_cairo_color_t *c0,
+				       float a1, hb_cairo_color_t *c1,
+				       cairo_pattern_t *pattern)
+{
+  hb_cairo_point_t center = hb_cairo_point_t { cx, cy };
+  int num_splits;
+  hb_cairo_point_t p0;
+  hb_cairo_color_t color0, color1;
+
+  num_splits = ceilf (fabsf (a1 - a0) / MAX_ANGLE);
+  p0 = hb_cairo_point_t { cosf (a0), sinf (a0) };
+  color0 = *c0;
+
+  for (int a = 0; a < num_splits; a++)
+    {
+      float k = (a + 1.) / num_splits;
+      float angle1;
+      hb_cairo_point_t p1;
+      hb_cairo_point_t A, U;
+      hb_cairo_point_t C0, C1;
+      hb_cairo_patch_t patch;
+
+      angle1 = _hb_cairo_interpolate (a0, a1, k);
+      _hb_cairo_interpolate_colors (c0, c1, k, &color1);
+
+      patch.color0 = color0;
+      patch.color1 = color1;
+
+      p1 = hb_cairo_point_t { cosf (angle1), sinf (angle1) };
+      patch.p0 = _hb_cairo_sum (center, _hb_cairo_scale (p0, radius));
+      patch.p1 = _hb_cairo_sum (center, _hb_cairo_scale (p1, radius));
+
+      A = _hb_cairo_normalize (_hb_cairo_sum (p0, p1));
+      U = hb_cairo_point_t { -A.y, A.x };
+      C0 = _hb_cairo_sum (A, _hb_cairo_scale (U, _hb_cairo_dot (_hb_cairo_difference (p0, A), p0) / _hb_cairo_dot (U, p0)));
+      C1 = _hb_cairo_sum (A, _hb_cairo_scale (U, _hb_cairo_dot (_hb_cairo_difference (p1, A), p1) / _hb_cairo_dot (U, p1)));
+
+      patch.c0 = _hb_cairo_sum (center, _hb_cairo_scale (_hb_cairo_sum (C0, _hb_cairo_scale (_hb_cairo_difference (C0, p0), 0.33333f)), radius));
+      patch.c1 = _hb_cairo_sum (center, _hb_cairo_scale (_hb_cairo_sum (C1, _hb_cairo_scale (_hb_cairo_difference (C1, p1), 0.33333f)), radius));
+
+      _hb_cairo_add_patch (pattern, &center, &patch);
+
+      p0 = p1;
+      color0 = color1;
+    }
+}
+
+static void
+_hb_cairo_add_sweep_gradient_patches (hb_color_stop_t *stops,
+				      unsigned int n_stops,
+				      cairo_extend_t extend,
+				      float cx, float cy,
+				      float radius,
+				      float start_angle,
+				      float end_angle,
+				      cairo_pattern_t *pattern)
+{
+  float angles_[PREALLOCATED_COLOR_STOPS];
+  float *angles = angles_;
+  hb_cairo_color_t colors_[PREALLOCATED_COLOR_STOPS];
+  hb_cairo_color_t *colors = colors_;
+  hb_cairo_color_t color0, color1;
+
+  if (start_angle == end_angle)
+  {
+    if (extend == CAIRO_EXTEND_PAD)
+    {
+      hb_cairo_color_t c;
+      if (start_angle > 0)
+      {
+	c.r = hb_color_get_red (stops[0].color) / 255.;
+	c.g = hb_color_get_green (stops[0].color) / 255.;
+	c.b = hb_color_get_blue (stops[0].color) / 255.;
+	c.a = hb_color_get_alpha (stops[0].color) / 255.;
+	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					       0.,          &c,
+					       start_angle, &c,
+					       pattern);
+      }
+      if (end_angle < _2_M_PIf)
+      {
+	c.r = hb_color_get_red (stops[n_stops - 1].color) / 255.;
+	c.g = hb_color_get_green (stops[n_stops - 1].color) / 255.;
+	c.b = hb_color_get_blue (stops[n_stops - 1].color) / 255.;
+	c.a = hb_color_get_alpha (stops[n_stops - 1].color) / 255.;
+	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					       end_angle, &c,
+					       _2_M_PIf,  &c,
+					       pattern);
+      }
+    }
+    return;
+  }
+
+  assert (start_angle != end_angle);
+
+  /* handle directions */
+  if (end_angle < start_angle)
+  {
+    hb_swap (start_angle, end_angle);
+
+    for (unsigned i = 0; i < n_stops - 1 - i; i++)
+      hb_swap (stops[i], stops[n_stops - 1 - i]);
+    for (unsigned i = 0; i < n_stops; i++)
+      stops[i].offset = 1 - stops[i].offset;
+  }
+
+  if (n_stops > PREALLOCATED_COLOR_STOPS)
+  {
+    angles = (float *) hb_malloc (sizeof (float) * n_stops);
+    colors = (hb_cairo_color_t *) hb_malloc (sizeof (hb_cairo_color_t) * n_stops);
+    if (unlikely (!angles || !colors))
+    {
+      hb_free (angles);
+      hb_free (colors);
+      return;
+    }
+  }
+
+  for (unsigned i = 0; i < n_stops; i++)
+  {
+    angles[i] = start_angle + stops[i].offset * (end_angle - start_angle);
+    colors[i].r = hb_color_get_red (stops[i].color) / 255.;
+    colors[i].g = hb_color_get_green (stops[i].color) / 255.;
+    colors[i].b = hb_color_get_blue (stops[i].color) / 255.;
+    colors[i].a = hb_color_get_alpha (stops[i].color) / 255.;
+  }
+
+  if (extend == CAIRO_EXTEND_PAD)
+  {
+    unsigned pos;
+
+    color0 = colors[0];
+    for (pos = 0; pos < n_stops; pos++)
+    {
+      if (angles[pos] >= 0)
+      {
+	if (pos > 0)
+	{
+	  float k = (0 - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
+	  _hb_cairo_interpolate_colors (&colors[pos-1], &colors[pos], k, &color0);
+	}
+	break;
+      }
+    }
+    if (pos == n_stops)
+    {
+      /* everything is below 0 */
+      color0 = colors[n_stops-1];
+      _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					     0.,       &color0,
+					     _2_M_PIf, &color0,
+					     pattern);
+      goto done;
+    }
+
+    _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					   0.,          &color0,
+					   angles[pos], &colors[pos],
+					   pattern);
+
+    for (pos++; pos < n_stops; pos++)
+    {
+      if (angles[pos] <= _2_M_PIf)
+      {
+	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					       angles[pos - 1], &colors[pos-1],
+					       angles[pos],     &colors[pos],
+					       pattern);
+      }
+      else
+      {
+	float k = (_2_M_PIf - angles[pos - 1]) / (angles[pos] - angles[pos - 1]);
+	_hb_cairo_interpolate_colors (&colors[pos - 1], &colors[pos], k, &color1);
+	_hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					       angles[pos - 1], &colors[pos - 1],
+					       _2_M_PIf,        &color1,
+					       pattern);
+	break;
+      }
+    }
+
+    if (pos == n_stops)
+    {
+      /* everything is below 2*M_PI */
+      color0 = colors[n_stops - 1];
+      _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+					     angles[n_stops - 1], &color0,
+					     _2_M_PIf,            &color0,
+					     pattern);
+      goto done;
+    }
+  }
+  else
+  {
+    int k;
+    float span;
+
+    span = angles[n_stops - 1] - angles[0];
+    k = 0;
+    if (angles[0] >= 0)
+    {
+      float ss = angles[0];
+      while (ss > 0)
+      {
+	if (span > 0)
+	{
+	  ss -= span;
+	  k--;
+	}
+	else
+	{
+	  ss += span;
+	  k++;
+	}
+      }
+    }
+    else if (angles[0] < 0)
+    {
+      float ee = angles[n_stops - 1];
+      while (ee < 0)
+      {
+	if (span > 0)
+	{
+	  ee += span;
+	  k++;
+	}
+	else
+	{
+	  ee -= span;
+	  k--;
+	}
+      }
+    }
+
+    //assert (angles[0] + k * span <= 0 && 0 < angles[n_stops - 1] + k * span);
+    span = fabs (span);
+
+    for (signed l = k; l < 1000; l++)
+    {
+      for (unsigned i = 1; i < n_stops; i++)
+      {
+        float a0, a1;
+	hb_cairo_color_t *c0, *c1;
+
+	if ((l % 2 != 0) && (extend == CAIRO_EXTEND_REFLECT))
+	{
+	  a0 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - (i-1)] + l * span;
+	  a1 = angles[0] + angles[n_stops - 1] - angles[n_stops - 1 - i] + l * span;
+	  c0 = &colors[n_stops - 1 - (i - 1)];
+	  c1 = &colors[n_stops - 1 - i];
+	}
+	else
+	{
+	  a0 = angles[i-1] + l * span;
+	  a1 = angles[i] + l * span;
+	  c0 = &colors[i-1];
+	  c1 = &colors[i];
+	}
+
+	if (a1 < 0)
+	  continue;
+	if (a0 < 0)
+	{
+	  hb_cairo_color_t color;
+	  float f = (0 - a0)/(a1 - a0);
+	  _hb_cairo_interpolate_colors (c0, c1, f, &color);
+	  _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+						 0,  &color,
+						 a1, c1,
+						 pattern);
+	}
+	else if (a1 >= _2_M_PIf)
+	{
+	  hb_cairo_color_t color;
+	  float f = (_2_M_PIf - a0)/(a1 - a0);
+	  _hb_cairo_interpolate_colors (c0, c1, f, &color);
+	  _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+						 a0,       c0,
+						 _2_M_PIf, &color,
+						 pattern);
+	  goto done;
+	}
+	else
+	{
+	  _hb_cairo_add_sweep_gradient_patches1 (cx, cy, radius,
+						 a0, c0,
+						 a1, c1,
+						 pattern);
+	}
+      }
+    }
+  }
+
+done:
+
+  if (angles != angles_)
+    hb_free (angles);
+  if (colors != colors_)
+    hb_free (colors);
+}
+
+void
+_hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
+				hb_color_line_t *color_line,
+				float cx, float cy,
+				float start_angle,
+				float end_angle)
+{
+  cairo_t *cr = c->cr;
+
+  unsigned int len = PREALLOCATED_COLOR_STOPS;
+  hb_color_stop_t stops_[PREALLOCATED_COLOR_STOPS];
+  hb_color_stop_t *stops = stops_;
+  cairo_extend_t extend;
+  double x1, y1, x2, y2;
+  float max_x, max_y, radius;
+  cairo_pattern_t *pattern;
+
+  if (unlikely (!_hb_cairo_get_color_stops (c, color_line, &len, &stops)))
+    return;
+
+  hb_qsort (stops, len, sizeof (hb_color_stop_t), _hb_cairo_cmp_color_stop);
+
+  cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
+  max_x = (float) hb_max ((x1 - (double) cx) * (x1 - (double) cx), (x2 - (double) cx) * (x2 - (double) cx));
+  max_y = (float) hb_max ((y1 - (double) cy) * (y1 - (double) cy), (y2 - (double) cy) * (y2 - (double) cy));
+  radius = sqrtf (max_x + max_y);
+
+  extend = hb_cairo_extend (hb_color_line_get_extend (color_line));
+  pattern = cairo_pattern_create_mesh ();
+
+  _hb_cairo_add_sweep_gradient_patches (stops, len, extend, cx, cy,
+					radius, start_angle, end_angle, pattern);
+
+  cairo_set_source (cr, pattern);
+  cairo_paint (cr);
+
+  cairo_pattern_destroy (pattern);
+
+  if (stops != stops_)
+    hb_free (stops);
+}
+
+#endif

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo-utils.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2022  Red Hat, Inc
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Matthias Clasen
+ */
+
+#ifndef HB_CAIRO_UTILS_H
+#define HB_CAIRO_UTILS_H
+
+#include "hb.hh"
+#include "hb-cairo.h"
+
+
+typedef struct
+{
+  cairo_scaled_font_t *scaled_font;
+  cairo_t *cr;
+  hb_map_t *color_cache;
+} hb_cairo_context_t;
+
+static inline cairo_operator_t
+_hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode)
+{
+  switch (mode)
+    {
+    case HB_PAINT_COMPOSITE_MODE_CLEAR: return CAIRO_OPERATOR_CLEAR;
+    case HB_PAINT_COMPOSITE_MODE_SRC: return CAIRO_OPERATOR_SOURCE;
+    case HB_PAINT_COMPOSITE_MODE_DEST: return CAIRO_OPERATOR_DEST;
+    case HB_PAINT_COMPOSITE_MODE_SRC_OVER: return CAIRO_OPERATOR_OVER;
+    case HB_PAINT_COMPOSITE_MODE_DEST_OVER: return CAIRO_OPERATOR_DEST_OVER;
+    case HB_PAINT_COMPOSITE_MODE_SRC_IN: return CAIRO_OPERATOR_IN;
+    case HB_PAINT_COMPOSITE_MODE_DEST_IN: return CAIRO_OPERATOR_DEST_IN;
+    case HB_PAINT_COMPOSITE_MODE_SRC_OUT: return CAIRO_OPERATOR_OUT;
+    case HB_PAINT_COMPOSITE_MODE_DEST_OUT: return CAIRO_OPERATOR_DEST_OUT;
+    case HB_PAINT_COMPOSITE_MODE_SRC_ATOP: return CAIRO_OPERATOR_ATOP;
+    case HB_PAINT_COMPOSITE_MODE_DEST_ATOP: return CAIRO_OPERATOR_DEST_ATOP;
+    case HB_PAINT_COMPOSITE_MODE_XOR: return CAIRO_OPERATOR_XOR;
+    case HB_PAINT_COMPOSITE_MODE_PLUS: return CAIRO_OPERATOR_ADD;
+    case HB_PAINT_COMPOSITE_MODE_SCREEN: return CAIRO_OPERATOR_SCREEN;
+    case HB_PAINT_COMPOSITE_MODE_OVERLAY: return CAIRO_OPERATOR_OVERLAY;
+    case HB_PAINT_COMPOSITE_MODE_DARKEN: return CAIRO_OPERATOR_DARKEN;
+    case HB_PAINT_COMPOSITE_MODE_LIGHTEN: return CAIRO_OPERATOR_LIGHTEN;
+    case HB_PAINT_COMPOSITE_MODE_COLOR_DODGE: return CAIRO_OPERATOR_COLOR_DODGE;
+    case HB_PAINT_COMPOSITE_MODE_COLOR_BURN: return CAIRO_OPERATOR_COLOR_BURN;
+    case HB_PAINT_COMPOSITE_MODE_HARD_LIGHT: return CAIRO_OPERATOR_HARD_LIGHT;
+    case HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT: return CAIRO_OPERATOR_SOFT_LIGHT;
+    case HB_PAINT_COMPOSITE_MODE_DIFFERENCE: return CAIRO_OPERATOR_DIFFERENCE;
+    case HB_PAINT_COMPOSITE_MODE_EXCLUSION: return CAIRO_OPERATOR_EXCLUSION;
+    case HB_PAINT_COMPOSITE_MODE_MULTIPLY: return CAIRO_OPERATOR_MULTIPLY;
+    case HB_PAINT_COMPOSITE_MODE_HSL_HUE: return CAIRO_OPERATOR_HSL_HUE;
+    case HB_PAINT_COMPOSITE_MODE_HSL_SATURATION: return CAIRO_OPERATOR_HSL_SATURATION;
+    case HB_PAINT_COMPOSITE_MODE_HSL_COLOR: return CAIRO_OPERATOR_HSL_COLOR;
+    case HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY: return CAIRO_OPERATOR_HSL_LUMINOSITY;
+    default: return CAIRO_OPERATOR_CLEAR;
+    }
+}
+
+HB_INTERNAL hb_bool_t
+_hb_cairo_paint_glyph_image (hb_cairo_context_t *c,
+			     hb_blob_t *blob,
+			     unsigned width,
+			     unsigned height,
+			     hb_tag_t format,
+			     float slant,
+			     hb_glyph_extents_t *extents);
+
+HB_INTERNAL void
+_hb_cairo_paint_linear_gradient (hb_cairo_context_t *c,
+				 hb_color_line_t *color_line,
+				 float x0, float y0,
+				 float x1, float y1,
+				 float x2, float y2);
+
+HB_INTERNAL void
+_hb_cairo_paint_radial_gradient (hb_cairo_context_t *c,
+				 hb_color_line_t *color_line,
+				 float x0, float y0, float r0,
+				 float x1, float y1, float r1);
+
+HB_INTERNAL void
+_hb_cairo_paint_sweep_gradient (hb_cairo_context_t *c,
+				hb_color_line_t *color_line,
+				float x0, float y0,
+				float start_angle, float end_angle);
+
+
+#endif /* HB_CAIRO_UTILS_H */

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,1010 @@
+/*
+ * Copyright © 2022  Red Hat, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Matthias Clasen
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_CAIRO
+
+#include "hb-cairo.h"
+
+#include "hb-cairo-utils.hh"
+
+#include "hb-machinery.hh"
+#include "hb-utf.hh"
+
+
+/**
+ * SECTION:hb-cairo
+ * @title: hb-cairo
+ * @short_description: Cairo integration
+ * @include: hb-cairo.h
+ *
+ * Functions for using HarfBuzz with the cairo library.
+ *
+ * HarfBuzz supports using cairo for rendering.
+ **/
+
+static void
+hb_cairo_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
+		  void *draw_data,
+		  hb_draw_state_t *st HB_UNUSED,
+		  float to_x, float to_y,
+		  void *user_data HB_UNUSED)
+{
+  cairo_t *cr = (cairo_t *) draw_data;
+
+  cairo_move_to (cr, (double) to_x, (double) to_y);
+}
+
+static void
+hb_cairo_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
+		  void *draw_data,
+		  hb_draw_state_t *st HB_UNUSED,
+		  float to_x, float to_y,
+		  void *user_data HB_UNUSED)
+{
+  cairo_t *cr = (cairo_t *) draw_data;
+
+  cairo_line_to (cr, (double) to_x, (double) to_y);
+}
+
+static void
+hb_cairo_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
+		   void *draw_data,
+		   hb_draw_state_t *st HB_UNUSED,
+		   float control1_x, float control1_y,
+		   float control2_x, float control2_y,
+		   float to_x, float to_y,
+		   void *user_data HB_UNUSED)
+{
+  cairo_t *cr = (cairo_t *) draw_data;
+
+  cairo_curve_to (cr,
+                  (double) control1_x, (double) control1_y,
+                  (double) control2_x, (double) control2_y,
+                  (double) to_x, (double) to_y);
+}
+
+static void
+hb_cairo_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED,
+		     void *draw_data,
+		     hb_draw_state_t *st HB_UNUSED,
+		     void *user_data HB_UNUSED)
+{
+  cairo_t *cr = (cairo_t *) draw_data;
+
+  cairo_close_path (cr);
+}
+
+static inline void free_static_cairo_draw_funcs ();
+
+static struct hb_cairo_draw_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_cairo_draw_funcs_lazy_loader_t>
+{
+  static hb_draw_funcs_t *create ()
+  {
+    hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
+
+    hb_draw_funcs_set_move_to_func (funcs, hb_cairo_move_to, nullptr, nullptr);
+    hb_draw_funcs_set_line_to_func (funcs, hb_cairo_line_to, nullptr, nullptr);
+    hb_draw_funcs_set_cubic_to_func (funcs, hb_cairo_cubic_to, nullptr, nullptr);
+    hb_draw_funcs_set_close_path_func (funcs, hb_cairo_close_path, nullptr, nullptr);
+
+    hb_draw_funcs_make_immutable (funcs);
+
+    hb_atexit (free_static_cairo_draw_funcs);
+
+    return funcs;
+  }
+} static_cairo_draw_funcs;
+
+static inline
+void free_static_cairo_draw_funcs ()
+{
+  static_cairo_draw_funcs.free_instance ();
+}
+
+static hb_draw_funcs_t *
+hb_cairo_draw_get_funcs ()
+{
+  return static_cairo_draw_funcs.get_unconst ();
+}
+
+
+#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
+
+static void
+hb_cairo_push_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
+			 void *paint_data,
+			 float xx, float yx,
+			 float xy, float yy,
+			 float dx, float dy,
+			 void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_matrix_t m;
+
+  cairo_save (cr);
+  cairo_matrix_init (&m, (double) xx, (double) yx,
+                         (double) xy, (double) yy,
+                         (double) dx, (double) dy);
+  cairo_transform (cr, &m);
+}
+
+static void
+hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED,
+		        void *paint_data,
+		        void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_restore (cr);
+}
+
+static void
+hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
+			  void *paint_data,
+			  hb_codepoint_t glyph,
+			  hb_font_t *font,
+			  void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_save (cr);
+  cairo_new_path (cr);
+  hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
+  cairo_close_path (cr);
+  cairo_clip (cr);
+}
+
+static void
+hb_cairo_push_clip_rectangle (hb_paint_funcs_t *pfuncs HB_UNUSED,
+			      void *paint_data,
+			      float xmin, float ymin, float xmax, float ymax,
+			      void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_save (cr);
+  cairo_rectangle (cr,
+                   (double) xmin, (double) ymin,
+                   (double) (xmax - xmin), (double) (ymax - ymin));
+  cairo_clip (cr);
+}
+
+static void
+hb_cairo_pop_clip (hb_paint_funcs_t *pfuncs HB_UNUSED,
+		   void *paint_data,
+		   void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_restore (cr);
+}
+
+static void
+hb_cairo_push_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
+		     void *paint_data,
+		     void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_save (cr);
+  cairo_push_group (cr);
+}
+
+static void
+hb_cairo_pop_group (hb_paint_funcs_t *pfuncs HB_UNUSED,
+		    void *paint_data,
+		    hb_paint_composite_mode_t mode,
+		    void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  cairo_pop_group_to_source (cr);
+  cairo_set_operator (cr, _hb_paint_composite_mode_to_cairo (mode));
+  cairo_paint (cr);
+
+  cairo_restore (cr);
+}
+
+static void
+hb_cairo_paint_color (hb_paint_funcs_t *pfuncs HB_UNUSED,
+		      void *paint_data,
+		      hb_bool_t use_foreground,
+		      hb_color_t color,
+		      void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+  if (use_foreground)
+  {
+#ifdef HAVE_CAIRO_USER_SCALED_FONT_GET_FOREGROUND_SOURCE
+    double r, g, b, a;
+    cairo_pattern_t *foreground = cairo_user_scaled_font_get_foreground_source (c->scaled_font);
+    if (cairo_pattern_get_rgba (foreground, &r, &g, &b, &a) == CAIRO_STATUS_SUCCESS)
+      cairo_set_source_rgba (cr, r, g, b, a * hb_color_get_alpha (color) / 255.);
+    else
+#endif
+      cairo_set_source_rgba (cr, 0, 0, 0, hb_color_get_alpha (color) / 255.);
+  }
+  else
+    cairo_set_source_rgba (cr,
+			   hb_color_get_red (color) / 255.,
+			   hb_color_get_green (color) / 255.,
+			   hb_color_get_blue (color) / 255.,
+			   hb_color_get_alpha (color) / 255.);
+  cairo_paint (cr);
+}
+
+static hb_bool_t
+hb_cairo_paint_image (hb_paint_funcs_t *pfuncs HB_UNUSED,
+		      void *paint_data,
+		      hb_blob_t *blob,
+		      unsigned width,
+		      unsigned height,
+		      hb_tag_t format,
+		      float slant,
+		      hb_glyph_extents_t *extents,
+		      void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+
+  return _hb_cairo_paint_glyph_image (c, blob, width, height, format, slant, extents);
+}
+
+static void
+hb_cairo_paint_linear_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
+				void *paint_data,
+				hb_color_line_t *color_line,
+				float x0, float y0,
+				float x1, float y1,
+				float x2, float y2,
+				void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+
+  _hb_cairo_paint_linear_gradient (c, color_line, x0, y0, x1, y1, x2, y2);
+}
+
+static void
+hb_cairo_paint_radial_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
+				void *paint_data,
+				hb_color_line_t *color_line,
+				float x0, float y0, float r0,
+				float x1, float y1, float r1,
+				void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+
+  _hb_cairo_paint_radial_gradient (c, color_line, x0, y0, r0, x1, y1, r1);
+}
+
+static void
+hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
+			       void *paint_data,
+			       hb_color_line_t *color_line,
+			       float x0, float y0,
+			       float start_angle, float end_angle,
+			       void *user_data HB_UNUSED)
+{
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+
+  _hb_cairo_paint_sweep_gradient (c, color_line, x0, y0, start_angle, end_angle);
+}
+
+static const cairo_user_data_key_t color_cache_key = {0};
+
+static void
+_hb_cairo_destroy_map (void *p)
+{
+  hb_map_destroy ((hb_map_t *) p);
+}
+
+static hb_bool_t
+hb_cairo_paint_custom_palette_color (hb_paint_funcs_t *funcs,
+                                     void *paint_data,
+                                     unsigned int color_index,
+                                     hb_color_t *color,
+                                     void *user_data HB_UNUSED)
+{
+#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
+  hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data;
+  cairo_t *cr = c->cr;
+
+#define HB_DEADBEEF HB_TAG(0xDE,0xAD,0xBE,0xEF)
+
+  hb_map_t *color_cache = c->color_cache;
+  hb_codepoint_t *v;
+  if (likely (color_cache && color_cache->has (color_index, &v)))
+  {
+    if (*v == HB_DEADBEEF)
+      return false;
+    *color = *v;
+    return true;
+  }
+
+  cairo_font_options_t *options;
+  double red, green, blue, alpha;
+
+  options = cairo_font_options_create ();
+  cairo_get_font_options (cr, options);
+  if (CAIRO_STATUS_SUCCESS ==
+      cairo_font_options_get_custom_palette_color (options, color_index,
+                                                   &red, &green, &blue, &alpha))
+  {
+    cairo_font_options_destroy (options);
+    *color = HB_COLOR (round (255 * blue),
+		       round (255 * green),
+		       round (255 * red),
+		       round (255 * alpha));
+
+    if (likely (color_cache && *color != HB_DEADBEEF))
+      color_cache->set (color_index, *color);
+
+    return true;
+  }
+  cairo_font_options_destroy (options);
+
+  if (likely (color_cache))
+    color_cache->set (color_index, HB_DEADBEEF);
+
+#undef HB_DEADBEEF
+
+#endif
+
+  return false;
+}
+
+static inline void free_static_cairo_paint_funcs ();
+
+static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_cairo_paint_funcs_lazy_loader_t>
+{
+  static hb_paint_funcs_t *create ()
+  {
+    hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
+
+    hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr);
+    hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr);
+    hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr);
+    hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr);
+    hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr);
+    hb_paint_funcs_set_push_group_func (funcs, hb_cairo_push_group, nullptr, nullptr);
+    hb_paint_funcs_set_pop_group_func (funcs, hb_cairo_pop_group, nullptr, nullptr);
+    hb_paint_funcs_set_color_func (funcs, hb_cairo_paint_color, nullptr, nullptr);
+    hb_paint_funcs_set_image_func (funcs, hb_cairo_paint_image, nullptr, nullptr);
+    hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr);
+    hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr);
+    hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr);
+    hb_paint_funcs_set_custom_palette_color_func (funcs, hb_cairo_paint_custom_palette_color, nullptr, nullptr);
+
+    hb_paint_funcs_make_immutable (funcs);
+
+    hb_atexit (free_static_cairo_paint_funcs);
+
+    return funcs;
+  }
+} static_cairo_paint_funcs;
+
+static inline
+void free_static_cairo_paint_funcs ()
+{
+  static_cairo_paint_funcs.free_instance ();
+}
+
+static hb_paint_funcs_t *
+hb_cairo_paint_get_funcs ()
+{
+  return static_cairo_paint_funcs.get_unconst ();
+}
+#endif
+
+static const cairo_user_data_key_t hb_cairo_face_user_data_key = {0};
+static const cairo_user_data_key_t hb_cairo_font_user_data_key = {0};
+static const cairo_user_data_key_t hb_cairo_font_init_func_user_data_key = {0};
+static const cairo_user_data_key_t hb_cairo_font_init_user_data_user_data_key = {0};
+static const cairo_user_data_key_t hb_cairo_scale_factor_user_data_key = {0};
+
+static void hb_cairo_face_destroy (void *p) { hb_face_destroy ((hb_face_t *) p); }
+static void hb_cairo_font_destroy (void *p) { hb_font_destroy ((hb_font_t *) p); }
+
+static cairo_status_t
+hb_cairo_init_scaled_font (cairo_scaled_font_t  *scaled_font,
+			   cairo_t              *cr HB_UNUSED,
+			   cairo_font_extents_t *extents)
+{
+  cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (scaled_font);
+
+  hb_font_t *font = (hb_font_t *) cairo_font_face_get_user_data (font_face,
+								 &hb_cairo_font_user_data_key);
+
+  if (!font)
+  {
+    hb_face_t *face = (hb_face_t *) cairo_font_face_get_user_data (font_face,
+								   &hb_cairo_face_user_data_key);
+    font = hb_font_create (face);
+
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,16,0)
+    cairo_font_options_t *font_options = cairo_font_options_create ();
+
+    // Set variations
+    cairo_scaled_font_get_font_options (scaled_font, font_options);
+    const char *variations = cairo_font_options_get_variations (font_options);
+    hb_vector_t<hb_variation_t> vars;
+    const char *p = variations;
+    while (p && *p)
+    {
+      const char *end = strpbrk ((char *) p, ", ");
+      hb_variation_t var;
+      if (hb_variation_from_string (p, end ? end - p : -1, &var))
+	vars.push (var);
+      p = end ? end + 1 : nullptr;
+    }
+    hb_font_set_variations (font, &vars[0], vars.length);
+
+    cairo_font_options_destroy (font_options);
+#endif
+
+    // Set scale; Note: should NOT set slant, or we'll double-slant.
+    unsigned scale_factor = hb_cairo_font_face_get_scale_factor (font_face);
+    if (scale_factor)
+    {
+      cairo_matrix_t font_matrix;
+      cairo_scaled_font_get_scale_matrix (scaled_font, &font_matrix);
+      hb_font_set_scale (font,
+			 round (font_matrix.xx * scale_factor),
+			 round (font_matrix.yy * scale_factor));
+    }
+
+    auto *init_func = (hb_cairo_font_init_func_t)
+		      cairo_font_face_get_user_data (font_face,
+						     &hb_cairo_font_init_func_user_data_key);
+    if (init_func)
+    {
+      void *user_data = cairo_font_face_get_user_data (font_face,
+						       &hb_cairo_font_init_user_data_user_data_key);
+      font = init_func (font, scaled_font, user_data);
+    }
+
+    hb_font_make_immutable (font);
+  }
+
+  cairo_scaled_font_set_user_data (scaled_font,
+				   &hb_cairo_font_user_data_key,
+				   (void *) hb_font_reference (font),
+				   hb_cairo_font_destroy);
+
+  hb_position_t x_scale, y_scale;
+  hb_font_get_scale (font, &x_scale, &y_scale);
+
+  hb_font_extents_t hb_extents;
+  hb_font_get_h_extents (font, &hb_extents);
+
+  extents->ascent  = (double)  hb_extents.ascender  / y_scale;
+  extents->descent = (double) -hb_extents.descender / y_scale;
+  extents->height  = extents->ascent + extents->descent;
+
+#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
+  hb_map_t *color_cache = hb_map_create ();
+  if (unlikely (CAIRO_STATUS_SUCCESS != cairo_scaled_font_set_user_data (scaled_font,
+									 &color_cache_key,
+									 color_cache,
+									 _hb_cairo_destroy_map)))
+    hb_map_destroy (color_cache);
+#endif
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+hb_cairo_text_to_glyphs (cairo_scaled_font_t        *scaled_font,
+			 const char	            *utf8,
+			 int		             utf8_len,
+			 cairo_glyph_t	           **glyphs,
+			 int		            *num_glyphs,
+			 cairo_text_cluster_t      **clusters,
+			 int		            *num_clusters,
+			 cairo_text_cluster_flags_t *cluster_flags)
+{
+  hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
+								   &hb_cairo_font_user_data_key);
+
+  hb_buffer_t *buffer = hb_buffer_create ();
+  hb_buffer_add_utf8 (buffer, utf8, utf8_len, 0, utf8_len);
+  hb_buffer_guess_segment_properties (buffer);
+  hb_shape (font, buffer, nullptr, 0);
+
+  hb_cairo_glyphs_from_buffer (buffer,
+			       true,
+			       font->x_scale, font->y_scale,
+			       0., 0.,
+			       utf8, utf8_len,
+			       glyphs, (unsigned *) num_glyphs,
+			       clusters, (unsigned *) num_clusters,
+			       cluster_flags);
+
+  hb_buffer_destroy (buffer);
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+hb_cairo_render_glyph (cairo_scaled_font_t  *scaled_font,
+		       unsigned long         glyph,
+		       cairo_t              *cr,
+		       cairo_text_extents_t *extents)
+{
+  hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
+								   &hb_cairo_font_user_data_key);
+
+  hb_position_t x_scale, y_scale;
+  hb_font_get_scale (font, &x_scale, &y_scale);
+  cairo_scale (cr, +1./x_scale, -1./y_scale);
+
+  hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
+
+  cairo_fill (cr);
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
+
+static cairo_status_t
+hb_cairo_render_color_glyph (cairo_scaled_font_t  *scaled_font,
+			     unsigned long         glyph,
+			     cairo_t              *cr,
+			     cairo_text_extents_t *extents)
+{
+  hb_font_t *font = (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font,
+								   &hb_cairo_font_user_data_key);
+
+  unsigned int palette = 0;
+#ifdef CAIRO_COLOR_PALETTE_DEFAULT
+  cairo_font_options_t *options = cairo_font_options_create ();
+  cairo_scaled_font_get_font_options (scaled_font, options);
+  palette = cairo_font_options_get_color_palette (options);
+  cairo_font_options_destroy (options);
+#endif
+
+  hb_color_t color = HB_COLOR (0, 0, 0, 255);
+  hb_position_t x_scale, y_scale;
+  hb_font_get_scale (font, &x_scale, &y_scale);
+  cairo_scale (cr, +1./x_scale, -1./y_scale);
+
+  hb_cairo_context_t c;
+  c.scaled_font = scaled_font;
+  c.cr = cr;
+  c.color_cache = (hb_map_t *) cairo_scaled_font_get_user_data (scaled_font, &color_cache_key);
+
+  hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), &c, palette, color);
+
+
+  return CAIRO_STATUS_SUCCESS;
+}
+
+#endif
+
+static cairo_font_face_t *
+user_font_face_create (hb_face_t *face)
+{
+  cairo_font_face_t *cairo_face;
+
+  cairo_face = cairo_user_font_face_create ();
+  cairo_user_font_face_set_init_func (cairo_face, hb_cairo_init_scaled_font);
+  cairo_user_font_face_set_text_to_glyphs_func (cairo_face, hb_cairo_text_to_glyphs);
+  cairo_user_font_face_set_render_glyph_func (cairo_face, hb_cairo_render_glyph);
+#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
+  if (hb_ot_color_has_png (face) || hb_ot_color_has_layers (face) || hb_ot_color_has_paint (face))
+    cairo_user_font_face_set_render_color_glyph_func (cairo_face, hb_cairo_render_color_glyph);
+#endif
+
+  if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
+								       &hb_cairo_face_user_data_key,
+								       (void *) hb_face_reference (face),
+								       hb_cairo_face_destroy)))
+    hb_face_destroy (face);
+
+  return cairo_face;
+}
+
+/**
+ * hb_cairo_font_face_create_for_font:
+ * @font: a #hb_font_t
+ *
+ * Creates a #cairo_font_face_t for rendering text according
+ * to @font.
+ *
+ * Note that the scale of @font does not affect the rendering,
+ * but the variations and slant that are set on @font do.
+ *
+ * Returns: (transfer full): a newly created #cairo_font_face_t
+ *
+ * Since: 7.0.0
+ */
+cairo_font_face_t *
+hb_cairo_font_face_create_for_font (hb_font_t *font)
+{
+  hb_font_make_immutable (font);
+
+  auto *cairo_face =  user_font_face_create (font->face);
+
+  if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (cairo_face,
+								       &hb_cairo_font_user_data_key,
+								       (void *) hb_font_reference (font),
+								       hb_cairo_font_destroy)))
+    hb_font_destroy (font);
+
+  return cairo_face;
+}
+
+/**
+ * hb_cairo_font_face_get_font:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Gets the #hb_font_t that @font_face was created from.
+ *
+ * Returns: (nullable) (transfer none): the #hb_font_t that @font_face was created from
+ *
+ * Since: 7.0.0
+ */
+hb_font_t *
+hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
+{
+  return (hb_font_t *) cairo_font_face_get_user_data (font_face,
+						      &hb_cairo_font_user_data_key);
+}
+
+/**
+ * hb_cairo_font_face_create_for_face:
+ * @face: a #hb_face_t
+ *
+ * Creates a #cairo_font_face_t for rendering text according
+ * to @face.
+ *
+ * Returns: (transfer full): a newly created #cairo_font_face_t
+ *
+ * Since: 7.0.0
+ */
+cairo_font_face_t *
+hb_cairo_font_face_create_for_face (hb_face_t *face)
+{
+  hb_face_make_immutable (face);
+
+  return user_font_face_create (face);
+}
+
+/**
+ * hb_cairo_font_face_get_face:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Gets the #hb_face_t associated with @font_face.
+ *
+ * Returns: (nullable) (transfer none): the #hb_face_t associated with @font_face
+ *
+ * Since: 7.0.0
+ */
+hb_face_t *
+hb_cairo_font_face_get_face (cairo_font_face_t *font_face)
+{
+  return (hb_face_t *) cairo_font_face_get_user_data (font_face,
+						      &hb_cairo_face_user_data_key);
+}
+
+/**
+ * hb_cairo_font_face_set_font_init_func:
+ * @font_face: a #cairo_font_face_t
+ * @func: The virtual method to use
+ * @user_data: user data accompanying the method
+ * @destroy: function to call when @user_data is not needed anymore
+ *
+ * Set the virtual method to be called when a cairo
+ * face created using hb_cairo_font_face_create_for_face()
+ * creates an #hb_font_t for a #cairo_scaled_font_t.
+ *
+ * Since: 7.0.0
+ */
+void
+hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
+				       hb_cairo_font_init_func_t func,
+				       void *user_data,
+				       hb_destroy_func_t destroy)
+{
+  cairo_font_face_set_user_data (font_face,
+				 &hb_cairo_font_init_func_user_data_key,
+				 (void *) func,
+				 nullptr);
+  if (unlikely (CAIRO_STATUS_SUCCESS != cairo_font_face_set_user_data (font_face,
+								       &hb_cairo_font_init_user_data_user_data_key,
+								       (void *) user_data,
+								       destroy)) && destroy)
+  {
+    destroy (user_data);
+    cairo_font_face_set_user_data (font_face,
+				   &hb_cairo_font_init_func_user_data_key,
+				   nullptr,
+				   nullptr);
+  }
+}
+
+/**
+ * hb_cairo_scaled_font_get_font:
+ * @scaled_font: a #cairo_scaled_font_t
+ *
+ * Gets the #hb_font_t associated with @scaled_font.
+ *
+ * Returns: (nullable) (transfer none): the #hb_font_t associated with @scaled_font
+ *
+ * Since: 7.0.0
+ */
+hb_font_t *
+hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font)
+{
+  return (hb_font_t *) cairo_scaled_font_get_user_data (scaled_font, &hb_cairo_font_user_data_key);
+}
+
+
+/**
+ * hb_cairo_font_face_set_scale_factor:
+ * @scale_factor: The scale factor to use. See below
+ * @font_face: a #cairo_font_face_t
+ *
+ * Sets the scale factor of the @font_face. Default scale
+ * factor is zero.
+ *
+ * When a #cairo_font_face_t is created from a #hb_face_t using
+ * hb_cairo_font_face_create_for_face(), such face will create
+ * #hb_font_t objects during scaled-font creation.  The scale
+ * factor defines how the scale set on such #hb_font_t objects
+ * relates to the font-matrix (as such font size) of the cairo
+ * scaled-font.
+ *
+ * If the scale-factor is zero (default), then the scale of the
+ * #hb_font_t object will be left at default, which is the UPEM
+ * value of the respective #hb_face_t.
+ *
+ * If the scale-factor is set to non-zero, then the X and Y scale
+ * of the #hb_font_t object will be respectively set to the
+ * @scale_factor times the xx and yy elements of the scale-matrix
+ * of the cairo scaled-font being created.
+ *
+ * When using the hb_cairo_glyphs_from_buffer() API to convert the
+ * HarfBuzz glyph buffer that resulted from shaping with such a #hb_font_t,
+ * if the scale-factor was non-zero, you can pass it directly to
+ * that API as both X and Y scale factors.
+ *
+ * If the scale-factor was zero however, or the cairo face was
+ * created using the alternative constructor
+ * hb_cairo_font_face_create_for_font(), you need to calculate the
+ * correct X/Y scale-factors to pass to hb_cairo_glyphs_from_buffer()
+ * by dividing the #hb_font_t X/Y scale-factors by the
+ * cairo scaled-font's scale-matrix XX/YY components respectively
+ * and use those values.  Or if you know that relationship offhand
+ * (because you set the scale of the #hb_font_t yourself), use
+ * the conversion rate involved.
+ *
+ * Since: 7.0.0
+ */
+void
+hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
+				     unsigned int scale_factor)
+{
+  cairo_font_face_set_user_data (font_face,
+				 &hb_cairo_scale_factor_user_data_key,
+				 (void *) (uintptr_t) scale_factor,
+				 nullptr);
+}
+
+/**
+ * hb_cairo_font_face_get_scale_factor:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Gets the scale factor set on the @font_face. Defaults to zero.
+ * See hb_cairo_font_face_set_scale_factor() for details.
+ *
+ * Returns: the scale factor of @font_face
+ *
+ * Since: 7.0.0
+ */
+unsigned int
+hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face)
+{
+  return (unsigned int) (uintptr_t)
+	 cairo_font_face_get_user_data (font_face,
+					&hb_cairo_scale_factor_user_data_key);
+}
+
+
+/**
+ * hb_cairo_glyphs_from_buffer:
+ * @buffer: a #hb_buffer_t containing glyphs
+ * @utf8_clusters: `true` if @buffer clusters are in bytes, instead of characters
+ * @x_scale_factor: scale factor to divide #hb_position_t Y values by
+ * @y_scale_factor: scale factor to divide #hb_position_t X values by
+ * @x: X position to place first glyph
+ * @y: Y position to place first glyph
+ * @utf8: (nullable): the text that was shaped in @buffer
+ * @utf8_len: the length of @utf8 in bytes
+ * @glyphs: (out): return location for an array of #cairo_glyph_t
+ * @num_glyphs: (inout): return location for the length of @glyphs
+ * @clusters: (out) (nullable): return location for an array of cluster positions
+ * @num_clusters: (inout) (nullable): return location for the length of @clusters
+ * @cluster_flags: (out) (nullable): return location for cluster flags
+ *
+ * Extracts information from @buffer in a form that can be
+ * passed to cairo_show_text_glyphs() or cairo_show_glyphs().
+ * This API is modeled after cairo_scaled_font_text_to_glyphs() and
+ * cairo_user_scaled_font_text_to_glyphs_func_t.
+ *
+ * The @num_glyphs argument should be preset to the number of glyph entries available
+ * in the @glyphs buffer. If the @glyphs buffer is `NULL`, the value of
+ * @num_glyphs must be zero.  If the provided glyph array is too short for
+ * the conversion (or for convenience), a new glyph array may be allocated
+ * using cairo_glyph_allocate() and placed in @glyphs.  Upon return,
+ * @num_glyphs should contain the number of generated glyphs.  If the value
+ * @glyphs points at has changed after the call, the caller will free the
+ * allocated glyph array using cairo_glyph_free().  The caller will also free
+ * the original value of @glyphs, so this function shouldn't do so.
+ *
+ * If @clusters is not `NULL`, then @num_clusters and @cluster_flags
+ * should not be either, and @utf8 must be provided, and cluster
+ * mapping will be computed. The semantics of how
+ * cluster array allocation works is similar to the glyph array.  That is,
+ * if @clusters initially points to a non-`NULL` value, that array may be used
+ * as a cluster buffer, and @num_clusters points to the number of cluster
+ * entries available there.  If the provided cluster array is too short for
+ * the conversion (or for convenience), a new cluster array may be allocated
+ * using cairo_text_cluster_allocate() and placed in @clusters.  In this case,
+ * the original value of @clusters will still be freed by the caller.  Upon
+ * return, @num_clusters will contain the number of generated clusters.
+ * If the value @clusters points at has changed after the call, the caller
+ * will free the allocated cluster array using cairo_text_cluster_free().
+ *
+ * See hb_cairo_font_face_set_scale_factor() for the details of
+ * the @scale_factor argument.
+ *
+ * The returned @glyphs vector actually has `@num_glyphs + 1` entries in
+ * it and the x,y values of the extra entry at the end add up the advance
+ * x,y of all the glyphs in the @buffer.
+ *
+ * Since: 7.0.0
+ */
+void
+hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
+			     hb_bool_t utf8_clusters,
+			     double x_scale_factor,
+			     double y_scale_factor,
+			     double x,
+			     double y,
+			     const char *utf8,
+			     int utf8_len,
+			     cairo_glyph_t **glyphs,
+			     unsigned int *num_glyphs,
+			     cairo_text_cluster_t **clusters,
+			     unsigned int *num_clusters,
+			     cairo_text_cluster_flags_t *cluster_flags)
+{
+  if (utf8 && utf8_len < 0)
+    utf8_len = strlen (utf8);
+
+  unsigned orig_num_glyphs = *num_glyphs;
+  *num_glyphs = hb_buffer_get_length (buffer);
+  hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr);
+  hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr);
+  if (orig_num_glyphs < *num_glyphs + 1)
+    *glyphs = cairo_glyph_allocate (*num_glyphs + 1);
+
+  if (clusters && utf8)
+  {
+    unsigned orig_num_clusters = *num_clusters;
+    *num_clusters = *num_glyphs ? 1 : 0;
+    for (unsigned int i = 1; i < *num_glyphs; i++)
+      if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
+	(*num_clusters)++;
+    if (orig_num_clusters < *num_clusters)
+      *clusters = cairo_text_cluster_allocate (*num_clusters);
+  }
+
+  double x_scale = x_scale_factor ? 1. / x_scale_factor : 0.;
+  double y_scale = y_scale_factor ? 1. / y_scale_factor : 0.;
+  hb_position_t hx = 0, hy = 0;
+  int i;
+  for (i = 0; i < (int) *num_glyphs; i++)
+  {
+    (*glyphs)[i].index = hb_glyph[i].codepoint;
+    (*glyphs)[i].x = x + (+hb_position->x_offset + hx) * x_scale;
+    (*glyphs)[i].y = y + (-hb_position->y_offset + hy) * y_scale;
+    hx +=  hb_position->x_advance;
+    hy += -hb_position->y_advance;
+
+    hb_position++;
+  }
+  (*glyphs)[i].index = -1;
+  (*glyphs)[i].x = round (hx * x_scale);
+  (*glyphs)[i].y = round (hy * y_scale);
+
+  if (clusters && *num_clusters && utf8)
+  {
+    memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0]));
+    hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer));
+    *cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0;
+    unsigned int cluster = 0;
+    const char *start = utf8, *end;
+    (*clusters)[cluster].num_glyphs++;
+    if (backward)
+    {
+      for (i = *num_glyphs - 2; i >= 0; i--)
+      {
+	if (hb_glyph[i].cluster != hb_glyph[i+1].cluster)
+	{
+	  assert (hb_glyph[i].cluster > hb_glyph[i+1].cluster);
+	  if (utf8_clusters)
+	    end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster;
+	  else
+	    end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
+								      (signed) (hb_glyph[i].cluster - hb_glyph[i+1].cluster));
+	  (*clusters)[cluster].num_bytes = end - start;
+	  start = end;
+	  cluster++;
+	}
+	(*clusters)[cluster].num_glyphs++;
+      }
+      (*clusters)[cluster].num_bytes = utf8 + utf8_len - start;
+    }
+    else
+    {
+      for (i = 1; i < (int) *num_glyphs; i++)
+      {
+	if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
+	{
+	  assert (hb_glyph[i].cluster > hb_glyph[i-1].cluster);
+	  if (utf8_clusters)
+	    end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster;
+	  else
+	    end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
+								      (signed) (hb_glyph[i].cluster - hb_glyph[i-1].cluster));
+	  (*clusters)[cluster].num_bytes = end - start;
+	  start = end;
+	  cluster++;
+	}
+	(*clusters)[cluster].num_glyphs++;
+      }
+      (*clusters)[cluster].num_bytes = utf8 + utf8_len - start;
+    }
+  }
+  else if (num_clusters)
+    *num_clusters = 0;
+}
+
+#endif

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.h	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cairo.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,99 @@
+/*
+ * Copyright © 2022 Red Hat, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Matthias Clasen
+ */
+
+#ifndef HB_CAIRO_H
+#define HB_CAIRO_H
+
+#include "hb.h"
+
+#include <cairo.h>
+
+HB_BEGIN_DECLS
+
+HB_EXTERN cairo_font_face_t *
+hb_cairo_font_face_create_for_font (hb_font_t *font);
+
+HB_EXTERN hb_font_t *
+hb_cairo_font_face_get_font (cairo_font_face_t *font_face);
+
+HB_EXTERN cairo_font_face_t *
+hb_cairo_font_face_create_for_face (hb_face_t *face);
+
+HB_EXTERN hb_face_t *
+hb_cairo_font_face_get_face (cairo_font_face_t *font_face);
+
+/**
+ * hb_cairo_font_init_func_t:
+ * @font: The #hb_font_t being created
+ * @scaled_font: The respective #cairo_scaled_font_t
+ * @user_data: User data accompanying this method
+ *
+ * The type of a virtual method to be called when a cairo
+ * face created using hb_cairo_font_face_create_for_face()
+ * creates an #hb_font_t for a #cairo_scaled_font_t.
+ *
+ * Return value: the #hb_font_t value to use; in most cases same as @font
+ *
+ * Since: 7.0.0
+ */
+typedef hb_font_t * (*hb_cairo_font_init_func_t) (hb_font_t *font,
+						  cairo_scaled_font_t *scaled_font,
+						  void *user_data);
+
+HB_EXTERN void
+hb_cairo_font_face_set_font_init_func (cairo_font_face_t *font_face,
+				       hb_cairo_font_init_func_t func,
+				       void *user_data,
+				       hb_destroy_func_t destroy);
+
+HB_EXTERN hb_font_t *
+hb_cairo_scaled_font_get_font (cairo_scaled_font_t *scaled_font);
+
+HB_EXTERN void
+hb_cairo_font_face_set_scale_factor (cairo_font_face_t *font_face,
+				     unsigned int scale_factor);
+
+HB_EXTERN unsigned int
+hb_cairo_font_face_get_scale_factor (cairo_font_face_t *font_face);
+
+HB_EXTERN void
+hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
+			     hb_bool_t utf8_clusters,
+			     double x_scale_factor,
+			     double y_scale_factor,
+			     double x,
+			     double y,
+			     const char *utf8,
+			     int utf8_len,
+			     cairo_glyph_t **glyphs,
+			     unsigned int *num_glyphs,
+			     cairo_text_cluster_t **clusters,
+			     unsigned int *num_clusters,
+			     cairo_text_cluster_flags_t *cluster_flags);
+
+HB_END_DECLS
+
+#endif /* HB_CAIRO_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-common.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -488,7 +488,7 @@
 
   const unsigned char *ptr = nullptr;
 
-  op_code_t  op;
+  op_code_t  op = OpCode_Invalid;
 
   uint8_t length = 0;
 };
@@ -522,21 +522,11 @@
 
   void alloc (unsigned n)
   {
-    values.alloc (n);
+    values.alloc (n, true);
   }
 
-  void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t ())
+  void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t (), const VAL &v = VAL ())
   {
-    VAL *val = values.push ();
-    val->op = op;
-    auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
-    val->ptr = arr.arrayZ;
-    val->length = arr.length;
-    opStart = str_ref.get_offset ();
-  }
-
-  void add_op (op_code_t op, const byte_str_ref_t& str_ref, const VAL &v)
-  {
     VAL *val = values.push (v);
     val->op = op;
     auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff-interp-cs-common.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -57,7 +57,6 @@
 
 /* call stack */
 const unsigned int kMaxCallLimit = 10;
-const unsigned int kMaxOps = 10000;
 struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {};
 
 template <typename SUBRS>
@@ -882,7 +881,7 @@
   {
     SUPER::env.set_endchar (false);
 
-    unsigned max_ops = kMaxOps;
+    unsigned max_ops = HB_CFF_MAX_OPS;
     for (;;) {
       if (unlikely (!--max_ops))
       {

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff1-interp-cs.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -38,7 +38,8 @@
 struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
 {
   template <typename ACC>
-  cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd)
+  cff1_cs_interp_env_t (const hb_ubytes_t &str, ACC &acc, unsigned int fd,
+			const int *coords_=nullptr, unsigned int num_coords_=0)
     : SUPER (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs)
   {
     processed_width = false;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cff2-interp-cs.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -45,7 +45,7 @@
     numValues = numValues_;
     valueIndex = valueIndex_;
     unsigned numBlends = blends_.length;
-    if (unlikely (!deltas.resize (numBlends)))
+    if (unlikely (!deltas.resize_exact (numBlends)))
       return;
     for (unsigned int i = 0; i < numBlends; i++)
       deltas.arrayZ[i] = blends_.arrayZ[i];
@@ -55,7 +55,7 @@
   void reset_blends ()
   {
     numValues = valueIndex = 0;
-    deltas.resize (0);
+    deltas.shrink (0);
   }
 
   unsigned int numValues;
@@ -118,7 +118,7 @@
       region_count = varStore->varStore.get_region_index_count (get_ivs ());
       if (do_blend)
       {
-	if (unlikely (!scalars.resize (region_count)))
+	if (unlikely (!scalars.resize_exact (region_count)))
 	  SUPER::set_error ();
 	else
 	  varStore->varStore.get_region_scalars (get_ivs (), coords, num_coords,
@@ -163,6 +163,8 @@
     return v;
   }
 
+  bool have_coords () const { return num_coords; }
+
   protected:
   const int     *coords;
   unsigned int  num_coords;
@@ -222,7 +224,10 @@
 				 const hb_array_t<const ELEM> blends,
 				 unsigned n, unsigned i)
   {
-    arg.set_blends (n, i, blends);
+    if (env.have_coords ())
+      arg.set_int (round (arg.to_real () + env.blend_deltas (blends)));
+    else
+      arg.set_blends (n, i, blends);
   }
   template <typename T = ELEM,
 	    hb_enable_if (!hb_is_same (T, blend_arg_t))>

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-common.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -897,6 +897,32 @@
 hb_color_get_blue (hb_color_t color);
 #define hb_color_get_blue(color)	(((color) >> 24) & 0xFF)
 
+/**
+ * hb_glyph_extents_t:
+ * @x_bearing: Distance from the x-origin to the left extremum of the glyph.
+ * @y_bearing: Distance from the top extremum of the glyph to the y-origin.
+ * @width: Distance from the left extremum of the glyph to the right extremum.
+ * @height: Distance from the top extremum of the glyph to the bottom extremum.
+ *
+ * Glyph extent values, measured in font units.
+ *
+ * Note that @height is negative, in coordinate systems that grow up.
+ **/
+typedef struct hb_glyph_extents_t {
+  hb_position_t x_bearing;
+  hb_position_t y_bearing;
+  hb_position_t width;
+  hb_position_t height;
+} hb_glyph_extents_t;
+
+/**
+ * hb_font_t:
+ *
+ * Data type for holding fonts.
+ *
+ */
+typedef struct hb_font_t hb_font_t;
+
 HB_END_DECLS
 
 #endif /* HB_COMMON_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-config.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -37,6 +37,7 @@
 
 #ifndef HB_EXPERIMENTAL_API
 #define HB_NO_BEYOND_64K
+#define HB_NO_CUBIC_GLYF
 #define HB_NO_VAR_COMPOSITES
 #endif
 
@@ -80,9 +81,10 @@
 #define HB_NO_MMAP
 #define HB_NO_NAME
 #define HB_NO_OPEN
-#define HB_NO_SETLOCALE
 #define HB_NO_OT_FONT_GLYPH_NAMES
 #define HB_NO_OT_SHAPE_FRACTIONS
+#define HB_NO_PAINT
+#define HB_NO_SETLOCALE
 #define HB_NO_STYLE
 #define HB_NO_SUBSET_LAYOUT
 #define HB_NO_VERTICAL

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -511,7 +511,6 @@
 	buffer->merge_clusters (i - 1, i + 1);
   }
 
-  hb_vector_t<feature_record_t> feature_records;
   hb_vector_t<range_record_t> range_records;
 
   /*

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-cplusplus.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -160,6 +160,8 @@
 HB_DEFINE_VTABLE (set);
 HB_DEFINE_VTABLE (shape_plan);
 HB_DEFINE_VTABLE (unicode_funcs);
+HB_DEFINE_VTABLE (draw_funcs);
+HB_DEFINE_VTABLE (paint_funcs);
 
 #undef HB_DEFINE_VTABLE
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-debug.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -113,7 +113,7 @@
     const char *paren = strchr (func, '(');
     if (paren)
       func_len = paren - func;
-    fprintf (stderr, "%.*s", func_len, func);
+    fprintf (stderr, "%.*s", (int) func_len, func);
   }
 }
 
@@ -142,9 +142,9 @@
   fprintf (stderr, "%-10s", what ? what : "");
 
   if (obj)
-    fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj);
+    fprintf (stderr, "(%*p) ", (int) (2 * sizeof (void *)), obj);
   else
-    fprintf (stderr, " %*s  ", (unsigned int) (2 * sizeof (void *)), "");
+    fprintf (stderr, " %*s  ", (int) (2 * sizeof (void *)), "");
 
   if (indented) {
 #define VBAR	"\342\224\202"	/* U+2502 BOX DRAWINGS LIGHT VERTICAL */
@@ -306,7 +306,7 @@
     }
 
     _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
-			      "return %s (line %d)",
+			      "return %s (line %u)",
 			      hb_printer_t<hb_decay<decltype (v)>>().print (v), line);
     if (plevel) --*plevel;
     plevel = nullptr;
@@ -396,7 +396,7 @@
 #define TRACE_APPLY(this) \
 	hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
 	(&c->debug_depth, c->get_name (), this, HB_FUNC, \
-	 "idx %d gid %u lookup %d", \
+	 "idx %u gid %u lookup %d", \
 	 c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index)
 #else
 #define TRACE_APPLY(this) hb_no_trace_t<bool> trace
@@ -454,7 +454,7 @@
 #define TRACE_DISPATCH(this, format) \
 	hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
 	(&c->debug_depth, c->get_name (), this, HB_FUNC, \
-	 "format %d", (int) format)
+	 "format %u", (unsigned) format)
 #else
 #define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-deprecated.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -102,7 +102,8 @@
 					       hb_codepoint_t *glyph,
 					       void *user_data);
 
-HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func) void
+HB_DEPRECATED_FOR (hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func)
+HB_EXTERN void
 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 			      hb_font_get_glyph_func_t func,
 			      void *user_data, hb_destroy_func_t destroy);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -251,16 +251,12 @@
       data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader);
     data->dwriteFactory->Release ();
   }
-  if (data->fontFileLoader)
-    delete data->fontFileLoader;
-  if (data->fontFileStream)
-    delete data->fontFileStream;
-  if (data->faceBlob)
-    hb_blob_destroy (data->faceBlob);
+  delete data->fontFileLoader;
+  delete data->fontFileStream;
+  hb_blob_destroy (data->faceBlob);
   if (data->dwrite_dll)
     FreeLibrary (data->dwrite_dll);
-  if (data)
-    delete data;
+  delete data;
 }
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -35,6 +35,8 @@
  * @include: hb.h
  *
  * Functions for drawing (extracting) glyph shapes.
+ *
+ * The #hb_draw_funcs_t struct can be used with hb_font_draw_glyph().
  **/
 
 static void
@@ -198,14 +200,30 @@
   }
 };
 
+/**
+ * hb_draw_funcs_get_empty:
+ *
+ * Fetches the singleton empty draw-functions structure.
+ *
+ * Return value: (transfer full): The empty draw-functions structure
+ *
+ * Since: 7.0.0
+ **/
+hb_draw_funcs_t *
+hb_draw_funcs_get_empty ()
+{
+  return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
+}
 
 /**
  * hb_draw_funcs_reference: (skip)
  * @dfuncs: draw functions
  *
- * Increases the reference count on @dfuncs by one. This prevents @buffer from
- * being destroyed until a matching call to hb_draw_funcs_destroy() is made.
+ * Increases the reference count on @dfuncs by one.
  *
+ * This prevents @dfuncs from being destroyed until a matching
+ * call to hb_draw_funcs_destroy() is made.
+ *
  * Return value: (transfer full):
  * The referenced #hb_draw_funcs_t.
  *
@@ -247,6 +265,49 @@
 }
 
 /**
+ * hb_draw_funcs_set_user_data: (skip)
+ * @dfuncs: The draw-functions structure
+ * @key: The user-data key
+ * @data: A pointer to the user data
+ * @destroy: (nullable): A callback to call when @data is not needed anymore
+ * @replace: Whether to replace an existing data with the same key
+ *
+ * Attaches a user-data key/data pair to the specified draw-functions structure. 
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * Since: 7.0.0
+ **/
+hb_bool_t
+hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs,
+			     hb_user_data_key_t *key,
+			     void *              data,
+			     hb_destroy_func_t   destroy,
+			     hb_bool_t           replace)
+{
+  return hb_object_set_user_data (dfuncs, key, data, destroy, replace);
+}
+
+/**
+ * hb_draw_funcs_get_user_data: (skip)
+ * @dfuncs: The draw-functions structure
+ * @key: The user-data key to query
+ *
+ * Fetches the user-data associated with the specified key,
+ * attached to the specified draw-functions structure.
+ *
+ * Return value: (transfer none): A pointer to the user data
+ *
+ * Since: 7.0.0
+ **/
+void *
+hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs,
+			     hb_user_data_key_t       *key)
+{
+  return hb_object_get_user_data (dfuncs, key);
+}
+
+/**
  * hb_draw_funcs_make_immutable:
  * @dfuncs: draw functions
  *

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-draw.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -92,11 +92,11 @@
 /**
  * hb_draw_move_to_func_t:
  * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions
+ * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
  * @st: current draw state
  * @to_x: X component of target point
  * @to_y: Y component of target point
- * @user_data: User data pointer passed by the caller
+ * @user_data: User data pointer passed to hb_draw_funcs_set_move_to_func()
  *
  * A virtual method for the #hb_draw_funcs_t to perform a "move-to" draw
  * operation.
@@ -112,11 +112,11 @@
 /**
  * hb_draw_line_to_func_t:
  * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions
+ * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
  * @st: current draw state
  * @to_x: X component of target point
  * @to_y: Y component of target point
- * @user_data: User data pointer passed by the caller
+ * @user_data: User data pointer passed to hb_draw_funcs_set_line_to_func()
  *
  * A virtual method for the #hb_draw_funcs_t to perform a "line-to" draw
  * operation.
@@ -132,13 +132,13 @@
 /**
  * hb_draw_quadratic_to_func_t:
  * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions
+ * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
  * @st: current draw state
  * @control_x: X component of control point
  * @control_y: Y component of control point
  * @to_x: X component of target point
  * @to_y: Y component of target point
- * @user_data: User data pointer passed by the caller
+ * @user_data: User data pointer passed to hb_draw_funcs_set_quadratic_to_func()
  *
  * A virtual method for the #hb_draw_funcs_t to perform a "quadratic-to" draw
  * operation.
@@ -155,7 +155,7 @@
 /**
  * hb_draw_cubic_to_func_t:
  * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions
+ * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
  * @st: current draw state
  * @control1_x: X component of first control point
  * @control1_y: Y component of first control point
@@ -163,7 +163,7 @@
  * @control2_y: Y component of second control point
  * @to_x: X component of target point
  * @to_y: Y component of target point
- * @user_data: User data pointer passed by the caller
+ * @user_data: User data pointer passed to hb_draw_funcs_set_cubic_to_func()
  *
  * A virtual method for the #hb_draw_funcs_t to perform a "cubic-to" draw
  * operation.
@@ -181,9 +181,9 @@
 /**
  * hb_draw_close_path_func_t:
  * @dfuncs: draw functions object
- * @draw_data: The data accompanying the draw functions
+ * @draw_data: The data accompanying the draw functions in hb_font_draw_glyph()
  * @st: current draw state
- * @user_data: User data pointer passed by the caller
+ * @user_data: User data pointer passed to hb_draw_funcs_set_close_path_func()
  *
  * A virtual method for the #hb_draw_funcs_t to perform a "close-path" draw
  * operation.
@@ -280,11 +280,26 @@
 hb_draw_funcs_create (void);
 
 HB_EXTERN hb_draw_funcs_t *
+hb_draw_funcs_get_empty (void);
+
+HB_EXTERN hb_draw_funcs_t *
 hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs);
 
 HB_EXTERN void
 hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs);
 
+HB_EXTERN hb_bool_t
+hb_draw_funcs_set_user_data (hb_draw_funcs_t *dfuncs,
+			     hb_user_data_key_t *key,
+			     void *              data,
+			     hb_destroy_func_t   destroy,
+			     hb_bool_t           replace);
+
+
+HB_EXTERN void *
+hb_draw_funcs_get_user_data (const hb_draw_funcs_t *dfuncs,
+			     hb_user_data_key_t       *key);
+
 HB_EXTERN void
 hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs);
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-builder.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-builder.cc	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face-builder.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb.hh"
+
+#include "hb-face.hh"
+
+#include "hb-map.hh"
+#include "hb-open-file.hh"
+#include "hb-serialize.hh"
+
+
+/*
+ * face-builder: A face that has add_table().
+ */
+
+struct face_table_info_t
+{
+  hb_blob_t* data;
+  signed order;
+};
+
+struct hb_face_builder_data_t
+{
+  hb_hashmap_t<hb_tag_t, face_table_info_t> tables;
+};
+
+static int compare_entries (const void* pa, const void* pb)
+{
+  const auto& a = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pa;
+  const auto& b = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pb;
+
+  /* Order by blob size first (smallest to largest) and then table tag */
+
+  if (a.second.order != b.second.order)
+    return a.second.order < b.second.order ? -1 : +1;
+
+  if (a.second.data->length != b.second.data->length)
+    return a.second.data->length < b.second.data->length ? -1 : +1;
+
+  return a.first < b.first ? -1 : a.first == b.first ? 0 : +1;
+}
+
+static hb_face_builder_data_t *
+_hb_face_builder_data_create ()
+{
+  hb_face_builder_data_t *data = (hb_face_builder_data_t *) hb_calloc (1, sizeof (hb_face_builder_data_t));
+  if (unlikely (!data))
+    return nullptr;
+
+  data->tables.init ();
+
+  return data;
+}
+
+static void
+_hb_face_builder_data_destroy (void *user_data)
+{
+  hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
+
+  for (auto info : data->tables.values())
+    hb_blob_destroy (info.data);
+
+  data->tables.fini ();
+
+  hb_free (data);
+}
+
+static hb_blob_t *
+_hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
+{
+
+  unsigned int table_count = data->tables.get_population ();
+  unsigned int face_length = table_count * 16 + 12;
+
+  for (auto info : data->tables.values())
+    face_length += hb_ceil_to_4 (hb_blob_get_length (info.data));
+
+  char *buf = (char *) hb_malloc (face_length);
+  if (unlikely (!buf))
+    return nullptr;
+
+  hb_serialize_context_t c (buf, face_length);
+  c.propagate_error (data->tables);
+  OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> ();
+
+  bool is_cff = (data->tables.has (HB_TAG ('C','F','F',' '))
+                 || data->tables.has (HB_TAG ('C','F','F','2')));
+  hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
+
+  // Sort the tags so that produced face is deterministic.
+  hb_vector_t<hb_pair_t <hb_tag_t, face_table_info_t>> sorted_entries;
+  data->tables.iter () | hb_sink (sorted_entries);
+  if (unlikely (sorted_entries.in_error ()))
+  {
+    hb_free (buf);
+    return nullptr;
+  }
+
+  sorted_entries.qsort (compare_entries);
+
+  bool ret = f->serialize_single (&c,
+                                  sfnt_tag,
+                                  + sorted_entries.iter()
+                                  | hb_map ([&] (hb_pair_t<hb_tag_t, face_table_info_t> _) {
+                                    return hb_pair_t<hb_tag_t, hb_blob_t*> (_.first, _.second.data);
+                                  }));
+
+  c.end_serialize ();
+
+  if (unlikely (!ret))
+  {
+    hb_free (buf);
+    return nullptr;
+  }
+
+  return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, hb_free);
+}
+
+static hb_blob_t *
+_hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+  hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
+
+  if (!tag)
+    return _hb_face_builder_data_reference_blob (data);
+
+  return hb_blob_reference (data->tables[tag].data);
+}
+
+
+/**
+ * hb_face_builder_create:
+ *
+ * Creates a #hb_face_t that can be used with hb_face_builder_add_table().
+ * After tables are added to the face, it can be compiled to a binary
+ * font file by calling hb_face_reference_blob().
+ *
+ * Return value: (transfer full): New face.
+ *
+ * Since: 1.9.0
+ **/
+hb_face_t *
+hb_face_builder_create ()
+{
+  hb_face_builder_data_t *data = _hb_face_builder_data_create ();
+  if (unlikely (!data)) return hb_face_get_empty ();
+
+  return hb_face_create_for_tables (_hb_face_builder_reference_table,
+				    data,
+				    _hb_face_builder_data_destroy);
+}
+
+/**
+ * hb_face_builder_add_table:
+ * @face: A face object created with hb_face_builder_create()
+ * @tag: The #hb_tag_t of the table to add
+ * @blob: The blob containing the table data to add
+ *
+ * Add table for @tag with data provided by @blob to the face.  @face must
+ * be created using hb_face_builder_create().
+ *
+ * Since: 1.9.0
+ **/
+hb_bool_t
+hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
+{
+  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
+    return false;
+
+  if (tag == HB_MAP_VALUE_INVALID)
+    return false;
+
+  hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
+
+  hb_blob_t* previous = data->tables.get (tag).data;
+  if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1}))
+  {
+    hb_blob_destroy (blob);
+    return false;
+  }
+
+  hb_blob_destroy (previous);
+  return true;
+}
+
+/**
+ * hb_face_builder_sort_tables:
+ * @face: A face object created with hb_face_builder_create()
+ * @tags: (array zero-terminated=1): ordered list of table tags terminated by
+ *   %HB_TAG_NONE
+ *
+ * Set the ordering of tables for serialization. Any tables not
+ * specified in the tags list will be ordered after the tables in
+ * tags, ordered by the default sort ordering.
+ *
+ * Since: 5.3.0
+ **/
+void
+hb_face_builder_sort_tables (hb_face_t *face,
+                             const hb_tag_t  *tags)
+{
+  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
+    return;
+
+  hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
+
+  // Sort all unspecified tables after any specified tables.
+  for (auto& info : data->tables.values_ref())
+    info.order = (unsigned) -1;
+
+  signed order = 0;
+  for (const hb_tag_t* tag = tags;
+       *tag;
+       tag++)
+  {
+    face_table_info_t* info;
+    if (!data->tables.has (*tag, &info)) continue;
+    info->order = order++;
+  }
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -33,7 +33,6 @@
 #include "hb-open-file.hh"
 #include "hb-ot-face.hh"
 #include "hb-ot-cmap-table.hh"
-#include "hb-map.hh"
 
 
 /**
@@ -472,6 +471,8 @@
  *
  * Sets the units-per-em (upem) for a face object to the specified value.
  *
+ * This API is used in rare circumstances.
+ *
  * Since: 0.9.2
  **/
 void
@@ -488,8 +489,11 @@
  * hb_face_get_upem:
  * @face: A face object
  *
- * Fetches the units-per-em (upem) value of the specified face object.
+ * Fetches the units-per-em (UPEM) value of the specified face object.
  *
+ * Typical UPEM values for fonts are 1000, or 2048, but any value
+ * in between 16 and 16,384 is allowed for OpenType fonts.
+ *
  * Return value: The upem value of @face
  *
  * Since: 0.9.2
@@ -507,6 +511,8 @@
  *
  * Sets the glyph count for a face object to the specified value.
  *
+ * This API is used in rare circumstances.
+ *
  * Since: 0.9.7
  **/
 void
@@ -581,7 +587,7 @@
 /**
  * hb_face_collect_unicodes:
  * @face: A face object
- * @out: The set to add Unicode characters to
+ * @out: (out): The set to add Unicode characters to
  *
  * Collects all of the Unicode characters covered by @face and adds
  * them to the #hb_set_t set @out.
@@ -595,9 +601,30 @@
   face->table.cmap->collect_unicodes (out, face->get_num_glyphs ());
 }
 /**
+ * hb_face_collect_nominal_glyph_mapping:
+ * @face: A face object
+ * @mapping: (out): The map to add Unicode-to-glyph mapping to
+ * @unicodes: (nullable) (out): The set to add Unicode characters to, or `NULL`
+ *
+ * Collects the mapping from Unicode characters to nominal glyphs of the @face,
+ * and optionally all of the Unicode characters covered by @face.
+ *
+ * Since: 7.0.0
+ */
+void
+hb_face_collect_nominal_glyph_mapping (hb_face_t *face,
+				       hb_map_t  *mapping,
+				       hb_set_t  *unicodes)
+{
+  hb_set_t stack_unicodes;
+  if (!unicodes)
+    unicodes = &stack_unicodes;
+  face->table.cmap->collect_mapping (unicodes, mapping, face->get_num_glyphs ());
+}
+/**
  * hb_face_collect_variation_selectors:
  * @face: A face object
- * @out: The set to add Variation Selector characters to
+ * @out: (out): The set to add Variation Selector characters to
  *
  * Collects all Unicode "Variation Selector" characters covered by @face and adds
  * them to the #hb_set_t set @out.
@@ -614,7 +641,7 @@
  * hb_face_collect_variation_unicodes:
  * @face: A face object
  * @variation_selector: The Variation Selector to query
- * @out: The set to add Unicode characters to
+ * @out: (out): The set to add Unicode characters to
  *
  * Collects all Unicode characters for @variation_selector covered by @face and adds
  * them to the #hb_set_t set @out.
@@ -629,214 +656,3 @@
   face->table.cmap->collect_variation_unicodes (variation_selector, out);
 }
 #endif
-
-
-/*
- * face-builder: A face that has add_table().
- */
-
-struct face_table_info_t
-{
-  hb_blob_t* data;
-  signed order;
-};
-
-struct hb_face_builder_data_t
-{
-  hb_hashmap_t<hb_tag_t, face_table_info_t> tables;
-};
-
-static int compare_entries (const void* pa, const void* pb)
-{
-  const auto& a = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pa;
-  const auto& b = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pb;
-
-  /* Order by blob size first (smallest to largest) and then table tag */
-
-  if (a.second.order != b.second.order)
-    return a.second.order < b.second.order ? -1 : +1;
-
-  if (a.second.data->length != b.second.data->length)
-    return a.second.data->length < b.second.data->length ? -1 : +1;
-
-  return a.first < b.first ? -1 : a.first == b.first ? 0 : +1;
-}
-
-static hb_face_builder_data_t *
-_hb_face_builder_data_create ()
-{
-  hb_face_builder_data_t *data = (hb_face_builder_data_t *) hb_calloc (1, sizeof (hb_face_builder_data_t));
-  if (unlikely (!data))
-    return nullptr;
-
-  data->tables.init ();
-
-  return data;
-}
-
-static void
-_hb_face_builder_data_destroy (void *user_data)
-{
-  hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
-
-  for (auto info : data->tables.values())
-    hb_blob_destroy (info.data);
-
-  data->tables.fini ();
-
-  hb_free (data);
-}
-
-static hb_blob_t *
-_hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
-{
-
-  unsigned int table_count = data->tables.get_population ();
-  unsigned int face_length = table_count * 16 + 12;
-
-  for (auto info : data->tables.values())
-    face_length += hb_ceil_to_4 (hb_blob_get_length (info.data));
-
-  char *buf = (char *) hb_malloc (face_length);
-  if (unlikely (!buf))
-    return nullptr;
-
-  hb_serialize_context_t c (buf, face_length);
-  c.propagate_error (data->tables);
-  OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> ();
-
-  bool is_cff = (data->tables.has (HB_TAG ('C','F','F',' '))
-                 || data->tables.has (HB_TAG ('C','F','F','2')));
-  hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
-
-  // Sort the tags so that produced face is deterministic.
-  hb_vector_t<hb_pair_t <hb_tag_t, face_table_info_t>> sorted_entries;
-  data->tables.iter () | hb_sink (sorted_entries);
-  if (unlikely (sorted_entries.in_error ()))
-  {
-    hb_free (buf);
-    return nullptr;
-  }
-
-  sorted_entries.qsort (compare_entries);
-
-  bool ret = f->serialize_single (&c,
-                                  sfnt_tag,
-                                  + sorted_entries.iter()
-                                  | hb_map ([&] (hb_pair_t<hb_tag_t, face_table_info_t> _) {
-                                    return hb_pair_t<hb_tag_t, hb_blob_t*> (_.first, _.second.data);
-                                  }));
-
-  c.end_serialize ();
-
-  if (unlikely (!ret))
-  {
-    hb_free (buf);
-    return nullptr;
-  }
-
-  return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, hb_free);
-}
-
-static hb_blob_t *
-_hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
-{
-  hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
-
-  if (!tag)
-    return _hb_face_builder_data_reference_blob (data);
-
-  return hb_blob_reference (data->tables[tag].data);
-}
-
-
-/**
- * hb_face_builder_create:
- *
- * Creates a #hb_face_t that can be used with hb_face_builder_add_table().
- * After tables are added to the face, it can be compiled to a binary
- * font file by calling hb_face_reference_blob().
- *
- * Return value: (transfer full): New face.
- *
- * Since: 1.9.0
- **/
-hb_face_t *
-hb_face_builder_create ()
-{
-  hb_face_builder_data_t *data = _hb_face_builder_data_create ();
-  if (unlikely (!data)) return hb_face_get_empty ();
-
-  return hb_face_create_for_tables (_hb_face_builder_reference_table,
-				    data,
-				    _hb_face_builder_data_destroy);
-}
-
-/**
- * hb_face_builder_add_table:
- * @face: A face object created with hb_face_builder_create()
- * @tag: The #hb_tag_t of the table to add
- * @blob: The blob containing the table data to add
- *
- * Add table for @tag with data provided by @blob to the face.  @face must
- * be created using hb_face_builder_create().
- *
- * Since: 1.9.0
- **/
-hb_bool_t
-hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
-{
-  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
-    return false;
-
-  if (tag == HB_MAP_VALUE_INVALID)
-    return false;
-
-  hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
-
-  hb_blob_t* previous = data->tables.get (tag).data;
-  if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), -1}))
-  {
-    hb_blob_destroy (blob);
-    return false;
-  }
-
-  hb_blob_destroy (previous);
-  return true;
-}
-
-/**
- * hb_face_builder_sort_tables:
- * @face: A face object created with hb_face_builder_create()
- * @tags: (array zero-terminated=1): ordered list of table tags terminated by
- *   %HB_TAG_NONE
- *
- * Set the ordering of tables for serialization. Any tables not
- * specified in the tags list will be ordered after the tables in
- * tags, ordered by the default sort ordering.
- *
- * Since: 5.3.0
- **/
-void
-hb_face_builder_sort_tables (hb_face_t *face,
-                             const hb_tag_t  *tags)
-{
-  if (unlikely (face->destroy != (hb_destroy_func_t) _hb_face_builder_data_destroy))
-    return;
-
-  hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
-
-  // Sort all unspecified tables after any specified tables.
-  for (auto& info : data->tables.values_ref())
-    info.order = (unsigned) -1;
-
-  signed order = 0;
-  for (const hb_tag_t* tag = tags;
-       *tag;
-       tag++)
-  {
-    face_table_info_t* info;
-    if (!data->tables.has (*tag, &info)) continue;
-    info->order = order++;
-  }
-}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -33,6 +33,7 @@
 
 #include "hb-common.h"
 #include "hb-blob.h"
+#include "hb-map.h"
 #include "hb-set.h"
 
 HB_BEGIN_DECLS
@@ -150,6 +151,11 @@
 			  hb_set_t  *out);
 
 HB_EXTERN void
+hb_face_collect_nominal_glyph_mapping (hb_face_t *face,
+				       hb_map_t  *mapping,
+				       hb_set_t  *unicodes);
+
+HB_EXTERN void
 hb_face_collect_variation_selectors (hb_face_t *face,
 				     hb_set_t  *out);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -30,6 +30,7 @@
 
 #include "hb-font.hh"
 #include "hb-draw.hh"
+#include "hb-paint.hh"
 #include "hb-machinery.hh"
 
 #include "hb-ot.h"
@@ -503,23 +504,34 @@
 }
 
 static void
-hb_font_get_glyph_shape_nil (hb_font_t       *font HB_UNUSED,
-			     void            *font_data HB_UNUSED,
-			     hb_codepoint_t   glyph,
-			     hb_draw_funcs_t *draw_funcs,
-			     void            *draw_data,
-			     void            *user_data HB_UNUSED)
+hb_font_draw_glyph_nil (hb_font_t       *font HB_UNUSED,
+			void            *font_data HB_UNUSED,
+			hb_codepoint_t   glyph,
+			hb_draw_funcs_t *draw_funcs,
+			void            *draw_data,
+			void            *user_data HB_UNUSED)
 {
 }
 
+static void
+hb_font_paint_glyph_nil (hb_font_t *font HB_UNUSED,
+                         void *font_data HB_UNUSED,
+                         hb_codepoint_t glyph HB_UNUSED,
+                         hb_paint_funcs_t *paint_funcs HB_UNUSED,
+                         void *paint_data HB_UNUSED,
+                         unsigned int palette HB_UNUSED,
+                         hb_color_t foreground HB_UNUSED,
+                         void *user_data HB_UNUSED)
+{
+}
 
-typedef struct hb_font_get_glyph_shape_default_adaptor_t {
+typedef struct hb_font_draw_glyph_default_adaptor_t {
   hb_draw_funcs_t *draw_funcs;
   void		  *draw_data;
   float		   x_scale;
   float		   y_scale;
   float		   slant;
-} hb_font_get_glyph_shape_default_adaptor_t;
+} hb_font_draw_glyph_default_adaptor_t;
 
 static void
 hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED,
@@ -528,7 +540,7 @@
 			 float to_x, float to_y,
 			 void *user_data HB_UNUSED)
 {
-  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
   float x_scale = adaptor->x_scale;
   float y_scale = adaptor->y_scale;
   float slant   = adaptor->slant;
@@ -543,7 +555,7 @@
 			 float to_x, float to_y,
 			 void *user_data HB_UNUSED)
 {
-  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
   float x_scale = adaptor->x_scale;
   float y_scale = adaptor->y_scale;
   float slant   = adaptor->slant;
@@ -562,7 +574,7 @@
 			      float to_x, float to_y,
 			      void *user_data HB_UNUSED)
 {
-  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
   float x_scale = adaptor->x_scale;
   float y_scale = adaptor->y_scale;
   float slant   = adaptor->slant;
@@ -583,7 +595,7 @@
 			  float to_x, float to_y,
 			  void *user_data HB_UNUSED)
 {
-  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
   float x_scale = adaptor->x_scale;
   float y_scale = adaptor->y_scale;
   float slant   = adaptor->slant;
@@ -602,7 +614,7 @@
 			    hb_draw_state_t *st,
 			    void *user_data HB_UNUSED)
 {
-  hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
+  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
 
   adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st);
 }
@@ -618,7 +630,7 @@
 };
 
 static void
-hb_font_get_glyph_shape_default (hb_font_t       *font,
+hb_font_draw_glyph_default (hb_font_t       *font,
 				 void            *font_data HB_UNUSED,
 				 hb_codepoint_t   glyph,
 				 hb_draw_funcs_t *draw_funcs,
@@ -625,7 +637,7 @@
 				 void            *draw_data,
 				 void            *user_data HB_UNUSED)
 {
-  hb_font_get_glyph_shape_default_adaptor_t adaptor = {
+  hb_font_draw_glyph_default_adaptor_t adaptor = {
     draw_funcs,
     draw_data,
     font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
@@ -634,11 +646,34 @@
 			    (float) font->x_scale / (float) font->parent->y_scale : 0.f
   };
 
-  font->parent->get_glyph_shape (glyph,
+  font->parent->draw_glyph (glyph,
 				 const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default),
 				 &adaptor);
 }
 
+static void
+hb_font_paint_glyph_default (hb_font_t *font,
+                             void *font_data,
+                             hb_codepoint_t glyph,
+                             hb_paint_funcs_t *paint_funcs,
+                             void *paint_data,
+                             unsigned int palette,
+                             hb_color_t foreground,
+                             void *user_data)
+{
+  paint_funcs->push_transform (paint_data,
+    font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
+    font->parent->y_scale ? (font->slant - font->parent->slant) *
+			    (float) font->x_scale / (float) font->parent->y_scale : 0.f,
+    0.f,
+    font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f,
+    0.f, 0.f);
+
+  font->parent->paint_glyph (glyph, paint_funcs, paint_data, palette, foreground);
+
+  paint_funcs->pop_transform (paint_data);
+}
+
 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
 {
   HB_OBJECT_HEADER_STATIC,
@@ -647,7 +682,7 @@
   nullptr,
   {
     {
-#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_nil,
       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
     }
@@ -661,7 +696,7 @@
   nullptr,
   {
     {
-#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_default,
       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
     }
@@ -739,7 +774,7 @@
 
   if (ffuncs->destroy)
   {
-#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) if (ffuncs->destroy->name) \
     ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name);
     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
@@ -879,11 +914,11 @@
   return false;
 }
 
-#define HB_FONT_FUNC_IMPLEMENT(name) \
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) \
 									 \
 void                                                                     \
 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
-				 hb_font_get_##name##_func_t  func,      \
+				 hb_font_##get_##name##_func_t func,     \
 				 void                        *user_data, \
 				 hb_destroy_func_t            destroy)   \
 {                                                                        \
@@ -899,7 +934,7 @@
   if (func)                                                              \
     ffuncs->get.f.name = func;                                           \
   else                                                                   \
-    ffuncs->get.f.name = hb_font_get_##name##_default;                   \
+    ffuncs->get.f.name = hb_font_##get_##name##_default;                   \
 									 \
   if (ffuncs->user_data)                                                 \
     ffuncs->user_data->name = user_data;                                 \
@@ -1026,7 +1061,8 @@
  * @glyph_stride: The stride between successive glyph IDs
  *
  * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
- * IDs must be returned in a #hb_codepoint_t output parameter.
+ * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the
+ * first unsupported glyph ID.
  *
  * Return value: the number of code points processed
  *
@@ -1308,6 +1344,9 @@
  *
  * Fetches the glyph-name string for a glyph ID in the specified @font.
  *
+ * According to the OpenType specification, glyph names are limited to 63
+ * characters and can only contain (a subset of) ASCII.
+ *
  * Return value: `true` if data found, `false` otherwise
  *
  * Since: 0.9.2
@@ -1357,15 +1396,69 @@
  * objects, with @draw_data passed to them.
  *
  * Since: 4.0.0
+ * Deprecated: 7.0.0: Use hb_font_draw_glyph() instead
+ */
+void
+hb_font_get_glyph_shape (hb_font_t *font,
+		         hb_codepoint_t glyph,
+		         hb_draw_funcs_t *dfuncs, void *draw_data)
+{
+  hb_font_draw_glyph (font, glyph, dfuncs, draw_data);
+}
+
+/**
+ * hb_font_draw_glyph:
+ * @font: #hb_font_t to work upon
+ * @glyph: : The glyph ID
+ * @dfuncs: #hb_draw_funcs_t to draw to
+ * @draw_data: User data to pass to draw callbacks
+ *
+ * Draws the outline that corresponds to a glyph in the specified @font.
+ *
+ * The outline is returned by way of calls to the callbacks of the @dfuncs
+ * objects, with @draw_data passed to them.
+ *
+ * Since: 7.0.0
  **/
 void
-hb_font_get_glyph_shape (hb_font_t *font,
+hb_font_draw_glyph (hb_font_t *font,
 			 hb_codepoint_t glyph,
 			 hb_draw_funcs_t *dfuncs, void *draw_data)
 {
-  font->get_glyph_shape (glyph, dfuncs, draw_data);
+  font->draw_glyph (glyph, dfuncs, draw_data);
 }
 
+/**
+ * hb_font_paint_glyph:
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph ID
+ * @pfuncs: #hb_paint_funcs_t to paint with
+ * @paint_data: User data to pass to paint callbacks
+ * @palette_index: The index of the font's color palette to use
+ * @foreground: The foreground color, unpremultipled
+ *
+ * Paints the glyph.
+ *
+ * The painting instructions are returned by way of calls to
+ * the callbacks of the @funcs object, with @paint_data passed
+ * to them.
+ *
+ * If the font has color palettes (see hb_ot_color_has_palettes()),
+ * then @palette_index selects the palette to use. If the font only
+ * has one palette, this will be 0.
+ *
+ * Since: 7.0.0
+ */
+void
+hb_font_paint_glyph (hb_font_t *font,
+                     hb_codepoint_t glyph,
+                     hb_paint_funcs_t *pfuncs, void *paint_data,
+                     unsigned int palette_index,
+                     hb_color_t foreground)
+{
+  font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground);
+}
+
 /* A bit higher-level, and with fallback */
 
 /**
@@ -1624,6 +1717,9 @@
  * If the glyph ID has no name in @font, a string of the form `gidDDD` is
  * generated, with `DDD` being the glyph ID.
  *
+ * According to the OpenType specification, glyph names are limited to 63
+ * characters and can only contain (a subset of) ASCII.
+ *
  * Since: 0.9.2
  **/
 void
@@ -1677,8 +1773,13 @@
 
   1000, /* x_scale */
   1000, /* y_scale */
-  0., /* slant */
-  0., /* slant_xy; */
+  0.f, /* x_embolden */
+  0.f, /* y_embolden */
+  true, /* embolden_in_place */
+  0, /* x_strength */
+  0, /* y_strength */
+  0.f, /* slant */
+  0.f, /* slant_xy; */
   1.f, /* x_multf */
   1.f, /* y_multf */
   1<<16, /* x_mult */
@@ -1688,6 +1789,7 @@
   0, /* y_ppem */
   0, /* ptem */
 
+  HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */
   0, /* num_coords */
   nullptr, /* coords */
   nullptr, /* design_coords */
@@ -1715,8 +1817,10 @@
   font->klass = hb_font_funcs_get_empty ();
   font->data.init0 (font);
   font->x_scale = font->y_scale = face->get_upem ();
+  font->embolden_in_place = true;
   font->x_multf = font->y_multf = 1.f;
   font->x_mult = font->y_mult = 1 << 16;
+  font->instance_index = HB_FONT_NO_VAR_NAMED_INSTANCE;
 
   return font;
 }
@@ -1798,6 +1902,9 @@
 
   font->x_scale = parent->x_scale;
   font->y_scale = parent->y_scale;
+  font->x_embolden = parent->x_embolden;
+  font->y_embolden = parent->y_embolden;
+  font->embolden_in_place = parent->embolden_in_place;
   font->slant = parent->slant;
   font->x_ppem = parent->x_ppem;
   font->y_ppem = parent->y_ppem;
@@ -2187,6 +2294,31 @@
  *
  * Sets the horizontal and vertical scale of a font.
  *
+ * The font scale is a number related to, but not the same as,
+ * font size. Typically the client establishes a scale factor
+ * to be used between the two. For example, 64, or 256, which
+ * would be the fractional-precision part of the font scale.
+ * This is necessary because #hb_position_t values are integer
+ * types and you need to leave room for fractional values
+ * in there.
+ *
+ * For example, to set the font size to 20, with 64
+ * levels of fractional precision you would call
+ * `hb_font_set_scale(font, 20 * 64, 20 * 64)`.
+ *
+ * In the example above, even what font size 20 means is up to
+ * you. It might be 20 pixels, or 20 points, or 20 millimeters.
+ * HarfBuzz does not care about that.  You can set the point
+ * size of the font using hb_font_set_ptem(), and the pixel
+ * size using hb_font_set_ppem().
+ *
+ * The choice of scale is yours but needs to be consistent between
+ * what you set here, and what you expect out of #hb_position_t
+ * as well has draw / paint API output values.
+ *
+ * Fonts default to a scale equal to the UPEM value of their face.
+ * A font with this setting is sometimes called an "unscaled" font.
+ *
  * Since: 0.9.2
  **/
 void
@@ -2232,8 +2364,12 @@
  * @x_ppem: Horizontal ppem value to assign
  * @y_ppem: Vertical ppem value to assign
  *
- * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
+ * Sets the horizontal and vertical pixels-per-em (PPEM) of a font.
  *
+ * These values are used for pixel-size-specific adjustment to
+ * shaping and draw results, though for the most part they are
+ * unused and can be left unset.
+ *
  * Since: 0.9.2
  **/
 void
@@ -2317,6 +2453,76 @@
 }
 
 /**
+ * hb_font_set_synthetic_bold:
+ * @font: #hb_font_t to work upon
+ * @x_embolden: the amount to embolden horizontally
+ * @y_embolden: the amount to embolden vertically
+ * @in_place: whether to embolden glyphs in-place
+ *
+ * Sets the "synthetic boldness" of a font.
+ *
+ * Positive values for @x_embolden / @y_embolden make a font
+ * bolder, negative values thinner. Typical values are in the
+ * 0.01 to 0.05 range. The default value is zero.
+ *
+ * Synthetic boldness is applied by offsetting the contour
+ * points of the glyph shape.
+ *
+ * Synthetic boldness is applied when rendering a glyph via
+ * hb_font_draw_glyph().
+ *
+ * If @in_place is `false`, then glyph advance-widths are also
+ * adjusted, otherwise they are not.  The in-place mode is
+ * useful for simulating [font grading](https://fonts.google.com/knowledge/glossary/grade).
+ *
+ *
+ * Since: 7.0.0
+ **/
+void
+hb_font_set_synthetic_bold (hb_font_t *font,
+			    float x_embolden,
+			    float y_embolden,
+			    hb_bool_t in_place)
+{
+  if (hb_object_is_immutable (font))
+    return;
+
+  if (font->x_embolden == x_embolden &&
+      font->y_embolden == y_embolden &&
+      font->embolden_in_place == in_place)
+    return;
+
+  font->serial++;
+
+  font->x_embolden = x_embolden;
+  font->y_embolden = y_embolden;
+  font->embolden_in_place = in_place;
+  font->mults_changed ();
+}
+
+/**
+ * hb_font_get_synthetic_bold:
+ * @font: #hb_font_t to work upon
+ * @x_embolden: (out): return location for horizontal value
+ * @y_embolden: (out): return location for vertical value
+ * @in_place: (out): return location for in-place value
+ *
+ * Fetches the "synthetic boldness" parameters of a font.
+ *
+ * Since: 7.0.0
+ **/
+void
+hb_font_get_synthetic_bold (hb_font_t *font,
+			    float *x_embolden,
+			    float *y_embolden,
+			    hb_bool_t *in_place)
+{
+  if (x_embolden) *x_embolden = font->x_embolden;
+  if (y_embolden) *y_embolden = font->y_embolden;
+  if (in_place) *in_place = font->embolden_in_place;
+}
+
+/**
  * hb_font_set_synthetic_slant:
  * @font: #hb_font_t to work upon
  * @slant: synthetic slant value.
@@ -2328,9 +2534,8 @@
  * HarfBuzz needs to know this value to adjust shaping results,
  * metrics, and style values to match the slanted rendering.
  *
- * <note>Note: The glyph shape fetched via the
- * hb_font_get_glyph_shape() is slanted to reflect this value
- * as well.</note>
+ * <note>Note: The glyph shape fetched via the hb_font_draw_glyph()
+ * function is slanted to reflect this value as well.</note>
  *
  * <note>Note: The slant value is a ratio.  For example, a
  * 20% slant would be represented as a 0.2 value.</note>
@@ -2397,7 +2602,7 @@
 
   font->serial_coords = ++font->serial;
 
-  if (!variations_length)
+  if (!variations_length && font->instance_index == HB_FONT_NO_VAR_NAMED_INSTANCE)
   {
     hb_font_set_var_coords_normalized (font, nullptr, 0);
     return;
@@ -2417,9 +2622,18 @@
     return;
   }
 
-  /* Initialize design coords to default from fvar. */
+  /* Initialize design coords. */
   for (unsigned int i = 0; i < coords_length; i++)
     design_coords[i] = axes[i].get_default ();
+  if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE)
+  {
+    unsigned count = coords_length;
+    /* This may fail if index is out-of-range;
+     * That's why we initialize design_coords from fvar above
+     * unconditionally. */
+    hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index,
+						&count, design_coords);
+  }
 
   for (unsigned int i = 0; i < variations_length; i++)
   {
@@ -2427,13 +2641,11 @@
     const auto v = variations[i].value;
     for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
       if (axes[axis_index].axisTag == tag)
-      {
 	design_coords[axis_index] = v;
-	normalized[axis_index] = fvar.normalize_axis_value (axis_index, v);
-      }
   }
   font->face->table.avar->map_coords (normalized, coords_length);
 
+  hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
 }
 
@@ -2484,28 +2696,40 @@
  * @font: a font.
  * @instance_index: named instance index.
  *
- * Sets design coords of a font from a named instance index.
+ * Sets design coords of a font from a named-instance index.
  *
  * Since: 2.6.0
  */
 void
 hb_font_set_var_named_instance (hb_font_t *font,
-				unsigned instance_index)
+				unsigned int instance_index)
 {
   if (hb_object_is_immutable (font))
     return;
 
+  if (font->instance_index == instance_index)
+    return;
+
   font->serial_coords = ++font->serial;
 
-  unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
+  font->instance_index = instance_index;
+  hb_font_set_variations (font, nullptr, 0);
+}
 
-  float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
-  if (unlikely (coords_length && !coords))
-    return;
-
-  hb_ot_var_named_instance_get_design_coords (font->face, instance_index, &coords_length, coords);
-  hb_font_set_var_coords_design (font, coords, coords_length);
-  hb_free (coords);
+/**
+ * hb_font_get_var_named_instance:
+ * @font: a font.
+ *
+ * Returns the currently-set named-instance index of the font.
+ *
+ * Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE.
+ *
+ * Since: 7.0.0
+ **/
+unsigned int
+hb_font_get_var_named_instance (hb_font_t *font)
+{
+  return font->instance_index;
 }
 
 /**
@@ -2754,3 +2978,13 @@
 					  trampoline_destroy);
 }
 #endif
+
+
+void
+hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t               *ffuncs,
+                                   hb_font_get_glyph_shape_func_t  func,
+                                   void                           *user_data,
+                                   hb_destroy_func_t               destroy /* May be NULL. */)
+{
+  hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy);
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -34,18 +34,10 @@
 #include "hb-common.h"
 #include "hb-face.h"
 #include "hb-draw.h"
+#include "hb-paint.h"
 
 HB_BEGIN_DECLS
 
-/**
- * hb_font_t:
- *
- * Data type for holding fonts.
- *
- */
-typedef struct hb_font_t hb_font_t;
-
-
 /*
  * hb_font_funcs_t
  */
@@ -97,7 +89,7 @@
 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
 
 
-/* font and glyph extents */
+/* font extents */
 
 /**
  * hb_font_extents_t:
@@ -126,24 +118,6 @@
   hb_position_t reserved1;
 } hb_font_extents_t;
 
-/**
- * hb_glyph_extents_t:
- * @x_bearing: Distance from the x-origin to the left extremum of the glyph.
- * @y_bearing: Distance from the top extremum of the glyph to the y-origin.
- * @width: Distance from the left extremum of the glyph to the right extremum.
- * @height: Distance from the top extremum of the glyph to the bottom extremum.
- *
- * Glyph extent values, measured in font units.
- *
- * Note that @height is negative, in coordinate systems that grow up.
- **/
-typedef struct hb_glyph_extents_t {
-  hb_position_t x_bearing;
-  hb_position_t y_bearing;
-  hb_position_t width;
-  hb_position_t height;
-} hb_glyph_extents_t;
-
 /* func types */
 
 /**
@@ -523,7 +497,7 @@
  * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
  *
  * Since: 4.0.0
- *
+ * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead
  **/
 typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
 						hb_codepoint_t glyph,
@@ -530,7 +504,47 @@
 						hb_draw_funcs_t *draw_funcs, void *draw_data,
 						void *user_data);
 
+/**
+ * hb_font_draw_glyph_func_t:
+ * @font: #hb_font_t to work upon
+ * @font_data: @font user data pointer
+ * @glyph: The glyph ID to query
+ * @draw_funcs: The draw functions to send the shape data to
+ * @draw_data: The data accompanying the draw functions
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * Since: 7.0.0
+ *
+ **/
+typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
+                                           hb_codepoint_t glyph,
+                                           hb_draw_funcs_t *draw_funcs, void *draw_data,
+                                           void *user_data);
 
+/**
+ * hb_font_paint_glyph_func_t:
+ * @font: #hb_font_t to work upon
+ * @font_data: @font user data pointer
+ * @glyph: The glyph ID to query
+ * @paint_funcs: The paint functions to use
+ * @paint_data: The data accompanying the paint functions
+ * @palette_index: The color palette to use
+ * @foreground: The foreground color
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * Since: 7.0.0
+ */
+typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data,
+                                            hb_codepoint_t glyph,
+                                            hb_paint_funcs_t *paint_funcs, void *paint_data,
+                                            unsigned int palette_index,
+                                            hb_color_t foreground,
+                                            void *user_data);
+
 /* func setters */
 
 /**
@@ -796,9 +810,11 @@
  * @user_data: Data to pass to @func
  * @destroy: (nullable): The function to call when @user_data is not needed anymore
  *
- * Sets the implementation function for #hb_font_get_glyph_shape_func_t.
+ * Sets the implementation function for #hb_font_get_glyph_shape_func_t,
+ * which is the same as #hb_font_draw_glyph_func_t.
  *
  * Since: 4.0.0
+ * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
  **/
 HB_EXTERN void
 hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
@@ -805,6 +821,39 @@
 				    hb_font_get_glyph_shape_func_t func,
 				    void *user_data, hb_destroy_func_t destroy);
 
+/**
+ * hb_font_funcs_set_draw_glyph_func:
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets the implementation function for #hb_font_draw_glyph_func_t,
+ * which is the same as #hb_font_get_glyph_shape_func_t.
+ *
+ * Since: 7.0.0
+ **/
+HB_EXTERN void
+hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t *ffuncs,
+                                   hb_font_draw_glyph_func_t func,
+                                   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_paint_glyph_func:
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is no longer needed
+ *
+ * Sets the implementation function for #hb_font_paint_glyph_func_t.
+ *
+ * Since: 7.0.0
+ */
+HB_EXTERN void
+hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t *ffuncs,
+                                    hb_font_paint_glyph_func_t func,
+                                    void *user_data, hb_destroy_func_t destroy);
+
 /* func dispatch */
 
 HB_EXTERN hb_bool_t
@@ -890,7 +939,18 @@
 			 hb_codepoint_t glyph,
 			 hb_draw_funcs_t *dfuncs, void *draw_data);
 
+HB_EXTERN void
+hb_font_draw_glyph (hb_font_t *font,
+                    hb_codepoint_t glyph,
+                    hb_draw_funcs_t *dfuncs, void *draw_data);
 
+HB_EXTERN void
+hb_font_paint_glyph (hb_font_t *font,
+                     hb_codepoint_t glyph,
+                     hb_paint_funcs_t *pfuncs, void *paint_data,
+                     unsigned int palette_index,
+                     hb_color_t foreground);
+
 /* high-level funcs, with fallback */
 
 /* Calls either hb_font_get_nominal_glyph() if variation_selector is 0,
@@ -1070,6 +1130,16 @@
 hb_font_get_ptem (hb_font_t *font);
 
 HB_EXTERN void
+hb_font_set_synthetic_bold (hb_font_t *font,
+			    float x_embolden, float y_embolden,
+			    hb_bool_t in_place);
+
+HB_EXTERN void
+hb_font_get_synthetic_bold (hb_font_t *font,
+			    float *x_embolden, float *y_embolden,
+			    hb_bool_t *in_place);
+
+HB_EXTERN void
 hb_font_set_synthetic_slant (hb_font_t *font, float slant);
 
 HB_EXTERN float
@@ -1098,10 +1168,23 @@
 hb_font_get_var_coords_normalized (hb_font_t *font,
 				   unsigned int *length);
 
+/**
+ * HB_FONT_NO_VAR_NAMED_INSTANCE:
+ *
+ * Constant signifying that a font does not have any
+ * named-instance index set.  This is the default of
+ * a font.
+ *
+ * Since: 7.0.0
+ */
+#define HB_FONT_NO_VAR_NAMED_INSTANCE 0xFFFFFFFF
+
 HB_EXTERN void
 hb_font_set_var_named_instance (hb_font_t *font,
-				unsigned instance_index);
+				unsigned int instance_index);
 
+HB_EXTERN unsigned int
+hb_font_get_var_named_instance (hb_font_t *font);
 
 HB_END_DECLS
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -40,24 +40,25 @@
  */
 
 #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
-  HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
-  HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
-  HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
-  HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \
-  HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_h_advances) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
-  HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_name) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_shape) \
+  HB_FONT_FUNC_IMPLEMENT (get_,font_h_extents) \
+  HB_FONT_FUNC_IMPLEMENT (get_,font_v_extents) \
+  HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyph) \
+  HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyphs) \
+  HB_FONT_FUNC_IMPLEMENT (get_,variation_glyph) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advance) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advance) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advances) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \
+  HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \
+  HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \
+  HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \
+  HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \
   /* ^--- Add new callbacks here */
 
 struct hb_font_funcs_t
@@ -65,13 +66,13 @@
   hb_object_header_t header;
 
   struct {
-#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) void *name;
     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
   } *user_data;
 
   struct {
-#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_destroy_func_t name;
     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
   } *destroy;
@@ -79,12 +80,12 @@
   /* Don't access these directly.  Call font->get_*() instead. */
   union get_t {
     struct get_funcs_t {
-#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_func_t name;
       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
     } f;
     void (*array[0
-#define HB_FONT_FUNC_IMPLEMENT(name) +1
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) +1
       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
 #undef HB_FONT_FUNC_IMPLEMENT
 		]) ();
@@ -112,8 +113,16 @@
 
   int32_t x_scale;
   int32_t y_scale;
+
+  float x_embolden;
+  float y_embolden;
+  bool embolden_in_place;
+  int32_t x_strength; /* x_embolden, in scaled units. */
+  int32_t y_strength; /* y_embolden, in scaled units. */
+
   float slant;
   float slant_xy;
+
   float x_multf;
   float y_multf;
   int64_t x_mult;
@@ -125,6 +134,7 @@
   float ptem;
 
   /* Font variation coordinates. */
+  unsigned int instance_index;
   unsigned int num_coords;
   int *coords;
   float *design_coords;
@@ -179,7 +189,43 @@
     *y = parent_scale_y_position (*y);
   }
 
+  void scale_glyph_extents (hb_glyph_extents_t *extents)
+  {
+    float x1 = em_fscale_x (extents->x_bearing);
+    float y1 = em_fscale_y (extents->y_bearing);
+    float x2 = em_fscale_x (extents->x_bearing + extents->width);
+    float y2 = em_fscale_y (extents->y_bearing + extents->height);
 
+    /* Apply slant. */
+    if (slant_xy)
+    {
+      x1 += hb_min (y1 * slant_xy, y2 * slant_xy);
+      x2 += hb_max (y1 * slant_xy, y2 * slant_xy);
+    }
+
+    extents->x_bearing = floorf (x1);
+    extents->y_bearing = floorf (y1);
+    extents->width = ceilf (x2) - extents->x_bearing;
+    extents->height = ceilf (y2) - extents->y_bearing;
+
+    if (x_strength || y_strength)
+    {
+      /* Y */
+      int y_shift = y_strength;
+      if (y_scale < 0) y_shift = -y_shift;
+      extents->y_bearing += y_shift;
+      extents->height -= y_shift;
+
+      /* X */
+      int x_shift = x_strength;
+      if (x_scale < 0) x_shift = -x_shift;
+      if (embolden_in_place)
+	extents->x_bearing -= x_shift / 2;
+      extents->width += x_shift;
+    }
+  }
+
+
   /* Public getters */
 
   HB_INTERNAL bool has_func (unsigned int i);
@@ -186,7 +232,7 @@
   HB_INTERNAL bool has_func_set (unsigned int i);
 
   /* has_* ... */
-#define HB_FONT_FUNC_IMPLEMENT(name) \
+#define HB_FONT_FUNC_IMPLEMENT(get_,name) \
   bool \
   has_##name##_func () \
   { \
@@ -380,15 +426,26 @@
 					 !klass->user_data ? nullptr : klass->user_data->glyph_from_name);
   }
 
-  void get_glyph_shape (hb_codepoint_t glyph,
-			hb_draw_funcs_t *draw_funcs, void *draw_data)
+  void draw_glyph (hb_codepoint_t glyph,
+		   hb_draw_funcs_t *draw_funcs, void *draw_data)
   {
-    klass->get.f.glyph_shape (this, user_data,
-			      glyph,
-			      draw_funcs, draw_data,
-			      !klass->user_data ? nullptr : klass->user_data->glyph_shape);
+    klass->get.f.draw_glyph (this, user_data,
+			     glyph,
+			     draw_funcs, draw_data,
+			     !klass->user_data ? nullptr : klass->user_data->draw_glyph);
   }
 
+  void paint_glyph (hb_codepoint_t glyph,
+                    hb_paint_funcs_t *paint_funcs, void *paint_data,
+                    unsigned int palette,
+                    hb_color_t foreground)
+  {
+    klass->get.f.paint_glyph (this, user_data,
+                              glyph,
+                              paint_funcs, paint_data,
+                              palette, foreground,
+                              !klass->user_data ? nullptr : klass->user_data->paint_glyph);
+  }
 
   /* A bit higher-level, and with fallback */
 
@@ -632,6 +689,7 @@
   void mults_changed ()
   {
     float upem = face->get_upem ();
+
     x_multf = x_scale / upem;
     y_multf = y_scale / upem;
     bool x_neg = x_scale < 0;
@@ -638,6 +696,10 @@
     x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem;
     bool y_neg = y_scale < 0;
     y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem;
+
+    x_strength = fabs (roundf (x_scale * x_embolden));
+    y_strength = fabs (roundf (y_scale * y_embolden));
+
     slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
 
     data.fini ();

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft-colr.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,567 @@
+/*
+ * Copyright © 2022  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_FT_COLR_HH
+#define HB_FT_COLR_HH
+
+#include "hb.hh"
+
+#include "hb-paint-extents.hh"
+
+#include FT_COLOR_H
+
+
+static hb_paint_composite_mode_t
+_hb_ft_paint_composite_mode (FT_Composite_Mode mode)
+{
+  switch (mode)
+  {
+    case FT_COLR_COMPOSITE_CLEAR:          return HB_PAINT_COMPOSITE_MODE_CLEAR;
+    case FT_COLR_COMPOSITE_SRC:            return HB_PAINT_COMPOSITE_MODE_SRC;
+    case FT_COLR_COMPOSITE_DEST:           return HB_PAINT_COMPOSITE_MODE_DEST;
+    case FT_COLR_COMPOSITE_SRC_OVER:       return HB_PAINT_COMPOSITE_MODE_SRC_OVER;
+    case FT_COLR_COMPOSITE_DEST_OVER:      return HB_PAINT_COMPOSITE_MODE_DEST_OVER;
+    case FT_COLR_COMPOSITE_SRC_IN:         return HB_PAINT_COMPOSITE_MODE_SRC_IN;
+    case FT_COLR_COMPOSITE_DEST_IN:        return HB_PAINT_COMPOSITE_MODE_DEST_IN;
+    case FT_COLR_COMPOSITE_SRC_OUT:        return HB_PAINT_COMPOSITE_MODE_SRC_OUT;
+    case FT_COLR_COMPOSITE_DEST_OUT:       return HB_PAINT_COMPOSITE_MODE_DEST_OUT;
+    case FT_COLR_COMPOSITE_SRC_ATOP:       return HB_PAINT_COMPOSITE_MODE_SRC_ATOP;
+    case FT_COLR_COMPOSITE_DEST_ATOP:      return HB_PAINT_COMPOSITE_MODE_DEST_ATOP;
+    case FT_COLR_COMPOSITE_XOR:            return HB_PAINT_COMPOSITE_MODE_XOR;
+    case FT_COLR_COMPOSITE_PLUS:           return HB_PAINT_COMPOSITE_MODE_PLUS;
+    case FT_COLR_COMPOSITE_SCREEN:         return HB_PAINT_COMPOSITE_MODE_SCREEN;
+    case FT_COLR_COMPOSITE_OVERLAY:        return HB_PAINT_COMPOSITE_MODE_OVERLAY;
+    case FT_COLR_COMPOSITE_DARKEN:         return HB_PAINT_COMPOSITE_MODE_DARKEN;
+    case FT_COLR_COMPOSITE_LIGHTEN:        return HB_PAINT_COMPOSITE_MODE_LIGHTEN;
+    case FT_COLR_COMPOSITE_COLOR_DODGE:    return HB_PAINT_COMPOSITE_MODE_COLOR_DODGE;
+    case FT_COLR_COMPOSITE_COLOR_BURN:     return HB_PAINT_COMPOSITE_MODE_COLOR_BURN;
+    case FT_COLR_COMPOSITE_HARD_LIGHT:     return HB_PAINT_COMPOSITE_MODE_HARD_LIGHT;
+    case FT_COLR_COMPOSITE_SOFT_LIGHT:     return HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT;
+    case FT_COLR_COMPOSITE_DIFFERENCE:     return HB_PAINT_COMPOSITE_MODE_DIFFERENCE;
+    case FT_COLR_COMPOSITE_EXCLUSION:      return HB_PAINT_COMPOSITE_MODE_EXCLUSION;
+    case FT_COLR_COMPOSITE_MULTIPLY:       return HB_PAINT_COMPOSITE_MODE_MULTIPLY;
+    case FT_COLR_COMPOSITE_HSL_HUE:        return HB_PAINT_COMPOSITE_MODE_HSL_HUE;
+    case FT_COLR_COMPOSITE_HSL_SATURATION: return HB_PAINT_COMPOSITE_MODE_HSL_SATURATION;
+    case FT_COLR_COMPOSITE_HSL_COLOR:      return HB_PAINT_COMPOSITE_MODE_HSL_COLOR;
+    case FT_COLR_COMPOSITE_HSL_LUMINOSITY: return HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY;
+
+    case FT_COLR_COMPOSITE_MAX:            HB_FALLTHROUGH;
+    default:                               return HB_PAINT_COMPOSITE_MODE_CLEAR;
+  }
+}
+
+typedef struct hb_ft_paint_context_t hb_ft_paint_context_t;
+
+static void
+_hb_ft_paint (hb_ft_paint_context_t *c,
+	      FT_OpaquePaint opaque_paint);
+
+struct hb_ft_paint_context_t
+{
+  hb_ft_paint_context_t (const hb_ft_font_t *ft_font,
+			 hb_font_t *font,
+			 hb_paint_funcs_t *paint_funcs, void *paint_data,
+			 FT_Color *palette,
+			 unsigned palette_index,
+			 hb_color_t foreground) :
+    ft_font (ft_font), font(font),
+    funcs (paint_funcs), data (paint_data),
+    palette (palette), palette_index (palette_index), foreground (foreground) {}
+
+  void recurse (FT_OpaquePaint paint)
+  {
+    if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
+    depth_left--;
+    edge_count--;
+    _hb_ft_paint (this, paint);
+    depth_left++;
+  }
+
+  const hb_ft_font_t *ft_font;
+  hb_font_t *font;
+  hb_paint_funcs_t *funcs;
+  void *data;
+  FT_Color *palette;
+  unsigned palette_index;
+  hb_color_t foreground;
+  int depth_left = HB_MAX_NESTING_LEVEL;
+  int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
+};
+
+static unsigned
+_hb_ft_color_line_get_color_stops (hb_color_line_t *color_line,
+				   void *color_line_data,
+				   unsigned int start,
+				   unsigned int *count,
+				   hb_color_stop_t *color_stops,
+				   void *user_data)
+{
+  FT_ColorLine *cl = (FT_ColorLine *) color_line_data;
+  hb_ft_paint_context_t *c = (hb_ft_paint_context_t *) user_data;
+
+  if (count)
+  {
+    FT_ColorStop stop;
+    unsigned wrote = 0;
+    FT_ColorStopIterator iter = cl->color_stop_iterator;
+
+    if (start >= cl->color_stop_iterator.num_color_stops)
+    {
+      *count = 0;
+      return cl->color_stop_iterator.num_color_stops;
+    }
+
+    while (cl->color_stop_iterator.current_color_stop < start)
+      FT_Get_Colorline_Stops(c->ft_font->ft_face,
+			     &stop,
+			     &cl->color_stop_iterator);
+
+    while (count && *count &&
+	   FT_Get_Colorline_Stops(c->ft_font->ft_face,
+				  &stop,
+				  &cl->color_stop_iterator))
+    {
+      // https://github.com/harfbuzz/harfbuzz/issues/4013
+      if (sizeof stop.stop_offset == 2)
+	color_stops->offset = stop.stop_offset / 16384.f;
+      else
+	color_stops->offset = stop.stop_offset / 65536.f;
+
+      color_stops->is_foreground = stop.color.palette_index == 0xFFFF;
+      if (color_stops->is_foreground)
+	color_stops->color = HB_COLOR (hb_color_get_blue (c->foreground),
+				       hb_color_get_green (c->foreground),
+				       hb_color_get_red (c->foreground),
+				       (hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
+      else
+      {
+	hb_color_t color;
+        if (c->funcs->custom_palette_color (c->data, stop.color.palette_index, &color))
+	{
+	  color_stops->color = HB_COLOR (hb_color_get_blue (color),
+					 hb_color_get_green (color),
+					 hb_color_get_red (color),
+					 (hb_color_get_alpha (color) * stop.color.alpha) >> 14);
+	}
+	else
+	{
+	  FT_Color ft_color = c->palette[stop.color.palette_index];
+	  color_stops->color = HB_COLOR (ft_color.blue,
+					 ft_color.green,
+					 ft_color.red,
+					 (ft_color.alpha * stop.color.alpha) >> 14);
+	}
+      }
+
+      color_stops++;
+      wrote++;
+    }
+
+    *count = wrote;
+
+    // reset the iterator for next time
+    cl->color_stop_iterator = iter;
+  }
+
+  return cl->color_stop_iterator.num_color_stops;
+}
+
+static hb_paint_extend_t
+_hb_ft_color_line_get_extend (hb_color_line_t *color_line,
+			      void *color_line_data,
+			      void *user_data)
+{
+  FT_ColorLine *c = (FT_ColorLine *) color_line_data;
+  switch (c->extend)
+  {
+    default:
+    case FT_COLR_PAINT_EXTEND_PAD:     return HB_PAINT_EXTEND_PAD;
+    case FT_COLR_PAINT_EXTEND_REPEAT:  return HB_PAINT_EXTEND_REPEAT;
+    case FT_COLR_PAINT_EXTEND_REFLECT: return HB_PAINT_EXTEND_REFLECT;
+  }
+}
+
+void
+_hb_ft_paint (hb_ft_paint_context_t *c,
+	      FT_OpaquePaint opaque_paint)
+{
+  FT_Face ft_face = c->ft_font->ft_face;
+  FT_COLR_Paint paint;
+  if (!FT_Get_Paint (ft_face, opaque_paint, &paint))
+    return;
+
+  switch (paint.format)
+  {
+    case FT_COLR_PAINTFORMAT_COLR_LAYERS:
+    {
+      FT_OpaquePaint other_paint = {0};
+      while (FT_Get_Paint_Layers (ft_face,
+				  &paint.u.colr_layers.layer_iterator,
+				  &other_paint))
+      {
+	c->funcs->push_group (c->data);
+	c->recurse (other_paint);
+	c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+      }
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_SOLID:
+    {
+      bool is_foreground = paint.u.solid.color.palette_index ==  0xFFFF;
+      hb_color_t color;
+      if (is_foreground)
+	color = HB_COLOR (hb_color_get_blue (c->foreground),
+			  hb_color_get_green (c->foreground),
+			  hb_color_get_red (c->foreground),
+			  (hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
+      else
+      {
+	if (c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index, &color))
+	{
+	  color = HB_COLOR (hb_color_get_blue (color),
+			    hb_color_get_green (color),
+			    hb_color_get_red (color),
+			    (hb_color_get_alpha (color) * paint.u.solid.color.alpha) >> 14);
+	}
+	else
+	{
+	  FT_Color ft_color = c->palette[paint.u.solid.color.palette_index];
+	  color = HB_COLOR (ft_color.blue,
+			    ft_color.green,
+			    ft_color.red,
+			    (ft_color.alpha * paint.u.solid.color.alpha) >> 14);
+	}
+      }
+      c->funcs->color (c->data, is_foreground, color);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT:
+    {
+      hb_color_line_t cl = {
+	&paint.u.linear_gradient.colorline,
+	_hb_ft_color_line_get_color_stops, c,
+	_hb_ft_color_line_get_extend, nullptr
+      };
+
+      c->funcs->linear_gradient (c->data, &cl,
+				 paint.u.linear_gradient.p0.x / 65536.f,
+				 paint.u.linear_gradient.p0.y / 65536.f,
+				 paint.u.linear_gradient.p1.x / 65536.f,
+				 paint.u.linear_gradient.p1.y / 65536.f,
+				 paint.u.linear_gradient.p2.x / 65536.f,
+				 paint.u.linear_gradient.p2.y / 65536.f);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT:
+    {
+      hb_color_line_t cl = {
+	&paint.u.linear_gradient.colorline,
+	_hb_ft_color_line_get_color_stops, c,
+	_hb_ft_color_line_get_extend, nullptr
+      };
+
+      c->funcs->radial_gradient (c->data, &cl,
+				 paint.u.radial_gradient.c0.x / 65536.f,
+				 paint.u.radial_gradient.c0.y / 65536.f,
+				 paint.u.radial_gradient.r0 / 65536.f,
+				 paint.u.radial_gradient.c1.x / 65536.f,
+				 paint.u.radial_gradient.c1.y / 65536.f,
+				 paint.u.radial_gradient.r1 / 65536.f);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT:
+    {
+      hb_color_line_t cl = {
+	&paint.u.linear_gradient.colorline,
+	_hb_ft_color_line_get_color_stops, c,
+	_hb_ft_color_line_get_extend, nullptr
+      };
+
+      c->funcs->sweep_gradient (c->data, &cl,
+				paint.u.sweep_gradient.center.x / 65536.f,
+				paint.u.sweep_gradient.center.y / 65536.f,
+				(paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI,
+				(paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_GLYPH:
+    {
+      c->funcs->push_inverse_root_transform (c->data, c->font);
+      c->ft_font->lock.unlock ();
+      c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font);
+      c->ft_font->lock.lock ();
+      c->funcs->push_root_transform (c->data, c->font);
+      c->recurse (paint.u.glyph.paint);
+      c->funcs->pop_transform (c->data);
+      c->funcs->pop_clip (c->data);
+      c->funcs->pop_transform (c->data);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_COLR_GLYPH:
+    {
+      FT_OpaquePaint other_paint = {0};
+      if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID,
+				    FT_COLOR_NO_ROOT_TRANSFORM,
+				    &other_paint))
+      {
+        bool has_clip_box;
+        FT_ClipBox clip_box;
+        has_clip_box = FT_Get_Color_Glyph_ClipBox (ft_face, paint.u.colr_glyph.glyphID, &clip_box);
+
+        if (has_clip_box)
+	{
+	  /* The FreeType ClipBox is in scaled coordinates, whereas we need
+	   * unscaled clipbox here. Oh well...
+	   */
+
+	  float upem = c->font->face->get_upem ();
+	  float xscale = upem / (c->font->x_scale ? c->font->x_scale : upem);
+	  float yscale = upem / (c->font->y_scale ? c->font->y_scale : upem);
+
+          c->funcs->push_clip_rectangle (c->data,
+					 clip_box.bottom_left.x * xscale,
+					 clip_box.bottom_left.y * yscale,
+					 clip_box.top_right.x * xscale,
+					 clip_box.top_right.y * yscale);
+	}
+
+	c->recurse (other_paint);
+
+        if (has_clip_box)
+          c->funcs->pop_clip (c->data);
+      }
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_TRANSFORM:
+    {
+      c->funcs->push_transform (c->data,
+				paint.u.transform.affine.xx / 65536.f,
+				paint.u.transform.affine.yx / 65536.f,
+				paint.u.transform.affine.xy / 65536.f,
+				paint.u.transform.affine.yy / 65536.f,
+				paint.u.transform.affine.dx / 65536.f,
+				paint.u.transform.affine.dy / 65536.f);
+      c->recurse (paint.u.transform.paint);
+      c->funcs->pop_transform (c->data);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_TRANSLATE:
+    {
+      float dx = paint.u.translate.dx / 65536.f;
+      float dy = paint.u.translate.dy / 65536.f;
+
+      bool p1 = c->funcs->push_translate (c->data, dx, dy);
+      c->recurse (paint.u.translate.paint);
+      if (p1) c->funcs->pop_transform (c->data);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_SCALE:
+    {
+      float dx = paint.u.scale.center_x / 65536.f;
+      float dy = paint.u.scale.center_y / 65536.f;
+      float sx = paint.u.scale.scale_x / 65536.f;
+      float sy = paint.u.scale.scale_y / 65536.f;
+
+      bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
+      bool p2 = c->funcs->push_scale (c->data, sx, sy);
+      bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
+      c->recurse (paint.u.scale.paint);
+      if (p3) c->funcs->pop_transform (c->data);
+      if (p2) c->funcs->pop_transform (c->data);
+      if (p1) c->funcs->pop_transform (c->data);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_ROTATE:
+    {
+      float dx = paint.u.rotate.center_x / 65536.f;
+      float dy = paint.u.rotate.center_y / 65536.f;
+      float a = paint.u.rotate.angle / 65536.f;
+
+      bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
+      bool p2 = c->funcs->push_rotate (c->data, a);
+      bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
+      c->recurse (paint.u.rotate.paint);
+      if (p3) c->funcs->pop_transform (c->data);
+      if (p2) c->funcs->pop_transform (c->data);
+      if (p1) c->funcs->pop_transform (c->data);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_SKEW:
+    {
+      float dx = paint.u.skew.center_x / 65536.f;
+      float dy = paint.u.skew.center_y / 65536.f;
+      float sx = paint.u.skew.x_skew_angle / 65536.f;
+      float sy = paint.u.skew.y_skew_angle / 65536.f;
+
+      bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
+      bool p2 = c->funcs->push_skew (c->data, sx, sy);
+      bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
+      c->recurse (paint.u.skew.paint);
+      if (p3) c->funcs->pop_transform (c->data);
+      if (p2) c->funcs->pop_transform (c->data);
+      if (p1) c->funcs->pop_transform (c->data);
+    }
+    break;
+    case FT_COLR_PAINTFORMAT_COMPOSITE:
+    {
+      c->recurse (paint.u.composite.backdrop_paint);
+      c->funcs->push_group (c->data);
+      c->recurse (paint.u.composite.source_paint);
+      c->funcs->pop_group (c->data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode));
+    }
+    break;
+
+    case FT_COLR_PAINT_FORMAT_MAX: break;
+    default: HB_FALLTHROUGH;
+    case FT_COLR_PAINTFORMAT_UNSUPPORTED: break;
+  }
+}
+
+
+static bool
+hb_ft_paint_glyph_colr (hb_font_t *font,
+			void *font_data,
+			hb_codepoint_t gid,
+			hb_paint_funcs_t *paint_funcs, void *paint_data,
+			unsigned int palette_index,
+			hb_color_t foreground,
+			void *user_data)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Face ft_face = ft_font->ft_face;
+
+  /* Face is locked. */
+
+  FT_Error error;
+  FT_Color*         palette;
+  FT_LayerIterator  iterator;
+
+  FT_Bool  have_layers;
+  FT_UInt  layer_glyph_index;
+  FT_UInt  layer_color_index;
+
+  error = FT_Palette_Select(ft_face, palette_index, &palette);
+  if (error)
+    palette = NULL;
+
+  /* COLRv1 */
+  FT_OpaquePaint paint = {0};
+  if (FT_Get_Color_Glyph_Paint (ft_face, gid,
+			        FT_COLOR_NO_ROOT_TRANSFORM,
+			        &paint))
+  {
+    hb_ft_paint_context_t c (ft_font, font,
+			     paint_funcs, paint_data,
+			     palette, palette_index, foreground);
+
+    bool is_bounded = true;
+    FT_ClipBox clip_box;
+    if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box))
+    {
+      c.funcs->push_clip_rectangle (c.data,
+				    clip_box.bottom_left.x +
+				      roundf (hb_min (font->slant_xy * clip_box.bottom_left.y,
+						      font->slant_xy * clip_box.top_left.y)),
+				    clip_box.bottom_left.y,
+				    clip_box.top_right.x +
+				      roundf (hb_max (font->slant_xy * clip_box.bottom_right.y,
+						      font->slant_xy * clip_box.top_right.y)),
+				    clip_box.top_right.y);
+    }
+    else
+    {
+
+      auto *extents_funcs = hb_paint_extents_get_funcs ();
+      hb_paint_extents_context_t extents_data;
+      hb_ft_paint_context_t ce (ft_font, font,
+			        extents_funcs, &extents_data,
+			        palette, palette_index, foreground);
+      ce.funcs->push_root_transform (ce.data, font);
+      ce.recurse (paint);
+      ce.funcs->pop_transform (ce.data);
+      hb_extents_t extents = extents_data.get_extents ();
+      is_bounded = extents_data.is_bounded ();
+
+      c.funcs->push_clip_rectangle (c.data,
+				    extents.xmin,
+				    extents.ymin,
+				    extents.xmax,
+				    extents.ymax);
+    }
+
+    c.funcs->push_root_transform (c.data, font);
+
+    if (is_bounded)
+      c.recurse (paint);
+
+    c.funcs->pop_transform (c.data);
+    c.funcs->pop_clip (c.data);
+
+    return true;
+  }
+
+  /* COLRv0 */
+  iterator.p  = NULL;
+  have_layers = FT_Get_Color_Glyph_Layer(ft_face,
+					 gid,
+					 &layer_glyph_index,
+					 &layer_color_index,
+					 &iterator);
+
+  if (palette && have_layers)
+  {
+    do
+    {
+      hb_bool_t is_foreground = true;
+      hb_color_t color = foreground;
+
+      if ( layer_color_index != 0xFFFF )
+      {
+	FT_Color layer_color = palette[layer_color_index];
+	color = HB_COLOR (layer_color.blue,
+			  layer_color.green,
+			  layer_color.red,
+			  layer_color.alpha);
+	is_foreground = false;
+      }
+
+      ft_font->lock.unlock ();
+      paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font);
+      ft_font->lock.lock ();
+      paint_funcs->color (paint_data, is_foreground, color);
+      paint_funcs->pop_clip (paint_data);
+
+    } while (FT_Get_Color_Glyph_Layer(ft_face,
+				      gid,
+				      &layer_glyph_index,
+				      &layer_color_index,
+				      &iterator));
+    return true;
+  }
+
+  return false;
+}
+
+
+#endif /* HB_FT_COLR_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -33,17 +33,22 @@
 
 #include "hb-ft.h"
 
+#include "hb-cache.hh"
 #include "hb-draw.hh"
 #include "hb-font.hh"
 #include "hb-machinery.hh"
-#include "hb-cache.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-shaper-arabic-pua.hh"
+#include "hb-paint.hh"
 
 #include FT_ADVANCES_H
 #include FT_MULTIPLE_MASTERS_H
 #include FT_OUTLINE_H
 #include FT_TRUETYPE_TABLES_H
+#include FT_SYNTHESIS_H
+#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
+#include FT_COLOR_H
+#endif
 
 
 /**
@@ -80,7 +85,7 @@
  */
 
 
-using hb_ft_advance_cache_t = hb_cache_t<16, 24, 8, false>;
+using hb_ft_advance_cache_t = hb_cache_t<16, 8, 8, false>;
 
 struct hb_ft_font_t
 {
@@ -125,8 +130,6 @@
 {
   hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
 
-  ft_font->advance_cache.fini ();
-
   if (ft_font->unref)
     _hb_ft_face_destroy (ft_font->ft_face);
 
@@ -157,9 +160,9 @@
   {
 #ifdef HAVE_FT_GET_TRANSFORM
     /* Bitmap font, eg. bitmap color emoji. */
-    /* TODO Pick largest size? */
-    int x_scale  = ft_face->available_sizes[0].x_ppem;
-    int y_scale = ft_face->available_sizes[0].y_ppem;
+    /* Pick largest size? */
+    int x_scale  = ft_face->available_sizes[ft_face->num_fixed_sizes - 1].x_ppem;
+    int y_scale = ft_face->available_sizes[ft_face->num_fixed_sizes - 1].y_ppem;
     FT_Set_Char_Size (ft_face,
 		      x_scale, y_scale,
 		      0, 0);
@@ -224,6 +227,9 @@
  * For more information, see 
  * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx
  *
+ * This function works with #hb_font_t objects created by
+ * hb_ft_font_create() or hb_ft_font_create_referenced().
+ *
  * Since: 1.0.5
  **/
 void
@@ -249,8 +255,11 @@
  * For more information, see 
  * https://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#ft_load_xxx
  *
- * Return value: FT_Load_Glyph flags found
+ * This function works with #hb_font_t objects created by
+ * hb_ft_font_create() or hb_ft_font_create_referenced().
  *
+ * Return value: FT_Load_Glyph flags found, or 0
+ *
  * Since: 1.0.5
  **/
 int
@@ -271,6 +280,9 @@
  * Fetches the FT_Face associated with the specified #hb_font_t
  * font object.
  *
+ * This function works with #hb_font_t objects created by
+ * hb_ft_font_create() or hb_ft_font_create_referenced().
+ *
  * Return value: (nullable): the FT_Face found or `NULL`
  *
  * Since: 0.9.2
@@ -290,9 +302,14 @@
  * hb_ft_font_lock_face: (skip)
  * @font: #hb_font_t to work upon
  *
- * Gets the FT_Face associated with @font, This face will be kept around until
- * you call hb_ft_font_unlock_face().
+ * Gets the FT_Face associated with @font.
  *
+ * This face will be kept around and access to the FT_Face object
+ * from other HarfBuzz API wil be blocked until you call hb_ft_font_unlock_face().
+ *
+ * This function works with #hb_font_t objects created by
+ * hb_ft_font_create() or hb_ft_font_create_referenced().
+ *
  * Return value: (nullable) (transfer none): the FT_Face associated with @font or `NULL`
  * Since: 2.6.5
  **/
@@ -431,6 +448,7 @@
 			    void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_position_t *orig_first_advance = first_advance;
   hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
   int load_flags = ft_font->load_flags;
@@ -441,6 +459,7 @@
     FT_Matrix matrix;
     FT_Get_Transform (ft_face, &matrix, nullptr);
     x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f;
+    x_mult *= font->x_scale < 0 ? -1 : +1;
   }
   else
 #endif
@@ -459,13 +478,29 @@
     else
     {
       FT_Get_Advance (ft_face, glyph, load_flags, &v);
+      /* Work around bug that FreeType seems to return negative advance
+       * for variable-set fonts if x_scale is negative! */
+      v = abs (v);
+      v = (int) (v * x_mult + (1<<9)) >> 10;
       ft_font->advance_cache.set (glyph, v);
     }
 
-    *first_advance = (int) (v * x_mult + (1<<9)) >> 10;
+    *first_advance = v;
     first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
   }
+
+  if (font->x_strength && !font->embolden_in_place)
+  {
+    /* Emboldening. */
+    hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength;
+    first_advance = orig_first_advance;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      *first_advance += *first_advance ? x_strength : 0;
+      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+    }
+  }
 }
 
 #ifndef HB_NO_VERTICAL
@@ -485,6 +520,7 @@
     FT_Matrix matrix;
     FT_Get_Transform (ft_font->ft_face, &matrix, nullptr);
     y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
+    y_mult *= font->y_scale < 0 ? -1 : +1;
   }
   else
 #endif
@@ -500,7 +536,8 @@
   /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
    * have a Y growing upward.  Hence the extra negation. */
 
-  return (-v + (1<<9)) >> 10;
+  hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength;
+  return ((-v + (1<<9)) >> 10) + (font->embolden_in_place ? 0 : y_strength);
 }
 #endif
 
@@ -523,7 +560,9 @@
     FT_Matrix matrix;
     FT_Get_Transform (ft_face, &matrix, nullptr);
     x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f;
+    x_mult *= font->x_scale < 0 ? -1 : +1;
     y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
+    y_mult *= font->y_scale < 0 ? -1 : +1;
   }
   else
 #endif
@@ -578,6 +617,7 @@
   hb_lock_t lock (ft_font->lock);
   FT_Face ft_face = ft_font->ft_face;
   float x_mult, y_mult;
+  float slant_xy = font->slant_xy;
 #ifdef HAVE_FT_GET_TRANSFORM
   if (ft_font->transform)
   {
@@ -584,7 +624,9 @@
     FT_Matrix matrix;
     FT_Get_Transform (ft_face, &matrix, nullptr);
     x_mult = sqrtf ((float)matrix.xx * matrix.xx + (float)matrix.xy * matrix.xy) / 65536.f;
+    x_mult *= font->x_scale < 0 ? -1 : +1;
     y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
+    y_mult *= font->y_scale < 0 ? -1 : +1;
   }
   else
 #endif
@@ -596,11 +638,41 @@
   if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
     return false;
 
-  extents->x_bearing = (hb_position_t) (x_mult * ft_face->glyph->metrics.horiBearingX);
-  extents->y_bearing = (hb_position_t) (y_mult * ft_face->glyph->metrics.horiBearingY);
-  extents->width  = (hb_position_t) (x_mult *  ft_face->glyph->metrics.width);
-  extents->height = (hb_position_t) (y_mult * -ft_face->glyph->metrics.height);
+  /* Copied from hb_font_t::scale_glyph_extents. */
 
+  float x1 = x_mult * ft_face->glyph->metrics.horiBearingX;
+  float y1 = y_mult * ft_face->glyph->metrics.horiBearingY;
+  float x2 = x1 + x_mult *  ft_face->glyph->metrics.width;
+  float y2 = y1 + y_mult * -ft_face->glyph->metrics.height;
+
+  /* Apply slant. */
+  if (slant_xy)
+  {
+    x1 += hb_min (y1 * slant_xy, y2 * slant_xy);
+    x2 += hb_max (y1 * slant_xy, y2 * slant_xy);
+  }
+
+  extents->x_bearing = floorf (x1);
+  extents->y_bearing = floorf (y1);
+  extents->width = ceilf (x2) - extents->x_bearing;
+  extents->height = ceilf (y2) - extents->y_bearing;
+
+  if (font->x_strength || font->y_strength)
+  {
+    /* Y */
+    int y_shift = font->y_strength;
+    if (font->y_scale < 0) y_shift = -y_shift;
+    extents->y_bearing += y_shift;
+    extents->height -= y_shift;
+
+    /* X */
+    int x_shift = font->x_strength;
+    if (font->x_scale < 0) x_shift = -x_shift;
+    if (font->embolden_in_place)
+      extents->x_bearing -= x_shift / 2;
+    extents->width += x_shift;
+  }
+
   return true;
 }
 
@@ -700,6 +772,7 @@
     FT_Matrix matrix;
     FT_Get_Transform (ft_face, &matrix, nullptr);
     y_mult = sqrtf ((float)matrix.yx * matrix.yx + (float)matrix.yy * matrix.yy) / 65536.f;
+    y_mult *= font->y_scale < 0 ? -1 : +1;
   }
   else
 #endif
@@ -721,7 +794,7 @@
     metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender);
   }
 
-  metrics->ascender  = (hb_position_t) (y_mult * metrics->ascender);
+  metrics->ascender  = (hb_position_t) (y_mult * (metrics->ascender + font->y_strength));
   metrics->descender = (hb_position_t) (y_mult * metrics->descender);
   metrics->line_gap  = (hb_position_t) (y_mult * metrics->line_gap);
 
@@ -773,11 +846,11 @@
 }
 
 static void
-hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED,
-		       void *font_data,
-		       hb_codepoint_t glyph,
-		       hb_draw_funcs_t *draw_funcs, void *draw_data,
-		       void *user_data HB_UNUSED)
+hb_ft_draw_glyph (hb_font_t *font,
+		  void *font_data,
+		  hb_codepoint_t glyph,
+		  hb_draw_funcs_t *draw_funcs, void *draw_data,
+		  void *user_data HB_UNUSED)
 {
   const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
   hb_lock_t lock (ft_font->lock);
@@ -801,6 +874,38 @@
 
   hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
 
+  /* Embolden */
+  if (font->x_strength || font->y_strength)
+  {
+    FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_strength, font->y_strength);
+
+    int x_shift = 0;
+    int y_shift = 0;
+    if (font->embolden_in_place)
+    {
+      /* Undo the FreeType shift. */
+      x_shift = -font->x_strength / 2;
+      y_shift = 0;
+      if (font->y_scale < 0) y_shift = -font->y_strength;
+    }
+    else
+    {
+      /* FreeType applied things in the wrong direction for negative scale; fix up. */
+      if (font->x_scale < 0) x_shift = -font->x_strength;
+      if (font->y_scale < 0) y_shift = -font->y_strength;
+    }
+    if (x_shift || y_shift)
+    {
+      auto &outline = ft_face->glyph->outline;
+      for (auto &point : hb_iter (outline.points, outline.contours[outline.n_contours - 1] + 1))
+      {
+	point.x += x_shift;
+	point.y += y_shift;
+      }
+    }
+  }
+
+
   FT_Outline_Decompose (&ft_face->glyph->outline,
 			&outline_funcs,
 			&draw_session);
@@ -807,7 +912,92 @@
 }
 #endif
 
+#ifndef HB_NO_PAINT
+#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
 
+#include "hb-ft-colr.hh"
+
+static void
+hb_ft_paint_glyph (hb_font_t *font,
+                   void *font_data,
+                   hb_codepoint_t gid,
+                   hb_paint_funcs_t *paint_funcs, void *paint_data,
+                   unsigned int palette_index,
+                   hb_color_t foreground,
+                   void *user_data)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  hb_lock_t lock (ft_font->lock);
+  FT_Face ft_face = ft_font->ft_face;
+
+  /* We release the lock before calling into glyph callbacks, such that
+   * eg. draw API can call back into the face.*/
+
+  if (unlikely (FT_Load_Glyph (ft_face, gid,
+			       ft_font->load_flags | FT_LOAD_COLOR)))
+    return;
+
+  if (ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
+  {
+    if (hb_ft_paint_glyph_colr (font, font_data, gid,
+				paint_funcs, paint_data,
+				palette_index, foreground,
+				user_data))
+      return;
+
+    /* Simple outline. */
+    ft_font->lock.unlock ();
+    paint_funcs->push_clip_glyph (paint_data, gid, font);
+    ft_font->lock.lock ();
+    paint_funcs->color (paint_data, true, foreground);
+    paint_funcs->pop_clip (paint_data);
+
+    return;
+  }
+
+  auto *glyph = ft_face->glyph;
+  if (glyph->format == FT_GLYPH_FORMAT_BITMAP)
+  {
+    auto &bitmap = glyph->bitmap;
+    if (bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
+    {
+      if (bitmap.pitch != (signed) bitmap.width * 4)
+        return;
+
+      ft_font->lock.unlock ();
+
+      hb_blob_t *blob = hb_blob_create ((const char *) bitmap.buffer,
+					bitmap.pitch * bitmap.rows,
+					HB_MEMORY_MODE_DUPLICATE,
+					nullptr, nullptr);
+
+      hb_glyph_extents_t extents;
+      if (!hb_font_get_glyph_extents (font, gid, &extents))
+	goto out;
+
+      if (!paint_funcs->image (paint_data,
+			       blob,
+			       bitmap.width,
+			       bitmap.rows,
+			       HB_PAINT_IMAGE_FORMAT_BGRA,
+			       font->slant_xy,
+			       &extents))
+      {
+        /* TODO Try a forced outline load and paint? */
+      }
+
+    out:
+      hb_blob_destroy (blob);
+      ft_font->lock.lock ();
+    }
+
+    return;
+  }
+}
+#endif
+#endif
+
+
 static inline void free_static_ft_funcs ();
 
 static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft_font_funcs_lazy_loader_t>
@@ -840,9 +1030,15 @@
     hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr);
 
 #ifndef HB_NO_DRAW
-    hb_font_funcs_set_glyph_shape_func (funcs, hb_ft_get_glyph_shape, nullptr, nullptr);
+    hb_font_funcs_set_draw_glyph_func (funcs, hb_ft_draw_glyph, nullptr, nullptr);
 #endif
 
+#ifndef HB_NO_PAINT
+#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 21300
+    hb_font_funcs_set_paint_glyph_func (funcs, hb_ft_paint_glyph, nullptr, nullptr);
+#endif
+#endif
+
     hb_font_funcs_make_immutable (funcs);
 
     hb_atexit (free_static_ft_funcs);
@@ -915,6 +1111,10 @@
  *
  * Creates an #hb_face_t face object from the specified FT_Face.
  *
+ * Note that this is using the FT_Face object just to get at the underlying
+ * font data, and fonts created from the returned #hb_face_t will use the native
+ * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them.
+ *
  * This variant of the function does not provide any life-cycle management.
  *
  * Most client programs should use hb_ft_face_create_referenced()
@@ -959,6 +1159,10 @@
  *
  * Creates an #hb_face_t face object from the specified FT_Face.
  *
+ * Note that this is using the FT_Face object just to get at the underlying
+ * font data, and fonts created from the returned #hb_face_t will use the native
+ * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them.
+ *
  * This is the preferred variant of the hb_ft_face_create*
  * function family, because it calls FT_Reference_Face() on @ft_face,
  * ensuring that @ft_face remains alive as long as the resulting
@@ -991,6 +1195,10 @@
  *
  * Creates an #hb_face_t face object from the specified FT_Face.
  *
+ * Note that this is using the FT_Face object just to get at the underlying
+ * font data, and fonts created from the returned #hb_face_t will use the native
+ * HarfBuzz font implementation, unless you call hb_ft_font_set_funcs() on them.
+ *
  * This variant of the function caches the newly created #hb_face_t
  * face object, using the @generic pointer of @ft_face. Subsequent function
  * calls that are passed the same @ft_face parameter will have the same
@@ -1241,10 +1449,14 @@
  * created with hb_face_create(), and therefore was not
  * initially configured to use FreeType font functions.
  *
- * An #hb_face_t face object created with hb_ft_face_create()
+ * An #hb_font_t object created with hb_ft_font_create()
  * is preconfigured for FreeType font functions and does not
  * require this function to be used.
  *
+ * Note that if you modify the underlying #hb_font_t after
+ * calling this function, you need to call hb_ft_hb_font_changed()
+ * to update the underlying FT_Face.
+ *
  * <note>Note: Internally, this function creates an FT_Face.
 * </note>
  *
@@ -1285,5 +1497,4 @@
   _hb_ft_hb_font_changed (font, ft_face);
 }
 
-
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -91,6 +91,7 @@
 HB_DEFINE_OBJECT_TYPE (buffer)
 HB_DEFINE_OBJECT_TYPE (blob)
 HB_DEFINE_OBJECT_TYPE (draw_funcs)
+HB_DEFINE_OBJECT_TYPE (paint_funcs)
 HB_DEFINE_OBJECT_TYPE (face)
 HB_DEFINE_OBJECT_TYPE (font)
 HB_DEFINE_OBJECT_TYPE (font_funcs)
@@ -102,8 +103,12 @@
 HB_DEFINE_VALUE_TYPE (glyph_info)
 HB_DEFINE_VALUE_TYPE (glyph_position)
 HB_DEFINE_VALUE_TYPE (segment_properties)
+HB_DEFINE_VALUE_TYPE (draw_state)
+HB_DEFINE_VALUE_TYPE (color_stop)
+HB_DEFINE_VALUE_TYPE (color_line)
 HB_DEFINE_VALUE_TYPE (user_data_key)
 
+HB_DEFINE_VALUE_TYPE (ot_var_axis_info)
 HB_DEFINE_VALUE_TYPE (ot_math_glyph_variant)
 HB_DEFINE_VALUE_TYPE (ot_math_glyph_part)
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-gobject-structs.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -53,6 +53,10 @@
 #define HB_GOBJECT_TYPE_DRAW_FUNCS (hb_gobject_draw_funcs_get_type ())
 
 HB_EXTERN GType
+hb_gobject_paint_funcs_get_type (void);
+#define HB_GOBJECT_TYPE_PAINT_FUNCS (hb_gobject_paint_funcs_get_type ())
+
+HB_EXTERN GType
 hb_gobject_face_get_type (void);
 #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
 
@@ -99,10 +103,26 @@
 #define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ())
 
 HB_EXTERN GType
+hb_gobject_draw_state_get_type (void);
+#define HB_GOBJECT_TYPE_DRAW_STATE (hb_gobject_draw_state_get_type ())
+
+HB_EXTERN GType
+hb_gobject_color_stop_get_type (void);
+#define HB_GOBJECT_TYPE_COLOR_STOP (hb_gobject_color_stop_get_type ())
+
+HB_EXTERN GType
+hb_gobject_color_line_get_type (void);
+#define HB_GOBJECT_TYPE_COLOR_LINE (hb_gobject_color_line_get_type ())
+
+HB_EXTERN GType
 hb_gobject_user_data_key_get_type (void);
 #define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ())
 
 HB_EXTERN GType
+hb_gobject_ot_var_axis_info_get_type (void);
+#define HB_GOBJECT_TYPE_OT_VAR_AXIS_INFO (hb_gobject_ot_var_axis_info_get_type ())
+
+HB_EXTERN GType
 hb_gobject_ot_math_glyph_variant_get_type (void);
 #define HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT (hb_gobject_ot_math_glyph_variant_get_type ())
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -49,7 +49,8 @@
 
 #ifndef HB_DISABLE_DEPRECATED
 
-HB_EXTERN HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face) gr_font *
+HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face)
+HB_EXTERN gr_font *
 hb_graphite2_font_get_gr_font (hb_font_t *font);
 
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-iter.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -172,10 +172,16 @@
 HB_FUNCOBJ (hb_iter);
 struct
 {
-  template <typename T> unsigned
-  operator () (T&& c) const
-  { return c.len (); }
+  template <typename T> auto
+  impl (T&& c, hb_priority<1>) const HB_RETURN (unsigned, c.len ())
 
+  template <typename T> auto
+  impl (T&& c, hb_priority<0>) const HB_RETURN (unsigned, c.len)
+
+  public:
+
+  template <typename T> auto
+  operator () (T&& c) const HB_RETURN (unsigned, impl (std::forward<T> (c), hb_prioritize))
 }
 HB_FUNCOBJ (hb_len);
 

Added: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh	                        (rev 0)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-limits.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2022  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_LIMITS_HH
+#define HB_LIMITS_HH
+
+#include "hb.hh"
+
+
+#ifndef HB_BUFFER_MAX_LEN_FACTOR
+#define HB_BUFFER_MAX_LEN_FACTOR 64
+#endif
+#ifndef HB_BUFFER_MAX_LEN_MIN
+#define HB_BUFFER_MAX_LEN_MIN 16384
+#endif
+#ifndef HB_BUFFER_MAX_LEN_DEFAULT
+#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
+#endif
+
+#ifndef HB_BUFFER_MAX_OPS_FACTOR
+#define HB_BUFFER_MAX_OPS_FACTOR 1024
+#endif
+#ifndef HB_BUFFER_MAX_OPS_MIN
+#define HB_BUFFER_MAX_OPS_MIN 16384
+#endif
+#ifndef HB_BUFFER_MAX_OPS_DEFAULT
+#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
+#endif
+
+
+#ifndef HB_MAX_NESTING_LEVEL
+#define HB_MAX_NESTING_LEVEL 64
+#endif
+
+
+#ifndef HB_MAX_CONTEXT_LENGTH
+#define HB_MAX_CONTEXT_LENGTH 64
+#endif
+
+#ifndef HB_CLOSURE_MAX_STAGES
+/*
+ * The maximum number of times a lookup can be applied during shaping.
+ * Used to limit the number of iterations of the closure algorithm.
+ * This must be larger than the number of times add_gsub_pause() is
+ * called in a collect_features call of any shaper.
+ */
+#define HB_CLOSURE_MAX_STAGES 12
+#endif
+
+#ifndef HB_MAX_SCRIPTS
+#define HB_MAX_SCRIPTS 500
+#endif
+
+#ifndef HB_MAX_LANGSYS
+#define HB_MAX_LANGSYS 2000
+#endif
+
+#ifndef HB_MAX_LANGSYS_FEATURE_COUNT
+#define HB_MAX_LANGSYS_FEATURE_COUNT 50000
+#endif
+
+#ifndef HB_MAX_FEATURE_INDICES
+#define HB_MAX_FEATURE_INDICES 1500
+#endif
+
+#ifndef HB_MAX_LOOKUP_VISIT_COUNT
+#define HB_MAX_LOOKUP_VISIT_COUNT 35000
+#endif
+
+
+#ifndef HB_GLYF_MAX_POINTS
+#define HB_GLYF_MAX_POINTS 20000
+#endif
+
+#ifndef HB_GLYF_MAX_EDGE_COUNT
+#define HB_GLYF_MAX_EDGE_COUNT 1024
+#endif
+
+#ifndef HB_CFF_MAX_OPS
+#define HB_CFF_MAX_OPS 10000
+#endif
+
+#ifndef HB_COLRV1_MAX_EDGE_COUNT
+#define HB_COLRV1_MAX_EDGE_COUNT 1024
+#endif
+
+
+#endif /* HB_LIMITS_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -34,7 +34,6 @@
 
 #include "hb-dispatch.hh"
 #include "hb-sanitize.hh"
-#include "hb-serialize.hh"
 
 
 /*
@@ -305,22 +304,22 @@
   hb_blob_t* get_blob () const { return this->get_stored (); }
 };
 
-template <typename Subclass>
-struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<hb_font_funcs_t, Subclass>
-{
-  static void destroy (hb_font_funcs_t *p)
-  { hb_font_funcs_destroy (p); }
-  static const hb_font_funcs_t *get_null ()
-  { return hb_font_funcs_get_empty (); }
-};
-template <typename Subclass>
-struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<hb_unicode_funcs_t, Subclass>
-{
-  static void destroy (hb_unicode_funcs_t *p)
-  { hb_unicode_funcs_destroy (p); }
-  static const hb_unicode_funcs_t *get_null ()
-  { return hb_unicode_funcs_get_empty (); }
-};
+#define HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T(Type) \
+  template <typename Subclass> \
+  struct hb_##Type##_funcs_lazy_loader_t : hb_lazy_loader_t<hb_##Type##_funcs_t, Subclass> \
+  { \
+    static void destroy (hb_##Type##_funcs_t *p) \
+    { hb_##Type##_funcs_destroy (p); } \
+    static const hb_##Type##_funcs_t *get_null () \
+    { return hb_##Type##_funcs_get_empty (); } \
+  }
 
+HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (font);
+HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (unicode);
+HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (draw);
+HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (paint);
 
+#undef HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T
+
+
 #endif /* HB_MACHINERY_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -174,7 +174,7 @@
  *
  * Allocate a copy of @map.
  *
- * Return value: Newly-allocated map.
+ * Return value: (transfer full): Newly-allocated map.
  *
  * Since: 4.4.0
  **/
@@ -182,9 +182,10 @@
 hb_map_copy (const hb_map_t *map)
 {
   hb_map_t *copy = hb_map_create ();
-  if (unlikely (!copy)) return nullptr;
-  copy->resize (map->population);
-  hb_copy (*map, *copy);
+  if (unlikely (copy->in_error ()))
+    return hb_map_get_empty ();
+
+  *copy = *map;
   return copy;
 }
 
@@ -335,9 +336,84 @@
  *
  * Since: 4.4.0
  **/
-HB_EXTERN unsigned int
+unsigned int
 hb_map_hash (const hb_map_t *map)
 {
   return map->hash ();
 }
 
+/**
+ * hb_map_update:
+ * @map: A map
+ * @other: Another map
+ *
+ * Add the contents of @other to @map.
+ *
+ * Since: 7.0.0
+ **/
+HB_EXTERN void
+hb_map_update (hb_map_t *map,
+	       const hb_map_t *other)
+{
+  map->update (*other);
+}
+
+/**
+ * hb_map_next:
+ * @map: A map
+ * @idx: (inout): Iterator internal state
+ * @key: (out): Key retrieved
+ * @value: (out): Value retrieved
+ *
+ * Fetches the next key/value paire in @map.
+ *
+ * Set @idx to -1 to get started.
+ *
+ * If the map is modified during iteration, the behavior is undefined.
+ *
+ * The order in which the key/values are returned is undefined.
+ *
+ * Return value: `true` if there was a next value, `false` otherwise
+ *
+ * Since: 7.0.0
+ **/
+hb_bool_t
+hb_map_next (const hb_map_t *map,
+	     int *idx,
+	     hb_codepoint_t *key,
+	     hb_codepoint_t *value)
+{
+  return map->next (idx, key, value);
+}
+
+/**
+ * hb_map_keys:
+ * @map: A map
+ * @keys: A set
+ *
+ * Add the keys of @map to @keys.
+ *
+ * Since: 7.0.0
+ **/
+void
+hb_map_keys (const hb_map_t *map,
+	     hb_set_t *keys)
+{
+  map->keys (*keys);
+}
+
+/**
+ * hb_map_values:
+ * @map: A map
+ * @values: A set
+ *
+ * Add the values of @map to @values.
+ *
+ * Since: 7.0.0
+ **/
+void
+hb_map_values (const hb_map_t *map,
+	       hb_set_t *values)
+{
+  map->values (*values);
+}

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -32,6 +32,7 @@
 #define HB_MAP_H
 
 #include "hb-common.h"
+#include "hb-set.h"
 
 HB_BEGIN_DECLS
 
@@ -118,7 +119,25 @@
 hb_map_has (const hb_map_t *map,
 	    hb_codepoint_t  key);
 
+HB_EXTERN void
+hb_map_update (hb_map_t *map,
+	       const hb_map_t *other);
 
+/* Pass -1 in for idx to get started. */
+HB_EXTERN hb_bool_t
+hb_map_next (const hb_map_t *map,
+	     int *idx,
+	     hb_codepoint_t *key,
+	     hb_codepoint_t *value);
+
+HB_EXTERN void
+hb_map_keys (const hb_map_t *map,
+	     hb_set_t *keys);
+
+HB_EXTERN void
+hb_map_values (const hb_map_t *map,
+	       hb_set_t *values);
+
 HB_END_DECLS
 
 #endif /* HB_MAP_H */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-map.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -29,7 +29,9 @@
 
 #include "hb.hh"
 
+#include "hb-set.hh"
 
+
 /*
  * hb_hashmap_t
  */
@@ -308,6 +310,23 @@
 
   unsigned int get_population () const { return population; }
 
+  void update (const hb_hashmap_t &other)
+  {
+    if (unlikely (!successful)) return;
+
+    hb_copy (other, *this);
+  }
+
+  void keys (hb_set_t &keys_) const
+  {
+    hb_copy (keys() , keys_);
+  }
+
+  void values (hb_set_t &values_) const
+  {
+    hb_copy (values() , values_);
+  }
+
   /*
    * Iterator
    */
@@ -348,6 +367,30 @@
     | hb_map (hb_ridentity)
   )
 
+  /* C iterator. */
+  bool next (int *idx,
+	     K *key,
+	     V *value) const
+  {
+    unsigned i = (unsigned) (*idx + 1);
+
+    unsigned count = size ();
+    while (i < count && !items[i].is_real ())
+      i++;
+
+    if (i >= count)
+    {
+      *idx = -1;
+      return false;
+    }
+
+    *key = items[i].key;
+    *value = items[i].value;
+
+    *idx = (signed) i;
+    return true;
+  }
+
   /* Sink interface. */
   hb_hashmap_t& operator << (const hb_pair_t<K, V>& v)
   { set (v.first, v.second); return *this; }
@@ -451,37 +494,5 @@
   hb_map_t (const Iterable &o) : hashmap (o) {}
 };
 
-template <typename K, typename V>
-static inline
-hb_hashmap_t<K, V>* hb_hashmap_create ()
-{
-  using hashmap = hb_hashmap_t<K, V>;
-  hashmap* map;
-  if (!(map = hb_object_create<hashmap> ()))
-    return nullptr;
 
-  return map;
-}
-
-template <typename K, typename V>
-static inline
-void hb_hashmap_destroy (hb_hashmap_t<K, V>* map)
-{
-  if (!hb_object_destroy (map))
-    return;
-
-  hb_free (map);
-}
-
-namespace hb {
-
-template <typename K, typename V>
-struct vtable<hb_hashmap_t<K, V>>
-{
-  static constexpr auto destroy = hb_hashmap_destroy<K,V>;
-};
-
-}
-
-
 #endif /* HB_MAP_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ms-feature-ranges.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -30,6 +30,9 @@
 
 #include "hb.hh"
 
+/* Variations of this code exist in hb-coretext.cc as well
+ * as hb-aat-map.cc... */
+
 typedef struct hb_ms_feature_t {
   uint32_t tag_le;
   uint32_t value;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-multimap.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -65,7 +65,7 @@
 
   hb_array_t<const hb_codepoint_t> get (hb_codepoint_t k) const
   {
-    hb_codepoint_t *v;
+    const hb_codepoint_t *v;
     if (singulars.has (k, &v))
       return hb_array (v, 1);
 
@@ -73,7 +73,7 @@
     if (multiples_indices.has (k, &i))
       return multiples_values[*i].as_array ();
 
-    return hb_array_t<hb_codepoint_t> ();
+    return hb_array_t<const hb_codepoint_t> ();
   }
 
   bool in_error () const

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -60,7 +60,7 @@
 #elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && defined(_WIN32)
 
 typedef CRITICAL_SECTION hb_mutex_impl_t;
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
 #define hb_mutex_impl_init(M)	InitializeCriticalSectionEx (M, 0, 0)
 #else
 #define hb_mutex_impl_init(M)	InitializeCriticalSection (M)
@@ -97,6 +97,9 @@
   /* Create space for, but do not initialize m. */
   alignas(hb_mutex_impl_t) char m[sizeof (hb_mutex_impl_t)];
 
+  hb_mutex_t () { init (); }
+  ~hb_mutex_t () { fini (); }
+
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wcast-align"
   void init   () { hb_mutex_impl_init   ((hb_mutex_impl_t *) m); }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-number.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -24,7 +24,6 @@
  */
 
 #include "hb.hh"
-#include "hb-machinery.hh"
 #include "hb-number.hh"
 #include "hb-number-parser.hh"
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -69,7 +69,7 @@
       item = items.push (v);
       l.unlock ();
     }
-    return item;
+    return items.in_error () ? nullptr : item;
   }
 
   template <typename T>
@@ -175,14 +175,34 @@
 
   void init () { lock.init (); items.init (); }
 
-  HB_INTERNAL bool set (hb_user_data_key_t *key,
-			void *              data,
-			hb_destroy_func_t   destroy,
-			hb_bool_t           replace);
+  void fini () { items.fini (lock); lock.fini (); }
 
-  HB_INTERNAL void *get (hb_user_data_key_t *key);
+  bool set (hb_user_data_key_t *key,
+	    void *              data,
+	    hb_destroy_func_t   destroy,
+	    hb_bool_t           replace)
+  {
+    if (!key)
+      return false;
 
-  void fini () { items.fini (lock); lock.fini (); }
+    if (replace) {
+      if (!data && !destroy) {
+	items.remove (key, lock);
+	return true;
+      }
+    }
+    hb_user_data_item_t item = {key, data, destroy};
+    bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
+
+    return ret;
+  }
+
+  void *get (hb_user_data_key_t *key)
+  {
+    hb_user_data_item_t item = {nullptr, nullptr, nullptr};
+
+    return items.find (key, &item, lock) ? item.data : nullptr;
+  }
 };
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -147,7 +147,10 @@
   static constexpr float shift = (float) (1 << fraction_bits);
   static_assert (Type::static_size * 8 > fraction_bits, "");
 
-  HBFixed& operator = (typename Type::type i ) { Type::operator= (i); return *this; }
+  operator signed () const = delete;
+  operator unsigned () const = delete;
+  typename Type::type to_int () const { return Type::v; }
+  void set_int (typename Type::type i ) { Type::v = i; }
   float to_float (float offset = 0) const  { return ((int32_t) Type::v + offset) / shift; }
   void set_float (float f) { Type::v = roundf (f * shift); }
   public:
@@ -156,9 +159,8 @@
 
 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
 using F2DOT14 = HBFixed<HBINT16, 14>;
-
-/* 16-bit signed fixed number with the low 12 bits of fraction (4.12). */
 using F4DOT12 = HBFixed<HBINT16, 12>;
+using F6DOT10 = HBFixed<HBINT16, 10>;
 
 /* 32-bit signed fixed-point number (16.16). */
 using F16DOT16 = HBFixed<HBINT32, 16>;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -422,8 +422,8 @@
   }
   else
   {
-    extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ());
-    extents->width = font->em_scalef_x (bounds.max.x.to_real ()) - extents->x_bearing;
+    extents->x_bearing = roundf (bounds.min.x.to_real ());
+    extents->width = roundf (bounds.max.x.to_real () - extents->x_bearing);
   }
   if (bounds.min.y >= bounds.max.y)
   {
@@ -432,10 +432,12 @@
   }
   else
   {
-    extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ());
-    extents->height = font->em_scalef_y (bounds.min.y.to_real ()) - extents->y_bearing;
+    extents->y_bearing = roundf (bounds.max.y.to_real ());
+    extents->height = roundf (bounds.min.y.to_real () - extents->y_bearing);
   }
 
+  font->scale_glyph_extents (extents);
+
   return true;
 }
 
@@ -551,6 +553,15 @@
   return true;
 }
 
+bool OT::cff1::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
+{
+  funcs->push_clip_glyph (data, glyph, font);
+  funcs->color (data, true, foreground);
+  funcs->pop_clip (data);
+
+  return true;
+}
+
 bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const
 {
 #ifdef HB_NO_OT_FONT_CFF

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff1-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -30,6 +30,7 @@
 #include "hb-ot-cff-common.hh"
 #include "hb-subset-cff1.hh"
 #include "hb-draw.hh"
+#include "hb-paint.hh"
 
 #define HB_STRING_ARRAY_NAME cff1_std_strings
 #define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh"
@@ -1343,6 +1344,7 @@
     bool get_glyph_name (hb_codepoint_t glyph,
 			 char *buf, unsigned int buf_len) const
     {
+      if (unlikely (glyph >= num_glyphs)) return false;
       if (unlikely (!is_valid ())) return false;
       if (is_CID()) return false;
       if (unlikely (!buf_len)) return true;
@@ -1426,6 +1428,7 @@
     }
 
     HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
+    HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const;
     HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
     HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -124,8 +124,8 @@
   }
   else
   {
-    extents->x_bearing = font->em_scalef_x (param.min_x.to_real ());
-    extents->width = font->em_scalef_x (param.max_x.to_real ()) - extents->x_bearing;
+    extents->x_bearing = roundf (param.min_x.to_real ());
+    extents->width = roundf (param.max_x.to_real () - extents->x_bearing);
   }
   if (param.min_y >= param.max_y)
   {
@@ -134,13 +134,24 @@
   }
   else
   {
-    extents->y_bearing = font->em_scalef_y (param.max_y.to_real ());
-    extents->height = font->em_scalef_y (param.min_y.to_real ()) - extents->y_bearing;
+    extents->y_bearing = roundf (param.max_y.to_real ());
+    extents->height = roundf (param.min_y.to_real () - extents->y_bearing);
   }
 
+  font->scale_glyph_extents (extents);
+
   return true;
 }
 
+bool OT::cff2::accelerator_t::paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const
+{
+  funcs->push_clip_glyph (data, glyph, font);
+  funcs->color (data, true, foreground);
+  funcs->pop_clip (data);
+
+  return true;
+}
+
 struct cff2_path_param_t
 {
   cff2_path_param_t (hb_font_t *font_, hb_draw_session_t &draw_session_)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cff2-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -30,6 +30,7 @@
 #include "hb-ot-cff-common.hh"
 #include "hb-subset-cff2.hh"
 #include "hb-draw.hh"
+#include "hb-paint.hh"
 
 namespace CFF {
 
@@ -516,6 +517,7 @@
     HB_INTERNAL bool get_extents (hb_font_t *font,
 				  hb_codepoint_t glyph,
 				  hb_glyph_extents_t *extents) const;
+    HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const;
     HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
   };
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -31,6 +31,7 @@
 #include "hb-ot-shaper-arabic-pua.hh"
 #include "hb-open-type.hh"
 #include "hb-set.hh"
+#include "hb-cache.hh"
 
 /*
  * cmap -- Character to Glyph Index Mapping
@@ -1414,7 +1415,7 @@
     switch (format) {
     case  4: return u.format4.serialize (c, it);
     case 12: return u.format12.serialize (c, it);
-    case 14: return u.format14.serialize (c, plan->unicodes, plan->glyphs_requested, plan->glyph_map, base);
+    case 14: return u.format14.serialize (c, &plan->unicodes, &plan->glyphs_requested, plan->glyph_map, base);
     default: return;
     }
   }
@@ -1841,6 +1842,8 @@
 
   struct accelerator_t
   {
+    using cache_t = hb_cache_t<21, 16, 8, true>;
+
     accelerator_t (hb_face_t *face)
     {
       this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
@@ -1895,26 +1898,43 @@
     }
     ~accelerator_t () { this->table.destroy (); }
 
+    inline bool _cached_get (hb_codepoint_t unicode,
+			     hb_codepoint_t *glyph,
+			     cache_t *cache) const
+    {
+      unsigned v;
+      if (cache && cache->get (unicode, &v))
+      {
+        *glyph = v;
+	return true;
+      }
+      bool ret  = this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
+
+      if (cache && ret)
+        cache->set (unicode, *glyph);
+      return ret;
+    }
+
     bool get_nominal_glyph (hb_codepoint_t  unicode,
-			    hb_codepoint_t *glyph) const
+			    hb_codepoint_t *glyph,
+			    cache_t *cache = nullptr) const
     {
-      if (unlikely (!this->get_glyph_funcZ)) return false;
-      return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
+      if (unlikely (!this->get_glyph_funcZ)) return 0;
+      return _cached_get (unicode, glyph, cache);
     }
+
     unsigned int get_nominal_glyphs (unsigned int count,
 				     const hb_codepoint_t *first_unicode,
 				     unsigned int unicode_stride,
 				     hb_codepoint_t *first_glyph,
-				     unsigned int glyph_stride) const
+				     unsigned int glyph_stride,
+				     cache_t *cache = nullptr) const
     {
       if (unlikely (!this->get_glyph_funcZ)) return 0;
 
-      hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ;
-      const void *get_glyph_data = this->get_glyph_data;
-
       unsigned int done;
       for (done = 0;
-	   done < count && get_glyph_funcZ (get_glyph_data, *first_unicode, first_glyph);
+	   done < count && _cached_get (*first_unicode, first_glyph, cache);
 	   done++)
       {
 	first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
@@ -1925,7 +1945,8 @@
 
     bool get_variation_glyph (hb_codepoint_t  unicode,
 			      hb_codepoint_t  variation_selector,
-			      hb_codepoint_t *glyph) const
+			      hb_codepoint_t *glyph,
+			      cache_t *cache = nullptr) const
     {
       switch (this->subtable_uvs->get_glyph_variant (unicode,
 						     variation_selector,
@@ -1936,7 +1957,7 @@
 	case GLYPH_VARIANT_USE_DEFAULT:	break;
       }
 
-      return get_nominal_glyph (unicode, glyph);
+      return get_nominal_glyph (unicode, glyph, cache);
     }
 
     void collect_unicodes (hb_set_t *out, unsigned int num_glyphs) const

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,997 +0,0 @@
-/*
- * Copyright © 2016  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Seigo Nonaka, Calder Kitagawa
- */
-
-#ifndef HB_OT_COLOR_CBDT_TABLE_HH
-#define HB_OT_COLOR_CBDT_TABLE_HH
-
-#include "hb-open-type.hh"
-
-/*
- * CBLC -- Color Bitmap Location
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc
- * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc
- * CBDT -- Color Bitmap Data
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt
- * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt
- */
-#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
-#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
-
-
-namespace OT {
-
-struct cblc_bitmap_size_subset_context_t
-{
-  const char *cbdt;
-  unsigned int cbdt_length;
-  hb_vector_t<char> *cbdt_prime;
-  unsigned int size;		/* INOUT
-				 *  Input: old size of IndexSubtable
-				 *  Output: new size of IndexSubtable
-				 */
-  unsigned int num_tables;	/* INOUT
-				 *  Input: old number of subtables.
-				 *  Output: new number of subtables.
-				 */
-  hb_codepoint_t start_glyph;	/* OUT */
-  hb_codepoint_t end_glyph;	/* OUT */
-};
-
-static inline bool
-_copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime,
-		    const void        *data,
-		    unsigned           length)
-{
-  unsigned int new_len = cbdt_prime->length + length;
-  if (unlikely (!cbdt_prime->alloc (new_len))) return false;
-  hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
-  cbdt_prime->length = new_len;
-  return true;
-}
-
-struct SmallGlyphMetrics
-{
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
-  {
-    extents->x_bearing = font->em_scale_x (bearingX);
-    extents->y_bearing = font->em_scale_y (bearingY);
-    extents->width = font->em_scale_x (width);
-    extents->height = font->em_scale_y (-static_cast<int>(height));
-  }
-
-  HBUINT8	height;
-  HBUINT8	width;
-  HBINT8	bearingX;
-  HBINT8	bearingY;
-  HBUINT8	advance;
-  public:
-  DEFINE_SIZE_STATIC (5);
-};
-
-struct BigGlyphMetrics : SmallGlyphMetrics
-{
-  HBINT8	vertBearingX;
-  HBINT8	vertBearingY;
-  HBUINT8	vertAdvance;
-  public:
-  DEFINE_SIZE_STATIC (8);
-};
-
-struct SBitLineMetrics
-{
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBINT8	ascender;
-  HBINT8	decender;
-  HBUINT8	widthMax;
-  HBINT8	caretSlopeNumerator;
-  HBINT8	caretSlopeDenominator;
-  HBINT8	caretOffset;
-  HBINT8	minOriginSB;
-  HBINT8	minAdvanceSB;
-  HBINT8	maxBeforeBL;
-  HBINT8	minAfterBL;
-  HBINT8	padding1;
-  HBINT8	padding2;
-  public:
-  DEFINE_SIZE_STATIC (12);
-};
-
-
-/*
- * Index Subtables.
- */
-
-struct IndexSubtableHeader
-{
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBUINT16	indexFormat;
-  HBUINT16	imageFormat;
-  HBUINT32	imageDataOffset;
-  public:
-  DEFINE_SIZE_STATIC (8);
-};
-
-template <typename OffsetType>
-struct IndexSubtableFormat1Or3
-{
-  bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  offsetArrayZ.sanitize (c, glyph_count + 1));
-  }
-
-  bool get_image_data (unsigned int idx,
-		       unsigned int *offset,
-		       unsigned int *length) const
-  {
-    if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
-      return false;
-
-    *offset = header.imageDataOffset + offsetArrayZ[idx];
-    *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
-    return true;
-  }
-
-  bool add_offset (hb_serialize_context_t *c,
-		   unsigned int offset,
-		   unsigned int *size /* OUT (accumulated) */)
-  {
-    TRACE_SERIALIZE (this);
-    Offset<OffsetType> embedded_offset;
-    embedded_offset = offset;
-    *size += sizeof (OffsetType);
-    auto *o = c->embed (embedded_offset);
-    return_trace ((bool) o);
-  }
-
-  IndexSubtableHeader	header;
-  UnsizedArrayOf<Offset<OffsetType>>
-			offsetArrayZ;
-  public:
-  DEFINE_SIZE_ARRAY (8, offsetArrayZ);
-};
-
-struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
-struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {};
-
-struct IndexSubtable
-{
-  bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
-  {
-    TRACE_SANITIZE (this);
-    if (!u.header.sanitize (c)) return_trace (false);
-    switch (u.header.indexFormat)
-    {
-    case 1: return_trace (u.format1.sanitize (c, glyph_count));
-    case 3: return_trace (u.format3.sanitize (c, glyph_count));
-    default:return_trace (true);
-    }
-  }
-
-  bool
-  finish_subtable (hb_serialize_context_t *c,
-		   unsigned int cbdt_prime_len,
-		   unsigned int num_glyphs,
-		   unsigned int *size /* OUT (accumulated) */)
-  {
-    TRACE_SERIALIZE (this);
-
-    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
-    switch (u.header.indexFormat)
-    {
-    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
-    case 3: {
-      if (!u.format3.add_offset (c, local_offset, size))
-	return_trace (false);
-      if (!(num_glyphs & 0x01))  // Pad to 32-bit alignment if needed.
-	return_trace (u.format3.add_offset (c, 0, size));
-      return_trace (true);
-    }
-    // TODO: implement 2, 4, 5.
-    case 2: case 4:  // No-op.
-    case 5:  // Pad to 32-bit aligned.
-    default: return_trace (false);
-    }
-  }
-
-  bool
-  fill_missing_glyphs (hb_serialize_context_t *c,
-		       unsigned int cbdt_prime_len,
-		       unsigned int num_missing,
-		       unsigned int *size /* OUT (accumulated) */,
-		       unsigned int *num_glyphs /* OUT (accumulated) */)
-  {
-    TRACE_SERIALIZE (this);
-
-    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
-    switch (u.header.indexFormat)
-    {
-    case 1: {
-      for (unsigned int i = 0; i < num_missing; i++)
-      {
-	if (unlikely (!u.format1.add_offset (c, local_offset, size)))
-	  return_trace (false);
-	*num_glyphs += 1;
-      }
-      return_trace (true);
-    }
-    case 3: {
-      for (unsigned int i = 0; i < num_missing; i++)
-      {
-	if (unlikely (!u.format3.add_offset (c, local_offset, size)))
-	  return_trace (false);
-	*num_glyphs += 1;
-      }
-      return_trace (true);
-    }
-    // TODO: implement 2, 4, 5.
-    case 2:  // Add empty space in cbdt_prime?.
-    case 4: case 5:  // No-op as sparse is supported.
-    default: return_trace (false);
-    }
-  }
-
-  bool
-  copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx,
-		     const char *cbdt, unsigned int cbdt_length,
-		     hb_vector_t<char> *cbdt_prime /* INOUT */,
-		     IndexSubtable *subtable_prime /* INOUT */,
-		     unsigned int *size /* OUT (accumulated) */) const
-  {
-    TRACE_SERIALIZE (this);
-
-    unsigned int offset, length, format;
-    if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false);
-    if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false);
-
-    auto *header_prime = subtable_prime->get_header ();
-    unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset;
-    if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false);
-
-    return_trace (subtable_prime->add_offset (c, new_local_offset, size));
-  }
-
-  bool
-  add_offset (hb_serialize_context_t *c, unsigned int local_offset,
-	      unsigned int *size /* OUT (accumulated) */)
-  {
-    TRACE_SERIALIZE (this);
-    switch (u.header.indexFormat)
-    {
-    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
-    case 3: return_trace (u.format3.add_offset (c, local_offset, size));
-    // TODO: Implement tables 2, 4, 5
-    case 2:  // Should be a no-op.
-    case 4: case 5:  // Handle sparse cases.
-    default: return_trace (false);
-    }
-  }
-
-  bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const
-  {
-    switch (u.header.indexFormat)
-    {
-    case 2: case 5: /* TODO */
-    case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
-    default:return (false);
-    }
-  }
-
-  bool
-  get_image_data (unsigned int idx, unsigned int *offset,
-		  unsigned int *length, unsigned int *format) const
-  {
-    *format = u.header.imageFormat;
-    switch (u.header.indexFormat)
-    {
-    case 1: return u.format1.get_image_data (idx, offset, length);
-    case 3: return u.format3.get_image_data (idx, offset, length);
-    default: return false;
-    }
-  }
-
-  const IndexSubtableHeader* get_header () const { return &u.header; }
-
-  void populate_header (unsigned index_format,
-			unsigned image_format,
-			unsigned int image_data_offset,
-			unsigned int *size)
-  {
-    u.header.indexFormat = index_format;
-    u.header.imageFormat = image_format;
-    u.header.imageDataOffset = image_data_offset;
-    switch (u.header.indexFormat)
-    {
-    case 1: *size += IndexSubtableFormat1::min_size; break;
-    case 3: *size += IndexSubtableFormat3::min_size; break;
-    }
-  }
-
-  protected:
-  union {
-  IndexSubtableHeader	header;
-  IndexSubtableFormat1	format1;
-  IndexSubtableFormat3	format3;
-  /* TODO: Format 2, 4, 5. */
-  } u;
-  public:
-  DEFINE_SIZE_UNION (8, header);
-};
-
-struct IndexSubtableRecord
-{
-  /* XXX Remove this and fix by not inserting it into vector. */
-  IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
-  {
-    firstGlyphIndex = o.firstGlyphIndex;
-    lastGlyphIndex = o.lastGlyphIndex;
-    offsetToSubtable = (unsigned) o.offsetToSubtable;
-    assert (offsetToSubtable.is_null ());
-    return *this;
-  }
-
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  firstGlyphIndex <= lastGlyphIndex &&
-		  offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
-  }
-
-  const IndexSubtable* get_subtable (const void *base) const
-  {
-    return &(base+offsetToSubtable);
-  }
-
-  bool add_new_subtable (hb_subset_context_t* c,
-			 cblc_bitmap_size_subset_context_t *bitmap_size_context,
-			 IndexSubtableRecord *record,
-			 const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
-			 const void *base,
-			 unsigned int *start /* INOUT */) const
-  {
-    TRACE_SERIALIZE (this);
-
-    auto *subtable = c->serializer->start_embed<IndexSubtable> ();
-    if (unlikely (!subtable)) return_trace (false);
-    if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
-
-    auto *old_subtable = get_subtable (base);
-    auto *old_header = old_subtable->get_header ();
-
-    subtable->populate_header (old_header->indexFormat,
-			       old_header->imageFormat,
-			       bitmap_size_context->cbdt_prime->length,
-			       &bitmap_size_context->size);
-
-    unsigned int num_glyphs = 0;
-    bool early_exit = false;
-    for (unsigned int i = *start; i < lookup->length; i++)
-    {
-      hb_codepoint_t new_gid = (*lookup)[i].first;
-      const IndexSubtableRecord *next_record = (*lookup)[i].second;
-      const IndexSubtable *next_subtable = next_record->get_subtable (base);
-      auto *next_header = next_subtable->get_header ();
-      if (next_header != old_header)
-      {
-	*start = i;
-	early_exit = true;
-	break;
-      }
-      unsigned int num_missing = record->add_glyph_for_subset (new_gid);
-      if (unlikely (!subtable->fill_missing_glyphs (c->serializer,
-						    bitmap_size_context->cbdt_prime->length,
-						    num_missing,
-						    &bitmap_size_context->size,
-						    &num_glyphs)))
-	return_trace (false);
-
-      hb_codepoint_t old_gid = 0;
-      c->plan->old_gid_for_new_gid (new_gid, &old_gid);
-      if (old_gid < next_record->firstGlyphIndex)
-	return_trace (false);
-
-      unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex;
-      if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer,
-						       old_idx,
-						       bitmap_size_context->cbdt,
-						       bitmap_size_context->cbdt_length,
-						       bitmap_size_context->cbdt_prime,
-						       subtable,
-						       &bitmap_size_context->size)))
-	return_trace (false);
-      num_glyphs += 1;
-    }
-    if (!early_exit)
-      *start = lookup->length;
-    if (unlikely (!subtable->finish_subtable (c->serializer,
-					      bitmap_size_context->cbdt_prime->length,
-					      num_glyphs,
-					      &bitmap_size_context->size)))
-      return_trace (false);
-    return_trace (true);
-  }
-
-  bool add_new_record (hb_subset_context_t *c,
-		       cblc_bitmap_size_subset_context_t *bitmap_size_context,
-		       const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
-		       const void *base,
-		       unsigned int *start, /* INOUT */
-		       hb_vector_t<IndexSubtableRecord>* records /* INOUT */) const
-  {
-    TRACE_SERIALIZE (this);
-    auto snap = c->serializer->snapshot ();
-    unsigned int old_size = bitmap_size_context->size;
-    unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length;
-
-    // Set to invalid state to indicate filling glyphs is not yet started.
-    if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
-      return_trace (false);
-
-    records->tail ().firstGlyphIndex = 1;
-    records->tail ().lastGlyphIndex = 0;
-    bitmap_size_context->size += IndexSubtableRecord::min_size;
-
-    c->serializer->push ();
-
-    if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
-    {
-      c->serializer->pop_discard ();
-      c->serializer->revert (snap);
-      bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length);
-      bitmap_size_context->size = old_size;
-      records->resize (records->length - 1);
-      return_trace (false);
-    }
-
-    bitmap_size_context->num_tables += 1;
-    return_trace (true);
-  }
-
-  unsigned int add_glyph_for_subset (hb_codepoint_t gid)
-  {
-    if (firstGlyphIndex > lastGlyphIndex)
-    {
-      firstGlyphIndex = gid;
-      lastGlyphIndex = gid;
-      return 0;
-    }
-    // TODO maybe assert? this shouldn't occur.
-    if (lastGlyphIndex > gid)
-      return 0;
-    unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1);
-    lastGlyphIndex = gid;
-    return num_missing;
-  }
-
-  bool get_extents (hb_glyph_extents_t *extents, const void *base) const
-  { return (base+offsetToSubtable).get_extents (extents); }
-
-  bool get_image_data (unsigned int  gid,
-		       const void   *base,
-		       unsigned int *offset,
-		       unsigned int *length,
-		       unsigned int *format) const
-  {
-    if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
-    return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
-						   offset, length, format);
-  }
-
-  HBGlyphID16			firstGlyphIndex;
-  HBGlyphID16			lastGlyphIndex;
-  Offset32To<IndexSubtable>	offsetToSubtable;
-  public:
-  DEFINE_SIZE_STATIC (8);
-};
-
-struct IndexSubtableArray
-{
-  friend struct CBDT;
-
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (indexSubtablesZ.sanitize (c, count, this));
-  }
-
-  void
-  build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context,
-		hb_vector_t<hb_pair_t<hb_codepoint_t,
-		const IndexSubtableRecord*>> *lookup /* OUT */) const
-  {
-    bool start_glyph_is_set = false;
-    for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++)
-    {
-      hb_codepoint_t old_gid;
-      if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
-
-      const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables);
-      if (unlikely (!record)) continue;
-
-      // Don't add gaps to the lookup. The best way to determine if a glyph is a
-      // gap is that it has no image data.
-      unsigned int offset, length, format;
-      if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue;
-
-      lookup->push (hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*> (new_gid, record));
-
-      if (!start_glyph_is_set)
-      {
-	bitmap_size_context->start_glyph = new_gid;
-	start_glyph_is_set = true;
-      }
-
-      bitmap_size_context->end_glyph = new_gid;
-    }
-  }
-
-  bool
-  subset (hb_subset_context_t *c,
-	  cblc_bitmap_size_subset_context_t *bitmap_size_context) const
-  {
-    TRACE_SUBSET (this);
-
-    auto *dst = c->serializer->start_embed<IndexSubtableArray> ();
-    if (unlikely (!dst)) return_trace (false);
-
-    hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
-    build_lookup (c, bitmap_size_context, &lookup);
-    if (unlikely (!c->serializer->propagate_error (lookup)))
-      return false;
-
-    bitmap_size_context->size = 0;
-    bitmap_size_context->num_tables = 0;
-    hb_vector_t<IndexSubtableRecord> records;
-    for (unsigned int start = 0; start < lookup.length;)
-    {
-      if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records)))
-      {
-	// Discard any leftover pushes to the serializer from successful records.
-	for (unsigned int i = 0; i < records.length; i++)
-	  c->serializer->pop_discard ();
-	return_trace (false);
-      }
-    }
-
-    /* Workaround to ensure offset ordering is from least to greatest when
-     * resolving links. */
-    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
-    for (unsigned int i = 0; i < records.length; i++)
-      objidxs.push (c->serializer->pop_pack ());
-    for (unsigned int i = 0; i < records.length; i++)
-    {
-      IndexSubtableRecord* record = c->serializer->embed (records[i]);
-      if (unlikely (!record)) return_trace (false);
-      c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]);
-    }
-    return_trace (true);
-  }
-
-  public:
-  const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
-  {
-    for (unsigned int i = 0; i < numTables; ++i)
-    {
-      unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
-      unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
-      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
-	return &indexSubtablesZ[i];
-    }
-    return nullptr;
-  }
-
-  protected:
-  UnsizedArrayOf<IndexSubtableRecord>	indexSubtablesZ;
-};
-
-struct BitmapSizeTable
-{
-  friend struct CBLC;
-  friend struct CBDT;
-
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
-		  horizontal.sanitize (c) &&
-		  vertical.sanitize (c));
-  }
-
-  const IndexSubtableRecord *
-  find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const
-  {
-    *out_base = &(base+indexSubtableArrayOffset);
-    return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
-  }
-
-  bool
-  subset (hb_subset_context_t *c, const void *base,
-	  const char *cbdt, unsigned int cbdt_length,
-	  hb_vector_t<char> *cbdt_prime /* INOUT */) const
-  {
-    TRACE_SUBSET (this);
-    auto *out_table = c->serializer->embed (this);
-    if (unlikely (!out_table)) return_trace (false);
-
-    cblc_bitmap_size_subset_context_t bitmap_size_context;
-    bitmap_size_context.cbdt = cbdt;
-    bitmap_size_context.cbdt_length = cbdt_length;
-    bitmap_size_context.cbdt_prime = cbdt_prime;
-    bitmap_size_context.size = indexTablesSize;
-    bitmap_size_context.num_tables = numberOfIndexSubtables;
-    bitmap_size_context.start_glyph = 1;
-    bitmap_size_context.end_glyph = 0;
-
-    if (!out_table->indexSubtableArrayOffset.serialize_subset (c,
-							       indexSubtableArrayOffset,
-							       base,
-							       &bitmap_size_context))
-      return_trace (false);
-    if (!bitmap_size_context.size ||
-	!bitmap_size_context.num_tables ||
-	bitmap_size_context.start_glyph > bitmap_size_context.end_glyph)
-      return_trace (false);
-
-    out_table->indexTablesSize = bitmap_size_context.size;
-    out_table->numberOfIndexSubtables = bitmap_size_context.num_tables;
-    out_table->startGlyphIndex = bitmap_size_context.start_glyph;
-    out_table->endGlyphIndex = bitmap_size_context.end_glyph;
-    return_trace (true);
-  }
-
-  protected:
-  NNOffset32To<IndexSubtableArray>
-			indexSubtableArrayOffset;
-  HBUINT32		indexTablesSize;
-  HBUINT32		numberOfIndexSubtables;
-  HBUINT32		colorRef;
-  SBitLineMetrics	horizontal;
-  SBitLineMetrics	vertical;
-  HBGlyphID16		startGlyphIndex;
-  HBGlyphID16		endGlyphIndex;
-  HBUINT8		ppemX;
-  HBUINT8		ppemY;
-  HBUINT8		bitDepth;
-  HBINT8		flags;
-  public:
-  DEFINE_SIZE_STATIC (48);
-};
-
-
-/*
- * Glyph Bitmap Data Formats.
- */
-
-struct GlyphBitmapDataFormat17
-{
-  SmallGlyphMetrics	glyphMetrics;
-  Array32Of<HBUINT8>	data;
-  public:
-  DEFINE_SIZE_ARRAY (9, data);
-};
-
-struct GlyphBitmapDataFormat18
-{
-  BigGlyphMetrics	glyphMetrics;
-  Array32Of<HBUINT8>	data;
-  public:
-  DEFINE_SIZE_ARRAY (12, data);
-};
-
-struct GlyphBitmapDataFormat19
-{
-  Array32Of<HBUINT8>	data;
-  public:
-  DEFINE_SIZE_ARRAY (4, data);
-};
-
-struct CBLC
-{
-  friend struct CBDT;
-
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_CBLC;
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  likely (version.major == 2 || version.major == 3) &&
-		  sizeTables.sanitize (c, this));
-  }
-
-  static bool
-  sink_cbdt (hb_subset_context_t *c, hb_vector_t<char>* cbdt_prime)
-  {
-    hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ,
-						 cbdt_prime->length,
-						 HB_MEMORY_MODE_WRITABLE,
-						 cbdt_prime->arrayZ,
-						 hb_free);
-    cbdt_prime->init ();  // Leak arrayZ to the blob.
-    bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob);
-    hb_blob_destroy (cbdt_prime_blob);
-    return ret;
-  }
-
-  bool
-  subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table,
-		     const char *cbdt /* IN */, unsigned int cbdt_length,
-		     CBLC *cblc_prime /* INOUT */, hb_vector_t<char> *cbdt_prime /* INOUT */) const
-  {
-    TRACE_SUBSET (this);
-    cblc_prime->sizeTables.len++;
-
-    auto snap = c->serializer->snapshot ();
-    auto cbdt_prime_len = cbdt_prime->length;
-
-    if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime))
-    {
-      cblc_prime->sizeTables.len--;
-      c->serializer->revert (snap);
-      cbdt_prime->shrink (cbdt_prime_len);
-      return_trace (false);
-    }
-    return_trace (true);
-  }
-
-  // Implemented in cc file as it depends on definition of CBDT.
-  HB_INTERNAL bool subset (hb_subset_context_t *c) const;
-
-  protected:
-  const BitmapSizeTable &choose_strike (hb_font_t *font) const
-  {
-    unsigned count = sizeTables.len;
-    if (unlikely (!count))
-      return Null (BitmapSizeTable);
-
-    unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
-    if (!requested_ppem)
-      requested_ppem = 1<<30; /* Choose largest strike. */
-    unsigned int best_i = 0;
-    unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY);
-
-    for (unsigned int i = 1; i < count; i++)
-    {
-      unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY);
-      if ((requested_ppem <= ppem && ppem < best_ppem) ||
-	  (requested_ppem > best_ppem && ppem > best_ppem))
-      {
-	best_i = i;
-	best_ppem = ppem;
-      }
-    }
-
-    return sizeTables[best_i];
-  }
-
-  protected:
-  FixedVersion<>		version;
-  Array32Of<BitmapSizeTable>	sizeTables;
-  public:
-  DEFINE_SIZE_ARRAY (8, sizeTables);
-};
-
-struct CBDT
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_CBDT;
-
-  struct accelerator_t
-  {
-    accelerator_t (hb_face_t *face)
-    {
-      this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
-      this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
-
-      upem = hb_face_get_upem (face);
-    }
-    ~accelerator_t ()
-    {
-      this->cblc.destroy ();
-      this->cbdt.destroy ();
-    }
-
-    bool
-    get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
-    {
-      const void *base;
-      const BitmapSizeTable &strike = this->cblc->choose_strike (font);
-      const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
-      if (!subtable_record || !strike.ppemX || !strike.ppemY)
-	return false;
-
-      if (subtable_record->get_extents (extents, base))
-	return true;
-
-      unsigned int image_offset = 0, image_length = 0, image_format = 0;
-      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
-	return false;
-
-      unsigned int cbdt_len = cbdt.get_length ();
-      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
-	return false;
-
-      switch (image_format)
-      {
-      case 17: {
-	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
-	  return false;
-	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-	glyphFormat17.glyphMetrics.get_extents (font, extents);
-	break;
-      }
-      case 18: {
-	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
-	  return false;
-	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
-	glyphFormat18.glyphMetrics.get_extents (font, extents);
-	break;
-      }
-      default: return false; /* TODO: Support other image formats. */
-      }
-
-      /* Convert to font units. */
-      float x_scale = upem / (float) strike.ppemX;
-      float y_scale = upem / (float) strike.ppemY;
-      extents->x_bearing = roundf (extents->x_bearing * x_scale);
-      extents->y_bearing = roundf (extents->y_bearing * y_scale);
-      extents->width = roundf (extents->width * x_scale);
-      extents->height = roundf (extents->height * y_scale);
-
-      return true;
-    }
-
-    hb_blob_t*
-    reference_png (hb_font_t *font, hb_codepoint_t glyph) const
-    {
-      const void *base;
-      const BitmapSizeTable &strike = this->cblc->choose_strike (font);
-      const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
-      if (!subtable_record || !strike.ppemX || !strike.ppemY)
-	return hb_blob_get_empty ();
-
-      unsigned int image_offset = 0, image_length = 0, image_format = 0;
-      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
-	return hb_blob_get_empty ();
-
-      unsigned int cbdt_len = cbdt.get_length ();
-      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
-	return hb_blob_get_empty ();
-
-      switch (image_format)
-      {
-      case 17:
-      {
-	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
-	  return hb_blob_get_empty ();
-	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-	return hb_blob_create_sub_blob (cbdt.get_blob (),
-					image_offset + GlyphBitmapDataFormat17::min_size,
-					glyphFormat17.data.len);
-      }
-      case 18:
-      {
-	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
-	  return hb_blob_get_empty ();
-	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
-	return hb_blob_create_sub_blob (cbdt.get_blob (),
-					image_offset + GlyphBitmapDataFormat18::min_size,
-					glyphFormat18.data.len);
-      }
-      case 19:
-      {
-	if (unlikely (image_length < GlyphBitmapDataFormat19::min_size))
-	  return hb_blob_get_empty ();
-	auto &glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
-	return hb_blob_create_sub_blob (cbdt.get_blob (),
-					image_offset + GlyphBitmapDataFormat19::min_size,
-					glyphFormat19.data.len);
-      }
-      default: return hb_blob_get_empty (); /* TODO: Support other image formats. */
-      }
-    }
-
-    bool has_data () const { return cbdt.get_length (); }
-
-    private:
-    hb_blob_ptr_t<CBLC> cblc;
-    hb_blob_ptr_t<CBDT> cbdt;
-
-    unsigned int upem;
-  };
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  likely (version.major == 2 || version.major == 3));
-  }
-
-  protected:
-  FixedVersion<>		version;
-  UnsizedArrayOf<HBUINT8>	dataZ;
-  public:
-  DEFINE_SIZE_ARRAY (4, dataZ);
-};
-
-inline bool
-CBLC::subset (hb_subset_context_t *c) const
-{
-  TRACE_SUBSET (this);
-
-  auto *cblc_prime = c->serializer->start_embed<CBLC> ();
-
-  // Use a vector as a secondary buffer as the tables need to be built in parallel.
-  hb_vector_t<char> cbdt_prime;
-
-  if (unlikely (!cblc_prime)) return_trace (false);
-  if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
-  cblc_prime->version = version;
-
-  hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table<CBDT> (c->plan->source);
-  unsigned int cbdt_length;
-  CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length);
-  if (unlikely (cbdt_length < CBDT::min_size))
-  {
-    hb_blob_destroy (cbdt_blob);
-    return_trace (false);
-  }
-  _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size);
-
-  for (const BitmapSizeTable& table : + sizeTables.iter ())
-    subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime);
-
-  hb_blob_destroy (cbdt_blob);
-
-  return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
-}
-
-struct CBDT_accelerator_t : CBDT::accelerator_t {
-  CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
-};
-
-
-} /* namespace OT */
-
-#endif /* HB_OT_COLOR_CBDT_TABLE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,1641 +0,0 @@
-/*
- * Copyright © 2018  Ebrahim Byagowi
- * Copyright © 2020  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Calder Kitagawa
- */
-
-#ifndef HB_OT_COLOR_COLR_TABLE_HH
-#define HB_OT_COLOR_COLR_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-var-common.hh"
-
-/*
- * COLR -- Color
- * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
- */
-#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
-
-#ifndef HB_COLRV1_MAX_NESTING_LEVEL
-#define HB_COLRV1_MAX_NESTING_LEVEL	16
-#endif
-
-namespace OT {
-
-struct COLR;
-struct hb_colrv1_closure_context_t :
-       hb_dispatch_context_t<hb_colrv1_closure_context_t>
-{
-  template <typename T>
-  return_t dispatch (const T &obj)
-  {
-    if (unlikely (nesting_level_left == 0))
-      return hb_empty_t ();
-
-    if (paint_visited (&obj))
-      return hb_empty_t ();
-
-    nesting_level_left--;
-    obj.closurev1 (this);
-    nesting_level_left++;
-    return hb_empty_t ();
-  }
-  static return_t default_return_value () { return hb_empty_t (); }
-
-  bool paint_visited (const void *paint)
-  {
-    hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
-    if (visited_paint.in_error() || visited_paint.has (delta))
-      return true;
-
-    visited_paint.add (delta);
-    return false;
-  }
-
-  const COLR* get_colr_table () const
-  { return reinterpret_cast<const COLR *> (base); }
-
-  void add_glyph (unsigned glyph_id)
-  { glyphs->add (glyph_id); }
-
-  void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
-  { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
-
-  void add_palette_index (unsigned palette_index)
-  { palette_indices->add (palette_index); }
-
-  public:
-  const void *base;
-  hb_set_t visited_paint;
-  hb_set_t *glyphs;
-  hb_set_t *layer_indices;
-  hb_set_t *palette_indices;
-  unsigned nesting_level_left;
-
-  hb_colrv1_closure_context_t (const void *base_,
-                               hb_set_t *glyphs_,
-                               hb_set_t *layer_indices_,
-                               hb_set_t *palette_indices_,
-                               unsigned nesting_level_left_ = HB_COLRV1_MAX_NESTING_LEVEL) :
-                          base (base_),
-                          glyphs (glyphs_),
-                          layer_indices (layer_indices_),
-                          palette_indices (palette_indices_),
-                          nesting_level_left (nesting_level_left_)
-  {}
-};
-
-struct LayerRecord
-{
-  operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  public:
-  HBGlyphID16	glyphId;	/* Glyph ID of layer glyph */
-  Index		colorIdx;	/* Index value to use with a
-				 * selected color palette.
-				 * An index value of 0xFFFF
-				 * is a special case indicating
-				 * that the text foreground
-				 * color (defined by a
-				 * higher-level client) should
-				 * be used and shall not be
-				 * treated as actual index
-				 * into CPAL ColorRecord array. */
-  public:
-  DEFINE_SIZE_STATIC (4);
-};
-
-struct BaseGlyphRecord
-{
-  int cmp (hb_codepoint_t g) const
-  { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  public:
-  HBGlyphID16	glyphId;	/* Glyph ID of reference glyph */
-  HBUINT16	firstLayerIdx;	/* Index (from beginning of
-				 * the Layer Records) to the
-				 * layer record. There will be
-				 * numLayers consecutive entries
-				 * for this base glyph. */
-  HBUINT16	numLayers;	/* Number of color layers
-				 * associated with this glyph */
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-template <typename T>
-struct Variable
-{
-  Variable<T>* copy (hb_serialize_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-    return_trace (c->embed (this));
-  }
-
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { value.closurev1 (c); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    if (!value.subset (c)) return_trace (false);
-    return_trace (c->serializer->embed (varIdxBase));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && value.sanitize (c));
-  }
-
-  protected:
-  T      value;
-  public:
-  VarIdx varIdxBase;
-  public:
-  DEFINE_SIZE_STATIC (4 + T::static_size);
-};
-
-template <typename T>
-struct NoVariable
-{
-  static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
-
-  NoVariable<T>* copy (hb_serialize_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-    return_trace (c->embed (this));
-  }
-
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { value.closurev1 (c); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    return_trace (value.subset (c));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && value.sanitize (c));
-  }
-
-  T      value;
-  public:
-  DEFINE_SIZE_STATIC (T::static_size);
-};
-
-// Color structures
-
-struct ColorStop
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { c->add_palette_index (paletteIndex); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
-    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
-                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  F2DOT14	stopOffset;
-  HBUINT16	paletteIndex;
-  F2DOT14	alpha;
-  public:
-  DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size);
-};
-
-struct Extend : HBUINT8
-{
-  enum {
-    EXTEND_PAD     = 0,
-    EXTEND_REPEAT  = 1,
-    EXTEND_REFLECT = 2,
-  };
-  public:
-  DEFINE_SIZE_STATIC (1);
-};
-
-template <template<typename> class Var>
-struct ColorLine
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  {
-    for (const auto &stop : stops.iter ())
-      stop.closurev1 (c);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-    if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
-    if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false);
-
-    for (const auto& stop : stops.iter ())
-    {
-      if (!stop.subset (c)) return_trace (false);
-    }
-    return_trace (true);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  stops.sanitize (c));
-  }
-
-  Extend	extend;
-  Array16Of<Var<ColorStop>>	stops;
-  public:
-  DEFINE_SIZE_ARRAY_SIZED (3, stops);
-};
-
-// Composition modes
-
-// Compositing modes are taken from https://www.w3.org/TR/compositing-1/
-// NOTE: a brief audit of major implementations suggests most support most
-// or all of the specified modes.
-struct CompositeMode : HBUINT8
-{
-  enum {
-    // Porter-Duff modes
-    // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators
-    COMPOSITE_CLEAR          =  0,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_clear
-    COMPOSITE_SRC            =  1,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_src
-    COMPOSITE_DEST           =  2,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dst
-    COMPOSITE_SRC_OVER       =  3,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcover
-    COMPOSITE_DEST_OVER      =  4,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstover
-    COMPOSITE_SRC_IN         =  5,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin
-    COMPOSITE_DEST_IN        =  6,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin
-    COMPOSITE_SRC_OUT        =  7,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout
-    COMPOSITE_DEST_OUT       =  8,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout
-    COMPOSITE_SRC_ATOP       =  9,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop
-    COMPOSITE_DEST_ATOP      = 10,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop
-    COMPOSITE_XOR            = 11,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor
-    COMPOSITE_PLUS           = 12,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus
-
-    // Blend modes
-    // https://www.w3.org/TR/compositing-1/#blending
-    COMPOSITE_SCREEN         = 13,  // https://www.w3.org/TR/compositing-1/#blendingscreen
-    COMPOSITE_OVERLAY        = 14,  // https://www.w3.org/TR/compositing-1/#blendingoverlay
-    COMPOSITE_DARKEN         = 15,  // https://www.w3.org/TR/compositing-1/#blendingdarken
-    COMPOSITE_LIGHTEN        = 16,  // https://www.w3.org/TR/compositing-1/#blendinglighten
-    COMPOSITE_COLOR_DODGE    = 17,  // https://www.w3.org/TR/compositing-1/#blendingcolordodge
-    COMPOSITE_COLOR_BURN     = 18,  // https://www.w3.org/TR/compositing-1/#blendingcolorburn
-    COMPOSITE_HARD_LIGHT     = 19,  // https://www.w3.org/TR/compositing-1/#blendinghardlight
-    COMPOSITE_SOFT_LIGHT     = 20,  // https://www.w3.org/TR/compositing-1/#blendingsoftlight
-    COMPOSITE_DIFFERENCE     = 21,  // https://www.w3.org/TR/compositing-1/#blendingdifference
-    COMPOSITE_EXCLUSION      = 22,  // https://www.w3.org/TR/compositing-1/#blendingexclusion
-    COMPOSITE_MULTIPLY       = 23,  // https://www.w3.org/TR/compositing-1/#blendingmultiply
-
-    // Modes that, uniquely, do not operate on components
-    // https://www.w3.org/TR/compositing-1/#blendingnonseparable
-    COMPOSITE_HSL_HUE        = 24,  // https://www.w3.org/TR/compositing-1/#blendinghue
-    COMPOSITE_HSL_SATURATION = 25,  // https://www.w3.org/TR/compositing-1/#blendingsaturation
-    COMPOSITE_HSL_COLOR      = 26,  // https://www.w3.org/TR/compositing-1/#blendingcolor
-    COMPOSITE_HSL_LUMINOSITY = 27,  // https://www.w3.org/TR/compositing-1/#blendingluminosity
-  };
-  public:
-  DEFINE_SIZE_STATIC (1);
-};
-
-struct Affine2x3
-{
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  F16DOT16 xx;
-  F16DOT16 yx;
-  F16DOT16 xy;
-  F16DOT16 yy;
-  F16DOT16 dx;
-  F16DOT16 dy;
-  public:
-  DEFINE_SIZE_STATIC (6 * F16DOT16::static_size);
-};
-
-struct PaintColrLayers
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-    return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers->get (firstLayerIndex),
-                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
-
-    return_trace (true);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBUINT8	format; /* format = 1 */
-  HBUINT8	numLayers;
-  HBUINT32	firstLayerIndex;  /* index into COLRv1::layerList */
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct PaintSolid
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { c->add_palette_index (paletteIndex); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
-    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
-                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBUINT8	format; /* format = 2(noVar) or 3(Var)*/
-  HBUINT16	paletteIndex;
-  F2DOT14	alpha;
-  public:
-  DEFINE_SIZE_STATIC (3 + F2DOT14::static_size);
-};
-
-template <template<typename> class Var>
-struct PaintLinearGradient
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { (this+colorLine).closurev1 (c); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
-  }
-
-  HBUINT8			format; /* format = 4(noVar) or 5 (Var) */
-  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintLinearGradient
-                                            * table) to ColorLine subtable. */
-  FWORD			x0;
-  FWORD			y0;
-  FWORD			x1;
-  FWORD			y1;
-  FWORD			x2;
-  FWORD			y2;
-  public:
-  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
-};
-
-template <template<typename> class Var>
-struct PaintRadialGradient
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { (this+colorLine).closurev1 (c); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
-  }
-
-  HBUINT8			format; /* format = 6(noVar) or 7 (Var) */
-  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintRadialGradient
-                                            * table) to ColorLine subtable. */
-  FWORD			x0;
-  FWORD			y0;
-  UFWORD		radius0;
-  FWORD			x1;
-  FWORD			y1;
-  UFWORD		radius1;
-  public:
-  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
-};
-
-template <template<typename> class Var>
-struct PaintSweepGradient
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const
-  { (this+colorLine).closurev1 (c); }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
-  }
-
-  HBUINT8			format; /* format = 8(noVar) or 9 (Var) */
-  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintSweepGradient
-                                            * table) to ColorLine subtable. */
-  FWORD			centerX;
-  FWORD			centerY;
-  F2DOT14		startAngle;
-  F2DOT14		endAngle;
-  public:
-  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size);
-};
-
-struct Paint;
-
-// Paint a non-COLR glyph, filled as indicated by paint.
-struct PaintGlyph
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) 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));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && paint.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 10 */
-  Offset24To<Paint>	paint;  /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
-  HBUINT16		gid;
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct PaintColrGlyph
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
-                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBUINT8	format; /* format = 11 */
-  HBUINT16	gid;
-  public:
-  DEFINE_SIZE_STATIC (3);
-};
-
-template <template<typename> class Var>
-struct PaintTransform
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-    if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false);
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  src.sanitize (c, this) &&
-                  transform.sanitize (c, this));
-  }
-
-  HBUINT8			format; /* format = 12(noVar) or 13 (Var) */
-  Offset24To<Paint>		src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
-  Offset24To<Var<Affine2x3>>	transform;
-  public:
-  DEFINE_SIZE_STATIC (7);
-};
-
-struct PaintTranslate
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 14(noVar) or 15 (Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
-  FWORD		dx;
-  FWORD		dy;
-  public:
-  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size);
-};
-
-struct PaintScale
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
-  F2DOT14		scaleX;
-  F2DOT14		scaleY;
-  public:
-  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
-};
-
-struct PaintScaleAroundCenter
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 18 (noVar) or 19(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
-  F2DOT14	scaleX;
-  F2DOT14	scaleY;
-  FWORD		centerX;
-  FWORD		centerY;
-  public:
-  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintScaleUniform
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 20 (noVar) or 21(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
-  F2DOT14		scale;
-  public:
-  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
-};
-
-struct PaintScaleUniformAroundCenter
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 22 (noVar) or 23(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
-  F2DOT14	scale;
-  FWORD		centerX;
-  FWORD		centerY;
-  public:
-  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintRotate
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 24 (noVar) or 25(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
-  F2DOT14		angle;
-  public:
-  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
-};
-
-struct PaintRotateAroundCenter
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 26 (noVar) or 27(Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
-  F2DOT14	angle;
-  FWORD		centerX;
-  FWORD		centerY;
-  public:
-  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintSkew
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 28(noVar) or 29 (Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
-  F2DOT14		xSkewAngle;
-  F2DOT14		ySkewAngle;
-  public:
-  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
-};
-
-struct PaintSkewAroundCenter
-{
-  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->src.serialize_subset (c, src, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && src.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 30(noVar) or 31 (Var) */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
-  F2DOT14	xSkewAngle;
-  F2DOT14	ySkewAngle;
-  FWORD		centerX;
-  FWORD		centerY;
-  public:
-  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
-};
-
-struct PaintComposite
-{
-  void closurev1 (hb_colrv1_closure_context_t* c) const;
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-
-    if (!out->src.serialize_subset (c, src, this)) return_trace (false);
-    return_trace (out->backdrop.serialize_subset (c, backdrop, this));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  src.sanitize (c, this) &&
-                  backdrop.sanitize (c, this));
-  }
-
-  HBUINT8		format; /* format = 32 */
-  Offset24To<Paint>	src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
-  CompositeMode		mode;   /* If mode is unrecognized use COMPOSITE_CLEAR */
-  Offset24To<Paint>	backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */
-  public:
-  DEFINE_SIZE_STATIC (8);
-};
-
-struct ClipBoxData
-{
-  int xMin, yMin, xMax, yMax;
-};
-
-struct ClipBoxFormat1
-{
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const
-  {
-    clip_box.xMin = xMin;
-    clip_box.yMin = yMin;
-    clip_box.xMax = xMax;
-    clip_box.yMax = yMax;
-  }
-
-  public:
-  HBUINT8	format; /* format = 1(noVar) or 2(Var)*/
-  FWORD		xMin;
-  FWORD		yMin;
-  FWORD		xMax;
-  FWORD		yMax;
-  public:
-  DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
-};
-
-struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
-{
-  void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const
-  {
-    value.get_clip_box(clip_box, instancer);
-    if (instancer)
-    {
-      clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
-      clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
-      clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
-      clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
-    }
-  }
-};
-
-struct ClipBox
-{
-  ClipBox* copy (hb_serialize_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-    switch (u.format) {
-    case 1: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format1)));
-    case 2: return_trace (reinterpret_cast<ClipBox *> (c->embed (u.format2)));
-    default:return_trace (nullptr);
-    }
-  }
-
-  template <typename context_t, typename ...Ts>
-  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
-  {
-    TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
-    switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  bool get_extents (hb_glyph_extents_t *extents,
-                    const VarStoreInstancer &instancer) const
-  {
-    ClipBoxData clip_box;
-    switch (u.format) {
-    case 1:
-      u.format1.get_clip_box (clip_box, instancer);
-      break;
-    case 2:
-      u.format2.get_clip_box (clip_box, instancer);
-      break;
-    default:
-      return false;
-    }
-
-    extents->x_bearing = clip_box.xMin;
-    extents->y_bearing = clip_box.yMax;
-    extents->width = clip_box.xMax - clip_box.xMin;
-    extents->height = clip_box.yMin - clip_box.yMax;
-    return true;
-  }
-
-  protected:
-  union {
-  HBUINT8		format;         /* Format identifier */
-  ClipBoxFormat1	format1;
-  ClipBoxFormat2	format2;
-  } u;
-};
-
-struct ClipRecord
-{
-  int cmp (hb_codepoint_t g) const
-  { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
-
-  ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
-  {
-    TRACE_SERIALIZE (this);
-    auto *out = c->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
-    if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr);
-    return_trace (out);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
-  }
-
-  bool get_extents (hb_glyph_extents_t *extents,
-		    const void *base,
-		    const VarStoreInstancer &instancer) const
-  {
-    return (base+clipBox).get_extents (extents, instancer);
-  }
-
-  public:
-  HBUINT16		startGlyphID;  // first gid clip applies to
-  HBUINT16		endGlyphID;    // last gid clip applies to, inclusive
-  Offset24To<ClipBox>	clipBox;   // Box or VarBox
-  public:
-  DEFINE_SIZE_STATIC (7);
-};
-DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
-
-struct ClipList
-{
-  unsigned serialize_clip_records (hb_serialize_context_t *c,
-                                   const hb_set_t& gids,
-                                   const hb_map_t& gid_offset_map) const
-  {
-    TRACE_SERIALIZE (this);
-    if (gids.is_empty () ||
-        gid_offset_map.get_population () != gids.get_population ())
-      return_trace (0);
-
-    unsigned count  = 0;
-
-    hb_codepoint_t start_gid= gids.get_min ();
-    hb_codepoint_t prev_gid = start_gid;
-
-    unsigned offset = gid_offset_map.get (start_gid);
-    unsigned prev_offset = offset;
-    for (const hb_codepoint_t _ : gids.iter ())
-    {
-      if (_ == start_gid) continue;
-
-      offset = gid_offset_map.get (_);
-      if (_ == prev_gid + 1 &&  offset == prev_offset)
-      {
-        prev_gid = _;
-        continue;
-      }
-
-      ClipRecord record;
-      record.startGlyphID = start_gid;
-      record.endGlyphID = prev_gid;
-      record.clipBox = prev_offset;
-
-      if (!c->copy (record, this)) return_trace (0);
-      count++;
-
-      start_gid = _;
-      prev_gid = _;
-      prev_offset = offset;
-    }
-
-    //last one
-    {
-      ClipRecord record;
-      record.startGlyphID = start_gid;
-      record.endGlyphID = prev_gid;
-      record.clipBox = prev_offset;
-      if (!c->copy (record, this)) return_trace (0);
-      count++;
-    }
-    return_trace (count);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-    if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
-
-    const hb_set_t& glyphset = *c->plan->_glyphset_colred;
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    hb_map_t new_gid_offset_map;
-    hb_set_t new_gids;
-    for (const ClipRecord& record : clips.iter ())
-    {
-      unsigned start_gid = record.startGlyphID;
-      unsigned end_gid = record.endGlyphID;
-      for (unsigned gid = start_gid; gid <= end_gid; gid++)
-      {
-        if (!glyphset.has (gid) || !glyph_map.has (gid)) continue;
-        unsigned new_gid = glyph_map.get (gid);
-        new_gid_offset_map.set (new_gid, record.clipBox);
-        new_gids.add (new_gid);
-      }
-    }
-
-    unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map);
-    if (!count) return_trace (false);
-    return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    // TODO Make a formatted struct!
-    return_trace (c->check_struct (this) && clips.sanitize (c, this));
-  }
-
-  bool
-  get_extents (hb_codepoint_t gid,
-	       hb_glyph_extents_t *extents,
-	       const VarStoreInstancer &instancer) const
-  {
-    auto *rec = clips.as_array ().bsearch (gid);
-    if (rec)
-    {
-      rec->get_extents (extents, this, instancer);
-      return true;
-    }
-    return false;
-  }
-
-  HBUINT8			format;  // Set to 1.
-  SortedArray32Of<ClipRecord>	clips;  // Clip records, sorted by startGlyphID
-  public:
-  DEFINE_SIZE_ARRAY_SIZED (5, clips);
-};
-
-struct Paint
-{
-
-  template <typename ...Ts>
-  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
-  {
-    TRACE_SANITIZE (this);
-
-    if (unlikely (!c->check_start_recursion (HB_COLRV1_MAX_NESTING_LEVEL)))
-      return_trace (c->no_dispatch_return_value ());
-
-    return_trace (c->end_recursion (this->dispatch (c, std::forward<Ts> (ds)...)));
-  }
-
-  template <typename context_t, typename ...Ts>
-  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
-  {
-    TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
-    switch (u.format) {
-    case 1: return_trace (c->dispatch (u.paintformat1, std::forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...));
-    case 3: return_trace (c->dispatch (u.paintformat3, std::forward<Ts> (ds)...));
-    case 4: return_trace (c->dispatch (u.paintformat4, std::forward<Ts> (ds)...));
-    case 5: return_trace (c->dispatch (u.paintformat5, std::forward<Ts> (ds)...));
-    case 6: return_trace (c->dispatch (u.paintformat6, std::forward<Ts> (ds)...));
-    case 7: return_trace (c->dispatch (u.paintformat7, std::forward<Ts> (ds)...));
-    case 8: return_trace (c->dispatch (u.paintformat8, std::forward<Ts> (ds)...));
-    case 9: return_trace (c->dispatch (u.paintformat9, std::forward<Ts> (ds)...));
-    case 10: return_trace (c->dispatch (u.paintformat10, std::forward<Ts> (ds)...));
-    case 11: return_trace (c->dispatch (u.paintformat11, std::forward<Ts> (ds)...));
-    case 12: return_trace (c->dispatch (u.paintformat12, std::forward<Ts> (ds)...));
-    case 13: return_trace (c->dispatch (u.paintformat13, std::forward<Ts> (ds)...));
-    case 14: return_trace (c->dispatch (u.paintformat14, std::forward<Ts> (ds)...));
-    case 15: return_trace (c->dispatch (u.paintformat15, std::forward<Ts> (ds)...));
-    case 16: return_trace (c->dispatch (u.paintformat16, std::forward<Ts> (ds)...));
-    case 17: return_trace (c->dispatch (u.paintformat17, std::forward<Ts> (ds)...));
-    case 18: return_trace (c->dispatch (u.paintformat18, std::forward<Ts> (ds)...));
-    case 19: return_trace (c->dispatch (u.paintformat19, std::forward<Ts> (ds)...));
-    case 20: return_trace (c->dispatch (u.paintformat20, std::forward<Ts> (ds)...));
-    case 21: return_trace (c->dispatch (u.paintformat21, std::forward<Ts> (ds)...));
-    case 22: return_trace (c->dispatch (u.paintformat22, std::forward<Ts> (ds)...));
-    case 23: return_trace (c->dispatch (u.paintformat23, std::forward<Ts> (ds)...));
-    case 24: return_trace (c->dispatch (u.paintformat24, std::forward<Ts> (ds)...));
-    case 25: return_trace (c->dispatch (u.paintformat25, std::forward<Ts> (ds)...));
-    case 26: return_trace (c->dispatch (u.paintformat26, std::forward<Ts> (ds)...));
-    case 27: return_trace (c->dispatch (u.paintformat27, std::forward<Ts> (ds)...));
-    case 28: return_trace (c->dispatch (u.paintformat28, std::forward<Ts> (ds)...));
-    case 29: return_trace (c->dispatch (u.paintformat29, std::forward<Ts> (ds)...));
-    case 30: return_trace (c->dispatch (u.paintformat30, std::forward<Ts> (ds)...));
-    case 31: return_trace (c->dispatch (u.paintformat31, std::forward<Ts> (ds)...));
-    case 32: return_trace (c->dispatch (u.paintformat32, std::forward<Ts> (ds)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  protected:
-  union {
-  HBUINT8					format;
-  PaintColrLayers				paintformat1;
-  PaintSolid					paintformat2;
-  Variable<PaintSolid>				paintformat3;
-  PaintLinearGradient<NoVariable>		paintformat4;
-  Variable<PaintLinearGradient<Variable>>	paintformat5;
-  PaintRadialGradient<NoVariable>		paintformat6;
-  Variable<PaintRadialGradient<Variable>>	paintformat7;
-  PaintSweepGradient<NoVariable>		paintformat8;
-  Variable<PaintSweepGradient<Variable>>	paintformat9;
-  PaintGlyph					paintformat10;
-  PaintColrGlyph				paintformat11;
-  PaintTransform<NoVariable>			paintformat12;
-  PaintTransform<Variable>			paintformat13;
-  PaintTranslate				paintformat14;
-  Variable<PaintTranslate>			paintformat15;
-  PaintScale					paintformat16;
-  Variable<PaintScale>				paintformat17;
-  PaintScaleAroundCenter			paintformat18;
-  Variable<PaintScaleAroundCenter>		paintformat19;
-  PaintScaleUniform				paintformat20;
-  Variable<PaintScaleUniform>			paintformat21;
-  PaintScaleUniformAroundCenter			paintformat22;
-  Variable<PaintScaleUniformAroundCenter>	paintformat23;
-  PaintRotate					paintformat24;
-  Variable<PaintRotate>				paintformat25;
-  PaintRotateAroundCenter			paintformat26;
-  Variable<PaintRotateAroundCenter>		paintformat27;
-  PaintSkew					paintformat28;
-  Variable<PaintSkew>				paintformat29;
-  PaintSkewAroundCenter				paintformat30;
-  Variable<PaintSkewAroundCenter>		paintformat31;
-  PaintComposite				paintformat32;
-  } u;
-  public:
-  DEFINE_SIZE_MIN (2);
-};
-
-struct BaseGlyphPaintRecord
-{
-  int cmp (hb_codepoint_t g) const
-  { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
-
-  bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
-                  const void* src_base, hb_subset_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-    auto *out = s->embed (this);
-    if (unlikely (!out)) return_trace (false);
-    if (!s->check_assign (out->glyphId, glyph_map->get (glyphId),
-                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
-      return_trace (false);
-
-    return_trace (out->paint.serialize_subset (c, paint, src_base));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) && paint.sanitize (c, base)));
-  }
-
-  public:
-  HBGlyphID16		glyphId;    /* Glyph ID of reference glyph */
-  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint,
-                                     * Typically PaintColrLayers */
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
-{
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
-    const hb_set_t* glyphset = c->plan->_glyphset_colred;
-
-    for (const auto& _ : as_array ())
-    {
-      unsigned gid = _.glyphId;
-      if (!glyphset->has (gid)) continue;
-
-      if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
-      else return_trace (false);
-    }
-
-    return_trace (out->len != 0);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this));
-  }
-};
-
-struct LayerList : Array32OfOffset32To<Paint>
-{
-  const Paint& get_paint (unsigned i) const
-  { return this+(*this)[i]; }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
-
-    for (const auto& _ : + hb_enumerate (*this)
-                         | hb_filter (c->plan->colrv1_layers, hb_first))
-
-    {
-      auto *o = out->serialize_append (c->serializer);
-      if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
-        return_trace (false);
-    }
-    return_trace (true);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (Array32OfOffset32To<Paint>::sanitize (c, this));
-  }
-};
-
-struct COLR
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
-
-  bool has_data () const { return numBaseGlyphs; }
-
-  unsigned int get_glyph_layers (hb_codepoint_t       glyph,
-				 unsigned int         start_offset,
-				 unsigned int        *count, /* IN/OUT.  May be NULL. */
-				 hb_ot_color_layer_t *layers /* OUT.     May be NULL. */) const
-  {
-    const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
-
-    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
-    hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
-								       record.numLayers);
-    if (count)
-    {
-      + glyph_layers.sub_array (start_offset, count)
-      | hb_sink (hb_array (layers, *count))
-      ;
-    }
-    return glyph_layers.length;
-  }
-
-  struct accelerator_t
-  {
-    accelerator_t (hb_face_t *face)
-    { colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
-    ~accelerator_t () { this->colr.destroy (); }
-
-    bool is_valid () { return colr.get_blob ()->length; }
-
-    void closure_glyphs (hb_codepoint_t glyph,
-			 hb_set_t *related_ids /* OUT */) const
-    { colr->closure_glyphs (glyph, related_ids); }
-
-    void closure_V0palette_indices (const hb_set_t *glyphs,
-				    hb_set_t *palettes /* OUT */) const
-    { colr->closure_V0palette_indices (glyphs, palettes); }
-
-    void closure_forV1 (hb_set_t *glyphset,
-                        hb_set_t *layer_indices,
-                        hb_set_t *palette_indices) const
-    { colr->closure_forV1 (glyphset, layer_indices, palette_indices); }
-
-    private:
-    hb_blob_ptr_t<COLR> colr;
-  };
-
-  void closure_glyphs (hb_codepoint_t glyph,
-		       hb_set_t *related_ids /* OUT */) const
-  {
-    const BaseGlyphRecord *record = get_base_glyph_record (glyph);
-    if (!record) return;
-
-    auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx,
-								       record->numLayers);
-    if (!glyph_layers.length) return;
-    related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
-  }
-
-  void closure_V0palette_indices (const hb_set_t *glyphs,
-				  hb_set_t *palettes /* OUT */) const
-  {
-    if (!numBaseGlyphs || !numLayers) return;
-    hb_array_t<const BaseGlyphRecord> baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs);
-    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
-
-    for (const BaseGlyphRecord record : baseGlyphs)
-    {
-      if (!glyphs->has (record.glyphId)) continue;
-      hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
-                                                                   record.numLayers);
-      for (const LayerRecord layer : glyph_layers)
-        palettes->add (layer.colorIdx);
-    }
-  }
-
-  void closure_forV1 (hb_set_t *glyphset,
-                      hb_set_t *layer_indices,
-                      hb_set_t *palette_indices) const
-  {
-    if (version != 1) return;
-    hb_set_t visited_glyphs;
-
-    hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices);
-    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
-
-    for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ())
-    {
-      unsigned gid = baseglyph_paintrecord.glyphId;
-      if (!glyphset->has (gid)) continue;
-
-      const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint;
-      paint.dispatch (&c);
-    }
-    hb_set_union (glyphset, &visited_glyphs);
-  }
-
-  const LayerList& get_layerList () const
-  { return (this+layerList); }
-
-  const BaseGlyphList& get_baseglyphList () const
-  { return (this+baseGlyphList); }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
-                  (this+layersZ).sanitize (c, numLayers) &&
-                  (version == 0 ||
-		   (version == 1 &&
-		    baseGlyphList.sanitize (c, this) &&
-		    layerList.sanitize (c, this) &&
-		    clipList.sanitize (c, this) &&
-		    varIdxMap.sanitize (c, this) &&
-		    varStore.sanitize (c, this))));
-  }
-
-  template<typename BaseIterator, typename LayerIterator,
-	   hb_requires (hb_is_iterator (BaseIterator)),
-	   hb_requires (hb_is_iterator (LayerIterator))>
-  bool serialize_V0 (hb_serialize_context_t *c,
-		     unsigned version,
-		     BaseIterator base_it,
-		     LayerIterator layer_it)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (base_it.len () != layer_it.len ()))
-      return_trace (false);
-
-    this->version = version;
-    numLayers = 0;
-    numBaseGlyphs = base_it.len ();
-    if (numBaseGlyphs == 0)
-    {
-      baseGlyphsZ = 0;
-      layersZ = 0;
-      return_trace (true);
-    }
-
-    c->push ();
-    for (const hb_item_type<BaseIterator> _ : + base_it.iter ())
-    {
-      auto* record = c->embed (_);
-      if (unlikely (!record)) return_trace (false);
-      record->firstLayerIdx = numLayers;
-      numLayers += record->numLayers;
-    }
-    c->add_link (baseGlyphsZ, c->pop_pack ());
-
-    c->push ();
-    for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ())
-      _.as_array ().copy (c);
-
-    c->add_link (layersZ, c->pop_pack ());
-
-    return_trace (true);
-  }
-
-  const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const
-  {
-    const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid);
-    if (record == &Null (BaseGlyphRecord) ||
-        (record && (hb_codepoint_t) record->glyphId != gid))
-      record = nullptr;
-    return record;
-  }
-
-  const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const
-  {
-    const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid);
-    if ((record && (hb_codepoint_t) record->glyphId != gid))
-      record = nullptr;
-    return record;
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-
-    const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
-    const hb_set_t& glyphset = *c->plan->_glyphset_colred;
-
-    auto base_it =
-    + hb_range (c->plan->num_output_glyphs ())
-    | hb_filter ([&](hb_codepoint_t new_gid)
-		 {
-		    hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
-		    if (glyphset.has (old_gid)) return true;
-		    return false;
-		 })
-    | hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
-			      {
-				hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
-
-				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
-				if (unlikely (!old_record))
-				  return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
-				BaseGlyphRecord new_record = {};
-				new_record.glyphId = new_gid;
-				new_record.numLayers = old_record->numLayers;
-				return hb_pair_t<bool, BaseGlyphRecord> (true, new_record);
-			      })
-    | hb_filter (hb_first)
-    | hb_map_retains_sorting (hb_second)
-    ;
-
-    auto layer_it =
-    + hb_range (c->plan->num_output_glyphs ())
-    | hb_map (reverse_glyph_map)
-    | hb_filter (glyphset)
-    | hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
-			      {
-				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
-				hb_vector_t<LayerRecord> out_layers;
-
-				if (unlikely (!old_record ||
-					      old_record->firstLayerIdx >= numLayers ||
-					      old_record->firstLayerIdx + old_record->numLayers > numLayers))
-				  return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
-
-				auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx,
-											     old_record->numLayers);
-				out_layers.resize (layers.length);
-				for (unsigned int i = 0; i < layers.length; i++) {
-				  out_layers[i] = layers[i];
-				  hb_codepoint_t new_gid = 0;
-				  if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
-				    return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
-				  out_layers[i].glyphId = new_gid;
-				  out_layers[i].colorIdx = c->plan->colr_palettes->get (layers[i].colorIdx);
-				}
-
-				return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers);
-			      })
-    | hb_filter (hb_first)
-    | hb_map_retains_sorting (hb_second)
-    ;
-
-    if (version == 0 && (!base_it || !layer_it))
-      return_trace (false);
-
-    COLR *colr_prime = c->serializer->start_embed<COLR> ();
-    if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
-
-    if (version == 0)
-    return_trace (colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it));
-
-    auto snap = c->serializer->snapshot ();
-    if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
-    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
-    {
-      if (c->serializer->in_error ()) return_trace (false);
-      //no more COLRv1 glyphs: downgrade to version 0
-      c->serializer->revert (snap);
-      return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
-    }
-
-    if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
-
-    colr_prime->layerList.serialize_subset (c, layerList, this);
-    colr_prime->clipList.serialize_subset (c, clipList, this);
-    colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
-    //TODO: subset varStore once it's implemented in fonttools
-    return_trace (true);
-  }
-
-  bool
-  get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
-  {
-    if (version != 1)
-      return false;
-
-    VarStoreInstancer instancer (this+varStore,
-				 this+varIdxMap,
-				 hb_array (font->coords, font->num_coords));
-
-    if ((this+clipList).get_extents (glyph,
-				     extents,
-				     instancer))
-    {
-      extents->x_bearing = font->em_scale_x (extents->x_bearing);
-      extents->y_bearing = font->em_scale_x (extents->y_bearing);
-      extents->width = font->em_scale_x (extents->width);
-      extents->height = font->em_scale_x (extents->height);
-      return true;
-    }
-
-    return false;
-  }
-
-  protected:
-  HBUINT16	version;	/* Table version number (starts at 0). */
-  HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */
-  NNOffset32To<SortedUnsizedArrayOf<BaseGlyphRecord>>
-		baseGlyphsZ;	/* Offset to Base Glyph records. */
-  NNOffset32To<UnsizedArrayOf<LayerRecord>>
-		layersZ;	/* Offset to Layer Records. */
-  HBUINT16	numLayers;	/* Number of Layer Records. */
-  // Version-1 additions
-  Offset32To<BaseGlyphList>		baseGlyphList;
-  Offset32To<LayerList>			layerList;
-  Offset32To<ClipList>			clipList;   // Offset to ClipList table (may be NULL)
-  Offset32To<DeltaSetIndexMap>		varIdxMap;  // Offset to DeltaSetIndexMap table (may be NULL)
-  Offset32To<VariationStore>		varStore;
-  public:
-  DEFINE_SIZE_MIN (14);
-};
-
-struct COLR_accelerator_t : COLR::accelerator_t {
-  COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_COLOR_COLR_TABLE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colrv1-closure.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,108 +0,0 @@
-/*
- * Copyright © 2018  Ebrahim Byagowi
- * Copyright © 2020  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- */
-
-#ifndef HB_OT_COLR_COLRV1_CLOSURE_HH
-#define HB_OT_COLR_COLRV1_CLOSURE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-color-colr-table.hh"
-
-/*
- * COLR -- Color
- * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
- */
-namespace OT {
-
-HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  c->add_layer_indices (firstLayerIndex, numLayers);
-  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
-  for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
-  {
-    const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
-    paint.dispatch (c);
-  }
-}
-
-HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  c->add_glyph (gid);
-  (this+paint).dispatch (c);
-}
-
-HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  const COLR *colr_table = c->get_colr_table ();
-  const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
-  if (!baseglyph_paintrecord) return;
-  c->add_glyph (gid);
-
-  const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
-  (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
-}
-
-template <template<typename> class Var>
-HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
-{ (this+src).dispatch (c); }
-
-HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
-{
-  (this+src).dispatch (c);
-  (this+backdrop).dispatch (c);
-}
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_COLR_COLRV1_CLOSURE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cpal-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,322 +0,0 @@
-/*
- * Copyright © 2016  Google, Inc.
- * Copyright © 2018  Ebrahim Byagowi
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Sascha Brawer
- */
-
-#ifndef HB_OT_COLOR_CPAL_TABLE_HH
-#define HB_OT_COLOR_CPAL_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-color.h"
-#include "hb-ot-name.h"
-
-
-/*
- * CPAL -- Color Palette
- * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
- */
-#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
-
-namespace OT {
-
-
-struct CPALV1Tail
-{
-  friend struct CPAL;
-
-  private:
-  hb_ot_color_palette_flags_t get_palette_flags (const void *base,
-						 unsigned int palette_index,
-						 unsigned int palette_count) const
-  {
-    if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
-    return (hb_ot_color_palette_flags_t) (uint32_t)
-	   (base+paletteFlagsZ).as_array (palette_count)[palette_index];
-  }
-
-  hb_ot_name_id_t get_palette_name_id (const void *base,
-				       unsigned int palette_index,
-				       unsigned int palette_count) const
-  {
-    if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID;
-    return (base+paletteLabelsZ).as_array (palette_count)[palette_index];
-  }
-
-  hb_ot_name_id_t get_color_name_id (const void *base,
-				     unsigned int color_index,
-				     unsigned int color_count) const
-  {
-    if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID;
-    return (base+colorLabelsZ).as_array (color_count)[color_index];
-  }
-
-  public:
-  bool serialize (hb_serialize_context_t *c,
-                  unsigned palette_count,
-                  unsigned color_count,
-                  const void *base,
-                  const hb_map_t *color_index_map) const
-  {
-    TRACE_SERIALIZE (this);
-    auto *out = c->allocate_size<CPALV1Tail> (static_size);
-    if (unlikely (!out)) return_trace (false);
-
-    out->paletteFlagsZ = 0;
-    if (paletteFlagsZ)
-      out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
-
-    out->paletteLabelsZ = 0;
-    if (paletteLabelsZ)
-      out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
-
-    const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
-    if (colorLabelsZ)
-    {
-      c->push ();
-      for (const auto _ : colorLabels)
-      {
-	const hb_codepoint_t *v;
-        if (!color_index_map->has (_, &v)) continue;
-        NameID new_color_idx;
-	new_color_idx = *v;
-        if (!c->copy<NameID> (new_color_idx))
-        {
-          c->pop_discard ();
-          return_trace (false);
-        }
-      }
-      c->add_link (out->colorLabelsZ, c->pop_pack ());
-    }
-    return_trace (true);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c,
-		 const void *base,
-		 unsigned int palette_count,
-		 unsigned int color_count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  (!paletteFlagsZ  || (base+paletteFlagsZ).sanitize (c, palette_count)) &&
-		  (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) &&
-		  (!colorLabelsZ   || (base+colorLabelsZ).sanitize (c, color_count)));
-  }
-
-  protected:
-  // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
-  //                     here. Currently they are needed since UnsizedArrayOf doesn't define null_size
-  NNOffset32To<UnsizedArrayOf<HBUINT32>>
-		paletteFlagsZ;		/* Offset from the beginning of CPAL table to
-					 * the Palette Type Array. Set to 0 if no array
-					 * is provided. */
-  NNOffset32To<UnsizedArrayOf<NameID>>
-		paletteLabelsZ;		/* Offset from the beginning of CPAL table to
-					 * the palette labels array. Set to 0 if no
-					 * array is provided. */
-  NNOffset32To<UnsizedArrayOf<NameID>>
-		colorLabelsZ;		/* Offset from the beginning of CPAL table to
-					 * the color labels array. Set to 0
-					 * if no array is provided. */
-  public:
-  DEFINE_SIZE_STATIC (12);
-};
-
-typedef HBUINT32 BGRAColor;
-
-struct CPAL
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL;
-
-  bool has_data () const { return numPalettes; }
-
-  unsigned int get_size () const
-  { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
-
-  unsigned int get_palette_count () const { return numPalettes; }
-  unsigned int   get_color_count () const { return numColors; }
-
-  hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
-  { return v1 ().get_palette_flags (this, palette_index, numPalettes); }
-
-  hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const
-  { return v1 ().get_palette_name_id (this, palette_index, numPalettes); }
-
-  hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
-  { return v1 ().get_color_name_id (this, color_index, numColors); }
-
-  unsigned int get_palette_colors (unsigned int  palette_index,
-				   unsigned int  start_offset,
-				   unsigned int *color_count, /* IN/OUT.  May be NULL. */
-				   hb_color_t   *colors       /* OUT.     May be NULL. */) const
-  {
-    if (unlikely (palette_index >= numPalettes))
-    {
-      if (color_count) *color_count = 0;
-      return 0;
-    }
-    unsigned int start_index = colorRecordIndicesZ[palette_index];
-    hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
-    hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index,
-								       numColors);
-    if (color_count)
-    {
-      + palette_colors.sub_array (start_offset, color_count)
-      | hb_sink (hb_array (colors, *color_count))
-      ;
-    }
-    return numColors;
-  }
-
-  private:
-  const CPALV1Tail& v1 () const
-  {
-    if (version == 0) return Null (CPALV1Tail);
-    return StructAfter<CPALV1Tail> (*this);
-  }
-
-  public:
-  bool serialize (hb_serialize_context_t *c,
-                  const hb_array_t<const HBUINT16> &color_record_indices,
-                  const hb_array_t<const BGRAColor> &color_records,
-                  const hb_vector_t<unsigned>& first_color_index_for_layer,
-                  const hb_map_t& first_color_to_layer_index,
-                  const hb_set_t &retained_color_indices) const
-  {
-    TRACE_SERIALIZE (this);
-
-    // TODO(grieger): limit total final size.
-
-    for (const auto idx : color_record_indices)
-    {
-      hb_codepoint_t layer_index = first_color_to_layer_index[idx];
-
-      HBUINT16 new_idx;
-      new_idx = layer_index * retained_color_indices.get_population ();
-      if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
-    }
-
-    c->push ();
-    for (unsigned first_color_index : first_color_index_for_layer)
-    {
-      for (hb_codepoint_t color_index : retained_color_indices)
-      {
-        if (!c->copy<BGRAColor> (color_records[first_color_index + color_index]))
-        {
-          c->pop_discard ();
-          return_trace (false);
-        }
-      }
-    }
-
-    c->add_link (colorRecordsZ, c->pop_pack ());
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    if (!numPalettes) return_trace (false);
-
-    const hb_map_t *color_index_map = c->plan->colr_palettes;
-    if (color_index_map->is_empty ()) return_trace (false);
-
-    hb_set_t retained_color_indices;
-    for (const auto _ : color_index_map->keys ())
-    {
-      if (_ == 0xFFFF) continue;
-      retained_color_indices.add (_);
-    }
-    if (retained_color_indices.is_empty ()) return_trace (false);
-
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-
-    out->version = version;
-    out->numColors = retained_color_indices.get_population ();
-    out->numPalettes = numPalettes;
-
-    hb_vector_t<unsigned> first_color_index_for_layer;
-    hb_map_t first_color_to_layer_index;
-
-    const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
-    for (const auto first_color_record_idx : colorRecordIndices)
-    {
-      if (first_color_to_layer_index.has (first_color_record_idx)) continue;
-
-      first_color_index_for_layer.push (first_color_record_idx);
-      first_color_to_layer_index.set (first_color_record_idx,
-                                      first_color_index_for_layer.length - 1);
-    }
-
-    out->numColorRecords = first_color_index_for_layer.length
-                           * retained_color_indices.get_population ();
-
-    const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
-    if (!out->serialize (c->serializer,
-                         colorRecordIndices,
-                         color_records,
-                         first_color_index_for_layer,
-                         first_color_to_layer_index,
-                         retained_color_indices))
-      return_trace (false);
-
-    if (version == 1)
-      return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
-
-    return_trace (true);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  (this+colorRecordsZ).sanitize (c, numColorRecords) &&
-		  colorRecordIndicesZ.sanitize (c, numPalettes) &&
-		  (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors)));
-  }
-
-  protected:
-  HBUINT16	version;		/* Table version number */
-  /* Version 0 */
-  HBUINT16	numColors;		/* Number of colors in each palette. */
-  HBUINT16	numPalettes;		/* Number of palettes in the table. */
-  HBUINT16	numColorRecords;	/* Total number of color records, combined for
-					 * all palettes. */
-  NNOffset32To<UnsizedArrayOf<BGRAColor>>
-		colorRecordsZ;		/* Offset from the beginning of CPAL table to
-					 * the first ColorRecord. */
-  UnsizedArrayOf<HBUINT16>
-		colorRecordIndicesZ;	/* Index of each palette’s first color record in
-					 * the combined color record array. */
-/*CPALV1Tail	v1;*/
-  public:
-  DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_COLOR_CPAL_TABLE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,423 +0,0 @@
-/*
- * Copyright © 2018  Ebrahim Byagowi
- * Copyright © 2020  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Calder Kitagawa
- */
-
-#ifndef HB_OT_COLOR_SBIX_TABLE_HH
-#define HB_OT_COLOR_SBIX_TABLE_HH
-
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-
-/*
- * sbix -- Standard Bitmap Graphics
- * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix
- * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
- */
-#define HB_OT_TAG_sbix HB_TAG('s','b','i','x')
-
-
-namespace OT {
-
-
-struct SBIXGlyph
-{
-  SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const
-  {
-    TRACE_SERIALIZE (this);
-    SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
-    if (unlikely (!new_glyph)) return_trace (nullptr);
-    if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
-
-    new_glyph->xOffset = xOffset;
-    new_glyph->yOffset = yOffset;
-    new_glyph->graphicType = graphicType;
-    data.copy (c, data_length);
-    return_trace (new_glyph);
-  }
-
-  HBINT16	xOffset;	/* The horizontal (x-axis) offset from the left
-				 * edge of the graphic to the glyph’s origin.
-				 * That is, the x-coordinate of the point on the
-				 * baseline at the left edge of the glyph. */
-  HBINT16	yOffset;	/* The vertical (y-axis) offset from the bottom
-				 * edge of the graphic to the glyph’s origin.
-				 * That is, the y-coordinate of the point on the
-				 * baseline at the left edge of the glyph. */
-  Tag		graphicType;	/* Indicates the format of the embedded graphic
-				 * data: one of 'jpg ', 'png ' or 'tiff', or the
-				 * special format 'dupe'. */
-  UnsizedArrayOf<HBUINT8>
-		data;		/* The actual embedded graphic data. The total
-				 * length is inferred from sequential entries in
-				 * the glyphDataOffsets array and the fixed size
-				 * (8 bytes) of the preceding fields. */
-  public:
-  DEFINE_SIZE_ARRAY (8, data);
-};
-
-struct SBIXStrike
-{
-  static unsigned int get_size (unsigned num_glyphs)
-  { return min_size + num_glyphs * HBUINT32::static_size; }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
-  }
-
-  hb_blob_t *get_glyph_blob (unsigned int  glyph_id,
-			     hb_blob_t    *sbix_blob,
-			     hb_tag_t      file_type,
-			     int          *x_offset,
-			     int          *y_offset,
-			     unsigned int  num_glyphs,
-			     unsigned int *strike_ppem) const
-  {
-    if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */
-
-    unsigned int retry_count = 8;
-    unsigned int sbix_len = sbix_blob->length;
-    unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data;
-    assert (strike_offset < sbix_len);
-
-  retry:
-    if (unlikely (glyph_id >= num_glyphs ||
-		  imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] ||
-		  imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size ||
-		  (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset))
-      return hb_blob_get_empty ();
-
-    unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size;
-    unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
-
-    const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
-
-    if (glyph->graphicType == HB_TAG ('d','u','p','e'))
-    {
-      if (glyph_length >= 2)
-      {
-	glyph_id = *((HBUINT16 *) &glyph->data);
-	if (retry_count--)
-	  goto retry;
-      }
-      return hb_blob_get_empty ();
-    }
-
-    if (unlikely (file_type != glyph->graphicType))
-      return hb_blob_get_empty ();
-
-    if (strike_ppem) *strike_ppem = ppem;
-    if (x_offset) *x_offset = glyph->xOffset;
-    if (y_offset) *y_offset = glyph->yOffset;
-    return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
-  }
-
-  bool subset (hb_subset_context_t *c, unsigned int available_len) const
-  {
-    TRACE_SUBSET (this);
-    unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
-
-    auto* out = c->serializer->start_embed<SBIXStrike> ();
-    if (unlikely (!out)) return_trace (false);
-    auto snap = c->serializer->snapshot ();
-    if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
-    out->ppem = ppem;
-    out->resolution = resolution;
-    HBUINT32 head;
-    head = get_size (num_output_glyphs + 1);
-
-    bool has_glyphs = false;
-    for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
-    {
-      hb_codepoint_t old_gid;
-      if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
-	  unlikely (imageOffsetsZ[old_gid].is_null () ||
-		    imageOffsetsZ[old_gid + 1].is_null () ||
-		    imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
-		    imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) ||
-		    (unsigned int) imageOffsetsZ[old_gid + 1] > available_len)
-      {
-	out->imageOffsetsZ[new_gid] = head;
-	continue;
-      }
-      has_glyphs = true;
-      unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
-      unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
-      if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length))
-	return_trace (false);
-      out->imageOffsetsZ[new_gid] = head;
-      head += delta;
-    }
-    if (has_glyphs)
-      out->imageOffsetsZ[num_output_glyphs] = head;
-    else
-      c->serializer->revert (snap);
-    return_trace (has_glyphs);
-  }
-
-  public:
-  HBUINT16	ppem;		/* The PPEM size for which this strike was designed. */
-  HBUINT16	resolution;	/* The device pixel density (in PPI) for which this
-				 * strike was designed. (E.g., 96 PPI, 192 PPI.) */
-  protected:
-  UnsizedArrayOf<Offset32To<SBIXGlyph>>
-		imageOffsetsZ;	/* Offset from the beginning of the strike data header
-				 * to bitmap data for an individual glyph ID. */
-  public:
-  DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
-};
-
-struct sbix
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix;
-
-  bool has_data () const { return version; }
-
-  const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; }
-
-  struct accelerator_t
-  {
-    accelerator_t (hb_face_t *face)
-    {
-      table = hb_sanitize_context_t ().reference_table<sbix> (face);
-      num_glyphs = face->get_num_glyphs ();
-    }
-    ~accelerator_t () { table.destroy (); }
-
-    bool has_data () const { return table->has_data (); }
-
-    bool get_extents (hb_font_t          *font,
-		      hb_codepoint_t      glyph,
-		      hb_glyph_extents_t *extents) const
-    {
-      /* We only support PNG right now, and following function checks type. */
-      return get_png_extents (font, glyph, extents);
-    }
-
-    hb_blob_t *reference_png (hb_font_t      *font,
-			      hb_codepoint_t  glyph_id,
-			      int            *x_offset,
-			      int            *y_offset,
-			      unsigned int   *available_ppem) const
-    {
-      return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (),
-						  HB_TAG ('p','n','g',' '),
-						  x_offset, y_offset,
-						  num_glyphs, available_ppem);
-    }
-
-    private:
-
-    const SBIXStrike &choose_strike (hb_font_t *font) const
-    {
-      unsigned count = table->strikes.len;
-      if (unlikely (!count))
-	return Null (SBIXStrike);
-
-      unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
-      if (!requested_ppem)
-	requested_ppem = 1<<30; /* Choose largest strike. */
-      /* TODO Add DPI sensitivity as well? */
-      unsigned int best_i = 0;
-      unsigned int best_ppem = table->get_strike (0).ppem;
-
-      for (unsigned int i = 1; i < count; i++)
-      {
-	unsigned int ppem = (table->get_strike (i)).ppem;
-	if ((requested_ppem <= ppem && ppem < best_ppem) ||
-	    (requested_ppem > best_ppem && ppem > best_ppem))
-	{
-	  best_i = i;
-	  best_ppem = ppem;
-	}
-      }
-
-      return table->get_strike (best_i);
-    }
-
-    struct PNGHeader
-    {
-      HBUINT8	signature[8];
-      struct
-      {
-	struct
-	{
-	  HBUINT32	length;
-	  Tag		type;
-	}		header;
-	HBUINT32	width;
-	HBUINT32	height;
-	HBUINT8		bitDepth;
-	HBUINT8		colorType;
-	HBUINT8		compressionMethod;
-	HBUINT8		filterMethod;
-	HBUINT8		interlaceMethod;
-      } IHDR;
-
-      public:
-      DEFINE_SIZE_STATIC (29);
-    };
-
-    bool get_png_extents (hb_font_t          *font,
-			  hb_codepoint_t      glyph,
-			  hb_glyph_extents_t *extents) const
-    {
-      /* Following code is safe to call even without data.
-       * But faster to short-circuit. */
-      if (!has_data ())
-	return false;
-
-      int x_offset = 0, y_offset = 0;
-      unsigned int strike_ppem = 0;
-      hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
-
-      const PNGHeader &png = *blob->as<PNGHeader>();
-
-      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;
-      extents->height    = -1 * png.IHDR.height;
-
-      /* Convert to font units. */
-      if (strike_ppem)
-      {
-	float scale = font->face->get_upem () / (float) strike_ppem;
-	extents->x_bearing = font->em_scalef_x (extents->x_bearing * scale);
-	extents->y_bearing = font->em_scalef_y (extents->y_bearing * scale);
-	extents->width = font->em_scalef_x (extents->width * scale);
-	extents->height = font->em_scalef_y (extents->height * scale);
-      }
-      else
-      {
-	extents->x_bearing = font->em_scale_x (extents->x_bearing);
-	extents->y_bearing = font->em_scale_y (extents->y_bearing);
-	extents->width = font->em_scale_x (extents->width);
-	extents->height = font->em_scale_y (extents->height);
-      }
-
-      hb_blob_destroy (blob);
-
-      return strike_ppem;
-    }
-
-    private:
-    hb_blob_ptr_t<sbix> table;
-
-    unsigned int num_glyphs;
-  };
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  version >= 1 &&
-			  strikes.sanitize (c, this)));
-  }
-
-  bool
-  add_strike (hb_subset_context_t *c, unsigned i) const
-  {
-    if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i])
-      return false;
-
-    return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]);
-  }
-
-  bool serialize_strike_offsets (hb_subset_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-
-    auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
-    if (unlikely (!out)) return_trace (false);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-    hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
-    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
-    for (int i = strikes.len - 1; i >= 0; --i)
-    {
-      auto* o = out->serialize_append (c->serializer);
-      if (unlikely (!o)) return_trace (false);
-      *o = 0;
-      auto snap = c->serializer->snapshot ();
-      c->serializer->push ();
-      bool ret = add_strike (c, i);
-      if (!ret)
-      {
-	c->serializer->pop_discard ();
-	out->pop ();
-	c->serializer->revert (snap);
-      }
-      else
-      {
-	objidxs.push (c->serializer->pop_pack ());
-	new_strikes.push (o);
-      }
-    }
-    for (unsigned int i = 0; i < new_strikes.length; ++i)
-      c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]);
-
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t* c) const
-  {
-    TRACE_SUBSET (this);
-
-    sbix *sbix_prime = c->serializer->start_embed<sbix> ();
-    if (unlikely (!sbix_prime)) return_trace (false);
-    if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
-    if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
-
-    return_trace (serialize_strike_offsets (c));
-  }
-
-  protected:
-  HBUINT16	version;	/* Table version number — set to 1 */
-  HBUINT16	flags;		/* Bit 0: Set to 1. Bit 1: Draw outlines.
-				 * Bits 2 to 15: reserved (set to 0). */
-  Array32OfOffset32To<SBIXStrike>
-		strikes;	/* Offsets from the beginning of the 'sbix'
-				 * table to data for each individual bitmap strike. */
-  public:
-  DEFINE_SIZE_ARRAY (8, strikes);
-};
-
-struct sbix_accelerator_t : sbix::accelerator_t {
-  sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
-};
-
-
-} /* namespace OT */
-
-#endif /* HB_OT_COLOR_SBIX_TABLE_HH */

Deleted: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -1,126 +0,0 @@
-/*
- * Copyright © 2018  Ebrahim Byagowi
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#ifndef HB_OT_COLOR_SVG_TABLE_HH
-#define HB_OT_COLOR_SVG_TABLE_HH
-
-#include "hb-open-type.hh"
-
-/*
- * SVG -- SVG (Scalable Vector Graphics)
- * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
- */
-
-#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
-
-
-namespace OT {
-
-
-struct SVGDocumentIndexEntry
-{
-  int cmp (hb_codepoint_t g) const
-  { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
-
-  hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
-  {
-    return hb_blob_create_sub_blob (svg_blob,
-				    index_offset + (unsigned int) svgDoc,
-				    svgDocLength);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  svgDoc.sanitize (c, base, svgDocLength));
-  }
-
-  protected:
-  HBUINT16	startGlyphID;	/* The first glyph ID in the range described by
-				 * this index entry. */
-  HBUINT16	endGlyphID;	/* The last glyph ID in the range described by
-				 * this index entry. Must be >= startGlyphID. */
-  NNOffset32To<UnsizedArrayOf<HBUINT8>>
-		svgDoc;		/* Offset from the beginning of the SVG Document Index
-				 * to an SVG document. Must be non-zero. */
-  HBUINT32	svgDocLength;	/* Length of the SVG document.
-				 * Must be non-zero. */
-  public:
-  DEFINE_SIZE_STATIC (12);
-};
-
-struct SVG
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG;
-
-  bool has_data () const { return svgDocEntries; }
-
-  struct accelerator_t
-  {
-    accelerator_t (hb_face_t *face)
-    { table = hb_sanitize_context_t ().reference_table<SVG> (face); }
-    ~accelerator_t () { table.destroy (); }
-
-    hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
-    {
-      return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (),
-							       table->svgDocEntries);
-    }
-
-    bool has_data () const { return table->has_data (); }
-
-    private:
-    hb_blob_ptr_t<SVG> table;
-  };
-
-  const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
-  { return (this+svgDocEntries).bsearch (glyph_id); }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  (this+svgDocEntries).sanitize_shallow (c)));
-  }
-
-  protected:
-  HBUINT16	version;	/* Table version (starting at 0). */
-  Offset32To<SortedArray16Of<SVGDocumentIndexEntry>>
-		svgDocEntries;	/* Offset (relative to the start of the SVG table) to the
-				 * SVG Documents Index. Must be non-zero. */
-				/* Array of SVG Document Index Entries. */
-  HBUINT32	reserved;	/* Set to 0. */
-  public:
-  DEFINE_SIZE_STATIC (10);
-};
-
-struct SVG_accelerator_t : SVG::accelerator_t {
-  SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
-#endif /* HB_OT_COLOR_SVG_TABLE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -31,11 +31,11 @@
 
 #include "hb-ot.h"
 
-#include "hb-ot-color-cbdt-table.hh"
-#include "hb-ot-color-colr-table.hh"
-#include "hb-ot-color-cpal-table.hh"
-#include "hb-ot-color-sbix-table.hh"
-#include "hb-ot-color-svg-table.hh"
+#include "OT/Color/CBDT/CBDT.hh"
+#include "OT/Color/COLR/COLR.hh"
+#include "OT/Color/CPAL/CPAL.hh"
+#include "OT/Color/sbix/sbix.hh"
+#include "OT/Color/svg/svg.hh"
 
 
 /**
@@ -167,6 +167,10 @@
  * for allocating a buffer of suitable size before calling
  * hb_ot_color_palette_get_colors() a second time.
  *
+ * The RGBA values in the palette are unpremultiplied. See the
+ * OpenType spec [CPAL](https://learn.microsoft.com/en-us/typography/opentype/spec/cpal)
+ * section for details.
+ *
  * Return value: the total number of colors in the palette
  *
  * Since: 2.1.0
@@ -190,7 +194,8 @@
  * hb_ot_color_has_layers:
  * @face: #hb_face_t to work upon
  *
- * Tests whether a face includes any `COLR` color layers.
+ * Tests whether a face includes a `COLR` table
+ * with data according to COLRv0.
  *
  * Return value: `true` if data found, `false` otherwise
  *
@@ -199,10 +204,46 @@
 hb_bool_t
 hb_ot_color_has_layers (hb_face_t *face)
 {
-  return face->table.COLR->has_data ();
+  return face->table.COLR->has_v0_data ();
 }
 
 /**
+ * hb_ot_color_has_paint:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests where a face includes a `COLR` table
+ * with data according to COLRv1.
+ *
+ * Return value: `true` if data found, `false` otherwise
+ *
+ * Since: 7.0.0
+ */
+hb_bool_t
+hb_ot_color_has_paint (hb_face_t *face)
+{
+  return face->table.COLR->has_v1_data ();
+}
+
+/**
+ * hb_ot_color_glyph_has_paint:
+ * @face: #hb_face_t to work upon
+ * @glyph: The glyph index to query
+ *
+ * Tests where a face includes COLRv1 paint
+ * data for @glyph.
+ *
+ * Return value: `true` if data found, `false` otherwise
+ *
+ * Since: 7.0.0
+ */
+hb_bool_t
+hb_ot_color_glyph_has_paint (hb_face_t      *face,
+                             hb_codepoint_t  glyph)
+{
+  return face->table.COLR->has_paint_for_glyph (glyph);
+}
+
+/**
  * hb_ot_color_glyph_get_layers:
  * @face: #hb_face_t to work upon
  * @glyph: The glyph index to query

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -120,6 +120,15 @@
 			      unsigned int        *layer_count, /* IN/OUT.  May be NULL. */
 			      hb_ot_color_layer_t *layers /* OUT.     May be NULL. */);
 
+/* COLRv1 */
+
+HB_EXTERN hb_bool_t
+hb_ot_color_has_paint (hb_face_t *face);
+
+HB_EXTERN hb_bool_t
+hb_ot_color_glyph_has_paint (hb_face_t      *face,
+                             hb_codepoint_t  glyph);
+
 /*
  * SVG
  */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-deprecated.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -67,7 +67,8 @@
 
 
 /* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */
-HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t
+HB_DEPRECATED_FOR (hb_ot_layout_table_select_script)
+HB_EXTERN hb_bool_t
 hb_ot_layout_table_choose_script (hb_face_t      *face,
 				  hb_tag_t        table_tag,
 				  const hb_tag_t *script_tags,
@@ -74,7 +75,8 @@
 				  unsigned int   *script_index,
 				  hb_tag_t       *chosen_script);
 
-HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t
+HB_DEPRECATED_FOR (hb_ot_layout_script_select_language)
+HB_EXTERN hb_bool_t
 hb_ot_layout_script_find_language (hb_face_t    *face,
 				   hb_tag_t      table_tag,
 				   unsigned int  script_index,
@@ -81,12 +83,14 @@
 				   hb_tag_t      language_tag,
 				   unsigned int *language_index);
 
-HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void
+HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language)
+HB_EXTERN void
 hb_ot_tags_from_script (hb_script_t  script,
 			hb_tag_t    *script_tag_1,
 			hb_tag_t    *script_tag_2);
 
-HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t
+HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language)
+HB_EXTERN hb_tag_t
 hb_ot_tag_from_language (hb_language_t language);
 
 
@@ -121,13 +125,15 @@
   float max_value;
 } hb_ot_var_axis_t;
 
-HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos) unsigned int
+HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos)
+HB_EXTERN unsigned int
 hb_ot_var_get_axes (hb_face_t        *face,
 		    unsigned int      start_offset,
 		    unsigned int     *axes_count /* IN/OUT */,
 		    hb_ot_var_axis_t *axes_array /* OUT */);
 
-HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_find_axis_info) hb_bool_t
+HB_DEPRECATED_FOR (hb_ot_var_find_axis_info)
+HB_EXTERN hb_bool_t
 hb_ot_var_find_axis (hb_face_t        *face,
 		     hb_tag_t          axis_tag,
 		     unsigned int     *axis_index,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -35,9 +35,9 @@
 #include "hb-ot-meta-table.hh"
 #include "hb-ot-name-table.hh"
 #include "hb-ot-post-table.hh"
-#include "hb-ot-color-cbdt-table.hh"
-#include "hb-ot-color-sbix-table.hh"
-#include "hb-ot-color-svg-table.hh"
+#include "OT/Color/CBDT/CBDT.hh"
+#include "OT/Color/sbix/sbix.hh"
+#include "OT/Color/svg/svg.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -34,6 +34,7 @@
 #include "hb-font.hh"
 #include "hb-machinery.hh"
 #include "hb-ot-face.hh"
+#include "hb-outline.hh"
 
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
@@ -43,9 +44,10 @@
 #include "hb-ot-post-table.hh"
 #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-ot-vorg-table.hh"
-#include "hb-ot-color-cbdt-table.hh"
-#include "hb-ot-color-sbix-table.hh"
-#include "hb-ot-color-colr-table.hh"
+#include "OT/Color/CBDT/CBDT.hh"
+#include "OT/Color/COLR/COLR.hh"
+#include "OT/Color/sbix/sbix.hh"
+#include "OT/Color/svg/svg.hh"
 
 
 /**
@@ -59,12 +61,17 @@
  * never need to call these functions directly.
  **/
 
+using hb_ot_font_cmap_cache_t    = hb_cache_t<21, 16, 8, true>;
 using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
 
+static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
+
 struct hb_ot_font_t
 {
   const hb_ot_face_t *ot_face;
 
+  hb_ot_font_cmap_cache_t *cmap_cache;
+
   /* h_advance caching */
   mutable hb_atomic_int_t cached_coords_serial;
   mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache;
@@ -79,6 +86,33 @@
 
   ot_font->ot_face = &font->face->table;
 
+  // retry:
+  auto *cmap_cache  = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
+									 &hb_ot_font_cmap_cache_user_data_key);
+  if (!cmap_cache)
+  {
+    cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
+    if (unlikely (!cmap_cache)) goto out;
+    cmap_cache->init ();
+    if (unlikely (!hb_face_set_user_data (font->face,
+					  &hb_ot_font_cmap_cache_user_data_key,
+					  cmap_cache,
+					  hb_free,
+					  false)))
+    {
+      hb_free (cmap_cache);
+      cmap_cache = nullptr;
+      /* Normally we would retry here, but that would
+       * infinite-loop if the face is the empty-face.
+       * Just let it go and this font will be uncached if it
+       * happened to collide with another thread creating the
+       * cache at the same time. */
+      // goto retry;
+    }
+  }
+  out:
+  ot_font->cmap_cache = cmap_cache;
+
   return ot_font;
 }
 
@@ -88,11 +122,7 @@
   hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
 
   auto *cache = ot_font->advance_cache.get_relaxed ();
-  if (cache)
-  {
-    cache->fini ();
-    hb_free (cache);
-  }
+  hb_free (cache);
 
   hb_free (ot_font);
 }
@@ -106,7 +136,7 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
-  return ot_face->cmap->get_nominal_glyph (unicode, glyph);
+  return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
 }
 
 static unsigned int
@@ -123,7 +153,8 @@
   const hb_ot_face_t *ot_face = ot_font->ot_face;
   return ot_face->cmap->get_nominal_glyphs (count,
 					    first_unicode, unicode_stride,
-					    first_glyph, glyph_stride);
+					    first_glyph, glyph_stride,
+					    ot_font->cmap_cache);
 }
 
 static hb_bool_t
@@ -136,7 +167,9 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
-  return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph);
+  return ot_face->cmap->get_variation_glyph (unicode,
+                                             variation_selector, glyph,
+                                             ot_font->cmap_cache);
 }
 
 static void
@@ -148,10 +181,13 @@
 			    unsigned advance_stride,
 			    void *user_data HB_UNUSED)
 {
+
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
   const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
 
+  hb_position_t *orig_first_advance = first_advance;
+
 #ifndef HB_NO_VAR
   const OT::HVAR &HVAR = *hmtx.var_table;
   const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
@@ -225,6 +261,18 @@
 #ifndef HB_NO_VAR
   OT::VariationStore::destroy_cache (varStore_cache);
 #endif
+
+  if (font->x_strength && !font->embolden_in_place)
+  {
+    /* Emboldening. */
+    hb_position_t x_strength = font->x_scale >= 0 ? font->x_strength : -font->x_strength;
+    first_advance = orig_first_advance;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      *first_advance += *first_advance ? x_strength : 0;
+      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+    }
+  }
 }
 
 #ifndef HB_NO_VERTICAL
@@ -241,6 +289,8 @@
   const hb_ot_face_t *ot_face = ot_font->ot_face;
   const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
 
+  hb_position_t *orig_first_advance = first_advance;
+
   if (vmtx.has_data ())
   {
 #ifndef HB_NO_VAR
@@ -275,6 +325,18 @@
       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
     }
   }
+
+  if (font->y_strength && !font->embolden_in_place)
+  {
+    /* Emboldening. */
+    hb_position_t y_strength = font->y_scale >= 0 ? font->y_strength : -font->y_strength;
+    first_advance = orig_first_advance;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      *first_advance += *first_advance ? y_strength : 0;
+      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
+    }
+  }
 }
 #endif
 
@@ -404,9 +466,16 @@
 			  hb_font_extents_t *metrics,
 			  void *user_data HB_UNUSED)
 {
-  return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) &&
-	 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) &&
-	 _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
+  bool ret = _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) &&
+	     _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) &&
+	     _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
+
+  /* Embolden */
+  int y_shift = font->y_strength;
+  if (font->y_scale < 0) y_shift = -y_shift;
+  metrics->ascender += y_shift;
+
+  return ret;
 }
 
 #ifndef HB_NO_VERTICAL
@@ -424,21 +493,66 @@
 
 #ifndef HB_NO_DRAW
 static void
-hb_ot_get_glyph_shape (hb_font_t *font,
-		       void *font_data HB_UNUSED,
-		       hb_codepoint_t glyph,
-		       hb_draw_funcs_t *draw_funcs, void *draw_data,
-		       void *user_data)
+hb_ot_draw_glyph (hb_font_t *font,
+		  void *font_data HB_UNUSED,
+		  hb_codepoint_t glyph,
+		  hb_draw_funcs_t *draw_funcs, void *draw_data,
+		  void *user_data)
 {
-  hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
-  if (font->face->table.glyf->get_path (font, glyph, draw_session)) return;
+  bool embolden = font->x_strength || font->y_strength;
+  hb_outline_t outline;
+
+  { // Need draw_session to be destructed before emboldening.
+    hb_draw_session_t draw_session (embolden ? hb_outline_recording_pen_get_funcs () : draw_funcs,
+				    embolden ? &outline : draw_data, font->slant_xy);
+    if (!font->face->table.glyf->get_path (font, glyph, draw_session))
 #ifndef HB_NO_CFF
-  if (font->face->table.cff1->get_path (font, glyph, draw_session)) return;
-  if (font->face->table.cff2->get_path (font, glyph, draw_session)) return;
+    if (!font->face->table.cff1->get_path (font, glyph, draw_session))
+    if (!font->face->table.cff2->get_path (font, glyph, draw_session))
 #endif
+    {}
+  }
+
+  if (embolden)
+  {
+    float x_shift = font->embolden_in_place ? 0 : (float) font->x_strength / 2;
+    float y_shift = (float) font->y_strength / 2;
+    if (font->x_scale < 0) x_shift = -x_shift;
+    if (font->y_scale < 0) y_shift = -y_shift;
+    outline.embolden (font->x_strength, font->y_strength,
+		      x_shift, y_shift);
+
+    outline.replay (draw_funcs, draw_data);
+  }
 }
 #endif
 
+#ifndef HB_NO_PAINT
+static void
+hb_ot_paint_glyph (hb_font_t *font,
+                   void *font_data,
+                   hb_codepoint_t glyph,
+                   hb_paint_funcs_t *paint_funcs, void *paint_data,
+                   unsigned int palette,
+                   hb_color_t foreground,
+                   void *user_data)
+{
+#ifndef HB_NO_COLOR
+  if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return;
+  if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
+#ifndef HB_NO_OT_FONT_BITMAP
+  if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
+  if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
+#endif
+#endif
+  if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
+#ifndef HB_NO_CFF
+  if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
+  if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
+#endif
+}
+#endif
+
 static inline void free_static_ot_funcs ();
 
 static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
@@ -462,9 +576,13 @@
 #endif
 
 #ifndef HB_NO_DRAW
-    hb_font_funcs_set_glyph_shape_func (funcs, hb_ot_get_glyph_shape, nullptr, nullptr);
+    hb_font_funcs_set_draw_glyph_func (funcs, hb_ot_draw_glyph, nullptr, nullptr);
 #endif
 
+#ifndef HB_NO_PAINT
+    hb_font_funcs_set_paint_glyph_func (funcs, hb_ot_paint_glyph, nullptr, nullptr);
+#endif
+
     hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
     //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -156,6 +156,7 @@
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
 		  !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
+                  min_size + numRecords * sizeDeviceRecord > numRecords * sizeDeviceRecord &&
 		  sizeDeviceRecord >= DeviceRecord::min_size &&
 		  c->check_range (this, get_size ()));
   }

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-head-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -97,6 +97,7 @@
 					 * entire font as HBUINT32, then store
 					 * 0xB1B0AFBAu - sum. */
   HBUINT32	magicNumber;		/* Set to 0x5F0F3CF5u. */
+  public:
   HBUINT16	flags;			/* Bit 0: Baseline for font at y=0;
 					 * Bit 1: Left sidebearing point at x=0;
 					 * Bit 2: Instructions may depend on point size;
@@ -141,6 +142,7 @@
 					 * encoded in the cmap subtables represent proper
 					 * support for those code points.
 					 * Bit 15: Reserved, set to 0. */
+  protected:
   HBUINT16	unitsPerEm;		/* Valid range is from 16 to 16384. This value
 					 * should be a power of 2 for fonts that have
 					 * TrueType outlines. */
@@ -148,10 +150,12 @@
 					   January 1, 1904. 64-bit integer */
   LONGDATETIME	modified;		/* Number of seconds since 12:00 midnight,
 					   January 1, 1904. 64-bit integer */
+  public:
   HBINT16	xMin;			/* For all glyph bounding boxes. */
   HBINT16	yMin;			/* For all glyph bounding boxes. */
   HBINT16	xMax;			/* For all glyph bounding boxes. */
   HBINT16	yMax;			/* For all glyph bounding boxes. */
+  protected:
   HBUINT16	macStyle;		/* Bit 0: Bold (if set to 1);
 					 * Bit 1: Italic (if set to 1)
 					 * Bit 2: Underline (if set to 1)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -31,6 +31,7 @@
 #include "hb-ot-maxp-table.hh"
 #include "hb-ot-hhea-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-var-mvar-table.hh"
 #include "hb-ot-metrics.hh"
 
 /*
@@ -73,13 +74,15 @@
     return_trace (true);
   }
 
-  const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>* get_mtx_map (const hb_subset_plan_t *plan) const
-  { return T::is_horizontal ? plan->hmtx_map : plan->vmtx_map; }
+  const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>>* get_mtx_map (const hb_subset_plan_t *plan) const
+  { return T::is_horizontal ? &plan->hmtx_map : &plan->vmtx_map; }
 
-  bool subset_update_header (hb_subset_plan_t *plan,
-			     unsigned int num_hmetrics) const
+  bool subset_update_header (hb_subset_context_t *c,
+			     unsigned int num_hmetrics,
+			     const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map,
+			     const hb_map_t *bounds_map) const
   {
-    hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag);
+    hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (c->plan->source, H::tableTag);
     hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
     hb_blob_destroy (src_blob);
 
@@ -91,7 +94,56 @@
     H *table = (H *) hb_blob_get_data (dest_blob, &length);
     table->numberOfLongMetrics = num_hmetrics;
 
-    bool result = plan->add_table (H::tableTag, dest_blob);
+#ifndef HB_NO_VAR
+    if (c->plan->normalized_coords)
+    {
+      auto &MVAR = *c->plan->source->table.MVAR;
+      if (T::is_horizontal)
+      {
+	HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE,   caretSlopeRise);
+	HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN,    caretSlopeRun);
+	HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, caretOffset);
+      }
+      else
+      {
+	HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RISE,     caretSlopeRise);
+	HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_RUN,      caretSlopeRun);
+	HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET,   caretOffset);
+      }
+
+      int min_lsb = 0x7FFF;
+      int min_rsb = 0x7FFF;
+      int max_extent = -0x7FFF;
+      unsigned max_adv = 0;
+      for (const auto _ : *mtx_map)
+      {
+        hb_codepoint_t gid = _.first;
+        unsigned adv = _.second.first;
+        int lsb = _.second.second;
+        max_adv = hb_max (max_adv, adv);
+
+        if (bounds_map->has (gid))
+        {
+          unsigned bound_width = bounds_map->get (gid);
+          int rsb = adv - lsb - bound_width;
+          int extent = lsb + bound_width;
+          min_lsb = hb_min (min_lsb, lsb);
+          min_rsb = hb_min (min_rsb, rsb);
+          max_extent = hb_max (max_extent, extent);
+        }
+      }
+
+      table->advanceMax = max_adv;
+      if (!bounds_map->is_empty ())
+      {
+        table->minLeadingBearing = min_lsb;
+        table->minTrailingBearing = min_rsb;
+        table->maxExtent = max_extent;
+      }
+    }
+#endif
+
+    bool result = c->plan->add_table (H::tableTag, dest_blob);
     hb_blob_destroy (dest_blob);
 
     return result;
@@ -132,7 +184,7 @@
 
     accelerator_t _mtx (c->plan->source);
     unsigned num_long_metrics;
-    const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *mtx_map = get_mtx_map (c->plan);
+    const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map = get_mtx_map (c->plan);
     {
       /* Determine num_long_metrics to encode. */
       auto& plan = c->plan;
@@ -169,7 +221,8 @@
       return_trace (false);
 
     // Amend header num hmetrics
-    if (unlikely (!subset_update_header (c->plan, num_long_metrics)))
+    if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map,
+                                         T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map)))
       return_trace (false);
 
     return_trace (true);
@@ -291,8 +344,6 @@
       /* num_bearings <= glyph < num_glyphs;
        * num_bearings <= num_advances */
 
-      /* TODO Optimize */
-
       if (num_bearings == num_advances)
         return get_advance_without_var_unscaled (num_bearings - 1);
 
@@ -315,7 +366,7 @@
       if (var_table.get_length ())
 	return advance + roundf (var_table->get_advance_delta_unscaled (glyph,
 									font->coords, font->num_coords,
-									store_cache)); // TODO Optimize?!
+									store_cache));
 
       return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
 #else
@@ -340,19 +391,17 @@
   /* get advance: when no variations, call get_advance_without_var_unscaled.
    * when there're variations, get advance value from mtx_map in subset_plan*/
   unsigned get_new_gid_advance_unscaled (const hb_subset_plan_t *plan,
-                                         const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *mtx_map,
+                                         const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map,
                                          unsigned new_gid,
                                          const accelerator_t &_mtx) const
   {
-    if (mtx_map->is_empty () ||
-        (new_gid == 0 && !mtx_map->has (new_gid)))
+    if (mtx_map->is_empty ())
     {
       hb_codepoint_t old_gid = 0;
       return plan->old_gid_for_new_gid (new_gid, &old_gid) ?
              _mtx.get_advance_without_var_unscaled (old_gid) : 0;
     }
-    else
-    { return mtx_map->get (new_gid).first; }
+    return mtx_map->get (new_gid).first;
   }
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -44,43 +44,7 @@
 using OT::Layout::SmallTypes;
 using OT::Layout::MediumTypes;
 
-#ifndef HB_MAX_NESTING_LEVEL
-#define HB_MAX_NESTING_LEVEL	64
-#endif
-#ifndef HB_MAX_CONTEXT_LENGTH
-#define HB_MAX_CONTEXT_LENGTH	64
-#endif
-#ifndef HB_CLOSURE_MAX_STAGES
-/*
- * The maximum number of times a lookup can be applied during shaping.
- * Used to limit the number of iterations of the closure algorithm.
- * This must be larger than the number of times add_gsub_pause() is
- * called in a collect_features call of any shaper.
- */
-#define HB_CLOSURE_MAX_STAGES	12
-#endif
 
-#ifndef HB_MAX_SCRIPTS
-#define HB_MAX_SCRIPTS	500
-#endif
-
-#ifndef HB_MAX_LANGSYS
-#define HB_MAX_LANGSYS	2000
-#endif
-
-#ifndef HB_MAX_LANGSYS_FEATURE_COUNT
-#define HB_MAX_LANGSYS_FEATURE_COUNT 50000
-#endif
-
-#ifndef HB_MAX_FEATURE_INDICES
-#define HB_MAX_FEATURE_INDICES	1500
-#endif
-
-#ifndef HB_MAX_LOOKUP_VISIT_COUNT
-#define HB_MAX_LOOKUP_VISIT_COUNT	35000
-#endif
-
-
 namespace OT {
 
 template<typename Iterator>
@@ -192,19 +156,19 @@
   {
     if (tag_ == HB_OT_TAG_GSUB)
     {
-      lookup_index_map = c_->plan->gsub_lookups;
-      script_langsys_map = c_->plan->gsub_langsys;
-      feature_index_map = c_->plan->gsub_features;
-      feature_substitutes_map = c_->plan->gsub_feature_substitutes_map;
-      feature_record_cond_idx_map = c_->plan->user_axes_location->is_empty () ? nullptr : c_->plan->gsub_feature_record_cond_idx_map;
+      lookup_index_map = &c_->plan->gsub_lookups;
+      script_langsys_map = &c_->plan->gsub_langsys;
+      feature_index_map = &c_->plan->gsub_features;
+      feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map;
+      feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map;
     }
     else
     {
-      lookup_index_map = c_->plan->gpos_lookups;
-      script_langsys_map = c_->plan->gpos_langsys;
-      feature_index_map = c_->plan->gpos_features;
-      feature_substitutes_map = c_->plan->gpos_feature_substitutes_map;
-      feature_record_cond_idx_map = c_->plan->user_axes_location->is_empty () ? nullptr : c_->plan->gpos_feature_record_cond_idx_map;
+      lookup_index_map = &c_->plan->gpos_lookups;
+      script_langsys_map = &c_->plan->gpos_langsys;
+      feature_index_map = &c_->plan->gpos_features;
+      feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map;
+      feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map;
     }
   }
 
@@ -1181,7 +1145,7 @@
   {
     TRACE_SUBSET (this);
     if (!l->visitScript ()) return_trace (false);
-    if (tag && !c->plan->layout_scripts->has (*tag))
+    if (tag && !c->plan->layout_scripts.has (*tag))
       return false;
 
     auto *out = c->serializer->start_embed (*this);
@@ -1389,7 +1353,7 @@
     // Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning
     // phase, but it can happen in rare cases such as when during closure subtable is considered
     // degenerate (see: https://github.com/harfbuzz/harfbuzz/issues/3853)
-    return true;
+    return_trace (true);
   }
 
   template <typename TSubTable>
@@ -1568,7 +1532,7 @@
                const Coverage* glyph_filter = nullptr) const
   {
     TRACE_SUBSET (this);
-    const hb_map_t &glyph_map = *c->plan->glyph_map_gsub;
+    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
 
     hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
     hb_set_t orig_klasses;
@@ -1813,7 +1777,7 @@
                const Coverage* glyph_filter = nullptr) const
   {
     TRACE_SUBSET (this);
-    const hb_map_t &glyph_map = *c->plan->glyph_map_gsub;
+    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
     const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
 
     hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
@@ -2269,7 +2233,7 @@
 {
   float evaluate (int coord) const
   {
-    int start = startCoord, peak = peakCoord, end = endCoord;
+    int start = startCoord.to_int (), peak = peakCoord.to_int (), end = endCoord.to_int ();
 
     /* TODO Move these to sanitize(). */
     if (unlikely (start > peak || peak > end))
@@ -2389,6 +2353,9 @@
 
 struct VarData
 {
+  unsigned int get_item_count () const
+  { return itemCount; }
+
   unsigned int get_region_index_count () const
   { return regionIndices.len; }
 
@@ -2794,6 +2761,29 @@
     return_trace (true);
   }
 
+  VariationStore *copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    hb_vector_t <hb_inc_bimap_t> inner_maps;
+    unsigned count = dataSets.len;
+    for (unsigned i = 0; i < count; i++)
+    {
+      hb_inc_bimap_t *map = inner_maps.push ();
+      auto &data = this+dataSets[i];
+
+      unsigned itemCount = data.get_item_count ();
+      for (unsigned j = 0; j < itemCount; j++)
+	map->add (j);
+    }
+
+    if (unlikely (!out->serialize (c, this, inner_maps))) return_trace (nullptr);
+
+    return_trace (out);
+  }
+
   bool subset (hb_subset_context_t *c, const hb_array_t<const hb_inc_bimap_t> &inner_maps) const
   {
     TRACE_SUBSET (this);
@@ -2874,7 +2864,7 @@
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    const hb_map_t *index_map = c->plan->axes_index_map;
+    const hb_map_t *index_map = &c->plan->axes_index_map;
     if (index_map->is_empty ()) return_trace (true);
 
     if (!index_map->has (axisIndex))
@@ -2899,8 +2889,8 @@
     {
       // add axisIndex->value into the hashmap so we can check if the record is
       // unique with variations
-      int16_t min_val = filterRangeMinValue;
-      int16_t max_val = filterRangeMaxValue;
+      int16_t min_val = filterRangeMinValue.to_int ();
+      int16_t max_val = filterRangeMaxValue.to_int ();
       hb_codepoint_t val = (max_val << 16) + min_val;
 
       condition_map->set (axisIndex, val);
@@ -2912,7 +2902,7 @@
     int v = c->axes_location->get (axis_tag);
 
     //condition not met, drop the entire record
-    if (v < filterRangeMinValue || v > filterRangeMaxValue)
+    if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ())
       return DROP_RECORD_WITH_VAR;
 
     //axis pinned and condition met, drop the condition
@@ -2922,7 +2912,7 @@
   bool evaluate (const int *coords, unsigned int coord_len) const
   {
     int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
-    return filterRangeMinValue <= coord && coord <= filterRangeMaxValue;
+    return filterRangeMinValue.to_int () <= coord && coord <= filterRangeMaxValue.to_int ();
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2962,8 +2952,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -29,890 +29,6 @@
 #ifndef HB_OT_LAYOUT_GDEF_TABLE_HH
 #define HB_OT_LAYOUT_GDEF_TABLE_HH
 
-#include "hb-ot-layout-common.hh"
+#include "OT/Layout/GDEF/GDEF.hh"
 
-#include "hb-font.hh"
-
-
-namespace OT {
-
-
-/*
- * Attachment List Table
- */
-
-/* Array of contour point indices--in increasing numerical order */
-struct AttachPoint : Array16Of<HBUINT16>
-{
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
-
-    return_trace (out->serialize (c->serializer, + iter ()));
-  }
-};
-
-struct AttachList
-{
-  unsigned int get_attach_points (hb_codepoint_t glyph_id,
-				  unsigned int start_offset,
-				  unsigned int *point_count /* IN/OUT */,
-				  unsigned int *point_array /* OUT */) const
-  {
-    unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (index == NOT_COVERED)
-    {
-      if (point_count)
-	*point_count = 0;
-      return 0;
-    }
-
-    const AttachPoint &points = this+attachPoint[index];
-
-    if (point_count)
-    {
-      + points.as_array ().sub_array (start_offset, point_count)
-      | hb_sink (hb_array (point_array, *point_count))
-      ;
-    }
-
-    return points.len;
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
-    + hb_zip (this+coverage, attachPoint)
-    | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second)
-    | hb_map (hb_first)
-    | hb_map (glyph_map)
-    | hb_sink (new_coverage)
-    ;
-    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
-    return_trace (bool (new_coverage));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
-  }
-
-  protected:
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table -- from
-					 * beginning of AttachList table */
-  Array16OfOffset16To<AttachPoint>
-		attachPoint;		/* Array of AttachPoint tables
-					 * in Coverage Index order */
-  public:
-  DEFINE_SIZE_ARRAY (4, attachPoint);
-};
-
-/*
- * Ligature Caret Table
- */
-
-struct CaretValueFormat1
-{
-  friend struct CaretValue;
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-    return_trace (true);
-  }
-
-  private:
-  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
-  {
-    return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  protected:
-  HBUINT16	caretValueFormat;	/* Format identifier--format = 1 */
-  FWORD		coordinate;		/* X or Y value, in design units */
-  public:
-  DEFINE_SIZE_STATIC (4);
-};
-
-struct CaretValueFormat2
-{
-  friend struct CaretValue;
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (false);
-    return_trace (true);
-  }
-
-  private:
-  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
-  {
-    hb_position_t x, y;
-    font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
-    return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  protected:
-  HBUINT16	caretValueFormat;	/* Format identifier--format = 2 */
-  HBUINT16	caretValuePoint;	/* Contour point index on glyph */
-  public:
-  DEFINE_SIZE_STATIC (4);
-};
-
-struct CaretValueFormat3
-{
-  friend struct CaretValue;
-
-  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction,
-				 const VariationStore &var_store) const
-  {
-    return HB_DIRECTION_IS_HORIZONTAL (direction) ?
-	   font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
-	   font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
-    if (!c->serializer->embed (caretValueFormat)) return_trace (false);
-    if (!c->serializer->embed (coordinate)) return_trace (false);
-
-    unsigned varidx = (this+deviceTable).get_variation_index ();
-    if (c->plan->layout_variation_idx_delta_map->has (varidx))
-    {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map->get (varidx));
-      if (delta != 0)
-      {
-        if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
-          return_trace (false);
-      }
-    }
-
-    if (c->plan->all_axes_pinned)
-      return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
-
-    if (!c->serializer->embed (deviceTable))
-      return_trace (false);
-
-    return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out),
-						   hb_serialize_context_t::Head, c->plan->layout_variation_idx_delta_map));
-  }
-
-  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
-  { (this+deviceTable).collect_variation_indices (c); }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
-  }
-
-  protected:
-  HBUINT16	caretValueFormat;	/* Format identifier--format = 3 */
-  FWORD		coordinate;		/* X or Y value, in design units */
-  Offset16To<Device>
-		deviceTable;		/* Offset to Device table for X or Y
-					 * value--from beginning of CaretValue
-					 * table */
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct CaretValue
-{
-  hb_position_t get_caret_value (hb_font_t *font,
-				 hb_direction_t direction,
-				 hb_codepoint_t glyph_id,
-				 const VariationStore &var_store) const
-  {
-    switch (u.format) {
-    case 1: return u.format1.get_caret_value (font, direction);
-    case 2: return u.format2.get_caret_value (font, direction, glyph_id);
-    case 3: return u.format3.get_caret_value (font, direction, var_store);
-    default:return 0;
-    }
-  }
-
-  template <typename context_t, typename ...Ts>
-  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
-  {
-    TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
-    switch (u.format) {
-    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
-    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
-    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
-    default:return_trace (c->default_return_value ());
-    }
-  }
-
-  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
-  {
-    switch (u.format) {
-    case 1:
-    case 2:
-      return;
-    case 3:
-      u.format3.collect_variation_indices (c);
-      return;
-    default: return;
-    }
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (!u.format.sanitize (c)) return_trace (false);
-    switch (u.format) {
-    case 1: return_trace (u.format1.sanitize (c));
-    case 2: return_trace (u.format2.sanitize (c));
-    case 3: return_trace (u.format3.sanitize (c));
-    default:return_trace (true);
-    }
-  }
-
-  protected:
-  union {
-  HBUINT16		format;		/* Format identifier */
-  CaretValueFormat1	format1;
-  CaretValueFormat2	format2;
-  CaretValueFormat3	format3;
-  } u;
-  public:
-  DEFINE_SIZE_UNION (2, format);
-};
-
-struct LigGlyph
-{
-  unsigned get_lig_carets (hb_font_t            *font,
-			   hb_direction_t        direction,
-			   hb_codepoint_t        glyph_id,
-			   const VariationStore &var_store,
-			   unsigned              start_offset,
-			   unsigned             *caret_count /* IN/OUT */,
-			   hb_position_t        *caret_array /* OUT */) const
-  {
-    if (caret_count)
-    {
-      + carets.as_array ().sub_array (start_offset, caret_count)
-      | hb_map (hb_add (this))
-      | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
-      | hb_sink (hb_array (caret_array, *caret_count))
-      ;
-    }
-
-    return carets.len;
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-    + hb_iter (carets)
-    | hb_apply (subset_offset_array (c, out->carets, this))
-    ;
-
-    return_trace (bool (out->carets));
-  }
-
-  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
-  {
-    for (const Offset16To<CaretValue>& offset : carets.iter ())
-      (this+offset).collect_variation_indices (c);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (carets.sanitize (c, this));
-  }
-
-  protected:
-  Array16OfOffset16To<CaretValue>
-		carets;			/* Offset array of CaretValue tables
-					 * --from beginning of LigGlyph table
-					 * --in increasing coordinate order */
-  public:
-  DEFINE_SIZE_ARRAY (2, carets);
-};
-
-struct LigCaretList
-{
-  unsigned int get_lig_carets (hb_font_t *font,
-			       hb_direction_t direction,
-			       hb_codepoint_t glyph_id,
-			       const VariationStore &var_store,
-			       unsigned int start_offset,
-			       unsigned int *caret_count /* IN/OUT */,
-			       hb_position_t *caret_array /* OUT */) const
-  {
-    unsigned int index = (this+coverage).get_coverage (glyph_id);
-    if (index == NOT_COVERED)
-    {
-      if (caret_count)
-	*caret_count = 0;
-      return 0;
-    }
-    const LigGlyph &lig_glyph = this+ligGlyph[index];
-    return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
-
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
-    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
-    + hb_zip (this+coverage, ligGlyph)
-    | hb_filter (glyphset, hb_first)
-    | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
-    | hb_map (hb_first)
-    | hb_map (glyph_map)
-    | hb_sink (new_coverage)
-    ;
-    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
-    return_trace (bool (new_coverage));
-  }
-
-  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
-  {
-    + hb_zip (this+coverage, ligGlyph)
-    | hb_filter (c->glyph_set, hb_first)
-    | hb_map (hb_second)
-    | hb_map (hb_add (this))
-    | hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); })
-    ;
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
-  }
-
-  protected:
-  Offset16To<Coverage>
-		coverage;		/* Offset to Coverage table--from
-					 * beginning of LigCaretList table */
-  Array16OfOffset16To<LigGlyph>
-		ligGlyph;		/* Array of LigGlyph tables
-					 * in Coverage Index order */
-  public:
-  DEFINE_SIZE_ARRAY (4, ligGlyph);
-};
-
-
-struct MarkGlyphSetsFormat1
-{
-  bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
-  { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-    out->format = format;
-
-    bool ret = true;
-    for (const Offset32To<Coverage>& offset : coverage.iter ())
-    {
-      auto *o = out->coverage.serialize_append (c->serializer);
-      if (unlikely (!o))
-      {
-	ret = false;
-	break;
-      }
-
-      //not using o->serialize_subset (c, offset, this, out) here because
-      //OTS doesn't allow null offset.
-      //See issue: https://github.com/khaledhosny/ots/issues/172
-      c->serializer->push ();
-      c->dispatch (this+offset);
-      c->serializer->add_link (*o, c->serializer->pop_pack ());
-    }
-
-    return_trace (ret && out->coverage.len);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this));
-  }
-
-  protected:
-  HBUINT16	format;			/* Format identifier--format = 1 */
-  Array16Of<Offset32To<Coverage>>
-		coverage;		/* Array of long offsets to mark set
-					 * coverage tables */
-  public:
-  DEFINE_SIZE_ARRAY (4, coverage);
-};
-
-struct MarkGlyphSets
-{
-  bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
-  {
-    switch (u.format) {
-    case 1: return u.format1.covers (set_index, glyph_id);
-    default:return false;
-    }
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    switch (u.format) {
-    case 1: return_trace (u.format1.subset (c));
-    default:return_trace (false);
-    }
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (!u.format.sanitize (c)) return_trace (false);
-    switch (u.format) {
-    case 1: return_trace (u.format1.sanitize (c));
-    default:return_trace (true);
-    }
-  }
-
-  protected:
-  union {
-  HBUINT16		format;		/* Format identifier */
-  MarkGlyphSetsFormat1	format1;
-  } u;
-  public:
-  DEFINE_SIZE_UNION (2, format);
-};
-
-
-/*
- * GDEF -- Glyph Definition
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
- */
-
-
-template <typename Types>
-struct GDEFVersion1_2
-{
-  friend struct GDEF;
-
-  protected:
-  FixedVersion<>version;		/* Version of the GDEF table--currently
-					 * 0x00010003u */
-  typename Types::template OffsetTo<ClassDef>
-		glyphClassDef;		/* Offset to class definition table
-					 * for glyph type--from beginning of
-					 * GDEF header (may be Null) */
-  typename Types::template OffsetTo<AttachList>
-		attachList;		/* Offset to list of glyphs with
-					 * attachment points--from beginning
-					 * of GDEF header (may be Null) */
-  typename Types::template OffsetTo<LigCaretList>
-		ligCaretList;		/* Offset to list of positioning points
-					 * for ligature carets--from beginning
-					 * of GDEF header (may be Null) */
-  typename Types::template OffsetTo<ClassDef>
-		markAttachClassDef;	/* Offset to class definition table for
-					 * mark attachment type--from beginning
-					 * of GDEF header (may be Null) */
-  typename Types::template OffsetTo<MarkGlyphSets>
-		markGlyphSetsDef;	/* Offset to the table of mark set
-					 * definitions--from beginning of GDEF
-					 * header (may be NULL).  Introduced
-					 * in version 0x00010002. */
-  Offset32To<VariationStore>
-		varStore;		/* Offset to the table of Item Variation
-					 * Store--from beginning of GDEF
-					 * header (may be NULL).  Introduced
-					 * in version 0x00010003. */
-  public:
-  DEFINE_SIZE_MIN (4 + 4 * Types::size);
-
-  unsigned int get_size () const
-  {
-    return min_size +
-	   (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) +
-	   (version.to_int () >= 0x00010003u ? varStore.static_size : 0);
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (version.sanitize (c) &&
-		  glyphClassDef.sanitize (c, this) &&
-		  attachList.sanitize (c, this) &&
-		  ligCaretList.sanitize (c, this) &&
-		  markAttachClassDef.sanitize (c, this) &&
-		  (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
-		  (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-    auto *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
-
-    bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
-    bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
-    bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
-    bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
-
-    bool subset_markglyphsetsdef = false;
-    if (version.to_int () >= 0x00010002u)
-    {
-      subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
-    }
-
-    bool subset_varstore = false;
-    if (version.to_int () >= 0x00010003u)
-    {
-      if (c->plan->all_axes_pinned)
-        out->varStore = 0;
-      else
-        subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
-    }
-
-    if (subset_varstore)
-    {
-      out->version.minor = 3;
-    } else if (subset_markglyphsetsdef) {
-      out->version.minor = 2;
-    } else  {
-      out->version.minor = 0;
-    }
-
-    return_trace (subset_glyphclassdef || subset_attachlist ||
-		  subset_ligcaretlist || subset_markattachclassdef ||
-		  (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
-		  (out->version.to_int () >= 0x00010003u && subset_varstore));
-  }
-};
-
-struct GDEF
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF;
-
-  enum GlyphClasses {
-    UnclassifiedGlyph	= 0,
-    BaseGlyph		= 1,
-    LigatureGlyph	= 2,
-    MarkGlyph		= 3,
-    ComponentGlyph	= 4
-  };
-
-  unsigned int get_size () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version1.get_size ();
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.get_size ();
-#endif
-    default: return u.version.static_size;
-    }
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!u.version.sanitize (c))) return_trace (false);
-    switch (u.version.major) {
-    case 1: return_trace (u.version1.sanitize (c));
-#ifndef HB_NO_BEYOND_64K
-    case 2: return_trace (u.version2.sanitize (c));
-#endif
-    default: return_trace (true);
-    }
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    switch (u.version.major) {
-    case 1: return u.version1.subset (c);
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.subset (c);
-#endif
-    default: return false;
-    }
-  }
-
-  bool has_glyph_classes () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version1.glyphClassDef != 0;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.glyphClassDef != 0;
-#endif
-    default: return false;
-    }
-  }
-  const ClassDef &get_glyph_class_def () const
-  {
-    switch (u.version.major) {
-    case 1: return this+u.version1.glyphClassDef;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return this+u.version2.glyphClassDef;
-#endif
-    default: return Null(ClassDef);
-    }
-  }
-  bool has_attach_list () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version1.attachList != 0;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.attachList != 0;
-#endif
-    default: return false;
-    }
-  }
-  const AttachList &get_attach_list () const
-  {
-    switch (u.version.major) {
-    case 1: return this+u.version1.attachList;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return this+u.version2.attachList;
-#endif
-    default: return Null(AttachList);
-    }
-  }
-  bool has_lig_carets () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version1.ligCaretList != 0;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.ligCaretList != 0;
-#endif
-    default: return false;
-    }
-  }
-  const LigCaretList &get_lig_caret_list () const
-  {
-    switch (u.version.major) {
-    case 1: return this+u.version1.ligCaretList;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return this+u.version2.ligCaretList;
-#endif
-    default: return Null(LigCaretList);
-    }
-  }
-  bool has_mark_attachment_types () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version1.markAttachClassDef != 0;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.markAttachClassDef != 0;
-#endif
-    default: return false;
-    }
-  }
-  const ClassDef &get_mark_attach_class_def () const
-  {
-    switch (u.version.major) {
-    case 1: return this+u.version1.markAttachClassDef;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return this+u.version2.markAttachClassDef;
-#endif
-    default: return Null(ClassDef);
-    }
-  }
-  bool has_mark_glyph_sets () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.markGlyphSetsDef != 0;
-#endif
-    default: return false;
-    }
-  }
-  const MarkGlyphSets &get_mark_glyph_sets () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets);
-#ifndef HB_NO_BEYOND_64K
-    case 2: return this+u.version2.markGlyphSetsDef;
-#endif
-    default: return Null(MarkGlyphSets);
-    }
-  }
-  bool has_var_store () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0;
-#ifndef HB_NO_BEYOND_64K
-    case 2: return u.version2.varStore != 0;
-#endif
-    default: return false;
-    }
-  }
-  const VariationStore &get_var_store () const
-  {
-    switch (u.version.major) {
-    case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore);
-#ifndef HB_NO_BEYOND_64K
-    case 2: return this+u.version2.varStore;
-#endif
-    default: return Null(VariationStore);
-    }
-  }
-
-
-  bool has_data () const { return u.version.to_int (); }
-  unsigned int get_glyph_class (hb_codepoint_t glyph) const
-  { return get_glyph_class_def ().get_class (glyph); }
-  void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
-  { get_glyph_class_def ().collect_class (glyphs, klass); }
-
-  unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
-  { return get_mark_attach_class_def ().get_class (glyph); }
-
-  unsigned int get_attach_points (hb_codepoint_t glyph_id,
-				  unsigned int start_offset,
-				  unsigned int *point_count /* IN/OUT */,
-				  unsigned int *point_array /* OUT */) const
-  { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); }
-
-  unsigned int get_lig_carets (hb_font_t *font,
-			       hb_direction_t direction,
-			       hb_codepoint_t glyph_id,
-			       unsigned int start_offset,
-			       unsigned int *caret_count /* IN/OUT */,
-			       hb_position_t *caret_array /* OUT */) const
-  { return get_lig_caret_list ().get_lig_carets (font,
-						 direction, glyph_id, get_var_store(),
-						 start_offset, caret_count, caret_array); }
-
-  bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
-  { return get_mark_glyph_sets ().covers (set_index, glyph_id); }
-
-  /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
-   * glyph class and other bits, and high 8-bit the mark attachment type (if any).
-   * Not to be confused with lookup_props which is very similar. */
-  unsigned int get_glyph_props (hb_codepoint_t glyph) const
-  {
-    unsigned int klass = get_glyph_class (glyph);
-
-    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), "");
-    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), "");
-    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
-
-    switch (klass) {
-    default:			return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
-    case BaseGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
-    case LigatureGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
-    case MarkGlyph:
-	  klass = get_mark_attachment_type (glyph);
-	  return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
-    }
-  }
-
-  HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
-				   hb_face_t *face) const;
-
-  struct accelerator_t
-  {
-    accelerator_t (hb_face_t *face)
-    {
-      table = hb_sanitize_context_t ().reference_table<GDEF> (face);
-      if (unlikely (table->is_blocklisted (table.get_blob (), face)))
-      {
-	hb_blob_destroy (table.get_blob ());
-	table = hb_blob_get_empty ();
-      }
-    }
-    ~accelerator_t () { table.destroy (); }
-
-    hb_blob_ptr_t<GDEF> table;
-  };
-
-  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
-  { get_lig_caret_list ().collect_variation_indices (c); }
-
-  void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
-				       hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
-  {
-    if (!has_var_store ()) return;
-    if (layout_variation_indices->is_empty ()) return;
-
-    unsigned new_major = 0, new_minor = 0;
-    unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
-    for (unsigned idx : layout_variation_indices->iter ())
-    {
-      uint16_t major = idx >> 16;
-      if (major >= get_var_store ().get_sub_table_count ()) break;
-      if (major != last_major)
-      {
-	new_minor = 0;
-	++new_major;
-      }
-
-      unsigned new_idx = (new_major << 16) + new_minor;
-      if (!layout_variation_idx_delta_map->has (idx))
-        continue;
-      int delta = hb_second (layout_variation_idx_delta_map->get (idx));
-
-      layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
-      ++new_minor;
-      last_major = major;
-    }
-  }
-
-  protected:
-  union {
-  FixedVersion<>		version;	/* Version identifier */
-  GDEFVersion1_2<SmallTypes>	version1;
-#ifndef HB_NO_BEYOND_64K
-  GDEFVersion1_2<MediumTypes>	version2;
-#endif
-  } u;
-  public:
-  DEFINE_SIZE_MIN (4);
-};
-
-struct GDEF_accelerator_t : GDEF::accelerator_t {
-  GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
 #endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -56,12 +56,17 @@
 template <>
 inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
-  const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
+  auto *gpos = c->face->table.GPOS.get_relaxed ();
+  const PosLookup &l = gpos->table->get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
   unsigned int saved_lookup_index = c->lookup_index;
   c->set_lookup_index (lookup_index);
   c->set_lookup_props (l.get_props ());
-  bool ret = l.dispatch (c);
+
+  bool ret = false;
+  auto *accel = gpos->get_accel (lookup_index);
+  ret = accel && accel->apply (c, l.get_subtable_count (), false);
+
   c->set_lookup_index (saved_lookup_index);
   c->set_lookup_props (saved_lookup_props);
   return ret;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -69,12 +69,17 @@
 template <>
 inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
-  const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
+  auto *gsub = c->face->table.GSUB.get_relaxed ();
+  const SubstLookup &l = gsub->table->get_lookup (lookup_index);
   unsigned int saved_lookup_props = c->lookup_props;
   unsigned int saved_lookup_index = c->lookup_index;
   c->set_lookup_index (lookup_index);
   c->set_lookup_props (l.get_props ());
-  bool ret = l.dispatch (c);
+
+  bool ret = false;
+  auto *accel = gsub->get_accel (lookup_index);
+  ret = accel && accel->apply (c, l.get_subtable_count (), false);
+
   c->set_lookup_index (saved_lookup_index);
   c->set_lookup_props (saved_lookup_props);
   return ret;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -115,7 +115,7 @@
 	  return true;
       }
 
-      hb_set_clear (done_lookups_glyph_set->get (lookup_index));
+      done_lookups_glyph_set->get (lookup_index)->clear ();
     }
 
     hb_set_t *covered_glyph_set = done_lookups_glyph_set->get (lookup_index);
@@ -532,6 +532,30 @@
     may_skip (const hb_glyph_info_t &info) const
     { return matcher.may_skip (c, info); }
 
+    enum match_t {
+      MATCH,
+      NOT_MATCH,
+      SKIP
+    };
+
+    match_t match (hb_glyph_info_t &info)
+    {
+      matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+      if (unlikely (skip == matcher_t::SKIP_YES))
+	return SKIP;
+
+      matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ());
+      if (match == matcher_t::MATCH_YES ||
+	  (match == matcher_t::MATCH_MAYBE &&
+	   skip == matcher_t::SKIP_NO))
+	return MATCH;
+
+      if (skip == matcher_t::SKIP_NO)
+        return NOT_MATCH;
+
+      return SKIP;
+  }
+
     bool next (unsigned *unsafe_to = nullptr)
     {
       assert (num_items > 0);
@@ -543,28 +567,23 @@
       while ((signed) idx < stop)
       {
 	idx++;
-	hb_glyph_info_t &info = c->buffer->info[idx];
-
-	matcher_t::may_skip_t skip = matcher.may_skip (c, info);
-	if (unlikely (skip == matcher_t::SKIP_YES))
-	  continue;
-
-	matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ());
-	if (match == matcher_t::MATCH_YES ||
-	    (match == matcher_t::MATCH_MAYBE &&
-	     skip == matcher_t::SKIP_NO))
+	switch (match (c->buffer->info[idx]))
 	{
-	  num_items--;
-	  advance_glyph_data ();
-	  return true;
+	  case MATCH:
+	  {
+	    num_items--;
+	    advance_glyph_data ();
+	    return true;
+	  }
+	  case NOT_MATCH:
+	  {
+	    if (unsafe_to)
+	      *unsafe_to = idx + 1;
+	    return false;
+	  }
+	  case SKIP:
+	    continue;
 	}
-
-	if (skip == matcher_t::SKIP_NO)
-	{
-	  if (unsafe_to)
-	    *unsafe_to = idx + 1;
-	  return false;
-	}
       }
       if (unsafe_to)
         *unsafe_to = end;
@@ -581,28 +600,23 @@
       while (idx > stop)
       {
 	idx--;
-	hb_glyph_info_t &info = c->buffer->out_info[idx];
-
-	matcher_t::may_skip_t skip = matcher.may_skip (c, info);
-	if (unlikely (skip == matcher_t::SKIP_YES))
-	  continue;
-
-	matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ());
-	if (match == matcher_t::MATCH_YES ||
-	    (match == matcher_t::MATCH_MAYBE &&
-	     skip == matcher_t::SKIP_NO))
+	switch (match (c->buffer->out_info[idx]))
 	{
-	  num_items--;
-	  advance_glyph_data ();
-	  return true;
+	  case MATCH:
+	  {
+	    num_items--;
+	    advance_glyph_data ();
+	    return true;
+	  }
+	  case NOT_MATCH:
+	  {
+	    if (unsafe_from)
+	      *unsafe_from = hb_max (1u, idx) - 1u;
+	    return false;
+	  }
+	  case SKIP:
+	    continue;
 	}
-
-	if (skip == matcher_t::SKIP_NO)
-	{
-	  if (unsafe_from)
-	    *unsafe_from = hb_max (1u, idx) - 1u;
-	  return false;
-	}
       }
       if (unsafe_from)
         *unsafe_from = 0;
@@ -698,6 +712,9 @@
   uint32_t random_state = 1;
   unsigned new_syllables = (unsigned) -1;
 
+  signed last_base = -1; // GPOS uses
+  unsigned last_base_until = 0; // GPOS uses
+
   hb_ot_apply_context_t (unsigned int table_index_,
 			 hb_font_t *font_,
 			 hb_buffer_t *buffer_) :
@@ -736,7 +753,7 @@
     iter_context.init (this, true);
   }
 
-  void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; init_iters (); }
+  void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; last_base = -1; last_base_until = 0; init_iters (); }
   void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
   void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
   void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; init_iters (); }
@@ -944,8 +961,6 @@
     hb_set_digest_t digest;
   };
 
-  typedef hb_vector_t<hb_applicable_t> array_t;
-
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   template <typename T>
   auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () )
@@ -957,18 +972,16 @@
   template <typename T>
   return_t dispatch (const T &obj)
   {
-    hb_applicable_t entry;
+    hb_applicable_t *entry = &array[i++];
 
-    entry.init (obj,
-		apply_to<T>
+    entry->init (obj,
+		 apply_to<T>
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-		, apply_cached_to<T>
-		, cache_func_to<T>
+		 , apply_cached_to<T>
+		 , cache_func_to<T>
 #endif
-		);
+		 );
 
-    array.push (entry);
-
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     /* Cache handling
      *
@@ -979,9 +992,9 @@
      * and we allocate the cache opportunity to the costliest subtable.
      */
     unsigned cost = cache_cost (obj, hb_prioritize);
-    if (cost > cache_user_cost && !array.in_error ())
+    if (cost > cache_user_cost)
     {
-      cache_user_idx = array.length - 1;
+      cache_user_idx = i - 1;
       cache_user_cost = cost;
     }
 #endif
@@ -990,10 +1003,11 @@
   }
   static return_t default_return_value () { return hb_empty_t (); }
 
-  hb_accelerate_subtables_context_t (array_t &array_) :
+  hb_accelerate_subtables_context_t (hb_applicable_t *array_) :
 				     array (array_) {}
 
-  array_t &array;
+  hb_applicable_t *array;
+  unsigned i = 0;
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   unsigned cache_user_idx = (unsigned) -1;
@@ -1538,7 +1552,8 @@
 					     intersected_glyphs_func_t intersected_glyphs_func,
 					     void *cache)
 {
-  hb_set_t *covered_seq_indicies = hb_set_create ();
+  hb_set_t covered_seq_indicies;
+  hb_set_t pos_glyphs;
   for (unsigned int i = 0; i < lookupCount; i++)
   {
     unsigned seqIndex = lookupRecord[i].sequenceIndex;
@@ -1545,11 +1560,11 @@
     if (seqIndex >= inputCount) continue;
 
     bool has_pos_glyphs = false;
-    hb_set_t pos_glyphs;
 
-    if (!hb_set_has (covered_seq_indicies, seqIndex))
+    if (!covered_seq_indicies.has (seqIndex))
     {
       has_pos_glyphs = true;
+      pos_glyphs.clear ();
       if (seqIndex == 0)
       {
         switch (context_format) {
@@ -1578,7 +1593,7 @@
       }
     }
 
-    covered_seq_indicies->add (seqIndex);
+    covered_seq_indicies.add (seqIndex);
     if (has_pos_glyphs) {
       c->push_cur_active_glyphs () = std::move (pos_glyphs);
     } else {
@@ -1589,12 +1604,10 @@
     if (context_format == ContextFormat::CoverageBasedContext)
       endIndex += 1;
 
-    c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex);
+    c->recurse (lookupRecord[i].lookupListIndex, &covered_seq_indicies, seqIndex, endIndex);
 
     c->pop_cur_done_glyphs ();
   }
-
-  hb_set_destroy (covered_seq_indicies);
 }
 
 template <typename context_t>
@@ -1651,7 +1664,7 @@
       if (buffer->have_output)
         c->buffer->sync_so_far ();
       c->buffer->message (c->font,
-			  "recursing to lookup %u at %d",
+			  "recursing to lookup %u at %u",
 			  (unsigned) lookupRecord[i].lookupListIndex,
 			  buffer->idx);
     }
@@ -2224,7 +2237,7 @@
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
     out->format = format;
 
-    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
     hb_sorted_vector_t<hb_codepoint_t> new_coverage;
     + hb_zip (this+coverage, ruleSet)
     | hb_filter (glyphset, hb_first)
@@ -2461,7 +2474,7 @@
     hb_set_t coverage_glyph_classes;
     (this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
 
-    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
     bool ret = true;
     int non_zero_index = -1, index = 0;
     auto snapshot = c->serializer->snapshot();
@@ -2641,7 +2654,7 @@
     }
 
     const auto& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount));
-    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
 
 
     unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (lookupCount), lookup_map);
@@ -2681,8 +2694,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
@@ -3305,7 +3318,7 @@
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
     out->format = format;
 
-    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
     hb_sorted_vector_t<hb_codepoint_t> new_coverage;
     + hb_zip (this+coverage, ruleSet)
     | hb_filter (glyphset, hb_first)
@@ -3541,7 +3554,7 @@
      */
 
     struct ChainContextApplyLookupContext lookup_context = {
-      {{cached && &backtrack_class_def == &input_class_def ? match_class_cached : match_class,
+      {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached : match_class,
         cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class,
         cached ? match_class_cached : match_class}},
       {&backtrack_class_def,
@@ -3585,7 +3598,7 @@
 
     int non_zero_index = -1, index = 0;
     bool ret = true;
-    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
     auto last_non_zero = c->serializer->snapshot ();
     for (const auto& _ : + hb_enumerate (ruleSet)
 			 | hb_filter (input_klass_map, hb_first))
@@ -3827,7 +3840,7 @@
       return_trace (false);
 
     const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
-    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+    const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? &c->plan->gsub_lookups : &c->plan->gpos_lookups;
 
     HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookup.len);
     if (!lookupCount) return_trace (false);
@@ -3875,8 +3888,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
     case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
@@ -3915,8 +3928,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, this))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, format);
-    if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
     return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), std::forward<Ts> (ds)...));
   }
 
@@ -3994,8 +4007,8 @@
   template <typename context_t, typename ...Ts>
   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
     TRACE_DISPATCH (this, u.format);
-    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
     switch (u.format) {
     case 1: return_trace (u.format1.dispatch (c, std::forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
@@ -4017,35 +4030,50 @@
 struct hb_ot_layout_lookup_accelerator_t
 {
   template <typename TLookup>
-  void init (const TLookup &lookup)
+  static hb_ot_layout_lookup_accelerator_t *create (const TLookup &lookup)
   {
-    subtables.init ();
-    hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
+    unsigned count = lookup.get_subtable_count ();
+
+    unsigned size = sizeof (hb_ot_layout_lookup_accelerator_t) -
+		    HB_VAR_ARRAY * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t) +
+		    count * sizeof (hb_accelerate_subtables_context_t::hb_applicable_t);
+
+    /* The following is a calloc because when we are collecting subtables,
+     * some of them might be invalid and hence not collect; as a result,
+     * we might not fill in all the count entries of the subtables array.
+     * Zeroing it allows the set digest to gatekeep it without having to
+     * initialize it further. */
+    auto *thiz = (hb_ot_layout_lookup_accelerator_t *) hb_calloc (1, size);
+    if (unlikely (!thiz))
+      return nullptr;
+
+    hb_accelerate_subtables_context_t c_accelerate_subtables (thiz->subtables);
     lookup.dispatch (&c_accelerate_subtables);
 
-    digest.init ();
-    for (auto& subtable : hb_iter (subtables))
-      digest.add (subtable.digest);
+    thiz->digest.init ();
+    for (auto& subtable : hb_iter (thiz->subtables, count))
+      thiz->digest.add (subtable.digest);
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
-    cache_user_idx = c_accelerate_subtables.cache_user_idx;
-    for (unsigned i = 0; i < subtables.length; i++)
-      if (i != cache_user_idx)
-	subtables[i].apply_cached_func = subtables[i].apply_func;
+    thiz->cache_user_idx = c_accelerate_subtables.cache_user_idx;
+    for (unsigned i = 0; i < count; i++)
+      if (i != thiz->cache_user_idx)
+	thiz->subtables[i].apply_cached_func = thiz->subtables[i].apply_func;
 #endif
+
+    return thiz;
   }
-  void fini () { subtables.fini (); }
 
   bool may_have (hb_codepoint_t g) const
   { return digest.may_have (g); }
 
-  bool apply (hb_ot_apply_context_t *c, bool use_cache) const
+  bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
   {
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
     if (use_cache)
     {
       return
-      + hb_iter (subtables)
+      + hb_iter (hb_iter (subtables, subtables_count))
       | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); })
       | hb_any
       ;
@@ -4054,7 +4082,7 @@
 #endif
     {
       return
-      + hb_iter (subtables)
+      + hb_iter (hb_iter (subtables, subtables_count))
       | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); })
       | hb_any
       ;
@@ -4081,10 +4109,10 @@
 
   hb_set_digest_t digest;
   private:
-  hb_accelerate_subtables_context_t::array_t subtables;
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   unsigned cache_user_idx = (unsigned) -1;
 #endif
+  hb_accelerate_subtables_context_t::hb_applicable_t subtables[HB_VAR_ARRAY];
 };
 
 template <typename Types>
@@ -4142,9 +4170,12 @@
   bool subset (hb_subset_layout_context_t *c) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->subset_context->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
 
+    auto *out = c->subset_context->serializer->start_embed (this);
+    if (unlikely (!c->subset_context->serializer->extend_min (out))) return_trace (false);
+
+    out->version = version;
+
     typedef LookupOffsetList<TLookup, typename Types::HBUINT> TLookupList;
     reinterpret_cast<typename Types::template OffsetTo<TLookupList> &> (out->lookupList)
 	.serialize_subset (c->subset_context,
@@ -4166,9 +4197,23 @@
 #ifndef HB_NO_VAR
     if (version.to_int () >= 0x00010001u)
     {
-      bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c);
+      auto snapshot = c->subset_context->serializer->snapshot ();
+      if (!c->subset_context->serializer->extend_min (&out->featureVars))
+        return_trace (false);
+
+      // TODO(qxliu76): the current implementation doesn't correctly handle feature variations
+      //                that are dropped by instancing when the associated conditions don't trigger.
+      //                Since partial instancing isn't yet supported this isn't an issue yet but will
+      //                need to be fixed for partial instancing.
+
+
+
+      // if all axes are pinned all feature vars are dropped.
+      bool ret = !c->subset_context->plan->all_axes_pinned
+                 && out->featureVars.serialize_subset (c->subset_context, featureVars, this, c);
       if (!ret && version.major == 1)
       {
+        c->subset_context->serializer->revert (snapshot);
 	out->version.major = 1;
 	out->version.minor = 0;
       }
@@ -4430,7 +4475,7 @@
 
       this->lookup_count = table->get_lookup_count ();
 
-      this->accels = (hb_ot_layout_lookup_accelerator_t *) hb_calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t));
+      this->accels = (hb_atomic_ptr_t<hb_ot_layout_lookup_accelerator_t> *) hb_calloc (this->lookup_count, sizeof (*accels));
       if (unlikely (!this->accels))
       {
 	this->lookup_count = 0;
@@ -4437,21 +4482,40 @@
 	this->table.destroy ();
 	this->table = hb_blob_get_empty ();
       }
-
-      for (unsigned int i = 0; i < this->lookup_count; i++)
-	this->accels[i].init (table->get_lookup (i));
     }
     ~accelerator_t ()
     {
       for (unsigned int i = 0; i < this->lookup_count; i++)
-	this->accels[i].fini ();
+	hb_free (this->accels[i]);
       hb_free (this->accels);
       this->table.destroy ();
     }
 
+    hb_ot_layout_lookup_accelerator_t *get_accel (unsigned lookup_index) const
+    {
+      if (unlikely (lookup_index >= lookup_count)) return nullptr;
+
+    retry:
+      auto *accel = accels[lookup_index].get_acquire ();
+      if (unlikely (!accel))
+      {
+	accel = hb_ot_layout_lookup_accelerator_t::create (table->get_lookup (lookup_index));
+	if (unlikely (!accel))
+	  return nullptr;
+
+	if (unlikely (!accels[lookup_index].cmpexch (nullptr, accel)))
+	{
+	  hb_free (accel);
+	  goto retry;
+	}
+      }
+
+      return accel;
+    }
+
     hb_blob_ptr_t<T> table;
     unsigned int lookup_count;
-    hb_ot_layout_lookup_accelerator_t *accels;
+    hb_atomic_ptr_t<hb_ot_layout_lookup_accelerator_t> *accels;
   };
 
   protected:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -500,8 +500,8 @@
  * @face: #hb_face_t to work upon
  * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
  * @script_tags: Array of #hb_tag_t script tags
- * @script_index: (out): The index of the requested script tag
- * @chosen_script: (out): #hb_tag_t of the script tag requested
+ * @script_index: (out): The index of the chosen script
+ * @chosen_script: (out): #hb_tag_t of the chosen script
  *
  * Deprecated since 2.0.0
  **/
@@ -531,8 +531,8 @@
  *
  * If the table does not have any of the requested scripts, then `DFLT`,
  * `dflt`, and `latn` tags are tried in that order. If the table still does not
- * have any of these scripts, @script_index and @chosen_script are set to
- * #HB_OT_LAYOUT_NO_SCRIPT_INDEX.
+ * have any of these scripts, @script_index is set to
+ * #HB_OT_LAYOUT_NO_SCRIPT_INDEX and @chosen_script is set to #HB_TAG_NONE.
  *
  * Return value:
  * `true` if one of the requested scripts is selected, `false` if a fallback
@@ -586,7 +586,7 @@
 
   if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
   if (chosen_script)
-    *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+    *chosen_script = HB_TAG_NONE;
   return false;
 }
 
@@ -727,13 +727,14 @@
 
 
 /**
- * hb_ot_layout_script_select_language:
+ * hb_ot_layout_script_select_language2:
  * @face: #hb_face_t to work upon
  * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
  * @script_index: The index of the requested script tag
  * @language_count: The number of languages in the specified script
  * @language_tags: The array of language tags
- * @language_index: (out): The index of the requested language
+ * @language_index: (out): The index of the chosen language
+ * @chosen_language: (out): #hb_tag_t of the chosen language
  *
  * Fetches the index of the first language tag fom @language_tags that is present
  * in the specified face's GSUB or GPOS table, underneath the specified script
@@ -740,19 +741,21 @@
  * index.
  *
  * If none of the given language tags is found, `false` is returned and
- * @language_index is set to the default language index.
+ * @language_index is set to #HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX and
+ * @chosen_language is set to #HB_TAG_NONE.
  *
  * Return value: `true` if one of the given language tags is found, `false` otherwise
  *
- * Since: 2.0.0
+ * Since: 7.0.0
  **/
 hb_bool_t
-hb_ot_layout_script_select_language (hb_face_t      *face,
+hb_ot_layout_script_select_language2 (hb_face_t      *face,
 				     hb_tag_t        table_tag,
 				     unsigned int    script_index,
 				     unsigned int    language_count,
 				     const hb_tag_t *language_tags,
-				     unsigned int   *language_index /* OUT */)
+				     unsigned int   *language_index /* OUT */,
+				     hb_tag_t       *chosen_language /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), "");
   const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
@@ -761,18 +764,61 @@
   for (i = 0; i < language_count; i++)
   {
     if (s.find_lang_sys_index (language_tags[i], language_index))
+    {
+      if (chosen_language)
+        *chosen_language = language_tags[i];
       return true;
+    }
   }
 
   /* try finding 'dflt' */
   if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
+  {
+    if (chosen_language)
+      *chosen_language = HB_OT_TAG_DEFAULT_LANGUAGE;
     return false;
+  }
 
   if (language_index)
     *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
+  if (chosen_language)
+    *chosen_language = HB_TAG_NONE;
   return false;
 }
 
+/**
+ * hb_ot_layout_script_select_language:
+ * @face: #hb_face_t to work upon
+ * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_count: The number of languages in the specified script
+ * @language_tags: The array of language tags
+ * @language_index: (out): The index of the requested language
+ *
+ * Fetches the index of the first language tag fom @language_tags that is present
+ * in the specified face's GSUB or GPOS table, underneath the specified script
+ * index.
+ *
+ * If none of the given language tags is found, `false` is returned and
+ * @language_index is set to the default language index.
+ *
+ * Return value: `true` if one of the given language tags is found, `false` otherwise
+ *
+ * Since: 2.0.0
+ **/
+hb_bool_t
+hb_ot_layout_script_select_language (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    script_index,
+				     unsigned int    language_count,
+				     const hb_tag_t *language_tags,
+				     unsigned int   *language_index /* OUT */)
+{
+  return hb_ot_layout_script_select_language2 (face, table_tag,
+					       script_index,
+					       language_count, language_tags,
+					       language_index, nullptr);
+}
 
 /**
  * hb_ot_layout_language_get_required_feature_index:
@@ -1441,11 +1487,13 @@
 				      unsigned int          glyphs_length,
 				      hb_bool_t             zero_context)
 {
-  if (unlikely (lookup_index >= face->table.GSUB->lookup_count)) return false;
+  auto &gsub = face->table.GSUB;
+  if (unlikely (lookup_index >= gsub->lookup_count)) return false;
   OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context);
 
-  const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
-  return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]);
+  const OT::SubstLookup& l = gsub->table->get_lookup (lookup_index);
+  auto *accel = gsub->get_accel (lookup_index);
+  return accel && l.would_apply (&c, accel);
 }
 
 
@@ -1784,11 +1832,9 @@
   typedef OT::SubstLookup Lookup;
 
   GSUBProxy (hb_face_t *face) :
-    table (*face->table.GSUB->table),
-    accels (face->table.GSUB->accels) {}
+    accel (*face->table.GSUB) {}
 
-  const GSUB &table;
-  const OT::hb_ot_layout_lookup_accelerator_t *accels;
+  const GSUB::accelerator_t &accel;
 };
 
 struct GPOSProxy
@@ -1798,17 +1844,16 @@
   typedef OT::PosLookup Lookup;
 
   GPOSProxy (hb_face_t *face) :
-    table (*face->table.GPOS->table),
-    accels (face->table.GPOS->accels) {}
+    accel (*face->table.GPOS) {}
 
-  const GPOS &table;
-  const OT::hb_ot_layout_lookup_accelerator_t *accels;
+  const GPOS::accelerator_t &accel;
 };
 
 
 static inline bool
 apply_forward (OT::hb_ot_apply_context_t *c,
-	       const OT::hb_ot_layout_lookup_accelerator_t &accel)
+	       const OT::hb_ot_layout_lookup_accelerator_t &accel,
+	       unsigned subtable_count)
 {
   bool use_cache = accel.cache_enter (c);
 
@@ -1821,7 +1866,7 @@
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
      {
-       applied = accel.apply (c, use_cache);
+       applied = accel.apply (c, subtable_count, use_cache);
      }
 
     if (applied)
@@ -1838,7 +1883,8 @@
 
 static inline bool
 apply_backward (OT::hb_ot_apply_context_t *c,
-	       const OT::hb_ot_layout_lookup_accelerator_t &accel)
+	       const OT::hb_ot_layout_lookup_accelerator_t &accel,
+	       unsigned subtable_count)
 {
   bool ret = false;
   hb_buffer_t *buffer = c->buffer;
@@ -1847,7 +1893,7 @@
     if (accel.digest.may_have (buffer->cur().codepoint) &&
 	(buffer->cur().mask & c->lookup_mask) &&
 	c->check_glyph_property (&buffer->cur(), c->lookup_props))
-     ret |= accel.apply (c, false);
+     ret |= accel.apply (c, subtable_count, false);
 
     /* The reverse lookup doesn't "advance" cursor (for good reason). */
     buffer->idx--;
@@ -1863,12 +1909,14 @@
 	      const typename Proxy::Lookup &lookup,
 	      const OT::hb_ot_layout_lookup_accelerator_t &accel)
 {
-  bool ret = false;
   hb_buffer_t *buffer = c->buffer;
+  unsigned subtable_count = lookup.get_subtable_count ();
 
   if (unlikely (!buffer->len || !c->lookup_mask))
-    return ret;
+    return false;
 
+  bool ret = false;
+
   c->set_lookup_props (lookup.get_props ());
 
   if (likely (!lookup.is_reverse ()))
@@ -1878,7 +1926,7 @@
       buffer->clear_output ();
 
     buffer->idx = 0;
-    ret = apply_forward (c, accel);
+    ret = apply_forward (c, accel, subtable_count);
 
     if (!Proxy::always_inplace)
       buffer->sync ();
@@ -1888,7 +1936,7 @@
     /* in-place backward substitution/positioning */
     assert (!buffer->have_output);
     buffer->idx = buffer->len - 1;
-    ret = apply_backward (c, accel);
+    ret = apply_backward (c, accel, subtable_count);
   }
 
   return ret;
@@ -1913,13 +1961,18 @@
       auto &lookup = lookups[table_index][i];
 
       unsigned int lookup_index = lookup.index;
-      if (!buffer->message (font, "start lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue;
 
+      auto *accel = proxy.accel.get_accel (lookup_index);
+      if (unlikely (!accel)) continue;
+
+      if (buffer->messaging () &&
+	  !buffer->message (font, "start lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag))) continue;
+
       /* c.digest is a digest of all the current glyphs in the buffer
        * (plus some past glyphs).
        *
        * Only try applying the lookup if there is any overlap. */
-      if (proxy.accels[lookup_index].digest.may_have (c.digest))
+      if (accel->digest.may_have (c.digest))
       {
 	c.set_lookup_index (lookup_index);
 	c.set_lookup_mask (lookup.mask);
@@ -1929,13 +1982,14 @@
 	c.set_per_syllable (lookup.per_syllable);
 
 	apply_string<Proxy> (&c,
-			     proxy.table.get_lookup (lookup_index),
-			     proxy.accels[lookup_index]);
+			     proxy.accel.table->get_lookup (lookup_index),
+			     *accel);
       }
-      else
-	(void) buffer->message (font, "skipped lookup %d feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag));
+      else if (buffer->messaging ())
+	(void) buffer->message (font, "skipped lookup %u feature '%c%c%c%c' because no glyph matches", lookup_index, HB_UNTAG (lookup.feature_tag));
 
-      (void) buffer->message (font, "end lookup %d feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag));
+      if (buffer->messaging ())
+	(void) buffer->message (font, "end lookup %u feature '%c%c%c%c'", lookup_index, HB_UNTAG (lookup.feature_tag));
     }
 
     if (stage->pause_func)
@@ -1952,17 +2006,21 @@
 void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
 {
   GSUBProxy proxy (font->face);
-  if (!buffer->message (font, "start table GSUB")) return;
+  if (buffer->messaging () &&
+      !buffer->message (font, "start table GSUB")) return;
   apply (proxy, plan, font, buffer);
-  (void) buffer->message (font, "end table GSUB");
+  if (buffer->messaging ())
+    (void) buffer->message (font, "end table GSUB");
 }
 
 void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
 {
   GPOSProxy proxy (font->face);
-  if (!buffer->message (font, "start table GPOS")) return;
+  if (buffer->messaging () &&
+      !buffer->message (font, "start table GPOS")) return;
   apply (proxy, plan, font, buffer);
-  (void) buffer->message (font, "end table GPOS");
+  if (buffer->messaging ())
+    (void) buffer->message (font, "end table GPOS");
 }
 
 void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -255,6 +255,15 @@
 				     unsigned int   *language_index /* OUT */);
 
 HB_EXTERN hb_bool_t
+hb_ot_layout_script_select_language2 (hb_face_t      *face,
+				     hb_tag_t        table_tag,
+				     unsigned int    script_index,
+				     unsigned int    language_count,
+				     const hb_tag_t *language_tags,
+				     unsigned int   *language_index /* OUT */,
+				     hb_tag_t       *chosen_language /* OUT */);
+
+HB_EXTERN hb_bool_t
 hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
 						  hb_tag_t      table_tag,
 						  unsigned int  script_index,

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -201,7 +201,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_set_t &glyphset = c->plan->_glyphset_mathed;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);
@@ -254,7 +254,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_set_t &glyphset = c->plan->_glyphset_mathed;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);
@@ -486,7 +486,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_set_t &glyphset = c->plan->_glyphset_mathed;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);
@@ -567,7 +567,7 @@
     out->mathItalicsCorrectionInfo.serialize_subset (c, mathItalicsCorrectionInfo, this);
     out->mathTopAccentAttachment.serialize_subset (c, mathTopAccentAttachment, this);
 
-    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_set_t &glyphset = c->plan->_glyphset_mathed;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto it =
@@ -938,7 +938,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
+    const hb_set_t &glyphset = c->plan->_glyphset_mathed;
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-maxp-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -109,11 +109,24 @@
 
       if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
 	drop_hint_fields (dest_v1);
+
+      if (c->plan->normalized_coords)
+        instancing_update_fields (c->plan->head_maxp_info, dest_v1);
     }
 
     return_trace (true);
   }
 
+  void instancing_update_fields (head_maxp_info_t& maxp_info, maxpV1Tail* dest_v1) const
+  {
+    dest_v1->maxPoints = maxp_info.maxPoints;
+    dest_v1->maxContours = maxp_info.maxContours;
+    dest_v1->maxCompositePoints = maxp_info.maxCompositePoints;
+    dest_v1->maxCompositeContours = maxp_info.maxCompositeContours;
+    dest_v1->maxComponentElements = maxp_info.maxComponentElements;
+    dest_v1->maxComponentDepth = maxp_info.maxComponentDepth;
+  }
+
   static void drop_hint_fields (maxpV1Tail* dest_v1)
   {
     dest_v1->maxZones = 1;

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -27,569 +27,6 @@
 #ifndef HB_OT_NAME_TABLE_HH
 #define HB_OT_NAME_TABLE_HH
 
-#include "hb-open-type.hh"
-#include "hb-ot-name-language.hh"
-#include "hb-aat-layout.hh"
-#include "hb-utf.hh"
+#include "OT/name/name.hh"
 
-
-namespace OT {
-
-template <typename in_utf_t, typename out_utf_t>
-inline unsigned int
-hb_ot_name_convert_utf (hb_bytes_t                       bytes,
-			unsigned int                    *text_size /* IN/OUT */,
-			typename out_utf_t::codepoint_t *text /* OUT */)
-{
-  unsigned int src_len = bytes.length / sizeof (typename in_utf_t::codepoint_t);
-  const typename in_utf_t::codepoint_t *src = (const typename in_utf_t::codepoint_t *) bytes.arrayZ;
-  const typename in_utf_t::codepoint_t *src_end = src + src_len;
-
-  typename out_utf_t::codepoint_t *dst = text;
-
-  hb_codepoint_t unicode;
-  const hb_codepoint_t replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
-
-  if (text_size && *text_size)
-  {
-    (*text_size)--; /* Save room for NUL-termination. */
-    const typename out_utf_t::codepoint_t *dst_end = text + *text_size;
-
-    while (src < src_end && dst < dst_end)
-    {
-      const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
-      typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
-      if (dst_next == dst)
-	break; /* Out-of-room. */
-
-      dst = dst_next;
-      src = src_next;
-    }
-
-    *text_size = dst - text;
-    *dst = 0; /* NUL-terminate. */
-  }
-
-  /* Accumulate length of rest. */
-  unsigned int dst_len = dst - text;
-  while (src < src_end)
-  {
-    src = in_utf_t::next (src, src_end, &unicode, replacement);
-    dst_len += out_utf_t::encode_len (unicode);
-  }
-  return dst_len;
-}
-
-#define entry_score var.u16[0]
-#define entry_index var.u16[1]
-
-
-/*
- * name -- Naming
- * https://docs.microsoft.com/en-us/typography/opentype/spec/name
- */
-#define HB_OT_TAG_name HB_TAG('n','a','m','e')
-
-#define UNSUPPORTED	42
-
-struct NameRecord
-{
-  hb_language_t language (hb_face_t *face) const
-  {
-#ifndef HB_NO_OT_NAME_LANGUAGE
-    unsigned int p = platformID;
-    unsigned int l = languageID;
-
-    if (p == 3)
-      return _hb_ot_name_language_for_ms_code (l);
-
-    if (p == 1)
-      return _hb_ot_name_language_for_mac_code (l);
-
-#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
-    if (p == 0)
-      return face->table.ltag->get_language (l);
-#endif
-
-#endif
-    return HB_LANGUAGE_INVALID;
-  }
-
-  uint16_t score () const
-  {
-    /* Same order as in cmap::find_best_subtable(). */
-    unsigned int p = platformID;
-    unsigned int e = encodingID;
-
-    /* 32-bit. */
-    if (p == 3 && e == 10) return 0;
-    if (p == 0 && e ==  6) return 1;
-    if (p == 0 && e ==  4) return 2;
-
-    /* 16-bit. */
-    if (p == 3 && e ==  1) return 3;
-    if (p == 0 && e ==  3) return 4;
-    if (p == 0 && e ==  2) return 5;
-    if (p == 0 && e ==  1) return 6;
-    if (p == 0 && e ==  0) return 7;
-
-    /* Symbol. */
-    if (p == 3 && e ==  0) return 8;
-
-    /* We treat all Mac Latin names as ASCII only. */
-    if (p == 1 && e ==  0) return 10; /* 10 is magic number :| */
-
-    return UNSUPPORTED;
-  }
-
-  NameRecord* copy (hb_serialize_context_t *c, const void *base
-#ifdef HB_EXPERIMENTAL_API
-                    , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
-#endif
-		    ) const
-  {
-    TRACE_SERIALIZE (this);
-    HB_UNUSED auto snap = c->snapshot ();
-    auto *out = c->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
-#ifdef HB_EXPERIMENTAL_API
-    hb_ot_name_record_ids_t record_ids (platformID, encodingID, languageID, nameID);
-    hb_bytes_t* name_bytes;
-
-    if (name_table_overrides->has (record_ids, &name_bytes)) {
-      hb_bytes_t encoded_bytes = *name_bytes;
-      char *name_str_utf16_be = nullptr;
-
-      if (platformID != 1)
-      {
-        unsigned text_size = hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, nullptr, nullptr);
-  
-        text_size++; // needs to consider NULL terminator for use in hb_ot_name_convert_utf()
-        unsigned byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
-        name_str_utf16_be = (char *) hb_calloc (byte_len, 1);
-        if (!name_str_utf16_be)
-        {
-          c->revert (snap);
-          return_trace (nullptr);
-        }
-        hb_ot_name_convert_utf<hb_utf8_t, hb_utf16_be_t> (*name_bytes, &text_size,
-                                                          (hb_utf16_be_t::codepoint_t *) name_str_utf16_be);
-  
-        unsigned encoded_byte_len = text_size * hb_utf16_be_t::codepoint_t::static_size;
-        if (!encoded_byte_len || !c->check_assign (out->length, encoded_byte_len, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
-          c->revert (snap);
-          hb_free (name_str_utf16_be);
-          return_trace (nullptr);
-        }
-  
-        encoded_bytes = hb_bytes_t (name_str_utf16_be, encoded_byte_len);
-      }
-      else
-      {
-        // mac platform, copy the UTF-8 string(all ascii characters) as is
-        if (!c->check_assign (out->length, encoded_bytes.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) {
-          c->revert (snap);
-          return_trace (nullptr);
-        }
-      }
-
-      out->offset = 0;
-      c->push ();
-      encoded_bytes.copy (c);
-      c->add_link (out->offset, c->pop_pack (), hb_serialize_context_t::Tail, 0);
-      hb_free (name_str_utf16_be);
-    }
-    else
-#endif
-    {
-      out->offset.serialize_copy (c, offset, base, 0, hb_serialize_context_t::Tail, length);
-    }
-    return_trace (out);
-  }
-
-  bool isUnicode () const
-  {
-    unsigned int p = platformID;
-    unsigned int e = encodingID;
-
-    return (p == 0 ||
-	    (p == 3 && (e == 0 || e == 1 || e == 10)));
-  }
-
-  static int cmp (const void *pa, const void *pb)
-  {
-    const NameRecord *a = (const NameRecord *)pa;
-    const NameRecord *b = (const NameRecord *)pb;
-
-    if (a->platformID != b->platformID)
-      return a->platformID - b->platformID;
-
-    if (a->encodingID != b->encodingID)
-      return a->encodingID - b->encodingID;
-
-    if (a->languageID != b->languageID)
-      return a->languageID - b->languageID;
-
-    if (a->nameID != b->nameID)
-      return a->nameID - b->nameID;
-
-    if (a->length != b->length)
-      return a->length - b->length;
-
-    return 0;
-  }
-
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
-  }
-
-  HBUINT16	platformID;	/* Platform ID. */
-  HBUINT16	encodingID;	/* Platform-specific encoding ID. */
-  HBUINT16	languageID;	/* Language ID. */
-  HBUINT16	nameID;		/* Name ID. */
-  HBUINT16	length;		/* String length (in bytes). */
-  NNOffset16To<UnsizedArrayOf<HBUINT8>>
-		offset;		/* String offset from start of storage area (in bytes). */
-  public:
-  DEFINE_SIZE_STATIC (12);
-};
-
-static int
-_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
-{
-  const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
-  const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
-
-  /* Compare by name_id, then language. */
-
-  if (a->name_id != b->name_id)
-    return a->name_id - b->name_id;
-
-  if (a->language == b->language) return 0;
-  if (!a->language) return -1;
-  if (!b->language) return +1;
-
-  const char *astr = hb_language_to_string (a->language);
-  const char *bstr = hb_language_to_string (b->language);
-
-  signed c = strcmp (astr, bstr);
-
-  // 'a' is the user request, and 'b' is string in the font.
-  // If eg. user asks for "en-us" and font has "en", approve.
-  if (!exact && c &&
-      hb_language_matches (b->language, a->language))
-    return 0;
-
-  return c;
-}
-
-static int
-_hb_ot_name_entry_cmp (const void *pa, const void *pb)
-{
-  /* Compare by name_id, then language, then score, then index. */
-
-  int v = _hb_ot_name_entry_cmp_key (pa, pb, true);
-  if (v)
-    return v;
-
-  const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
-  const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
-
-  if (a->entry_score != b->entry_score)
-    return a->entry_score - b->entry_score;
-
-  if (a->entry_index != b->entry_index)
-    return a->entry_index - b->entry_index;
-
-  return 0;
-}
-
-struct name
-{
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_name;
-
-  unsigned int get_size () const
-  { return min_size + count * nameRecordZ.item_size; }
-
-  template <typename Iterator,
-	    hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
-  bool serialize (hb_serialize_context_t *c,
-		  Iterator it,
-		  const void *src_string_pool
-#ifdef HB_EXPERIMENTAL_API
-                  , const hb_vector_t<hb_ot_name_record_ids_t>& insert_name_records
-		  , const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides
-#endif
-		  )
-  {
-    TRACE_SERIALIZE (this);
-
-    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
-
-    unsigned total_count = it.len ()
-#ifdef HB_EXPERIMENTAL_API
-        + insert_name_records.length
-#endif
-        ;
-    this->format = 0;
-    if (!c->check_assign (this->count, total_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
-      return false;
-
-    NameRecord *name_records = (NameRecord *) hb_calloc (total_count, NameRecord::static_size);
-    if (unlikely (!name_records)) return_trace (false);
-
-    hb_array_t<NameRecord> records (name_records, total_count);
-
-    for (const NameRecord& record : it)
-    {
-      hb_memcpy (name_records, &record, NameRecord::static_size);
-      name_records++;
-    }
-
-#ifdef HB_EXPERIMENTAL_API
-    for (unsigned i = 0; i < insert_name_records.length; i++)
-    {
-      const hb_ot_name_record_ids_t& ids = insert_name_records[i];
-      NameRecord record;
-      record.platformID = ids.platform_id;
-      record.encodingID = ids.encoding_id;
-      record.languageID = ids.language_id;
-      record.nameID = ids.name_id;
-      record.length = 0; // handled in NameRecord copy()
-      record.offset = 0;
-      memcpy (name_records, &record, NameRecord::static_size);
-      name_records++;
-    }
-#endif
-
-    records.qsort ();
-
-    c->copy_all (records,
-		 src_string_pool
-#ifdef HB_EXPERIMENTAL_API
-		 , name_table_overrides
-#endif
-		 );
-    hb_free (records.arrayZ);
-
-
-    if (unlikely (c->ran_out_of_room ())) return_trace (false);
-
-    this->stringOffset = c->length ();
-
-    return_trace (true);
-  }
-
-  bool subset (hb_subset_context_t *c) const
-  {
-    TRACE_SUBSET (this);
-
-    name *name_prime = c->serializer->start_embed<name> ();
-    if (unlikely (!name_prime)) return_trace (false);
-
-#ifdef HB_EXPERIMENTAL_API
-    const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
-        c->plan->name_table_overrides;
-#endif
-    
-    auto it =
-    + nameRecordZ.as_array (count)
-    | hb_filter (c->plan->name_ids, &NameRecord::nameID)
-    | hb_filter (c->plan->name_languages, &NameRecord::languageID)
-    | hb_filter ([&] (const NameRecord& namerecord) {
-      return
-          (c->plan->flags & HB_SUBSET_FLAGS_NAME_LEGACY)
-          || namerecord.isUnicode ();
-    })
-#ifdef HB_EXPERIMENTAL_API
-    | hb_filter ([&] (const NameRecord& namerecord) {
-      if (name_table_overrides->is_empty ())
-        return true;
-      hb_ot_name_record_ids_t rec_ids (namerecord.platformID,
-                                       namerecord.encodingID,
-                                       namerecord.languageID,
-                                       namerecord.nameID);
-
-      hb_bytes_t *p;
-      if (name_table_overrides->has (rec_ids, &p) &&
-          (*p).length == 0)
-        return false;
-      return true;
-    })
-#endif
-    ;
-
-#ifdef HB_EXPERIMENTAL_API
-    hb_vector_t<hb_ot_name_record_ids_t> insert_name_records;
-    if (!name_table_overrides->is_empty ())
-    {
-      if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population ())))
-        return_trace (false);
-      for (const auto& record_ids : name_table_overrides->keys ())
-      {
-        if (name_table_overrides->get (record_ids).length == 0)
-          continue;
-        if (has_name_record_with_ids (record_ids))
-          continue;
-        insert_name_records.push (record_ids);
-      }
-    }
-#endif
-
-    return (name_prime->serialize (c->serializer, it,
-                                   std::addressof (this + stringOffset)
-#ifdef HB_EXPERIMENTAL_API
-                                   , insert_name_records
-                                   , name_table_overrides
-#endif
-                                   ));
-  }
-
-  bool sanitize_records (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    const void *string_pool = (this+stringOffset).arrayZ;
-    return_trace (nameRecordZ.sanitize (c, count, string_pool));
-  }
-
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  likely (format == 0 || format == 1) &&
-		  c->check_array (nameRecordZ.arrayZ, count) &&
-		  c->check_range (this, stringOffset) &&
-		  sanitize_records (c));
-  }
-
-  struct accelerator_t
-  {
-    accelerator_t (hb_face_t *face)
-    {
-      this->table = hb_sanitize_context_t ().reference_table<name> (face);
-      assert (this->table.get_length () >= this->table->stringOffset);
-      this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
-      this->pool_len = this->table.get_length () - this->table->stringOffset;
-      const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
-						    this->table->count);
-
-      this->names.alloc (all_names.length);
-
-      for (unsigned int i = 0; i < all_names.length; i++)
-      {
-	hb_ot_name_entry_t *entry = this->names.push ();
-
-	entry->name_id = all_names[i].nameID;
-	entry->language = all_names[i].language (face);
-	entry->entry_score =  all_names[i].score ();
-	entry->entry_index = i;
-      }
-
-      this->names.qsort (_hb_ot_name_entry_cmp);
-      /* Walk and pick best only for each name_id,language pair,
-       * while dropping unsupported encodings. */
-      unsigned int j = 0;
-      for (unsigned int i = 0; i < this->names.length; i++)
-      {
-	if (this->names[i].entry_score == UNSUPPORTED ||
-	    this->names[i].language == HB_LANGUAGE_INVALID)
-	  continue;
-	if (i &&
-	    this->names[i - 1].name_id  == this->names[i].name_id &&
-	    this->names[i - 1].language == this->names[i].language)
-	  continue;
-	this->names[j++] = this->names[i];
-      }
-      this->names.resize (j);
-    }
-    ~accelerator_t ()
-    {
-      this->table.destroy ();
-    }
-
-    int get_index (hb_ot_name_id_t  name_id,
-		   hb_language_t    language,
-		   unsigned int    *width=nullptr) const
-    {
-      const hb_ot_name_entry_t key = {name_id, {0}, language};
-      const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
-						    this->names.length,
-						    sizeof (hb_ot_name_entry_t),
-						    _hb_ot_name_entry_cmp_key,
-						    true);
-
-      if (!entry)
-      {
-	entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
-			    this->names.length,
-			    sizeof (hb_ot_name_entry_t),
-			    _hb_ot_name_entry_cmp_key,
-			    false);
-      }
-
-      if (!entry)
-	return -1;
-
-      if (width)
-	*width = entry->entry_score < 10 ? 2 : 1;
-
-      return entry->entry_index;
-    }
-
-    hb_bytes_t get_name (unsigned int idx) const
-    {
-      const hb_array_t<const NameRecord> all_names (table->nameRecordZ.arrayZ, table->count);
-      const NameRecord &record = all_names[idx];
-      const hb_bytes_t string_pool (pool, pool_len);
-      return string_pool.sub_array (record.offset, record.length);
-    }
-
-    private:
-    const char *pool;
-    unsigned int pool_len;
-    public:
-    hb_blob_ptr_t<name> table;
-    hb_vector_t<hb_ot_name_entry_t> names;
-  };
-
-  private:
-  // sometimes NameRecords are not sorted in the font file, so use linear search
-  // here
-  bool has_name_record_with_ids (const hb_ot_name_record_ids_t& record_ids) const
-  {
-    for (const auto& record : nameRecordZ.as_array (count))
-    {
-      if (record.platformID == record_ids.platform_id &&
-          record.encodingID == record_ids.encoding_id &&
-          record.languageID == record_ids.language_id &&
-          record.nameID == record_ids.name_id)
-        return true;
-    }
-    return false;
-  }
-
-  public:
-  /* We only implement format 0 for now. */
-  HBUINT16	format;		/* Format selector (=0/1). */
-  HBUINT16	count;		/* Number of name records. */
-  NNOffset16To<UnsizedArrayOf<HBUINT8>>
-		stringOffset;	/* Offset to start of string storage (from start of table). */
-  UnsizedArrayOf<NameRecord>
-		nameRecordZ;	/* The name records where count is the number of records. */
-  public:
-  DEFINE_SIZE_ARRAY (6, nameRecordZ);
-};
-
-#undef entry_index
-#undef entry_score
-
-struct name_accelerator_t : name::accelerator_t {
-  name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
-};
-
-} /* namespace OT */
-
-
 #endif /* HB_OT_NAME_TABLE_HH */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -181,4 +181,6 @@
   return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
 }
 
+#include "hb-ot-name-language-static.hh"
+
 #endif

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.h	2023-02-12 04:02:23 UTC (rev 65798)
@@ -33,9 +33,8 @@
 
 HB_BEGIN_DECLS
 
-
 /**
- * hb_ot_name_id_t:
+ * hb_ot_name_id_predefined_t:
  * @HB_OT_NAME_ID_COPYRIGHT: Copyright notice
  * @HB_OT_NAME_ID_FONT_FAMILY: Font Family name
  * @HB_OT_NAME_ID_FONT_SUBFAMILY: Font Subfamily name
@@ -65,16 +64,14 @@
  * @HB_OT_NAME_ID_VARIATIONS_PS_PREFIX: Variations PostScript Name Prefix
  * @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID.
  *
- * An integral type representing an OpenType 'name' table name identifier.
- * There are predefined name IDs, as well as name IDs return from other
- * API.  These can be used to fetch name strings from a font face.
+ * An enum type representing the pre-defined name IDs.
  *
  * For more information on these fields, see the
  * [OpenType spec](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids).
  *
- * Since: 2.0.0
+ * Since: 7.0.0
  **/
-enum
+typedef enum
 {
   HB_OT_NAME_ID_COPYRIGHT		= 0,
   HB_OT_NAME_ID_FONT_FAMILY		= 1,
@@ -104,8 +101,17 @@
   HB_OT_NAME_ID_VARIATIONS_PS_PREFIX	= 25,
 
   HB_OT_NAME_ID_INVALID			= 0xFFFF
-};
+} hb_ot_name_id_predefined_t;
 
+/**
+ * hb_ot_name_id_t:
+ *
+ * An integral type representing an OpenType 'name' table name identifier.
+ * There are predefined name IDs, as well as name IDs return from other
+ * API.  These can be used to fetch name strings from a font face.
+ *
+ * Since: 2.0.0
+ **/
 typedef unsigned int hb_ot_name_id_t;
 
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -30,6 +30,7 @@
 
 #include "hb-open-type.hh"
 #include "hb-ot-os2-unicode-ranges.hh"
+#include "hb-ot-var-mvar-table.hh"
 
 #include "hb-set.hh"
 
@@ -62,6 +63,7 @@
   bool has_data () const { return sxHeight || sCapHeight; }
 
   const OS2V2Tail * operator -> () const { return this; }
+  OS2V2Tail * operator -> () { return this; }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -213,10 +215,41 @@
     OS2 *os2_prime = c->serializer->embed (this);
     if (unlikely (!os2_prime)) return_trace (false);
 
-    if (c->plan->user_axes_location->has (HB_TAG ('w','g','h','t')) &&
+#ifndef HB_NO_VAR
+    if (c->plan->normalized_coords)
+    {
+      auto &MVAR = *c->plan->source->table.MVAR;
+      auto *table = os2_prime;
+
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER,         sTypoAscender);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER,        sTypoDescender);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP,         sTypoLineGap);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT,  usWinAscent);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT, usWinDescent);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE,         ySubscriptXSize);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE,         ySubscriptYSize);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET,       ySubscriptXOffset);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET,       ySubscriptYOffset);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE,       ySuperscriptXSize);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE,       ySuperscriptYSize);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET,     ySuperscriptXOffset);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET,     ySuperscriptYOffset);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_STRIKEOUT_SIZE,              yStrikeoutSize);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_STRIKEOUT_OFFSET,            yStrikeoutPosition);
+
+      if (os2_prime->version >= 2)
+      {
+        auto *table = & const_cast<OS2V2Tail &> (os2_prime->v2 ());
+        HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_X_HEIGHT,                   sxHeight);
+        HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_CAP_HEIGHT,                 sCapHeight);
+      }
+    }
+#endif
+
+    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) &&
         !c->plan->pinned_at_default)
     {
-      float weight_class = c->plan->user_axes_location->get (HB_TAG ('w','g','h','t'));
+      float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t'));
       if (!c->serializer->check_assign (os2_prime->usWeightClass,
                                         roundf (hb_clamp (weight_class, 1.0f, 1000.0f)),
                                         HB_SERIALIZE_ERROR_INT_OVERFLOW))
@@ -223,10 +256,10 @@
         return_trace (false);
     }
 
-    if (c->plan->user_axes_location->has (HB_TAG ('w','d','t','h')) &&
+    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) &&
         !c->plan->pinned_at_default)
     {
-      float width = c->plan->user_axes_location->get (HB_TAG ('w','d','t','h'));
+      float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h'));
       if (!c->serializer->check_assign (os2_prime->usWidthClass,
                                         roundf (map_wdth_to_widthclass (width)),
                                         HB_SERIALIZE_ERROR_INT_OVERFLOW))
@@ -236,14 +269,10 @@
     if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
       return_trace (true);
 
-    /* when --gids option is not used, no need to do collect_mapping that is
-       * iterating all codepoints in each subtable, which is not efficient */
-    uint16_t min_cp, max_cp;
-    find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
-    os2_prime->usFirstCharIndex = min_cp;
-    os2_prime->usLastCharIndex = max_cp;
+    os2_prime->usFirstCharIndex = hb_min (0xFFFFu, c->plan->unicodes.get_min ());
+    os2_prime->usLastCharIndex  = hb_min (0xFFFFu, c->plan->unicodes.get_max ());
 
-    _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
+    _update_unicode_ranges (&c->plan->unicodes, os2_prime->ulUnicodeRange);
 
     return_trace (true);
   }
@@ -251,12 +280,16 @@
   void _update_unicode_ranges (const hb_set_t *codepoints,
 			       HBUINT32 ulUnicodeRange[4]) const
   {
-    HBUINT32	newBits[4];
+    HBUINT32 newBits[4];
     for (unsigned int i = 0; i < 4; i++)
       newBits[i] = 0;
 
-    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
-    while (codepoints->next (&cp)) {
+    /* This block doesn't show up in profiles. If it ever did,
+     * we can rewrite it to iterate over OS/2 ranges and use
+     * set iteration to check if the range matches. */
+    for (hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+	 codepoints->next (&cp);)
+    {
       unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
       if (bit < 128)
       {
@@ -278,14 +311,6 @@
       ulUnicodeRange[i] = ulUnicodeRange[i] & newBits[i]; // set bits only if set in the original
   }
 
-  static void find_min_and_max_codepoint (const hb_set_t *codepoints,
-					  uint16_t *min_cp, /* OUT */
-					  uint16_t *max_cp  /* OUT */)
-  {
-    *min_cp = hb_min (0xFFFFu, codepoints->get_min ());
-    *max_cp = hb_min (0xFFFFu, codepoints->get_max ());
-  }
-
   /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
    * https://docs.microsoft.com/en-us/typography/legacy/legacy_arabic_fonts */
   enum font_page_t

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-unicode-ranges.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -34,10 +34,10 @@
 struct OS2Range
 {
   int cmp (hb_codepoint_t key) const
-  { return (key < start) ? -1 : key <= end ? 0 : +1; }
+  { return (key < first) ? -1 : key <= last ? 0 : +1; }
 
-  hb_codepoint_t start;
-  hb_codepoint_t end;
+  hb_codepoint_t first;
+  hb_codepoint_t last;
   unsigned int bit;
 };
 
@@ -223,7 +223,7 @@
 _hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
 {
   auto *range = hb_sorted_array (_hb_os2_unicode_ranges).bsearch (cp);
-  return range ? range->bit : -1;
+  return range ? range->bit : (unsigned) -1;
 }
 
 } /* namespace OT */

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -28,6 +28,7 @@
 #define HB_OT_POST_TABLE_HH
 
 #include "hb-open-type.hh"
+#include "hb-ot-var-mvar-table.hh"
 
 #define HB_STRING_ARRAY_NAME format1_names
 #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
@@ -98,14 +99,25 @@
     post *post_prime = c->serializer->start_embed<post> ();
     if (unlikely (!post_prime)) return_trace (false);
 
+#ifndef HB_NO_VAR
+    if (c->plan->normalized_coords)
+    {
+      auto &MVAR = *c->plan->source->table.MVAR;
+      auto *table = post_prime;
+
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_UNDERLINE_SIZE,   underlineThickness);
+      HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_UNDERLINE_OFFSET, underlinePosition);
+    }
+#endif
+
     bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
     if (!serialize (c->serializer, glyph_names))
       return_trace (false);
 
-    if (c->plan->user_axes_location->has (HB_TAG ('s','l','n','t')) &&
+    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) &&
         !c->plan->pinned_at_default)
     {
-      float italic_angle = c->plan->user_axes_location->get (HB_TAG ('s','l','n','t'));
+      float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t'));
       italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f));
       post_prime->italicAngle.set_float (italic_angle);
     }
@@ -134,6 +146,7 @@
       pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
 
       const uint8_t *end = (const uint8_t *) (const void *) table + table_length;
+      index_to_offset.alloc (hb_min (face->get_num_glyphs (), table_length / 8));
       for (const uint8_t *data = pool;
 	   index_to_offset.length < 65535 && data < end && data + *data < end;
 	   data += 1 + *data)

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -80,8 +80,7 @@
 					      const hb_segment_properties_t &props) :
 						face (face),
 						props (props),
-						map (face, props),
-						aat_map (face, props)
+						map (face, props)
 #ifndef HB_NO_AAT_SHAPE
 						, apply_morx (_hb_apply_morx (face, props))
 #endif
@@ -105,10 +104,6 @@
   plan.props = props;
   plan.shaper = shaper;
   map.compile (plan.map, key);
-#ifndef HB_NO_AAT_SHAPE
-  if (apply_morx)
-    aat_map.compile (plan.aat_map);
-#endif
 
 #ifndef HB_NO_OT_SHAPE_FRACTIONS
   plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
@@ -222,9 +217,6 @@
 			   const hb_shape_plan_key_t     *key)
 {
   map.init ();
-#ifndef HB_NO_AAT_SHAPE
-  aat_map.init ();
-#endif
 
   hb_ot_shape_planner_t planner (face,
 				 key->props);
@@ -241,9 +233,6 @@
     if (unlikely (!data))
     {
       map.fini ();
-#ifndef HB_NO_AAT_SHAPE
-      aat_map.fini ();
-#endif
       return false;
     }
   }
@@ -258,9 +247,6 @@
     shaper->data_destroy (const_cast<void *> (data));
 
   map.fini ();
-#ifndef HB_NO_AAT_SHAPE
-  aat_map.fini ();
-#endif
 }
 
 void
@@ -267,12 +253,7 @@
 hb_ot_shape_plan_t::substitute (hb_font_t   *font,
 				hb_buffer_t *buffer) const
 {
-#ifndef HB_NO_AAT_SHAPE
-  if (unlikely (apply_morx))
-    hb_aat_layout_substitute (this, font, buffer);
-  else
-#endif
-    map.substitute (this, font, buffer);
+  map.substitute (this, font, buffer);
 }
 
 void
@@ -406,18 +387,6 @@
 		      feature->value);
   }
 
-#ifndef HB_NO_AAT_SHAPE
-  if (planner->apply_morx)
-  {
-    hb_aat_map_builder_t *aat_map = &planner->aat_map;
-    for (unsigned int i = 0; i < num_user_features; i++)
-    {
-      const hb_feature_t *feature = &user_features[i];
-      aat_map->add_feature (feature->tag, feature->value);
-    }
-  }
-#endif
-
   if (planner->shaper->override_features)
     planner->shaper->override_features (planner);
 }
@@ -940,7 +909,13 @@
   if (c->plan->fallback_glyph_classes)
     hb_synthesize_glyph_classes (c->buffer);
 
-  c->plan->substitute (c->font, buffer);
+#ifndef HB_NO_AAT_SHAPE
+  if (unlikely (c->plan->apply_morx))
+    hb_aat_layout_substitute (c->plan, c->font, c->buffer,
+			      c->user_features, c->num_user_features);
+  else
+#endif
+    c->plan->substitute (c->font, buffer);
 }
 
 static inline void

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -65,7 +65,6 @@
   hb_segment_properties_t props;
   const struct hb_ot_shaper_t *shaper;
   hb_ot_map_t map;
-  hb_aat_map_t aat_map;
   const void *data;
 #ifndef HB_NO_OT_SHAPE_FRACTIONS
   hb_mask_t frac_mask, numr_mask, dnom_mask;
@@ -152,7 +151,6 @@
   hb_face_t *face;
   hb_segment_properties_t props;
   hb_ot_map_builder_t map;
-  hb_aat_map_builder_t aat_map;
 #ifndef HB_NO_AAT_SHAPE
   bool apply_morx : 1;
 #else

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic-fallback.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -154,16 +154,22 @@
       const auto &components = ligature_table[first_glyph_idx].ligatures[ligature_idx].components;
       unsigned component_count = ARRAY_LENGTH_CONST (components);
 
-      for (unsigned i = 0; i < component_count; i++)
+      bool matched = true;
+      for (unsigned j = 0; j < component_count; j++)
       {
-	hb_codepoint_t component_u   = ligature_table[first_glyph_idx].ligatures[ligature_idx].components[i];
+	hb_codepoint_t component_u   = ligature_table[first_glyph_idx].ligatures[ligature_idx].components[j];
 	hb_codepoint_t component_glyph;
 	if (!component_u ||
-	    !hb_font_get_glyph (font, component_u,   0, &component_glyph))
-	  continue;
+	    !hb_font_get_nominal_glyph (font, component_u, &component_glyph))
+	{
+	  matched = false;
+	  break;
+	}
 
 	component_list[num_components++] = component_glyph;
       }
+      if (!matched)
+        continue;
 
       component_count_list[num_ligatures] = 1 + component_count;
       ligature_list[num_ligatures] = ligature_glyph;
@@ -222,7 +228,7 @@
 
   hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
   OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
-  OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
+  OT::hb_ot_layout_lookup_accelerator_t *accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
 };
 
 #if defined(_WIN32) && !defined(HB_NO_WIN1256)
@@ -272,7 +278,7 @@
       fallback_plan->lookup_array[j] = const_cast<OT::SubstLookup*> (&(&manifest+manifest[i].lookupOffset));
       if (fallback_plan->lookup_array[j])
       {
-	fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
+	fallback_plan->accel_array[j] = OT::hb_ot_layout_lookup_accelerator_t::create (*fallback_plan->lookup_array[j]);
 	j++;
       }
     }
@@ -302,7 +308,7 @@
       fallback_plan->lookup_array[j] = arabic_fallback_synthesize_lookup (plan, font, i);
       if (fallback_plan->lookup_array[j])
       {
-	fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
+	fallback_plan->accel_array[j] = OT::hb_ot_layout_lookup_accelerator_t::create (*fallback_plan->lookup_array[j]);
 	j++;
       }
     }
@@ -349,7 +355,7 @@
   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
     if (fallback_plan->lookup_array[i])
     {
-      fallback_plan->accel_array[i].fini ();
+      hb_free (fallback_plan->accel_array[i]);
       if (fallback_plan->free_lookups)
 	hb_free (fallback_plan->lookup_array[i]);
     }
@@ -366,9 +372,10 @@
   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
     if (fallback_plan->lookup_array[i]) {
       c.set_lookup_mask (fallback_plan->mask_array[i]);
-      hb_ot_layout_substitute_lookup (&c,
-				      *fallback_plan->lookup_array[i],
-				      fallback_plan->accel_array[i]);
+      if (fallback_plan->accel_array[i])
+	hb_ot_layout_substitute_lookup (&c,
+					*fallback_plan->lookup_array[i],
+					*fallback_plan->accel_array[i]);
     }
 }
 

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-arabic.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -556,9 +556,9 @@
       }
       i++; // Don't touch i again.
 
-      DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%d,%d,%d)",
+      DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%u,%u,%u)",
 		 step == MEASURE ? "measuring" : "cutting", context, start, end);
-      DEBUG_MSG (ARABIC, nullptr, "rest of word:    count=%d width %d", start - context, w_total);
+      DEBUG_MSG (ARABIC, nullptr, "rest of word:    count=%u width %d", start - context, w_total);
       DEBUG_MSG (ARABIC, nullptr, "fixed tiles:     count=%d width=%d", n_fixed, w_fixed);
       DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating);
 
@@ -597,7 +597,7 @@
 	  if (info[k - 1].arabic_shaping_action() == STCH_REPEATING)
 	    repeat += n_copies;
 
-	  DEBUG_MSG (ARABIC, nullptr, "appending %d copies of glyph %d; j=%d",
+	  DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u",
 		     repeat, info[k - 1].codepoint, j);
 	  for (unsigned int n = 0; n < repeat; n++)
 	  {
@@ -675,15 +675,15 @@
 {
   hb_glyph_info_t *info = buffer->info;
 
-  DEBUG_MSG (ARABIC, buffer, "Reordering marks from %d to %d", start, end);
+  DEBUG_MSG (ARABIC, buffer, "Reordering marks from %u to %u", start, end);
 
   unsigned int i = start;
   for (unsigned int cc = 220; cc <= 230; cc += 10)
   {
-    DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d", cc, i);
+    DEBUG_MSG (ARABIC, buffer, "Looking for %u's starting at %u", cc, i);
     while (i < end && info_cc(info[i]) < cc)
       i++;
-    DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d", cc, i);
+    DEBUG_MSG (ARABIC, buffer, "Looking for %u's stopped at %u", cc, i);
 
     if (i == end)
       break;
@@ -698,10 +698,10 @@
     if (i == j)
       continue;
 
-    DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d", cc, i, j);
+    DEBUG_MSG (ARABIC, buffer, "Found %u's from %u to %u", cc, i, j);
 
     /* Shift it! */
-    DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j);
+    DEBUG_MSG (ARABIC, buffer, "Shifting %u's: %u %u", cc, i, j);
     hb_glyph_info_t temp[HB_OT_SHAPE_MAX_COMBINING_MARKS];
     assert (j - i <= ARRAY_LENGTH (temp));
     buffer->merge_clusters (start, j);

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -446,7 +446,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic-machine.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -119,7 +119,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-indic.cc	2023-02-12 04:02:23 UTC (rev 65798)
@@ -482,9 +482,7 @@
       is_one_of (info[start+2], FLAG (I_Cat(ZWJ))))
   {
     buffer->merge_clusters (start+1, start+3);
-    hb_glyph_info_t tmp = info[start+1];
-    info[start+1] = info[start+2];
-    info[start+2] = tmp;
+    hb_swap (info[start+1], info[start+2]);
   }
 
   /* 1. Find base consonant:

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -280,7 +280,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-khmer-machine.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -103,7 +103,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -429,7 +429,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-myanmar-machine.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -118,7 +118,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -835,7 +835,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
     for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shaper-use-machine.rl	2023-02-12 04:02:23 UTC (rev 65798)
@@ -183,7 +183,7 @@
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
-    if (0) fprintf (stderr, "syllable %d..%d %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
+    if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \
     for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     syllable_serial++; \

Modified: trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh
===================================================================
--- trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2023-02-12 00:49:45 UTC (rev 65797)
+++ trunk/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh	2023-02-12 04:02:23 UTC (rev 65798)
@@ -112,7 +112,7 @@
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t<hb_tag_t, float>*  user_axes_location = c->plan->user_axes_location;
+    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -171,7 +171,7 @@
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);

@@ Diff output truncated at 1234567 characters. @@


More information about the tex-live-commits mailing list.